From 2ffead788b8739dde01b0bc28d6f4631445286be Mon Sep 17 00:00:00 2001 From: Albort Xue Date: Mon, 14 Aug 2023 14:08:26 +0800 Subject: [PATCH] drivers: dac: Add driver for mcux lpdac Create dac_mcxu_lpdac.c file to implement mcux lpdac, add binding for the mcux lpdac, update Kconfig.mcux and CMakeLists.txt file to support mcux lpdac. Signed-off-by: Albort Xue --- drivers/dac/CMakeLists.txt | 1 + drivers/dac/Kconfig.mcux | 7 +++ drivers/dac/dac_mcux_lpdac.c | 107 ++++++++++++++++++++++++++++++++ dts/bindings/dac/nxp,lpdac.yaml | 29 +++++++++ 4 files changed, 144 insertions(+) create mode 100644 drivers/dac/dac_mcux_lpdac.c create mode 100644 dts/bindings/dac/nxp,lpdac.yaml diff --git a/drivers/dac/CMakeLists.txt b/drivers/dac/CMakeLists.txt index 7cce3c8e7c..d2164f92d7 100644 --- a/drivers/dac/CMakeLists.txt +++ b/drivers/dac/CMakeLists.txt @@ -4,6 +4,7 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/dac.h) zephyr_library() +zephyr_library_sources_ifdef(CONFIG_DAC_MCUX_LPDAC dac_mcux_lpdac.c) zephyr_library_sources_ifdef(CONFIG_DAC_MCUX_DAC dac_mcux_dac.c) zephyr_library_sources_ifdef(CONFIG_DAC_MCUX_DAC32 dac_mcux_dac32.c) zephyr_library_sources_ifdef(CONFIG_DAC_STM32 dac_stm32.c) diff --git a/drivers/dac/Kconfig.mcux b/drivers/dac/Kconfig.mcux index e02d498f50..87869775d0 100644 --- a/drivers/dac/Kconfig.mcux +++ b/drivers/dac/Kconfig.mcux @@ -19,6 +19,13 @@ config DAC_MCUX_DAC32 help Enable the driver for the NXP Kinetis MCUX DAC32. +config DAC_MCUX_LPDAC + bool "NXP MCUX LPDAC driver" + default y + depends on DT_HAS_NXP_LPDAC_ENABLED + help + Enable the driver for the NXP MCUX LPDAC. + config DAC_MCUX_DAC32_TESTOUT bool "DAC test output" depends on DAC_MCUX_DAC32 diff --git a/drivers/dac/dac_mcux_lpdac.c b/drivers/dac/dac_mcux_lpdac.c new file mode 100644 index 0000000000..d65624940e --- /dev/null +++ b/drivers/dac/dac_mcux_lpdac.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2020 Henrik Brix Andersen + * Copyright (c) 2023, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT nxp_lpdac + +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(dac_mcux_lpdac, CONFIG_DAC_LOG_LEVEL); + +struct mcux_lpdac_config { + LPDAC_Type *base; + dac_reference_voltage_source_t ref_voltage; + bool low_power; +}; + +struct mcux_lpdac_data { + bool configured; +}; + +static int mcux_lpdac_channel_setup(const struct device *dev, + const struct dac_channel_cfg *channel_cfg) +{ + const struct mcux_lpdac_config *config = dev->config; + struct mcux_lpdac_data *data = dev->data; + dac_config_t dac_config; + + if (channel_cfg->channel_id != 0) { + LOG_ERR("unsupported channel %d", channel_cfg->channel_id); + return -ENOTSUP; + } + + if (channel_cfg->resolution != 12) { + LOG_ERR("unsupported resolution %d", channel_cfg->resolution); + return -ENOTSUP; + } + + DAC_GetDefaultConfig(&dac_config); + dac_config.referenceVoltageSource = config->ref_voltage; +#if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL + dac_config.enableLowerLowPowerMode = config->low_power; +#else + dac_config.enableLowPowerMode = config->low_power; +#endif + DAC_Init(config->base, &dac_config); + DAC_Enable(config->base, false); + data->configured = true; + + return 0; +} + +static int mcux_lpdac_write_value(const struct device *dev, uint8_t channel, uint32_t value) +{ + const struct mcux_lpdac_config *config = dev->config; + struct mcux_lpdac_data *data = dev->data; + + if (!data->configured) { + LOG_ERR("channel not initialized"); + return -EINVAL; + } + + if (channel != 0) { + LOG_ERR("unsupported channel %d", channel); + return -ENOTSUP; + } + + if (value >= 4096) { + LOG_ERR("unsupported value %d", value); + return -EINVAL; + } + + DAC_Enable(config->base, true); + DAC_SetData(config->base, value); + + return 0; +} + +static int mcux_lpdac_init(const struct device *dev) +{ + return 0; +} + +static const struct dac_driver_api mcux_lpdac_driver_api = { + .channel_setup = mcux_lpdac_channel_setup, + .write_value = mcux_lpdac_write_value, +}; + +#define MCUX_LPDAC_INIT(n) \ + static struct mcux_lpdac_data mcux_lpdac_data_##n; \ + \ + static const struct mcux_lpdac_config mcux_lpdac_config_##n = { \ + .base = (LPDAC_Type *)DT_INST_REG_ADDR(n), \ + .ref_voltage = DT_INST_PROP(n, voltage_reference), \ + .low_power = DT_INST_PROP(n, low_power_mode), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, mcux_lpdac_init, NULL, &mcux_lpdac_data_##n, \ + &mcux_lpdac_config_##n, POST_KERNEL, CONFIG_DAC_INIT_PRIORITY, \ + &mcux_lpdac_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(MCUX_LPDAC_INIT) diff --git a/dts/bindings/dac/nxp,lpdac.yaml b/dts/bindings/dac/nxp,lpdac.yaml new file mode 100644 index 0000000000..2a79af254b --- /dev/null +++ b/dts/bindings/dac/nxp,lpdac.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2023, NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP MCUX LPDAC + +compatible: "nxp,lpdac" + +include: dac-controller.yaml + +properties: + reg: + required: true + + voltage-reference: + type: int + required: true + description: | + DAC voltage reference select. The meaning of the value may be + different for different SoCs. + + low-power-mode: + type: boolean + description: Enable low-power mode + + "#io-channel-cells": + const: 1 + +io-channel-cells: + - output