You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
2.3 KiB
101 lines
2.3 KiB
/* |
|
* Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#define DT_DRV_COMPAT espressif_esp32_dac |
|
|
|
#include <soc.h> |
|
#include <zephyr/device.h> |
|
#include <zephyr/drivers/dac.h> |
|
#include <zephyr/drivers/clock_control.h> |
|
#include <hal/rtc_io_types.h> |
|
#include <hal/rtc_io_hal.h> |
|
#include <hal/rtc_io_ll.h> |
|
#include "driver/dac.h" |
|
|
|
#include <zephyr/logging/log.h> |
|
LOG_MODULE_REGISTER(esp32_dac, CONFIG_DAC_LOG_LEVEL); |
|
|
|
struct dac_esp32_config { |
|
int irq_source; |
|
const struct device *clock_dev; |
|
clock_control_subsys_t clock_subsys; |
|
}; |
|
|
|
static int dac_esp32_write_value(const struct device *dev, |
|
uint8_t channel, uint32_t value) |
|
{ |
|
ARG_UNUSED(dev); |
|
|
|
dac_output_voltage(channel, value); |
|
|
|
return 0; |
|
} |
|
|
|
static int dac_esp32_channel_setup(const struct device *dev, |
|
const struct dac_channel_cfg *channel_cfg) |
|
{ |
|
ARG_UNUSED(dev); |
|
|
|
if (channel_cfg->channel_id >= SOC_DAC_CHAN_NUM) { |
|
LOG_ERR("Channel %d is not valid", channel_cfg->channel_id); |
|
return -EINVAL; |
|
} |
|
|
|
if (channel_cfg->internal) { |
|
LOG_ERR("Internal channels not supported"); |
|
return -ENOTSUP; |
|
} |
|
|
|
dac_output_enable(channel_cfg->channel_id); |
|
|
|
return 0; |
|
} |
|
|
|
static int dac_esp32_init(const struct device *dev) |
|
{ |
|
const struct dac_esp32_config *cfg = dev->config; |
|
|
|
if (!cfg->clock_dev) { |
|
LOG_ERR("Clock device missing"); |
|
return -EINVAL; |
|
} |
|
|
|
if (!device_is_ready(cfg->clock_dev)) { |
|
LOG_ERR("Clock device not ready"); |
|
return -ENODEV; |
|
} |
|
|
|
if (clock_control_on(cfg->clock_dev, (clock_control_subsys_t)cfg->clock_subsys) != 0) { |
|
LOG_ERR("DAC clock setup failed (%d)", -EIO); |
|
return -EIO; |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
static DEVICE_API(dac, dac_esp32_driver_api) = { |
|
.channel_setup = dac_esp32_channel_setup, |
|
.write_value = dac_esp32_write_value |
|
}; |
|
|
|
#define ESP32_DAC_INIT(id) \ |
|
\ |
|
static const struct dac_esp32_config dac_esp32_config_##id = { \ |
|
.irq_source = DT_INST_IRQN(id), \ |
|
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)), \ |
|
.clock_subsys = (clock_control_subsys_t) DT_INST_CLOCKS_CELL(id, offset), \ |
|
}; \ |
|
\ |
|
DEVICE_DT_INST_DEFINE(id, \ |
|
&dac_esp32_init, \ |
|
NULL, \ |
|
NULL, \ |
|
&dac_esp32_config_##id, \ |
|
POST_KERNEL, \ |
|
CONFIG_DAC_INIT_PRIORITY, \ |
|
&dac_esp32_driver_api); |
|
|
|
DT_INST_FOREACH_STATUS_OKAY(ESP32_DAC_INIT);
|
|
|