1 /*
2 * Copyright (c) 2024 Renesas Electronics Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT renesas_ra_adc
8
9 #include <zephyr/drivers/adc.h>
10 #include <zephyr/drivers/clock_control.h>
11 #include <zephyr/drivers/pinctrl.h>
12 #include <zephyr/drivers/reset.h>
13 #include <zephyr/logging/log.h>
14 #include <zephyr/sys/util_internal.h>
15 #include <instances/r_adc.h>
16
17 #include <zephyr/irq.h>
18
19 LOG_MODULE_REGISTER(adc_ra, CONFIG_ADC_LOG_LEVEL);
20
21 #define ADC_CONTEXT_USES_KERNEL_TIMER
22 #include "adc_context.h"
23
24 #define ADC_RA_MAX_RESOLUTION 12
25 #define ADC_AVERAGE_1 ADC_ADD_OFF
26 #define ADC_AVERAGE_2 ADC_ADD_AVERAGE_TWO
27 #define ADC_AVERAGE_4 ADC_ADD_AVERAGE_FOUR
28 #define ADC_AVERAGE_8 ADC_ADD_AVERAGE_EIGHT
29 #define ADC_AVERAGE_16 ADC_ADD_AVERAGE_SIXTEEN
30
31 void adc_scan_end_isr(void);
32
33 /**
34 * @brief RA ADC config
35 *
36 * This structure contains constant data for given instance of RA ADC.
37 */
38 struct adc_ra_config {
39 /** Number of supported channels */
40 uint8_t num_channels;
41 /** Mask for channels existed in each board */
42 uint32_t channel_available_mask;
43 /** pinctrl configs */
44 const struct pinctrl_dev_config *pcfg;
45 /** function pointer to irq setup */
46 void (*irq_configure)(void);
47 };
48
49 /**
50 * @brief RA ADC data
51 *
52 * This structure contains data structures used by a RA ADC.
53 */
54 struct adc_ra_data {
55 /** Structure that handle state of ongoing read operation */
56 struct adc_context ctx;
57 /** Pointer to RA ADC own device structure */
58 const struct device *dev;
59 /** Structure that handle fsp ADC */
60 adc_instance_ctrl_t adc;
61 /** Structure that handle fsp ADC config */
62 struct st_adc_cfg f_config;
63 /** Structure that handle fsp ADC channel config */
64 adc_channel_cfg_t f_channel_cfg;
65 /** Pointer to memory where next sample will be written */
66 uint16_t *buf;
67 /** Mask with channels that will be sampled */
68 uint32_t channels;
69 /** Buffer id */
70 uint16_t buf_id;
71 };
72
73 /**
74 * @brief Setup channels before starting to scan ADC
75 *
76 * @param dev RA ADC device
77 * @param channel_cfg channel configuration
78 *
79 * @return 0 on success
80 * @return -ENOTSUP if channel id or differential is wrong value
81 * @return -EINVAL if channel configuration is invalid
82 */
adc_ra_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)83 static int adc_ra_channel_setup(const struct device *dev, const struct adc_channel_cfg *channel_cfg)
84 {
85 fsp_err_t fsp_err = FSP_SUCCESS;
86 struct adc_ra_data *data = dev->data;
87 const struct adc_ra_config *config = dev->config;
88
89 if (!((config->channel_available_mask & (1 << channel_cfg->channel_id)) != 0)) {
90 LOG_ERR("unsupported channel id '%d'", channel_cfg->channel_id);
91 return -ENOTSUP;
92 }
93
94 if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
95 LOG_ERR("Acquisition time is not valid");
96 return -EINVAL;
97 }
98
99 if (channel_cfg->differential) {
100 LOG_ERR("unsupported differential mode");
101 return -ENOTSUP;
102 }
103
104 if (channel_cfg->gain != ADC_GAIN_1) {
105 LOG_ERR("Gain is not valid");
106 return -EINVAL;
107 }
108
109 data->f_channel_cfg.scan_mask |= (1U << channel_cfg->channel_id);
110 /* Configure ADC channel specific settings */
111 fsp_err = R_ADC_ScanCfg(&data->adc, &data->f_channel_cfg);
112 if (FSP_SUCCESS != fsp_err) {
113 return -ENOTSUP;
114 }
115
116 return 0;
117 }
118
119 /**
120 * Interrupt handler
121 */
adc_ra_isr(const struct device * dev)122 static void adc_ra_isr(const struct device *dev)
123 {
124 struct adc_ra_data *data = dev->data;
125 fsp_err_t fsp_err = FSP_SUCCESS;
126 adc_channel_t channel_id = 0;
127 uint32_t channels = 0;
128 int16_t *sample_buffer = (int16_t *)data->buf;
129
130 channels = data->channels;
131 for (channel_id = 0; channels > 0; channel_id++) {
132 /* Check if it is right channel id */
133 if ((channels & 0x01) != 0) {
134 fsp_err = R_ADC_Read(&data->adc, channel_id, &sample_buffer[data->buf_id]);
135 if (FSP_SUCCESS != fsp_err) {
136 break;
137 }
138 data->buf_id = data->buf_id + 1;
139 }
140
141 channels = channels >> 1;
142 }
143 adc_scan_end_isr();
144 adc_context_on_sampling_done(&data->ctx, dev);
145 }
146
147 /**
148 * @brief Check if buffer in @p sequence is big enough to hold all ADC samples
149 *
150 * @param dev RA ADC device
151 * @param sequence ADC sequence description
152 *
153 * @return 0 on success
154 * @return -ENOMEM if buffer is not big enough
155 */
adc_ra_check_buffer_size(const struct device * dev,const struct adc_sequence * sequence)156 static int adc_ra_check_buffer_size(const struct device *dev, const struct adc_sequence *sequence)
157 {
158 const struct adc_ra_config *config = dev->config;
159 uint8_t channels = 0;
160 size_t needed;
161 uint32_t mask;
162
163 for (mask = BIT(config->num_channels - 1); mask != 0; mask >>= 1) {
164 if (mask & sequence->channels) {
165 channels++;
166 }
167 }
168
169 needed = channels * sizeof(uint16_t);
170 if (sequence->options) {
171 needed *= (1 + sequence->options->extra_samplings);
172 }
173
174 if (sequence->buffer_size < needed) {
175 return -ENOMEM;
176 }
177
178 return 0;
179 }
180
181 /**
182 * @brief Start processing read request
183 *
184 * @param dev RA ADC device
185 * @param sequence ADC sequence description
186 *
187 * @return 0 on success
188 * @return -ENOTSUP if requested resolution or channel is out side of supported
189 * range
190 * @return -ENOMEM if buffer is not big enough
191 * (see @ref adc_ra_check_buffer_size)
192 * @return other error code returned by adc_context_wait_for_completion
193 */
adc_ra_start_read(const struct device * dev,const struct adc_sequence * sequence)194 static int adc_ra_start_read(const struct device *dev, const struct adc_sequence *sequence)
195 {
196 const struct adc_ra_config *config = dev->config;
197 struct adc_ra_data *data = dev->data;
198 int err;
199
200 if (sequence->resolution > ADC_RA_MAX_RESOLUTION || sequence->resolution == 0) {
201 LOG_ERR("unsupported resolution %d", sequence->resolution);
202 return -ENOTSUP;
203 }
204
205 if (find_msb_set(sequence->channels) > config->num_channels) {
206 LOG_ERR("unsupported channels in mask: 0x%08x", sequence->channels);
207 return -ENOTSUP;
208 }
209
210 err = adc_ra_check_buffer_size(dev, sequence);
211 if (err) {
212 LOG_ERR("buffer size too small");
213 return err;
214 }
215
216 data->buf_id = 0;
217 data->buf = sequence->buffer;
218 adc_context_start_read(&data->ctx, sequence);
219
220 adc_context_wait_for_completion(&data->ctx);
221
222 return 0;
223 }
224
225 /**
226 * @brief Start processing read request asynchronously
227 *
228 * @param dev RA ADC device
229 * @param sequence ADC sequence description
230 * @param async async pointer to asynchronous signal
231 *
232 * @return 0 on success
233 * @return -ENOTSUP if requested resolution or channel is out side of supported
234 * range
235 * @return -ENOMEM if buffer is not big enough
236 * (see @ref adc_ra_check_buffer_size)
237 * @return other error code returned by adc_context_wait_for_completion
238 */
adc_ra_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)239 static int adc_ra_read_async(const struct device *dev, const struct adc_sequence *sequence,
240 struct k_poll_signal *async)
241 {
242 struct adc_ra_data *data = dev->data;
243 int err;
244
245 adc_context_lock(&data->ctx, async ? true : false, async);
246 err = adc_ra_start_read(dev, sequence);
247 adc_context_release(&data->ctx, err);
248
249 return err;
250 }
251
252 /**
253 * @brief Start processing read request synchronously
254 *
255 * @param dev RA ADC device
256 * @param sequence ADC sequence description
257 *
258 * @return 0 on success
259 * @return -ENOTSUP if requested resolution or channel is out side of supported
260 * range
261 * @return -ENOMEM if buffer is not big enough
262 * (see @ref adc_ra_check_buffer_size)
263 * @return other error code returned by adc_context_wait_for_completion
264 */
adc_ra_read(const struct device * dev,const struct adc_sequence * sequence)265 static int adc_ra_read(const struct device *dev, const struct adc_sequence *sequence)
266 {
267 return adc_ra_read_async(dev, sequence, NULL);
268 }
269
adc_context_start_sampling(struct adc_context * ctx)270 static void adc_context_start_sampling(struct adc_context *ctx)
271 {
272 struct adc_ra_data *data = CONTAINER_OF(ctx, struct adc_ra_data, ctx);
273
274 data->channels = ctx->sequence.channels;
275
276 R_ADC_ScanStart(&data->adc);
277 }
278
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)279 static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling)
280 {
281 struct adc_ra_data *data = CONTAINER_OF(ctx, struct adc_ra_data, ctx);
282
283 if (repeat_sampling) {
284 data->buf_id = 0;
285 }
286 }
287
288 /**
289 * @brief Function called on init for each RA ADC device. It setups all
290 * channels to return constant 0 mV and create acquisition thread.
291 *
292 * @param dev RA ADC device
293 *
294 * @return -EIO if error
295 *
296 * @return 0 on success
297 */
adc_ra_init(const struct device * dev)298 static int adc_ra_init(const struct device *dev)
299 {
300 const struct adc_ra_config *config = dev->config;
301 struct adc_ra_data *data = dev->data;
302 int ret;
303 fsp_err_t fsp_err = FSP_SUCCESS;
304
305 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
306 if (ret < 0) {
307 return ret;
308 }
309
310 /* Open ADC module */
311 fsp_err = R_ADC_Open(&data->adc, &data->f_config);
312 if (FSP_SUCCESS != fsp_err) {
313 return -EIO;
314 }
315
316 config->irq_configure();
317
318 adc_context_unlock_unconditionally(&data->ctx);
319 return 0;
320 }
321
322 #define IRQ_CONFIGURE_FUNC(idx) \
323 static void adc_ra_configure_func_##idx(void) \
324 { \
325 R_ICU->IELSR[DT_INST_IRQ_BY_NAME(idx, scanend, irq)] = \
326 ELC_EVENT_ADC##idx##_SCAN_END; \
327 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(idx, scanend, irq), \
328 DT_INST_IRQ_BY_NAME(idx, scanend, priority), adc_ra_isr, \
329 DEVICE_DT_INST_GET(idx), 0); \
330 irq_enable(DT_INST_IRQ_BY_NAME(idx, scanend, irq)); \
331 }
332
333 #define IRQ_CONFIGURE_DEFINE(idx) .irq_configure = adc_ra_configure_func_##idx
334
335 #define ADC_RA_INIT(idx) \
336 IRQ_CONFIGURE_FUNC(idx) \
337 PINCTRL_DT_INST_DEFINE(idx); \
338 static const adc_extended_cfg_t g_adc_cfg_extend_##idx = { \
339 .add_average_count = UTIL_CAT(ADC_AVERAGE_, DT_INST_PROP(idx, average_count)), \
340 .clearing = ADC_CLEAR_AFTER_READ_ON, \
341 .trigger_group_b = ADC_START_SOURCE_DISABLED, \
342 .double_trigger_mode = ADC_DOUBLE_TRIGGER_DISABLED, \
343 .adc_vref_control = ADC_VREF_CONTROL_VREFH, \
344 .enable_adbuf = 0, \
345 .window_a_irq = FSP_INVALID_VECTOR, \
346 .window_a_ipl = (1), \
347 .window_b_irq = FSP_INVALID_VECTOR, \
348 .window_b_ipl = (BSP_IRQ_DISABLED), \
349 .trigger = ADC_START_SOURCE_DISABLED, \
350 }; \
351 static DEVICE_API(adc, adc_ra_api_##idx) = { \
352 .channel_setup = adc_ra_channel_setup, \
353 .read = adc_ra_read, \
354 .ref_internal = DT_INST_PROP(idx, vref_mv), \
355 IF_ENABLED(CONFIG_ADC_ASYNC, (.read_async = adc_ra_read_async))}; \
356 static const struct adc_ra_config adc_ra_config_##idx = { \
357 .num_channels = DT_INST_PROP(idx, channel_count), \
358 .channel_available_mask = DT_INST_PROP(idx, channel_available_mask), \
359 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
360 IRQ_CONFIGURE_DEFINE(idx), \
361 }; \
362 static struct adc_ra_data adc_ra_data_##idx = { \
363 ADC_CONTEXT_INIT_TIMER(adc_ra_data_##idx, ctx), \
364 ADC_CONTEXT_INIT_LOCK(adc_ra_data_##idx, ctx), \
365 ADC_CONTEXT_INIT_SYNC(adc_ra_data_##idx, ctx), \
366 .dev = DEVICE_DT_INST_GET(idx), \
367 .f_config = \
368 { \
369 .unit = idx, \
370 .mode = ADC_MODE_SINGLE_SCAN, \
371 .resolution = ADC_RESOLUTION_12_BIT, \
372 .alignment = (adc_alignment_t)ADC_ALIGNMENT_RIGHT, \
373 .trigger = 0, \
374 .p_callback = NULL, \
375 .p_context = NULL, \
376 .p_extend = &g_adc_cfg_extend_##idx, \
377 .scan_end_irq = DT_INST_IRQ_BY_NAME(idx, scanend, irq), \
378 .scan_end_ipl = DT_INST_IRQ_BY_NAME(idx, scanend, priority), \
379 .scan_end_b_irq = FSP_INVALID_VECTOR, \
380 .scan_end_b_ipl = (BSP_IRQ_DISABLED), \
381 }, \
382 .f_channel_cfg = \
383 { \
384 .scan_mask = 0, \
385 .scan_mask_group_b = 0, \
386 .priority_group_a = ADC_GROUP_A_PRIORITY_OFF, \
387 .add_mask = UINT16_MAX, \
388 .sample_hold_mask = 0, \
389 .sample_hold_states = 24, \
390 .p_window_cfg = NULL, \
391 }, \
392 }; \
393 \
394 DEVICE_DT_INST_DEFINE(idx, adc_ra_init, NULL, &adc_ra_data_##idx, &adc_ra_config_##idx, \
395 POST_KERNEL, CONFIG_ADC_INIT_PRIORITY, &adc_ra_api_##idx)
396
397 DT_INST_FOREACH_STATUS_OKAY(ADC_RA_INIT);
398