Lines Matching +full:conversion +full:- +full:rate

4  * SPDX-License-Identifier: Apache-2.0
34 /* ADC conversion mode */
107 * Bit-mask indicating the channels to be included in each sampling
131 #define HAL_INSTANCE(dev) ((struct adc_reg *)((const struct adc_npcx_config *)(dev)->config)->base)
138 if (atomic_test_and_set_bit(&data->current_pm_lock, 0) == 0) { in adc_npcx_pm_policy_state_lock_get()
145 if (atomic_test_and_clear_bit(&data->current_pm_lock, 0) == 1) { in adc_npcx_pm_policy_state_lock_put()
153 const struct adc_npcx_config *config = dev->config; in adc_npcx_config_channels()
156 inst->ADCCS = channels & BIT_MASK(NPCX_ADCCS_MAX_CHANNEL_COUNT); in adc_npcx_config_channels()
159 if (config->channel_count > NPCX_ADCCS_MAX_CHANNEL_COUNT) { in adc_npcx_config_channels()
160 inst->ADCCS2 = (channels >> NPCX_ADCCS_MAX_CHANNEL_COUNT) & in adc_npcx_config_channels()
168 const struct adc_npcx_config *config = dev->config; in adc_npcx_enable_threshold_detect()
172 THEN(config->base) |= BIT(th_sel); in adc_npcx_enable_threshold_detect()
174 THRCTL(config->base, th_sel) |= BIT(NPCX_THRCTL_THEN); in adc_npcx_enable_threshold_detect()
179 THEN(config->base) &= ~BIT(th_sel); in adc_npcx_enable_threshold_detect()
181 THRCTL(config->base, th_sel) &= ~BIT(NPCX_THRCTL_THEN); in adc_npcx_enable_threshold_detect()
188 const struct adc_npcx_config *config = dev->config; in adc_npcx_isr()
189 struct adc_npcx_data *const data = dev->data; in adc_npcx_isr()
191 struct adc_npcx_threshold_data *const t_data = data->threshold_data; in adc_npcx_isr()
192 uint16_t status = inst->ADCSTS; in adc_npcx_isr()
196 inst->ADCSTS = status; in adc_npcx_isr()
199 /* Is end of conversion cycle event? ie. Scan conversion is done. */ in adc_npcx_isr()
201 IS_BIT_SET(inst->ADCCNF, NPCX_ADCCNF_INTECCEN)) { in adc_npcx_isr()
202 /* Stop conversion for scan conversion mode */ in adc_npcx_isr()
203 inst->ADCCNF |= BIT(NPCX_ADCCNF_STOP); in adc_npcx_isr()
206 while (data->channels) { in adc_npcx_isr()
207 channel = find_lsb_set(data->channels) - 1; in adc_npcx_isr()
208 result = GET_FIELD(CHNDAT(config->base, channel), in adc_npcx_isr()
215 if (data->buffer < data->buf_end) { in adc_npcx_isr()
216 *data->buffer++ = result; in adc_npcx_isr()
218 data->channels &= ~BIT(channel); in adc_npcx_isr()
220 /* Disable End of cyclic conversion interruption */ in adc_npcx_isr()
221 inst->ADCCNF &= ~BIT(NPCX_ADCCNF_INTECCEN); in adc_npcx_isr()
224 t_data->active_thresholds) { in adc_npcx_isr()
226 adc_npcx_config_channels(dev, t_data->repetitive_channels); in adc_npcx_isr()
227 /* Start conversion */ in adc_npcx_isr()
228 inst->ADCCNF |= BIT(NPCX_ADCCNF_START); in adc_npcx_isr()
233 inst->ADCCNF &= ~(BIT(NPCX_ADCCNF_ADCEN)); in adc_npcx_isr()
240 adc_context_on_sampling_done(&data->ctx, data->adc_dev); in adc_npcx_isr()
243 if (!(IS_ENABLED(CONFIG_ADC_CMP_NPCX) && t_data->active_thresholds)) { in adc_npcx_isr()
248 for (uint8_t i = 0; i < config->threshold_count; i++) { in adc_npcx_isr()
249 if (IS_BIT_SET(inst->THRCTS, i) && IS_BIT_SET(inst->THRCTS, in adc_npcx_isr()
252 thrcts = inst->THRCTS & in adc_npcx_isr()
253 ~GENMASK(config->threshold_count - 1, 0); in adc_npcx_isr()
256 inst->THRCTS = thrcts; in adc_npcx_isr()
257 if (t_data->control[i].work) { in adc_npcx_isr()
260 t_data->control[i].work); in adc_npcx_isr()
268 * we need return -ENOSPC.
273 const struct adc_npcx_config *config = dev->config; in adc_npcx_validate_buffer_size()
278 for (mask = BIT(config->channel_count - 1); mask != 0; mask >>= 1) { in adc_npcx_validate_buffer_size()
279 if (mask & sequence->channels) { in adc_npcx_validate_buffer_size()
285 if (sequence->options) { in adc_npcx_validate_buffer_size()
286 needed *= (1 + sequence->options->extra_samplings); in adc_npcx_validate_buffer_size()
289 if (sequence->buffer_size < needed) { in adc_npcx_validate_buffer_size()
290 return -ENOSPC; in adc_npcx_validate_buffer_size()
298 const struct adc_npcx_config *config = dev->config; in adc_npcx_start_scan()
299 struct adc_npcx_data *const data = dev->data; in adc_npcx_start_scan()
306 inst->ADCCNF |= BIT(NPCX_ADCCNF_ADCEN); in adc_npcx_start_scan()
308 /* Stop conversion for scan conversion mode */ in adc_npcx_start_scan()
309 inst->ADCCNF |= BIT(NPCX_ADCCNF_STOP); in adc_npcx_start_scan()
311 /* Clear end of cyclic conversion event status flag */ in adc_npcx_start_scan()
312 inst->ADCSTS |= BIT(NPCX_ADCSTS_EOCCEV); in adc_npcx_start_scan()
315 adc_npcx_config_channels(dev, data->channels); in adc_npcx_start_scan()
317 /* Select 'Scan' Conversion mode. */ in adc_npcx_start_scan()
318 SET_FIELD(inst->ADCCNF, NPCX_ADCCNF_ADCMD_FIELD, in adc_npcx_start_scan()
321 /* Enable end of cyclic conversion event interrupt */ in adc_npcx_start_scan()
322 inst->ADCCNF |= BIT(NPCX_ADCCNF_INTECCEN); in adc_npcx_start_scan()
324 /* Start conversion */ in adc_npcx_start_scan()
325 inst->ADCCNF |= BIT(NPCX_ADCCNF_START); in adc_npcx_start_scan()
327 if (config->channel_count > NPCX_ADCCS_MAX_CHANNEL_COUNT) { in adc_npcx_start_scan()
328 LOG_DBG("Start ADC scan conversion and ADCCNF,ADCCS, ADCCS2 are " in adc_npcx_start_scan()
329 "(%04X,%04X,%04X)\n", inst->ADCCNF, inst->ADCCS, inst->ADCCS2); in adc_npcx_start_scan()
331 LOG_DBG("Start ADC scan conversion and ADCCNF,ADCCS are (%04X,%04X)\n", in adc_npcx_start_scan()
332 inst->ADCCNF, inst->ADCCS); in adc_npcx_start_scan()
339 const struct adc_npcx_config *config = dev->config; in adc_npcx_start_read()
340 struct adc_npcx_data *const data = dev->data; in adc_npcx_start_read()
343 if (!sequence->channels || in adc_npcx_start_read()
344 (sequence->channels & ~BIT_MASK(config->channel_count))) { in adc_npcx_start_read()
346 return -EINVAL; in adc_npcx_start_read()
350 if (sequence->resolution != 10) { in adc_npcx_start_read()
352 return -ENOTSUP; in adc_npcx_start_read()
362 data->buffer = sequence->buffer; in adc_npcx_start_read()
363 data->buf_end = data->buffer + sequence->buffer_size / sizeof(uint16_t); in adc_npcx_start_read()
365 /* Start ADC conversion */ in adc_npcx_start_read()
366 adc_context_start_read(&data->ctx, sequence); in adc_npcx_start_read()
367 error = adc_context_wait_for_completion(&data->ctx); in adc_npcx_start_read()
378 data->repeat_buffer = data->buffer; in adc_context_start_sampling()
379 data->channels = ctx->sequence.channels; in adc_context_start_sampling()
381 /* Start ADC scan conversion */ in adc_context_start_sampling()
382 adc_npcx_start_scan(data->adc_dev); in adc_context_start_sampling()
392 data->buffer = data->repeat_buffer; in adc_context_update_buffer_pointer()
399 const struct adc_npcx_config *config = dev->config; in adc_npcx_channel_setup()
400 uint8_t channel_id = channel_cfg->channel_id; in adc_npcx_channel_setup()
402 if (channel_id >= config->channel_count) { in adc_npcx_channel_setup()
404 return -EINVAL; in adc_npcx_channel_setup()
407 if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) { in adc_npcx_channel_setup()
409 return -ENOTSUP; in adc_npcx_channel_setup()
412 if (channel_cfg->differential) { in adc_npcx_channel_setup()
414 return -ENOTSUP; in adc_npcx_channel_setup()
417 if (channel_cfg->gain != ADC_GAIN_1) { in adc_npcx_channel_setup()
418 LOG_ERR("Unsupported channel gain %d", channel_cfg->gain); in adc_npcx_channel_setup()
419 return -ENOTSUP; in adc_npcx_channel_setup()
422 if (channel_cfg->reference != ADC_REF_INTERNAL) { in adc_npcx_channel_setup()
424 return -ENOTSUP; in adc_npcx_channel_setup()
427 LOG_DBG("ADC channel %d configured", channel_cfg->channel_id); in adc_npcx_channel_setup()
434 struct adc_npcx_data *const data = dev->data; in adc_npcx_read()
437 adc_context_lock(&data->ctx, false, NULL); in adc_npcx_read()
439 adc_context_release(&data->ctx, error); in adc_npcx_read()
449 struct adc_npcx_data *const data = dev->data; in adc_npcx_read_async()
452 adc_context_lock(&data->ctx, true, async); in adc_npcx_read_async()
454 adc_context_release(&data->ctx, error); in adc_npcx_read_async()
464 struct adc_npcx_data *const data = dev->data; in adc_npcx_set_repetitive()
465 struct adc_npcx_threshold_data *const t_data = data->threshold_data; in adc_npcx_set_repetitive()
467 /* Stop ADC conversion */ in adc_npcx_set_repetitive()
468 inst->ADCCNF |= BIT(NPCX_ADCCNF_STOP); in adc_npcx_set_repetitive()
475 inst->ADCCNF |= BIT(NPCX_ADCCNF_ADCEN); in adc_npcx_set_repetitive()
476 /* Set ADC conversion code to SW conversion mode */ in adc_npcx_set_repetitive()
477 SET_FIELD(inst->ADCCNF, NPCX_ADCCNF_ADCMD_FIELD, in adc_npcx_set_repetitive()
481 t_data->repetitive_channels |= BIT(chnsel); in adc_npcx_set_repetitive()
482 adc_npcx_config_channels(dev, t_data->repetitive_channels); in adc_npcx_set_repetitive()
484 /* Set conversion type to repetitive (runs continuously) */ in adc_npcx_set_repetitive()
485 inst->ADCCNF |= BIT(NPCX_ADCCNF_ADCRPTC); in adc_npcx_set_repetitive()
487 /* Start conversion */ in adc_npcx_set_repetitive()
488 inst->ADCCNF |= BIT(NPCX_ADCCNF_START); in adc_npcx_set_repetitive()
491 t_data->repetitive_channels &= ~BIT(chnsel); in adc_npcx_set_repetitive()
492 adc_npcx_config_channels(dev, t_data->repetitive_channels); in adc_npcx_set_repetitive()
494 if (!t_data->repetitive_channels) { in adc_npcx_set_repetitive()
496 inst->ADCCNF &= ~BIT(NPCX_ADCCNF_ADCRPTC); in adc_npcx_set_repetitive()
498 inst->ADCCNF &= ~BIT(NPCX_ADCCNF_ADCEN); in adc_npcx_set_repetitive()
503 /* Start conversion again */ in adc_npcx_set_repetitive()
504 inst->ADCCNF |= BIT(NPCX_ADCCNF_START); in adc_npcx_set_repetitive()
514 const struct adc_npcx_config *config = dev->config; in adc_npcx_threshold_ctrl_set_param()
515 struct adc_npcx_data *const data = dev->data; in adc_npcx_threshold_ctrl_set_param()
516 struct adc_npcx_threshold_data *const t_data = data->threshold_data; in adc_npcx_threshold_ctrl_set_param()
518 &t_data->control[th_sel]; in adc_npcx_threshold_ctrl_set_param()
522 return -EOPNOTSUPP; in adc_npcx_threshold_ctrl_set_param()
525 if (!param || th_sel >= config->threshold_count) { in adc_npcx_threshold_ctrl_set_param()
526 return -EINVAL; in adc_npcx_threshold_ctrl_set_param()
529 adc_context_lock(&data->ctx, false, NULL); in adc_npcx_threshold_ctrl_set_param()
530 switch (param->type) { in adc_npcx_threshold_ctrl_set_param()
532 if (param->val >= config->channel_count) { in adc_npcx_threshold_ctrl_set_param()
533 ret = -EINVAL; in adc_npcx_threshold_ctrl_set_param()
536 t_ctrl->chnsel = (uint8_t)param->val; in adc_npcx_threshold_ctrl_set_param()
540 t_ctrl->l_h = !!param->val; in adc_npcx_threshold_ctrl_set_param()
544 if (param->val == 0 || param->val >= ADC_NPCX_THRVAL_MAX) { in adc_npcx_threshold_ctrl_set_param()
545 ret = -EINVAL; in adc_npcx_threshold_ctrl_set_param()
548 t_ctrl->thrval = (uint16_t)param->val; in adc_npcx_threshold_ctrl_set_param()
552 if (param->val == 0) { in adc_npcx_threshold_ctrl_set_param()
553 ret = -EINVAL; in adc_npcx_threshold_ctrl_set_param()
556 t_ctrl->work = (struct k_work *)param->val; in adc_npcx_threshold_ctrl_set_param()
559 ret = -EINVAL; in adc_npcx_threshold_ctrl_set_param()
561 adc_context_release(&data->ctx, 0); in adc_npcx_threshold_ctrl_set_param()
568 struct adc_npcx_data *const data = dev->data; in adc_npcx_threshold_ctrl_setup()
569 struct adc_driver_api *api = (struct adc_driver_api *)dev->api; in adc_npcx_threshold_ctrl_setup()
570 struct adc_npcx_threshold_data *const t_data = data->threshold_data; in adc_npcx_threshold_ctrl_setup()
571 const struct adc_npcx_config *config = dev->config; in adc_npcx_threshold_ctrl_setup()
573 &t_data->control[th_sel]; in adc_npcx_threshold_ctrl_setup()
575 if (th_sel >= config->threshold_count) { in adc_npcx_threshold_ctrl_setup()
576 return -EINVAL; in adc_npcx_threshold_ctrl_setup()
579 adc_context_lock(&data->ctx, false, NULL); in adc_npcx_threshold_ctrl_setup()
581 if (t_data->active_thresholds & BIT(th_sel)) { in adc_npcx_threshold_ctrl_setup()
583 adc_context_release(&data->ctx, 0); in adc_npcx_threshold_ctrl_setup()
585 return -EBUSY; in adc_npcx_threshold_ctrl_setup()
588 if (t_ctrl->chnsel >= config->channel_count || in adc_npcx_threshold_ctrl_setup()
589 t_ctrl->thrval >= api->ref_internal || in adc_npcx_threshold_ctrl_setup()
590 t_ctrl->thrval == 0 || t_ctrl->work == 0) { in adc_npcx_threshold_ctrl_setup()
591 adc_context_release(&data->ctx, 0); in adc_npcx_threshold_ctrl_setup()
593 return -EINVAL; in adc_npcx_threshold_ctrl_setup()
596 SET_FIELD(THRCTL(config->base, th_sel), in adc_npcx_threshold_ctrl_setup()
597 NPCX_THRCTL_CHNSEL, t_ctrl->chnsel); in adc_npcx_threshold_ctrl_setup()
599 if (t_ctrl->l_h) { in adc_npcx_threshold_ctrl_setup()
600 THRCTL(config->base, th_sel) |= BIT(NPCX_THRCTL_L_H); in adc_npcx_threshold_ctrl_setup()
602 THRCTL(config->base, th_sel) &= ~BIT(NPCX_THRCTL_L_H); in adc_npcx_threshold_ctrl_setup()
605 SET_FIELD(THRCTL(config->base, th_sel), NPCX_THRCTL_THRVAL, in adc_npcx_threshold_ctrl_setup()
606 t_ctrl->thrval); in adc_npcx_threshold_ctrl_setup()
608 adc_context_release(&data->ctx, 0); in adc_npcx_threshold_ctrl_setup()
616 struct adc_driver_api *api = (struct adc_driver_api *)dev->api; in adc_npcx_threshold_enable_irq()
617 struct adc_npcx_data *const data = dev->data; in adc_npcx_threshold_enable_irq()
618 const struct adc_npcx_config *config = dev->config; in adc_npcx_threshold_enable_irq()
619 struct adc_npcx_threshold_data *const t_data = data->threshold_data; in adc_npcx_threshold_enable_irq()
621 &t_data->control[th_sel]; in adc_npcx_threshold_enable_irq()
624 if (th_sel >= config->threshold_count) { in adc_npcx_threshold_enable_irq()
626 return -EINVAL; in adc_npcx_threshold_enable_irq()
629 adc_context_lock(&data->ctx, false, NULL); in adc_npcx_threshold_enable_irq()
630 if (t_ctrl->chnsel >= config->channel_count || in adc_npcx_threshold_enable_irq()
631 t_ctrl->thrval >= api->ref_internal || in adc_npcx_threshold_enable_irq()
632 t_ctrl->thrval == 0 || t_ctrl->work == 0) { in adc_npcx_threshold_enable_irq()
633 adc_context_release(&data->ctx, 0); in adc_npcx_threshold_enable_irq()
635 return -EINVAL; in adc_npcx_threshold_enable_irq()
639 t_data->active_thresholds |= BIT(th_sel); in adc_npcx_threshold_enable_irq()
642 thrcts = inst->THRCTS & ~GENMASK(config->threshold_count - 1, 0); in adc_npcx_threshold_enable_irq()
653 inst->THRCTS = thrcts; in adc_npcx_threshold_enable_irq()
655 adc_npcx_set_repetitive(dev, t_data->control[th_sel].chnsel, true); in adc_npcx_threshold_enable_irq()
657 adc_context_release(&data->ctx, 0); in adc_npcx_threshold_enable_irq()
665 const struct adc_npcx_config *config = dev->config; in adc_npcx_threshold_disable_irq()
666 struct adc_npcx_data *const data = dev->data; in adc_npcx_threshold_disable_irq()
667 struct adc_npcx_threshold_data *const t_data = data->threshold_data; in adc_npcx_threshold_disable_irq()
671 return -EOPNOTSUPP; in adc_npcx_threshold_disable_irq()
674 if (th_sel >= config->threshold_count) { in adc_npcx_threshold_disable_irq()
676 return -EINVAL; in adc_npcx_threshold_disable_irq()
679 adc_context_lock(&data->ctx, false, NULL); in adc_npcx_threshold_disable_irq()
680 if (!(t_data->active_thresholds & BIT(th_sel))) { in adc_npcx_threshold_disable_irq()
681 adc_context_release(&data->ctx, 0); in adc_npcx_threshold_disable_irq()
683 return -ENODEV; in adc_npcx_threshold_disable_irq()
686 thrcts = inst->THRCTS & ~GENMASK(config->threshold_count - 1, 0); in adc_npcx_threshold_disable_irq()
690 inst->THRCTS = thrcts; in adc_npcx_threshold_disable_irq()
696 t_data->active_thresholds &= ~BIT(th_sel); in adc_npcx_threshold_disable_irq()
698 adc_npcx_set_repetitive(dev, t_data->control[th_sel].chnsel, false); in adc_npcx_threshold_disable_irq()
700 adc_context_release(&data->ctx, 0); in adc_npcx_threshold_disable_irq()
711 return -EOPNOTSUPP; in adc_npcx_threshold_ctrl_enable()
731 struct adc_driver_api *api = (struct adc_driver_api *)dev->api; in adc_npcx_threshold_mv_to_thrval()
734 return -EOPNOTSUPP; in adc_npcx_threshold_mv_to_thrval()
737 if (val_mv >= api->ref_internal) { in adc_npcx_threshold_mv_to_thrval()
738 return -EINVAL; in adc_npcx_threshold_mv_to_thrval()
742 api->ref_internal; in adc_npcx_threshold_mv_to_thrval()
773 const struct adc_npcx_config *const config = dev->config; in adc_npcx_init()
774 struct adc_npcx_data *const data = dev->data; in adc_npcx_init()
781 return -ENODEV; in adc_npcx_init()
785 data->adc_dev = dev; in adc_npcx_init()
789 &config->clk_cfg); in adc_npcx_init()
796 &config->clk_cfg, &data->input_clk); in adc_npcx_init()
798 LOG_ERR("Get ADC clock rate error %d", ret); in adc_npcx_init()
803 prescaler = DIV_ROUND_UP(data->input_clk, NPCX_ADC_CLK); in adc_npcx_init()
809 SET_FIELD(inst->ATCTL, NPCX_ATCTL_SCLKDIV_FIELD, prescaler - 1); in adc_npcx_init()
812 SET_FIELD(inst->ATCTL, NPCX_ATCTL_DLY_FIELD, ADC_REGULAR_DLY_VAL); in adc_npcx_init()
815 inst->ADCCNF2 = ADC_REGULAR_ADCCNF2_VAL; in adc_npcx_init()
816 inst->GENDLY = ADC_REGULAR_GENDLY_VAL; in adc_npcx_init()
817 inst->MEAST = ADC_REGULAR_MEAST_VAL; in adc_npcx_init()
820 config->irq_cfg_func(); in adc_npcx_init()
823 adc_context_unlock_unconditionally(&data->ctx); in adc_npcx_init()
825 /* Configure pin-mux for ADC device */ in adc_npcx_init()
826 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); in adc_npcx_init()