1 /*
2 * Copyright (c) 2020 Nuvoton Technology Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT nuvoton_npcx_adc
8
9 #include <assert.h>
10 #include <zephyr/drivers/adc.h>
11 #include <zephyr/drivers/adc/adc_npcx_threshold.h>
12 #include <zephyr/drivers/clock_control.h>
13 #include <zephyr/drivers/pinctrl.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/pm/policy.h>
16 #include <soc.h>
17
18 #define ADC_CONTEXT_USES_KERNEL_TIMER
19 #include "adc_context.h"
20
21 #include <zephyr/logging/log.h>
22 #include <zephyr/irq.h>
23 LOG_MODULE_REGISTER(adc_npcx, CONFIG_ADC_LOG_LEVEL);
24
25 /* ADC speed/delay values during initialization */
26 #define ADC_REGULAR_DLY_VAL 0x03
27 #define ADC_REGULAR_ADCCNF2_VAL 0x8B07
28 #define ADC_REGULAR_GENDLY_VAL 0x0100
29 #define ADC_REGULAR_MEAST_VAL 0x0001
30
31 /* ADC targeted operating frequency (2MHz) */
32 #define NPCX_ADC_CLK 2000000
33
34 /* ADC conversion mode */
35 #define NPCX_ADC_CHN_CONVERSION_MODE 0
36 #define NPCX_ADC_SCAN_CONVERSION_MODE 1
37
38 /* Max channel number to be converted in ADCCS */
39 #define NPCX_ADCCS_MAX_CHANNEL_COUNT 16
40
41 #define ADC_NPCX_THRVAL_RESOLUTION 10
42 #define ADC_NPCX_THRVAL_MAX BIT_MASK(ADC_NPCX_THRVAL_RESOLUTION)
43
44 /* Device config */
45 struct adc_npcx_config {
46 /* adc controller base address */
47 uintptr_t base;
48 /* clock configuration */
49 struct npcx_clk_cfg clk_cfg;
50 /* the number of ADC channels */
51 const uint8_t channel_count;
52 /* amount of thresholds supported */
53 const uint8_t threshold_count;
54 /* routine for configuring ADC's ISR */
55 void (*irq_cfg_func)(void);
56 const struct pinctrl_dev_config *pcfg;
57 };
58
59 struct adc_npcx_threshold_control {
60 /*
61 * Selects ADC channel number, for which the measured data is compared
62 * for threshold detection.
63 */
64 uint8_t chnsel;
65 /*
66 * Sets relation between measured value and assetion threshold value.
67 * in thrval:
68 * 0: Threshold event is generated if Measured data > thrval.
69 * 1: Threshold event is generated if Measured data <= thrval.
70 */
71 bool l_h;
72 /* Sets the threshold value to which measured data is compared. */
73 uint16_t thrval;
74 /*
75 * Pointer of work queue item to be notified when threshold assertion
76 * occurs.
77 */
78 struct k_work *work;
79 };
80
81 struct adc_npcx_threshold_data {
82 /*
83 * While threshold interruption is enabled we need to resume to repetitive
84 * sampling mode after adc_npcx_read is called. This variable records
85 * channels being used in repetitive mode in order to set ADC registers
86 * back to threshold detection when adc_npcx_read is completed.
87 */
88 uint32_t repetitive_channels;
89 /*
90 * While threshold interruption is enabled, adc_npcx_read must disable
91 * all active threshold running to avoid race condition, this variable
92 * helps restore active threshods after adc_npcs_read has finnished.
93 */
94 uint8_t active_thresholds;
95 /* This array holds current configuration for each threshold. */
96 struct adc_npcx_threshold_control
97 control[DT_INST_PROP(0, threshold_count)];
98 };
99
100 /* Driver data */
101 struct adc_npcx_data {
102 /* Input clock for ADC converter */
103 uint32_t input_clk;
104 /* mutex of ADC channels */
105 struct adc_context ctx;
106 /*
107 * Bit-mask indicating the channels to be included in each sampling
108 * of this sequence.
109 */
110 uint32_t channels;
111 /* ADC Device pointer used in api functions */
112 const struct device *adc_dev;
113 uint16_t *buffer;
114 uint16_t *repeat_buffer;
115 /* end pointer of buffer to ensure enough space for storing ADC data. */
116 uint16_t *buf_end;
117 /* Threshold comparator data pointer */
118 struct adc_npcx_threshold_data *threshold_data;
119 #ifdef CONFIG_PM
120 atomic_t current_pm_lock;
121 #endif
122 };
123
124 /*
125 * Pointer of internal work queue thread to be notified when threshold assertion
126 * occurs if CONFIG_ADC_CMP_NPCX_WORKQUEUE is enabled.
127 */
128 struct k_work_q *work_q;
129
130 /* Driver convenience defines */
131 #define HAL_INSTANCE(dev) ((struct adc_reg *)((const struct adc_npcx_config *)(dev)->config)->base)
132
133 /* ADC local functions */
134
135 #ifdef CONFIG_PM
adc_npcx_pm_policy_state_lock_get(struct adc_npcx_data * data)136 static void adc_npcx_pm_policy_state_lock_get(struct adc_npcx_data *data)
137 {
138 if (atomic_test_and_set_bit(&data->current_pm_lock, 0) == 0) {
139 pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
140 }
141 }
142
adc_npcx_pm_policy_state_lock_put(struct adc_npcx_data * data)143 static void adc_npcx_pm_policy_state_lock_put(struct adc_npcx_data *data)
144 {
145 if (atomic_test_and_clear_bit(&data->current_pm_lock, 0) == 1) {
146 pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
147 }
148 }
149 #endif
150
adc_npcx_config_channels(const struct device * dev,uint32_t channels)151 static inline void adc_npcx_config_channels(const struct device *dev, uint32_t channels)
152 {
153 const struct adc_npcx_config *config = dev->config;
154 struct adc_reg *const inst = HAL_INSTANCE(dev);
155
156 inst->ADCCS = channels & BIT_MASK(NPCX_ADCCS_MAX_CHANNEL_COUNT);
157
158 /* Only npcx4 and later series support over 16 ADC channels */
159 if (config->channel_count > NPCX_ADCCS_MAX_CHANNEL_COUNT) {
160 inst->ADCCS2 = (channels >> NPCX_ADCCS_MAX_CHANNEL_COUNT) &
161 BIT_MASK(NPCX_ADCCS_MAX_CHANNEL_COUNT);
162 }
163 }
164
adc_npcx_enable_threshold_detect(const struct device * dev,uint8_t th_sel,bool enable)165 static inline void adc_npcx_enable_threshold_detect(const struct device *dev, uint8_t th_sel,
166 bool enable)
167 {
168 const struct adc_npcx_config *config = dev->config;
169
170 if (enable) {
171 #ifdef CONFIG_ADC_NPCX_CMP_V2
172 THEN(config->base) |= BIT(th_sel);
173 #else /* CONFIG_ADC_NPCX_CMP_V1 */
174 THRCTL(config->base, th_sel) |= BIT(NPCX_THRCTL_THEN);
175 #endif
176
177 } else {
178 #ifdef CONFIG_ADC_NPCX_CMP_V2
179 THEN(config->base) &= ~BIT(th_sel);
180 #else /* CONFIG_ADC_NPCX_CMP_V1 */
181 THRCTL(config->base, th_sel) &= ~BIT(NPCX_THRCTL_THEN);
182 #endif
183 }
184 }
185
adc_npcx_isr(const struct device * dev)186 static void adc_npcx_isr(const struct device *dev)
187 {
188 const struct adc_npcx_config *config = dev->config;
189 struct adc_npcx_data *const data = dev->data;
190 struct adc_reg *const inst = HAL_INSTANCE(dev);
191 struct adc_npcx_threshold_data *const t_data = data->threshold_data;
192 uint16_t status = inst->ADCSTS;
193 uint16_t result, channel;
194
195 /* Clear status pending bits first */
196 inst->ADCSTS = status;
197 LOG_DBG("%s: status is %04X\n", __func__, status);
198
199 /* Is end of conversion cycle event? ie. Scan conversion is done. */
200 if (IS_BIT_SET(status, NPCX_ADCSTS_EOCCEV) &&
201 IS_BIT_SET(inst->ADCCNF, NPCX_ADCCNF_INTECCEN)) {
202 /* Stop conversion for scan conversion mode */
203 inst->ADCCNF |= BIT(NPCX_ADCCNF_STOP);
204
205 /* Get result for each ADC selected channel */
206 while (data->channels) {
207 channel = find_lsb_set(data->channels) - 1;
208 result = GET_FIELD(CHNDAT(config->base, channel),
209 NPCX_CHNDAT_CHDAT_FIELD);
210 /*
211 * Save ADC result and adc_npcx_validate_buffer_size()
212 * already ensures that the buffer has enough space for
213 * storing result.
214 */
215 if (data->buffer < data->buf_end) {
216 *data->buffer++ = result;
217 }
218 data->channels &= ~BIT(channel);
219 }
220 /* Disable End of cyclic conversion interruption */
221 inst->ADCCNF &= ~BIT(NPCX_ADCCNF_INTECCEN);
222
223 if (IS_ENABLED(CONFIG_ADC_CMP_NPCX) &&
224 t_data->active_thresholds) {
225 /* Set repetitive channels back */
226 adc_npcx_config_channels(dev, t_data->repetitive_channels);
227 /* Start conversion */
228 inst->ADCCNF |= BIT(NPCX_ADCCNF_START);
229 } else {
230 /* Disable all channels */
231 adc_npcx_config_channels(dev, 0);
232 /* Turn off ADC */
233 inst->ADCCNF &= ~(BIT(NPCX_ADCCNF_ADCEN));
234
235 #ifdef CONFIG_PM
236 adc_npcx_pm_policy_state_lock_put(data);
237 #endif
238 }
239 /* Inform sampling is done */
240 adc_context_on_sampling_done(&data->ctx, data->adc_dev);
241 }
242
243 if (!(IS_ENABLED(CONFIG_ADC_CMP_NPCX) && t_data->active_thresholds)) {
244 return;
245 }
246 uint16_t thrcts;
247
248 for (uint8_t i = 0; i < config->threshold_count; i++) {
249 if (IS_BIT_SET(inst->THRCTS, i) && IS_BIT_SET(inst->THRCTS,
250 (NPCX_THRCTS_THR1_IEN + i))) {
251 /* Avoid clearing other threshold status */
252 thrcts = inst->THRCTS &
253 ~GENMASK(config->threshold_count - 1, 0);
254 /* Clear threshold status */
255 thrcts |= BIT(i);
256 inst->THRCTS = thrcts;
257 if (t_data->control[i].work) {
258 /* Notify work thread */
259 k_work_submit_to_queue(work_q ? work_q : &k_sys_work_q,
260 t_data->control[i].work);
261 }
262 }
263 }
264 }
265
266 /*
267 * Validate the buffer size with adc channels mask. If it is lower than what
268 * we need return -ENOSPC.
269 */
adc_npcx_validate_buffer_size(const struct device * dev,const struct adc_sequence * sequence)270 static int adc_npcx_validate_buffer_size(const struct device *dev,
271 const struct adc_sequence *sequence)
272 {
273 const struct adc_npcx_config *config = dev->config;
274 uint8_t channels = 0;
275 uint32_t mask;
276 size_t needed;
277
278 for (mask = BIT(config->channel_count - 1); mask != 0; mask >>= 1) {
279 if (mask & sequence->channels) {
280 channels++;
281 }
282 }
283
284 needed = channels * sizeof(uint16_t);
285 if (sequence->options) {
286 needed *= (1 + sequence->options->extra_samplings);
287 }
288
289 if (sequence->buffer_size < needed) {
290 return -ENOSPC;
291 }
292
293 return 0;
294 }
295
adc_npcx_start_scan(const struct device * dev)296 static void adc_npcx_start_scan(const struct device *dev)
297 {
298 const struct adc_npcx_config *config = dev->config;
299 struct adc_npcx_data *const data = dev->data;
300 struct adc_reg *const inst = HAL_INSTANCE(dev);
301
302 #ifdef CONFIG_PM
303 adc_npcx_pm_policy_state_lock_get(data);
304 #endif
305 /* Turn on ADC first */
306 inst->ADCCNF |= BIT(NPCX_ADCCNF_ADCEN);
307
308 /* Stop conversion for scan conversion mode */
309 inst->ADCCNF |= BIT(NPCX_ADCCNF_STOP);
310
311 /* Clear end of cyclic conversion event status flag */
312 inst->ADCSTS |= BIT(NPCX_ADCSTS_EOCCEV);
313
314 /* Update selected channels in scan mode by channels mask */
315 adc_npcx_config_channels(dev, data->channels);
316
317 /* Select 'Scan' Conversion mode. */
318 SET_FIELD(inst->ADCCNF, NPCX_ADCCNF_ADCMD_FIELD,
319 NPCX_ADC_SCAN_CONVERSION_MODE);
320
321 /* Enable end of cyclic conversion event interrupt */
322 inst->ADCCNF |= BIT(NPCX_ADCCNF_INTECCEN);
323
324 /* Start conversion */
325 inst->ADCCNF |= BIT(NPCX_ADCCNF_START);
326
327 if (config->channel_count > NPCX_ADCCS_MAX_CHANNEL_COUNT) {
328 LOG_DBG("Start ADC scan conversion and ADCCNF,ADCCS, ADCCS2 are "
329 "(%04X,%04X,%04X)\n", inst->ADCCNF, inst->ADCCS, inst->ADCCS2);
330 } else {
331 LOG_DBG("Start ADC scan conversion and ADCCNF,ADCCS are (%04X,%04X)\n",
332 inst->ADCCNF, inst->ADCCS);
333 }
334 }
335
adc_npcx_start_read(const struct device * dev,const struct adc_sequence * sequence)336 static int adc_npcx_start_read(const struct device *dev,
337 const struct adc_sequence *sequence)
338 {
339 const struct adc_npcx_config *config = dev->config;
340 struct adc_npcx_data *const data = dev->data;
341 int error = 0;
342
343 if (!sequence->channels ||
344 (sequence->channels & ~BIT_MASK(config->channel_count))) {
345 LOG_ERR("Invalid ADC channels");
346 return -EINVAL;
347 }
348
349 /* Fixed 10 bit resolution of npcx ADC */
350 if (sequence->resolution != 10) {
351 LOG_ERR("Unfixed 10 bit ADC resolution");
352 return -ENOTSUP;
353 }
354
355 error = adc_npcx_validate_buffer_size(dev, sequence);
356 if (error) {
357 LOG_ERR("ADC buffer size too small");
358 return error;
359 }
360
361 /* Save ADC sequence sampling buffer and its end pointer address */
362 data->buffer = sequence->buffer;
363 data->buf_end = data->buffer + sequence->buffer_size / sizeof(uint16_t);
364
365 /* Start ADC conversion */
366 adc_context_start_read(&data->ctx, sequence);
367 error = adc_context_wait_for_completion(&data->ctx);
368
369 return error;
370 }
371
372 /* ADC api functions */
adc_context_start_sampling(struct adc_context * ctx)373 static void adc_context_start_sampling(struct adc_context *ctx)
374 {
375 struct adc_npcx_data *const data =
376 CONTAINER_OF(ctx, struct adc_npcx_data, ctx);
377
378 data->repeat_buffer = data->buffer;
379 data->channels = ctx->sequence.channels;
380
381 /* Start ADC scan conversion */
382 adc_npcx_start_scan(data->adc_dev);
383 }
384
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)385 static void adc_context_update_buffer_pointer(struct adc_context *ctx,
386 bool repeat_sampling)
387 {
388 struct adc_npcx_data *const data =
389 CONTAINER_OF(ctx, struct adc_npcx_data, ctx);
390
391 if (repeat_sampling) {
392 data->buffer = data->repeat_buffer;
393 }
394 }
395
adc_npcx_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)396 static int adc_npcx_channel_setup(const struct device *dev,
397 const struct adc_channel_cfg *channel_cfg)
398 {
399 const struct adc_npcx_config *config = dev->config;
400 uint8_t channel_id = channel_cfg->channel_id;
401
402 if (channel_id >= config->channel_count) {
403 LOG_ERR("Invalid channel %d", channel_id);
404 return -EINVAL;
405 }
406
407 if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
408 LOG_ERR("Unsupported channel acquisition time");
409 return -ENOTSUP;
410 }
411
412 if (channel_cfg->differential) {
413 LOG_ERR("Differential channels are not supported");
414 return -ENOTSUP;
415 }
416
417 if (channel_cfg->gain != ADC_GAIN_1) {
418 LOG_ERR("Unsupported channel gain %d", channel_cfg->gain);
419 return -ENOTSUP;
420 }
421
422 if (channel_cfg->reference != ADC_REF_INTERNAL) {
423 LOG_ERR("Unsupported channel reference");
424 return -ENOTSUP;
425 }
426
427 LOG_DBG("ADC channel %d configured", channel_cfg->channel_id);
428 return 0;
429 }
430
adc_npcx_read(const struct device * dev,const struct adc_sequence * sequence)431 static int adc_npcx_read(const struct device *dev,
432 const struct adc_sequence *sequence)
433 {
434 struct adc_npcx_data *const data = dev->data;
435 int error;
436
437 adc_context_lock(&data->ctx, false, NULL);
438 error = adc_npcx_start_read(dev, sequence);
439 adc_context_release(&data->ctx, error);
440
441 return error;
442 }
443
444 #if defined(CONFIG_ADC_ASYNC)
adc_npcx_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)445 static int adc_npcx_read_async(const struct device *dev,
446 const struct adc_sequence *sequence,
447 struct k_poll_signal *async)
448 {
449 struct adc_npcx_data *const data = dev->data;
450 int error;
451
452 adc_context_lock(&data->ctx, true, async);
453 error = adc_npcx_start_read(dev, sequence);
454 adc_context_release(&data->ctx, error);
455
456 return error;
457 }
458 #endif /* CONFIG_ADC_ASYNC */
459
adc_npcx_set_repetitive(const struct device * dev,int chnsel,uint8_t enable)460 static void adc_npcx_set_repetitive(const struct device *dev, int chnsel,
461 uint8_t enable)
462 {
463 struct adc_reg *const inst = HAL_INSTANCE(dev);
464 struct adc_npcx_data *const data = dev->data;
465 struct adc_npcx_threshold_data *const t_data = data->threshold_data;
466
467 /* Stop ADC conversion */
468 inst->ADCCNF |= BIT(NPCX_ADCCNF_STOP);
469
470 if (enable) {
471 #ifdef CONFIG_PM
472 adc_npcx_pm_policy_state_lock_get(data);
473 #endif
474 /* Turn on ADC */
475 inst->ADCCNF |= BIT(NPCX_ADCCNF_ADCEN);
476 /* Set ADC conversion code to SW conversion mode */
477 SET_FIELD(inst->ADCCNF, NPCX_ADCCNF_ADCMD_FIELD,
478 NPCX_ADC_SCAN_CONVERSION_MODE);
479
480 /* Add selected ADC channel to be converted */
481 t_data->repetitive_channels |= BIT(chnsel);
482 adc_npcx_config_channels(dev, t_data->repetitive_channels);
483
484 /* Set conversion type to repetitive (runs continuously) */
485 inst->ADCCNF |= BIT(NPCX_ADCCNF_ADCRPTC);
486
487 /* Start conversion */
488 inst->ADCCNF |= BIT(NPCX_ADCCNF_START);
489 } else {
490 /* Remove selected ADC channel to be converted */
491 t_data->repetitive_channels &= ~BIT(chnsel);
492 adc_npcx_config_channels(dev, t_data->repetitive_channels);
493
494 if (!t_data->repetitive_channels) {
495 /* No thesholdd active left, disable repetitive mode */
496 inst->ADCCNF &= ~BIT(NPCX_ADCCNF_ADCRPTC);
497 /* Turn off ADC */
498 inst->ADCCNF &= ~BIT(NPCX_ADCCNF_ADCEN);
499 #ifdef CONFIG_PM
500 adc_npcx_pm_policy_state_lock_put(data);
501 #endif
502 } else {
503 /* Start conversion again */
504 inst->ADCCNF |= BIT(NPCX_ADCCNF_START);
505 }
506 }
507 }
508
adc_npcx_threshold_ctrl_set_param(const struct device * dev,const uint8_t th_sel,const struct adc_npcx_threshold_param * param)509 int adc_npcx_threshold_ctrl_set_param(const struct device *dev,
510 const uint8_t th_sel,
511 const struct adc_npcx_threshold_param
512 *param)
513 {
514 const struct adc_npcx_config *config = dev->config;
515 struct adc_npcx_data *const data = dev->data;
516 struct adc_npcx_threshold_data *const t_data = data->threshold_data;
517 struct adc_npcx_threshold_control *const t_ctrl =
518 &t_data->control[th_sel];
519 int ret = 0;
520
521 if (!IS_ENABLED(CONFIG_ADC_CMP_NPCX)) {
522 return -EOPNOTSUPP;
523 }
524
525 if (!param || th_sel >= config->threshold_count) {
526 return -EINVAL;
527 }
528
529 adc_context_lock(&data->ctx, false, NULL);
530 switch (param->type) {
531 case ADC_NPCX_THRESHOLD_PARAM_CHNSEL:
532 if (param->val >= config->channel_count) {
533 ret = -EINVAL;
534 break;
535 }
536 t_ctrl->chnsel = (uint8_t)param->val;
537 break;
538
539 case ADC_NPCX_THRESHOLD_PARAM_L_H:
540 t_ctrl->l_h = !!param->val;
541 break;
542
543 case ADC_NPCX_THRESHOLD_PARAM_THVAL:
544 if (param->val == 0 || param->val >= ADC_NPCX_THRVAL_MAX) {
545 ret = -EINVAL;
546 break;
547 }
548 t_ctrl->thrval = (uint16_t)param->val;
549 break;
550
551 case ADC_NPCX_THRESHOLD_PARAM_WORK:
552 if (param->val == 0) {
553 ret = -EINVAL;
554 break;
555 }
556 t_ctrl->work = (struct k_work *)param->val;
557 break;
558 default:
559 ret = -EINVAL;
560 }
561 adc_context_release(&data->ctx, 0);
562 return ret;
563 }
564
adc_npcx_threshold_ctrl_setup(const struct device * dev,const uint8_t th_sel)565 static int adc_npcx_threshold_ctrl_setup(const struct device *dev,
566 const uint8_t th_sel)
567 {
568 struct adc_npcx_data *const data = dev->data;
569 struct adc_driver_api *api = (struct adc_driver_api *)dev->api;
570 struct adc_npcx_threshold_data *const t_data = data->threshold_data;
571 const struct adc_npcx_config *config = dev->config;
572 struct adc_npcx_threshold_control *const t_ctrl =
573 &t_data->control[th_sel];
574
575 if (th_sel >= config->threshold_count) {
576 return -EINVAL;
577 }
578
579 adc_context_lock(&data->ctx, false, NULL);
580
581 if (t_data->active_thresholds & BIT(th_sel)) {
582 /* Unable to setup threshold parameters while active */
583 adc_context_release(&data->ctx, 0);
584 LOG_ERR("Threshold selected (%d) is active!", th_sel);
585 return -EBUSY;
586 }
587
588 if (t_ctrl->chnsel >= config->channel_count ||
589 t_ctrl->thrval >= api->ref_internal ||
590 t_ctrl->thrval == 0 || t_ctrl->work == 0) {
591 adc_context_release(&data->ctx, 0);
592 LOG_ERR("Threshold selected (%d) is not configured!", th_sel);
593 return -EINVAL;
594 }
595
596 SET_FIELD(THRCTL(config->base, th_sel),
597 NPCX_THRCTL_CHNSEL, t_ctrl->chnsel);
598
599 if (t_ctrl->l_h) {
600 THRCTL(config->base, th_sel) |= BIT(NPCX_THRCTL_L_H);
601 } else {
602 THRCTL(config->base, th_sel) &= ~BIT(NPCX_THRCTL_L_H);
603 }
604 /* Set the threshold value. */
605 SET_FIELD(THRCTL(config->base, th_sel), NPCX_THRCTL_THRVAL,
606 t_ctrl->thrval);
607
608 adc_context_release(&data->ctx, 0);
609 return 0;
610 }
611
adc_npcx_threshold_enable_irq(const struct device * dev,const uint8_t th_sel)612 static int adc_npcx_threshold_enable_irq(const struct device *dev,
613 const uint8_t th_sel)
614 {
615 struct adc_reg *const inst = HAL_INSTANCE(dev);
616 struct adc_driver_api *api = (struct adc_driver_api *)dev->api;
617 struct adc_npcx_data *const data = dev->data;
618 const struct adc_npcx_config *config = dev->config;
619 struct adc_npcx_threshold_data *const t_data = data->threshold_data;
620 struct adc_npcx_threshold_control *const t_ctrl =
621 &t_data->control[th_sel];
622 uint16_t thrcts;
623
624 if (th_sel >= config->threshold_count) {
625 LOG_ERR("Invalid ADC threshold selection! (%d)", th_sel);
626 return -EINVAL;
627 }
628
629 adc_context_lock(&data->ctx, false, NULL);
630 if (t_ctrl->chnsel >= config->channel_count ||
631 t_ctrl->thrval >= api->ref_internal ||
632 t_ctrl->thrval == 0 || t_ctrl->work == 0) {
633 adc_context_release(&data->ctx, 0);
634 LOG_ERR("Threshold selected (%d) is not configured!", th_sel);
635 return -EINVAL;
636 }
637
638 /* Record new active threshold */
639 t_data->active_thresholds |= BIT(th_sel);
640
641 /* avoid clearing other threshold status */
642 thrcts = inst->THRCTS & ~GENMASK(config->threshold_count - 1, 0);
643
644 /* Enable threshold detection */
645 adc_npcx_enable_threshold_detect(dev, th_sel, true);
646
647 /* clear threshold status */
648 thrcts |= BIT(th_sel);
649
650 /* set enable threshold status */
651 thrcts |= BIT(NPCX_THRCTS_THR1_IEN + th_sel);
652
653 inst->THRCTS = thrcts;
654
655 adc_npcx_set_repetitive(dev, t_data->control[th_sel].chnsel, true);
656
657 adc_context_release(&data->ctx, 0);
658 return 0;
659 }
660
adc_npcx_threshold_disable_irq(const struct device * dev,const uint8_t th_sel)661 int adc_npcx_threshold_disable_irq(const struct device *dev,
662 const uint8_t th_sel)
663 {
664 struct adc_reg *const inst = HAL_INSTANCE(dev);
665 const struct adc_npcx_config *config = dev->config;
666 struct adc_npcx_data *const data = dev->data;
667 struct adc_npcx_threshold_data *const t_data = data->threshold_data;
668 uint16_t thrcts;
669
670 if (!IS_ENABLED(CONFIG_ADC_CMP_NPCX)) {
671 return -EOPNOTSUPP;
672 }
673
674 if (th_sel >= config->threshold_count) {
675 LOG_ERR("Invalid ADC threshold selection! (%d)", th_sel);
676 return -EINVAL;
677 }
678
679 adc_context_lock(&data->ctx, false, NULL);
680 if (!(t_data->active_thresholds & BIT(th_sel))) {
681 adc_context_release(&data->ctx, 0);
682 LOG_ERR("Threshold selection (%d) is not enabled", th_sel);
683 return -ENODEV;
684 }
685 /* avoid clearing other threshold status */
686 thrcts = inst->THRCTS & ~GENMASK(config->threshold_count - 1, 0);
687
688 /* set enable threshold status */
689 thrcts &= ~BIT(NPCX_THRCTS_THR1_IEN + th_sel);
690 inst->THRCTS = thrcts;
691
692 /* Disable threshold detection */
693 adc_npcx_enable_threshold_detect(dev, th_sel, false);
694
695 /* Update active threshold */
696 t_data->active_thresholds &= ~BIT(th_sel);
697
698 adc_npcx_set_repetitive(dev, t_data->control[th_sel].chnsel, false);
699
700 adc_context_release(&data->ctx, 0);
701
702 return 0;
703 }
704
adc_npcx_threshold_ctrl_enable(const struct device * dev,uint8_t th_sel,const bool enable)705 int adc_npcx_threshold_ctrl_enable(const struct device *dev, uint8_t th_sel,
706 const bool enable)
707 {
708 int ret;
709
710 if (!IS_ENABLED(CONFIG_ADC_CMP_NPCX)) {
711 return -EOPNOTSUPP;
712 }
713
714 /* Enable/Disable threshold IRQ */
715 if (enable) {
716 /* Set control threshold registers */
717 ret = adc_npcx_threshold_ctrl_setup(dev, th_sel);
718 if (ret) {
719 return ret;
720 }
721 ret = adc_npcx_threshold_enable_irq(dev, th_sel);
722 } else {
723 ret = adc_npcx_threshold_disable_irq(dev, th_sel);
724 }
725 return ret;
726 }
727
adc_npcx_threshold_mv_to_thrval(const struct device * dev,uint32_t val_mv,uint32_t * thrval)728 int adc_npcx_threshold_mv_to_thrval(const struct device *dev, uint32_t val_mv,
729 uint32_t *thrval)
730 {
731 struct adc_driver_api *api = (struct adc_driver_api *)dev->api;
732
733 if (!IS_ENABLED(CONFIG_ADC_CMP_NPCX)) {
734 return -EOPNOTSUPP;
735 }
736
737 if (val_mv >= api->ref_internal) {
738 return -EINVAL;
739 }
740
741 *thrval = (val_mv << ADC_NPCX_THRVAL_RESOLUTION) /
742 api->ref_internal;
743 return 0;
744 }
745
746 #if defined(CONFIG_ADC_CMP_NPCX_WORKQUEUE)
747 struct k_work_q adc_npcx_work_q;
748
749 static K_KERNEL_STACK_DEFINE(adc_npcx_work_q_stack,
750 CONFIG_ADC_CMP_NPCX_WORKQUEUE_STACK_SIZE);
751
adc_npcx_init_cmp_work_q(void)752 static int adc_npcx_init_cmp_work_q(void)
753 {
754 struct k_work_queue_config cfg = {
755 .name = "adc_cmp_work",
756 .no_yield = false,
757 };
758
759 k_work_queue_start(&adc_npcx_work_q,
760 adc_npcx_work_q_stack,
761 K_KERNEL_STACK_SIZEOF(adc_npcx_work_q_stack),
762 CONFIG_ADC_CMP_NPCX_WORKQUEUE_PRIORITY, &cfg);
763
764 work_q = &adc_npcx_work_q;
765 return 0;
766 }
767
768 SYS_INIT(adc_npcx_init_cmp_work_q, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY);
769 #endif
770
adc_npcx_init(const struct device * dev)771 static int adc_npcx_init(const struct device *dev)
772 {
773 const struct adc_npcx_config *const config = dev->config;
774 struct adc_npcx_data *const data = dev->data;
775 struct adc_reg *const inst = HAL_INSTANCE(dev);
776 const struct device *const clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE);
777 int prescaler = 0, ret;
778
779 if (!device_is_ready(clk_dev)) {
780 LOG_ERR("clock control device not ready");
781 return -ENODEV;
782 }
783
784 /* Save ADC device in data */
785 data->adc_dev = dev;
786
787 /* Turn on device clock first and get source clock freq. */
788 ret = clock_control_on(clk_dev, (clock_control_subsys_t)
789 &config->clk_cfg);
790 if (ret < 0) {
791 LOG_ERR("Turn on ADC clock fail %d", ret);
792 return ret;
793 }
794
795 ret = clock_control_get_rate(clk_dev, (clock_control_subsys_t)
796 &config->clk_cfg, &data->input_clk);
797 if (ret < 0) {
798 LOG_ERR("Get ADC clock rate error %d", ret);
799 return ret;
800 }
801
802 /* Configure the ADC clock */
803 prescaler = DIV_ROUND_UP(data->input_clk, NPCX_ADC_CLK);
804 if (prescaler > 0x40) {
805 prescaler = 0x40;
806 }
807
808 /* Set Core Clock Division Factor in order to obtain the ADC clock */
809 SET_FIELD(inst->ATCTL, NPCX_ATCTL_SCLKDIV_FIELD, prescaler - 1);
810
811 /* Set regular ADC delay */
812 SET_FIELD(inst->ATCTL, NPCX_ATCTL_DLY_FIELD, ADC_REGULAR_DLY_VAL);
813
814 /* Set ADC speed sequentially */
815 inst->ADCCNF2 = ADC_REGULAR_ADCCNF2_VAL;
816 inst->GENDLY = ADC_REGULAR_GENDLY_VAL;
817 inst->MEAST = ADC_REGULAR_MEAST_VAL;
818
819 /* Configure ADC interrupt and enable it */
820 config->irq_cfg_func();
821
822 /* Initialize mutex of ADC channels */
823 adc_context_unlock_unconditionally(&data->ctx);
824
825 /* Configure pin-mux for ADC device */
826 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
827 if (ret < 0) {
828 LOG_ERR("ADC pinctrl setup failed (%d)", ret);
829 return ret;
830 }
831
832 return 0;
833 }
834
835 #define NPCX_ADC_INIT(n) \
836 \
837 static void adc_npcx_irq_cfg_func_##n(void) \
838 { \
839 IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \
840 adc_npcx_isr, DEVICE_DT_INST_GET(n), 0); \
841 irq_enable(DT_INST_IRQN(n)); \
842 } \
843 \
844 static const struct adc_driver_api adc_npcx_driver_api_##n = { \
845 .channel_setup = adc_npcx_channel_setup, \
846 .read = adc_npcx_read, \
847 .ref_internal = DT_INST_PROP(n, vref_mv), \
848 IF_ENABLED(CONFIG_ADC_ASYNC, \
849 (.read_async = adc_npcx_read_async,)) \
850 }; \
851 \
852 PINCTRL_DT_INST_DEFINE(n); \
853 \
854 static const struct adc_npcx_config adc_npcx_cfg_##n = { \
855 .base = DT_INST_REG_ADDR(n), \
856 .clk_cfg = NPCX_DT_CLK_CFG_ITEM(n), \
857 .channel_count = DT_INST_PROP(n, channel_count), \
858 .threshold_count = DT_INST_PROP(n, threshold_count), \
859 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
860 .irq_cfg_func = adc_npcx_irq_cfg_func_##n, \
861 }; \
862 static struct adc_npcx_threshold_data threshold_data_##n; \
863 static struct adc_npcx_data adc_npcx_data_##n = { \
864 ADC_CONTEXT_INIT_TIMER(adc_npcx_data_##n, ctx), \
865 ADC_CONTEXT_INIT_LOCK(adc_npcx_data_##n, ctx), \
866 ADC_CONTEXT_INIT_SYNC(adc_npcx_data_##n, ctx), \
867 .threshold_data = &threshold_data_##n, \
868 }; \
869 DEVICE_DT_INST_DEFINE(n, \
870 adc_npcx_init, NULL, \
871 &adc_npcx_data_##n, &adc_npcx_cfg_##n, \
872 PRE_KERNEL_1, CONFIG_ADC_INIT_PRIORITY, \
873 &adc_npcx_driver_api_##n);
874
875 DT_INST_FOREACH_STATUS_OKAY(NPCX_ADC_INIT)
876