blob: 35d80dbda13fdfadf484c0cd1da7a138f7b6e34b [file] [log] [blame]
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +01001/*
2 * Copyright (c) 2020 Henrik Brix Andersen <henrik@brixandersen.dk>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#define DT_DRV_COMPAT nxp_kinetis_dac32
8
Gerard Marull-Paretas79e6b0e2022-08-25 09:58:46 +02009#include <zephyr/kernel.h>
Gerard Marull-Paretasfb60aab2022-05-06 10:25:46 +020010#include <zephyr/drivers/dac.h>
11#include <zephyr/logging/log.h>
12#include <zephyr/drivers/pinctrl.h>
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +010013
14#include <fsl_dac32.h>
15
16LOG_MODULE_REGISTER(dac_mcux_dac32, CONFIG_DAC_LOG_LEVEL);
17
18struct mcux_dac32_config {
19 DAC_Type *base;
20 dac32_reference_voltage_source_t reference;
21 bool buffered;
22 bool low_power;
Daniel DeGrasse9e12d232022-03-08 14:43:29 -060023 const struct pinctrl_dev_config *pincfg;
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +010024};
25
26struct mcux_dac32_data {
27 bool configured;
28};
29
Tomasz Bursztykae18fcbb2020-04-30 20:33:38 +020030static int mcux_dac32_channel_setup(const struct device *dev,
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +010031 const struct dac_channel_cfg *channel_cfg)
32{
Tomasz Bursztykaaf6140c2020-05-28 20:44:16 +020033 const struct mcux_dac32_config *config = dev->config;
Tomasz Bursztyka98d9b012020-05-28 21:23:02 +020034 struct mcux_dac32_data *data = dev->data;
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +010035 dac32_config_t dac32_config;
36
37 if (channel_cfg->channel_id != 0) {
38 LOG_ERR("unsupported channel %d", channel_cfg->channel_id);
39 return -ENOTSUP;
40 }
41
42 if (channel_cfg->resolution != 12) {
43 LOG_ERR("unsupported resolution %d", channel_cfg->resolution);
44 return -ENOTSUP;
45 }
46
47 DAC32_GetDefaultConfig(&dac32_config);
48 dac32_config.enableLowPowerMode = config->low_power;
49 dac32_config.referenceVoltageSource = config->reference;
50
51 DAC32_Init(config->base, &dac32_config);
52 DAC32_EnableBufferOutput(config->base, config->buffered);
53
Henrik Brix Andersen6494ce22020-05-22 10:10:26 +020054 DAC32_EnableTestOutput(config->base,
55 IS_ENABLED(CONFIG_DAC_MCUX_DAC32_TESTOUT));
56
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +010057 data->configured = true;
58
59 return 0;
60}
61
Tomasz Bursztykae18fcbb2020-04-30 20:33:38 +020062static int mcux_dac32_write_value(const struct device *dev, uint8_t channel,
63 uint32_t value)
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +010064{
Tomasz Bursztykaaf6140c2020-05-28 20:44:16 +020065 const struct mcux_dac32_config *config = dev->config;
Tomasz Bursztyka98d9b012020-05-28 21:23:02 +020066 struct mcux_dac32_data *data = dev->data;
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +010067
68 if (!data->configured) {
69 LOG_ERR("channel not initialized");
70 return -EINVAL;
71 }
72
73 if (channel != 0) {
74 LOG_ERR("unsupported channel %d", channel);
75 return -ENOTSUP;
76 }
77
78 if (value >= 4096) {
79 LOG_ERR("value %d out of range", value);
80 return -EINVAL;
81 }
82
83 /* Static operation */
84 DAC32_EnableBuffer(config->base, false);
85
86 DAC32_SetBufferValue(config->base, 0, value);
87 DAC32_Enable(config->base, true);
88
89 return 0;
90}
91
Tomasz Bursztykae18fcbb2020-04-30 20:33:38 +020092static int mcux_dac32_init(const struct device *dev)
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +010093{
Daniel DeGrasse9e12d232022-03-08 14:43:29 -060094 const struct mcux_dac32_config *config = dev->config;
95
96 return pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +010097}
98
99static const struct dac_driver_api mcux_dac32_driver_api = {
100 .channel_setup = mcux_dac32_channel_setup,
101 .write_value = mcux_dac32_write_value,
102};
103
104#define TO_DAC32_VREF_SRC(val) \
105 _DO_CONCAT(kDAC32_ReferenceVoltageSourceVref, val)
106
107#define MCUX_DAC32_INIT(n) \
108 static struct mcux_dac32_data mcux_dac32_data_##n; \
109 \
Daniel DeGrasse9e12d232022-03-08 14:43:29 -0600110 PINCTRL_DT_INST_DEFINE(n); \
111 \
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +0100112 static const struct mcux_dac32_config mcux_dac32_config_##n = { \
113 .base = (DAC_Type *)DT_INST_REG_ADDR(n), \
114 .reference = \
115 TO_DAC32_VREF_SRC(DT_INST_PROP(n, voltage_reference)), \
116 .buffered = DT_INST_PROP(n, buffered), \
117 .low_power = DT_INST_PROP(n, low_power_mode), \
Daniel DeGrasse9e12d232022-03-08 14:43:29 -0600118 .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +0100119 }; \
120 \
Gerard Marull-Paretased97e6d2021-04-28 10:29:41 +0200121 DEVICE_DT_INST_DEFINE(n, mcux_dac32_init, NULL, \
Kumar Gala6808d292020-12-14 10:40:18 -0600122 &mcux_dac32_data_##n, \
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +0100123 &mcux_dac32_config_##n, \
Maureen Helm9eef7642021-10-25 19:13:48 -0500124 POST_KERNEL, CONFIG_DAC_INIT_PRIORITY, \
Kumar Gala0a7d4e22020-05-07 14:09:05 -0500125 &mcux_dac32_driver_api);
Henrik Brix Andersen20b565a2020-02-16 13:58:28 +0100126
Martí Bolívar7e0eed92020-05-06 11:23:07 -0700127DT_INST_FOREACH_STATUS_OKAY(MCUX_DAC32_INIT)