1 /*
2 * Copyright (c) 2023 Caspar Friedrich <c.s.w.friedrich@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdint.h>
8
9 #include <zephyr/devicetree.h>
10 #include <zephyr/drivers/adc.h>
11 #include <zephyr/drivers/i2c.h>
12 #include <zephyr/kernel.h>
13 #include <zephyr/logging/log.h>
14 #include <zephyr/sys/byteorder.h>
15
16 #define ADC_CONTEXT_USES_KERNEL_TIMER
17
18 /*
19 * This requires to be included _after_ `#define ADC_CONTEXT_USES_KERNEL_TIMER`
20 */
21 #include "adc_context.h"
22
23 #define DT_DRV_COMPAT ti_tla2021
24
25 LOG_MODULE_REGISTER(tla2021, CONFIG_ADC_LOG_LEVEL);
26
27 #define ACQ_THREAD_PRIORITY CONFIG_ADC_TLA2021_ACQUISITION_THREAD_PRIORITY
28 #define ACQ_THREAD_STACK_SIZE CONFIG_ADC_TLA2021_ACQUISITION_THREAD_STACK_SIZE
29
30 #define ADC_CHANNEL_msk BIT(0)
31 #define ADC_RESOLUTION 12
32
33 /*
34 * Conversion Data Register (RP = 00h) [reset = 0000h]
35 */
36 #define REG_DATA 0x00
37 #define REG_DATA_pos 4
38
39 /*
40 * Configuration Register (RP = 01h) [reset = 8583h]
41 */
42 #define REG_CONFIG 0x01
43 #define REG_CONFIG_DEFAULT 0x8583
44 #define REG_CONFIG_DR_pos 5
45 #define REG_CONFIG_MODE_pos 8
46 #define REG_CONFIG_PGA_pos 9 /* TLA2022 and TLA2024 Only */
47 #define REG_CONFIG_MUX_pos 12 /* TLA2024 Only */
48 #define REG_CONFIG_OS_pos 15
49 #define REG_CONFIG_OS_msk (BIT_MASK(1) << REG_CONFIG_OS_pos)
50
51 typedef int16_t tla2021_reg_data_t;
52 typedef uint16_t tla2021_reg_config_t;
53
54 struct tla2021_config {
55 const struct i2c_dt_spec bus;
56 k_tid_t acq_thread_id;
57 };
58
59 struct tla2021_data {
60 const struct device *dev;
61 struct adc_context ctx;
62 struct k_sem acq_lock;
63 tla2021_reg_data_t *buffer;
64 tla2021_reg_data_t *repeat_buffer;
65
66 /*
67 * Shadow register
68 */
69 tla2021_reg_config_t reg_config;
70 };
71
tla2021_read_register(const struct device * dev,uint8_t reg,uint16_t * value)72 static int tla2021_read_register(const struct device *dev, uint8_t reg, uint16_t *value)
73 {
74 int ret;
75
76 const struct tla2021_config *config = dev->config;
77 uint8_t tmp[2];
78
79 ret = i2c_write_read_dt(&config->bus, ®, sizeof(reg), tmp, sizeof(tmp));
80 if (ret) {
81 return ret;
82 }
83
84 *value = sys_get_be16(tmp);
85
86 return 0;
87 }
88
tla2021_write_register(const struct device * dev,uint8_t reg,uint16_t value)89 static int tla2021_write_register(const struct device *dev, uint8_t reg, uint16_t value)
90 {
91 int ret;
92
93 const struct tla2021_config *config = dev->config;
94 uint8_t tmp[3] = {reg};
95
96 sys_put_be16(value, &tmp[1]);
97
98 ret = i2c_write_dt(&config->bus, tmp, sizeof(tmp));
99 if (ret) {
100 return ret;
101 }
102
103 return 0;
104 }
105
tla2021_channel_setup(const struct device * dev,const struct adc_channel_cfg * cfg)106 static int tla2021_channel_setup(const struct device *dev, const struct adc_channel_cfg *cfg)
107 {
108 if (cfg->gain != ADC_GAIN_1) {
109 LOG_ERR("Invalid gain");
110 return -EINVAL;
111 }
112
113 if (cfg->reference != ADC_REF_INTERNAL) {
114 LOG_ERR("Invalid reference");
115 return -EINVAL;
116 }
117
118 if (cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
119 LOG_ERR("Invalid acquisition time");
120 return -EINVAL;
121 }
122
123 return 0;
124 }
125
tla2021_start_read(const struct device * dev,const struct adc_sequence * seq)126 static int tla2021_start_read(const struct device *dev, const struct adc_sequence *seq)
127 {
128 struct tla2021_data *data = dev->data;
129
130 const size_t num_extra_samples = seq->options ? seq->options->extra_samplings : 0;
131 const size_t num_samples = (1 + num_extra_samples) * POPCOUNT(seq->channels);
132
133 if (!(seq->channels & ADC_CHANNEL_msk)) {
134 LOG_ERR("Selected channel(s) not supported: %x", seq->channels);
135 return -EINVAL;
136 }
137
138 if (seq->resolution != ADC_RESOLUTION) {
139 LOG_ERR("Selected resolution not supported: %d", seq->resolution);
140 return -EINVAL;
141 }
142
143 if (seq->oversampling) {
144 LOG_ERR("Oversampling is not supported");
145 return -EINVAL;
146 }
147
148 if (seq->calibrate) {
149 LOG_ERR("Calibration is not supported");
150 return -EINVAL;
151 }
152
153 if (!seq->buffer) {
154 LOG_ERR("Buffer invalid");
155 return -EINVAL;
156 }
157
158 if (seq->buffer_size < (num_samples * sizeof(tla2021_reg_data_t))) {
159 LOG_ERR("buffer size too small");
160 return -EINVAL;
161 }
162
163 data->buffer = seq->buffer;
164
165 adc_context_start_read(&data->ctx, seq);
166
167 return adc_context_wait_for_completion(&data->ctx);
168 }
169
tla2021_read_async(const struct device * dev,const struct adc_sequence * seq,struct k_poll_signal * async)170 static int tla2021_read_async(const struct device *dev, const struct adc_sequence *seq,
171 struct k_poll_signal *async)
172 {
173 int ret;
174
175 struct tla2021_data *data = dev->data;
176
177 adc_context_lock(&data->ctx, async ? true : false, async);
178 ret = tla2021_start_read(dev, seq);
179 adc_context_release(&data->ctx, ret);
180
181 return ret;
182 }
183
tla2021_read(const struct device * dev,const struct adc_sequence * seq)184 static int tla2021_read(const struct device *dev, const struct adc_sequence *seq)
185 {
186 return tla2021_read_async(dev, seq, NULL);
187 }
188
adc_context_start_sampling(struct adc_context * ctx)189 static void adc_context_start_sampling(struct adc_context *ctx)
190 {
191 int ret;
192
193 struct tla2021_data *data = CONTAINER_OF(ctx, struct tla2021_data, ctx);
194 const struct device *dev = data->dev;
195
196 tla2021_reg_config_t reg = data->reg_config;
197
198 /*
199 * Start single-shot conversion
200 */
201 WRITE_BIT(reg, REG_CONFIG_MODE_pos, 1);
202 WRITE_BIT(reg, REG_CONFIG_OS_pos, 1);
203 ret = tla2021_write_register(dev, REG_CONFIG, reg);
204 if (ret) {
205 LOG_WRN("Failed to start conversion");
206 }
207
208 data->repeat_buffer = data->buffer;
209
210 k_sem_give(&data->acq_lock);
211 }
212
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)213 static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling)
214 {
215 struct tla2021_data *data = CONTAINER_OF(ctx, struct tla2021_data, ctx);
216
217 if (repeat_sampling) {
218 data->buffer = data->repeat_buffer;
219 }
220 }
221
tla2021_acq_thread_fn(void * p1,void * p2,void * p3)222 static void tla2021_acq_thread_fn(void *p1, void *p2, void *p3)
223 {
224 int ret;
225
226 struct tla2021_data *data = p1;
227 const struct device *dev = data->dev;
228
229 while (true) {
230 k_sem_take(&data->acq_lock, K_FOREVER);
231
232 tla2021_reg_config_t reg;
233 tla2021_reg_data_t res;
234
235 /*
236 * Wait until sampling is done
237 */
238 do {
239 ret = tla2021_read_register(dev, REG_CONFIG, ®);
240 if (ret < 0) {
241 adc_context_complete(&data->ctx, ret);
242 }
243 } while (!(reg & REG_CONFIG_OS_msk));
244
245 /*
246 * Read result
247 */
248 ret = tla2021_read_register(dev, REG_DATA, &res);
249 if (ret) {
250 adc_context_complete(&data->ctx, ret);
251 }
252
253 /*
254 * ADC data is stored in the upper 12 bits
255 */
256 res >>= REG_DATA_pos;
257 *data->buffer++ = res;
258
259 adc_context_on_sampling_done(&data->ctx, data->dev);
260 }
261 }
262
tla2021_init(const struct device * dev)263 static int tla2021_init(const struct device *dev)
264 {
265 int ret;
266
267 const struct tla2021_config *config = dev->config;
268 struct tla2021_data *data = dev->data;
269
270 k_sem_init(&data->acq_lock, 0, 1);
271
272 if (!i2c_is_ready_dt(&config->bus)) {
273 LOG_ERR("Bus not ready");
274 return -EINVAL;
275 }
276
277 ret = tla2021_write_register(dev, REG_CONFIG, data->reg_config);
278 if (ret) {
279 LOG_ERR("Device reset failed: %d", ret);
280 return ret;
281 }
282
283 adc_context_unlock_unconditionally(&data->ctx);
284
285 return 0;
286 }
287
288 static const struct adc_driver_api tla2021_driver_api = {
289 .channel_setup = tla2021_channel_setup,
290 .read = tla2021_read,
291 .ref_internal = 2048,
292 #ifdef CONFIG_ADC_ASYNC
293 .read_async = tla2021_read_async,
294 #endif
295 };
296
297 #define TLA2021_INIT(n) \
298 static const struct tla2021_config inst_##n##_config; \
299 static struct tla2021_data inst_##n##_data; \
300 K_THREAD_DEFINE(inst_##n##_thread, ACQ_THREAD_STACK_SIZE, tla2021_acq_thread_fn, \
301 &inst_##n##_data, NULL, NULL, ACQ_THREAD_PRIORITY, 0, 0); \
302 static const struct tla2021_config inst_##n##_config = { \
303 .bus = I2C_DT_SPEC_INST_GET(n), \
304 .acq_thread_id = inst_##n##_thread, \
305 }; \
306 static struct tla2021_data inst_##n##_data = { \
307 .dev = DEVICE_DT_INST_GET(n), \
308 ADC_CONTEXT_INIT_LOCK(inst_##n##_data, ctx), \
309 ADC_CONTEXT_INIT_TIMER(inst_##n##_data, ctx), \
310 ADC_CONTEXT_INIT_SYNC(inst_##n##_data, ctx), \
311 .reg_config = REG_CONFIG_DEFAULT, \
312 }; \
313 DEVICE_DT_INST_DEFINE(n, &tla2021_init, NULL, &inst_##n##_data, &inst_##n##_config, \
314 POST_KERNEL, CONFIG_ADC_TLA2021_INIT_PRIORITY, &tla2021_driver_api);
315
316 DT_INST_FOREACH_STATUS_OKAY(TLA2021_INIT)
317
318 BUILD_ASSERT(CONFIG_I2C_INIT_PRIORITY < CONFIG_ADC_TLA2021_INIT_PRIORITY);
319