Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 1 | /* |
| 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-Paretas | 79e6b0e | 2022-08-25 09:58:46 +0200 | [diff] [blame] | 9 | #include <zephyr/kernel.h> |
Gerard Marull-Paretas | fb60aab | 2022-05-06 10:25:46 +0200 | [diff] [blame] | 10 | #include <zephyr/drivers/dac.h> |
| 11 | #include <zephyr/logging/log.h> |
| 12 | #include <zephyr/drivers/pinctrl.h> |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 13 | |
| 14 | #include <fsl_dac32.h> |
| 15 | |
| 16 | LOG_MODULE_REGISTER(dac_mcux_dac32, CONFIG_DAC_LOG_LEVEL); |
| 17 | |
| 18 | struct mcux_dac32_config { |
| 19 | DAC_Type *base; |
| 20 | dac32_reference_voltage_source_t reference; |
| 21 | bool buffered; |
| 22 | bool low_power; |
Daniel DeGrasse | 9e12d23 | 2022-03-08 14:43:29 -0600 | [diff] [blame] | 23 | const struct pinctrl_dev_config *pincfg; |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 24 | }; |
| 25 | |
| 26 | struct mcux_dac32_data { |
| 27 | bool configured; |
| 28 | }; |
| 29 | |
Tomasz Bursztyka | e18fcbb | 2020-04-30 20:33:38 +0200 | [diff] [blame] | 30 | static int mcux_dac32_channel_setup(const struct device *dev, |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 31 | const struct dac_channel_cfg *channel_cfg) |
| 32 | { |
Tomasz Bursztyka | af6140c | 2020-05-28 20:44:16 +0200 | [diff] [blame] | 33 | const struct mcux_dac32_config *config = dev->config; |
Tomasz Bursztyka | 98d9b01 | 2020-05-28 21:23:02 +0200 | [diff] [blame] | 34 | struct mcux_dac32_data *data = dev->data; |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 35 | 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 Andersen | 6494ce2 | 2020-05-22 10:10:26 +0200 | [diff] [blame] | 54 | DAC32_EnableTestOutput(config->base, |
| 55 | IS_ENABLED(CONFIG_DAC_MCUX_DAC32_TESTOUT)); |
| 56 | |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 57 | data->configured = true; |
| 58 | |
| 59 | return 0; |
| 60 | } |
| 61 | |
Tomasz Bursztyka | e18fcbb | 2020-04-30 20:33:38 +0200 | [diff] [blame] | 62 | static int mcux_dac32_write_value(const struct device *dev, uint8_t channel, |
| 63 | uint32_t value) |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 64 | { |
Tomasz Bursztyka | af6140c | 2020-05-28 20:44:16 +0200 | [diff] [blame] | 65 | const struct mcux_dac32_config *config = dev->config; |
Tomasz Bursztyka | 98d9b01 | 2020-05-28 21:23:02 +0200 | [diff] [blame] | 66 | struct mcux_dac32_data *data = dev->data; |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 67 | |
| 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 Bursztyka | e18fcbb | 2020-04-30 20:33:38 +0200 | [diff] [blame] | 92 | static int mcux_dac32_init(const struct device *dev) |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 93 | { |
Daniel DeGrasse | 9e12d23 | 2022-03-08 14:43:29 -0600 | [diff] [blame] | 94 | const struct mcux_dac32_config *config = dev->config; |
| 95 | |
| 96 | return pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 97 | } |
| 98 | |
| 99 | static 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 DeGrasse | 9e12d23 | 2022-03-08 14:43:29 -0600 | [diff] [blame] | 110 | PINCTRL_DT_INST_DEFINE(n); \ |
| 111 | \ |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 112 | 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 DeGrasse | 9e12d23 | 2022-03-08 14:43:29 -0600 | [diff] [blame] | 118 | .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 119 | }; \ |
| 120 | \ |
Gerard Marull-Paretas | ed97e6d | 2021-04-28 10:29:41 +0200 | [diff] [blame] | 121 | DEVICE_DT_INST_DEFINE(n, mcux_dac32_init, NULL, \ |
Kumar Gala | 6808d29 | 2020-12-14 10:40:18 -0600 | [diff] [blame] | 122 | &mcux_dac32_data_##n, \ |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 123 | &mcux_dac32_config_##n, \ |
Maureen Helm | 9eef764 | 2021-10-25 19:13:48 -0500 | [diff] [blame] | 124 | POST_KERNEL, CONFIG_DAC_INIT_PRIORITY, \ |
Kumar Gala | 0a7d4e2 | 2020-05-07 14:09:05 -0500 | [diff] [blame] | 125 | &mcux_dac32_driver_api); |
Henrik Brix Andersen | 20b565a | 2020-02-16 13:58:28 +0100 | [diff] [blame] | 126 | |
Martí Bolívar | 7e0eed9 | 2020-05-06 11:23:07 -0700 | [diff] [blame] | 127 | DT_INST_FOREACH_STATUS_OKAY(MCUX_DAC32_INIT) |