Lines Matching +full:adc +full:- +full:chan

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Freescale MXS LRADC ADC driver
18 #include <linux/mfd/mxs-lradc.h>
43 "mxs-lradc-channel0",
44 "mxs-lradc-channel1",
45 "mxs-lradc-channel2",
46 "mxs-lradc-channel3",
47 "mxs-lradc-channel4",
48 "mxs-lradc-channel5",
52 "mxs-lradc-thresh0",
53 "mxs-lradc-thresh1",
54 "mxs-lradc-channel0",
55 "mxs-lradc-channel1",
56 "mxs-lradc-channel2",
57 "mxs-lradc-channel3",
58 "mxs-lradc-channel4",
59 "mxs-lradc-channel5",
60 "mxs-lradc-button0",
61 "mxs-lradc-button1",
130 static int mxs_lradc_adc_read_single(struct iio_dev *iio_dev, int chan, in mxs_lradc_adc_read_single() argument
133 struct mxs_lradc_adc *adc = iio_priv(iio_dev); in mxs_lradc_adc_read_single() local
134 struct mxs_lradc *lradc = adc->lradc; in mxs_lradc_adc_read_single()
147 reinit_completion(&adc->completion); in mxs_lradc_adc_read_single()
154 if (lradc->soc == IMX28_LRADC) in mxs_lradc_adc_read_single()
156 adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_read_single()
157 writel(0x1, adc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_read_single()
160 if (test_bit(chan, &adc->is_divided)) in mxs_lradc_adc_read_single()
162 adc->base + LRADC_CTRL2 + STMP_OFFSET_REG_SET); in mxs_lradc_adc_read_single()
165 adc->base + LRADC_CTRL2 + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_read_single()
169 adc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_read_single()
170 writel(chan, adc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET); in mxs_lradc_adc_read_single()
172 writel(0, adc->base + LRADC_CH(0)); in mxs_lradc_adc_read_single()
176 adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET); in mxs_lradc_adc_read_single()
177 writel(BIT(0), adc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET); in mxs_lradc_adc_read_single()
180 ret = wait_for_completion_killable_timeout(&adc->completion, HZ); in mxs_lradc_adc_read_single()
182 ret = -ETIMEDOUT; in mxs_lradc_adc_read_single()
187 *val = readl(adc->base + LRADC_CH(0)) & LRADC_CH_VALUE_MASK; in mxs_lradc_adc_read_single()
192 adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_read_single()
211 *val = max - min; in mxs_lradc_adc_read_temp()
217 const struct iio_chan_spec *chan, in mxs_lradc_adc_read_raw() argument
220 struct mxs_lradc_adc *adc = iio_priv(iio_dev); in mxs_lradc_adc_read_raw() local
224 if (chan->type == IIO_TEMP) in mxs_lradc_adc_read_raw()
227 return mxs_lradc_adc_read_single(iio_dev, chan->channel, val); in mxs_lradc_adc_read_raw()
230 if (chan->type == IIO_TEMP) { in mxs_lradc_adc_read_raw()
240 *val = adc->vref_mv[chan->channel]; in mxs_lradc_adc_read_raw()
241 *val2 = chan->scan_type.realbits - in mxs_lradc_adc_read_raw()
242 test_bit(chan->channel, &adc->is_divided); in mxs_lradc_adc_read_raw()
246 if (chan->type == IIO_TEMP) { in mxs_lradc_adc_read_raw()
248 * The calculated value from the ADC is in Kelvin, we in mxs_lradc_adc_read_raw()
249 * want Celsius for hwmon so the offset is -273.15 in mxs_lradc_adc_read_raw()
251 * actually -213.15 * 4 / 1.012 = -1079.644268 in mxs_lradc_adc_read_raw()
253 *val = -1079; in mxs_lradc_adc_read_raw()
259 return -EINVAL; in mxs_lradc_adc_read_raw()
265 return -EINVAL; in mxs_lradc_adc_read_raw()
269 const struct iio_chan_spec *chan, in mxs_lradc_adc_write_raw() argument
272 struct mxs_lradc_adc *adc = iio_priv(iio_dev); in mxs_lradc_adc_write_raw() local
274 adc->scale_avail[chan->channel]; in mxs_lradc_adc_write_raw()
283 ret = -EINVAL; in mxs_lradc_adc_write_raw()
287 clear_bit(chan->channel, &adc->is_divided); in mxs_lradc_adc_write_raw()
292 set_bit(chan->channel, &adc->is_divided); in mxs_lradc_adc_write_raw()
298 ret = -EINVAL; in mxs_lradc_adc_write_raw()
308 const struct iio_chan_spec *chan, in mxs_lradc_adc_write_raw_get_fmt() argument
319 struct mxs_lradc_adc *adc = iio_priv(iio); in mxs_lradc_adc_show_scale_avail() local
323 ch = iio_attr->address; in mxs_lradc_adc_show_scale_avail()
324 for (i = 0; i < ARRAY_SIZE(adc->scale_avail[ch]); i++) in mxs_lradc_adc_show_scale_avail()
326 adc->scale_avail[ch][i].integer, in mxs_lradc_adc_show_scale_avail()
327 adc->scale_avail[ch][i].nano); in mxs_lradc_adc_show_scale_avail()
386 struct mxs_lradc_adc *adc = iio_priv(iio); in mxs_lradc_adc_handle_irq() local
387 struct mxs_lradc *lradc = adc->lradc; in mxs_lradc_adc_handle_irq()
388 unsigned long reg = readl(adc->base + LRADC_CTRL1); in mxs_lradc_adc_handle_irq()
395 if (reg & lradc->buffer_vchans) { in mxs_lradc_adc_handle_irq()
396 spin_lock_irqsave(&adc->lock, flags); in mxs_lradc_adc_handle_irq()
397 iio_trigger_poll(iio->trig); in mxs_lradc_adc_handle_irq()
398 spin_unlock_irqrestore(&adc->lock, flags); in mxs_lradc_adc_handle_irq()
401 complete(&adc->completion); in mxs_lradc_adc_handle_irq()
405 adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_handle_irq()
415 struct iio_dev *iio = pf->indio_dev; in mxs_lradc_adc_trigger_handler()
416 struct mxs_lradc_adc *adc = iio_priv(iio); in mxs_lradc_adc_trigger_handler() local
418 ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET); in mxs_lradc_adc_trigger_handler()
421 for_each_set_bit(i, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) { in mxs_lradc_adc_trigger_handler()
422 adc->buffer[j] = readl(adc->base + LRADC_CH(j)); in mxs_lradc_adc_trigger_handler()
423 writel(chan_value, adc->base + LRADC_CH(j)); in mxs_lradc_adc_trigger_handler()
424 adc->buffer[j] &= LRADC_CH_VALUE_MASK; in mxs_lradc_adc_trigger_handler()
425 adc->buffer[j] /= LRADC_DELAY_TIMER_LOOP; in mxs_lradc_adc_trigger_handler()
429 iio_push_to_buffers_with_timestamp(iio, adc->buffer, pf->timestamp); in mxs_lradc_adc_trigger_handler()
431 iio_trigger_notify_done(iio->trig); in mxs_lradc_adc_trigger_handler()
439 struct mxs_lradc_adc *adc = iio_priv(iio); in mxs_lradc_adc_configure_trigger() local
442 writel(LRADC_DELAY_KICK, adc->base + (LRADC_DELAY(0) + st)); in mxs_lradc_adc_configure_trigger()
455 struct mxs_lradc_adc *adc = iio_priv(iio); in mxs_lradc_adc_trigger_init() local
457 trig = devm_iio_trigger_alloc(&iio->dev, "%s-dev%i", iio->name, in mxs_lradc_adc_trigger_init()
458 iio->id); in mxs_lradc_adc_trigger_init()
460 return -ENOMEM; in mxs_lradc_adc_trigger_init()
462 trig->dev.parent = adc->dev; in mxs_lradc_adc_trigger_init()
464 trig->ops = &mxs_lradc_adc_trigger_ops; in mxs_lradc_adc_trigger_init()
470 adc->trig = trig; in mxs_lradc_adc_trigger_init()
477 struct mxs_lradc_adc *adc = iio_priv(iio); in mxs_lradc_adc_trigger_remove() local
479 iio_trigger_unregister(adc->trig); in mxs_lradc_adc_trigger_remove()
484 struct mxs_lradc_adc *adc = iio_priv(iio); in mxs_lradc_adc_buffer_preenable() local
485 struct mxs_lradc *lradc = adc->lradc; in mxs_lradc_adc_buffer_preenable()
486 int chan, ofs = 0; in mxs_lradc_adc_buffer_preenable() local
492 ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET); in mxs_lradc_adc_buffer_preenable()
494 if (lradc->soc == IMX28_LRADC) in mxs_lradc_adc_buffer_preenable()
495 writel(lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET, in mxs_lradc_adc_buffer_preenable()
496 adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_buffer_preenable()
497 writel(lradc->buffer_vchans, in mxs_lradc_adc_buffer_preenable()
498 adc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_buffer_preenable()
500 for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) { in mxs_lradc_adc_buffer_preenable()
501 ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs); in mxs_lradc_adc_buffer_preenable()
504 writel(chan_value, adc->base + LRADC_CH(ofs)); in mxs_lradc_adc_buffer_preenable()
510 adc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_buffer_preenable()
511 writel(ctrl4_clr, adc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_buffer_preenable()
512 writel(ctrl4_set, adc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET); in mxs_lradc_adc_buffer_preenable()
513 writel(ctrl1_irq, adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET); in mxs_lradc_adc_buffer_preenable()
515 adc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_SET); in mxs_lradc_adc_buffer_preenable()
522 struct mxs_lradc_adc *adc = iio_priv(iio); in mxs_lradc_adc_buffer_postdisable() local
523 struct mxs_lradc *lradc = adc->lradc; in mxs_lradc_adc_buffer_postdisable()
526 adc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_buffer_postdisable()
528 writel(lradc->buffer_vchans, in mxs_lradc_adc_buffer_postdisable()
529 adc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_buffer_postdisable()
530 if (lradc->soc == IMX28_LRADC) in mxs_lradc_adc_buffer_postdisable()
531 writel(lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET, in mxs_lradc_adc_buffer_postdisable()
532 adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR); in mxs_lradc_adc_buffer_postdisable()
540 struct mxs_lradc_adc *adc = iio_priv(iio); in mxs_lradc_adc_validate_scan_mask() local
541 struct mxs_lradc *lradc = adc->lradc; in mxs_lradc_adc_validate_scan_mask()
546 if (lradc->use_touchbutton) in mxs_lradc_adc_validate_scan_mask()
548 if (lradc->touchscreen_wire == MXS_LRADC_TOUCHSCREEN_4WIRE) in mxs_lradc_adc_validate_scan_mask()
550 if (lradc->touchscreen_wire == MXS_LRADC_TOUCHSCREEN_5WIRE) in mxs_lradc_adc_validate_scan_mask()
553 if (lradc->use_touchbutton) in mxs_lradc_adc_validate_scan_mask()
555 if (lradc->touchscreen_wire) in mxs_lradc_adc_validate_scan_mask()
617 .scan_index = -1,
653 .scan_index = -1,
664 static void mxs_lradc_adc_hw_init(struct mxs_lradc_adc *adc) in mxs_lradc_adc_hw_init() argument
666 /* The ADC always uses DELAY CHANNEL 0. */ in mxs_lradc_adc_hw_init()
671 /* Configure DELAY CHANNEL 0 for generic ADC sampling. */ in mxs_lradc_adc_hw_init()
672 writel(adc_cfg, adc->base + LRADC_DELAY(0)); in mxs_lradc_adc_hw_init()
679 writel(0, adc->base + LRADC_CTRL2); in mxs_lradc_adc_hw_init()
682 static void mxs_lradc_adc_hw_stop(struct mxs_lradc_adc *adc) in mxs_lradc_adc_hw_stop() argument
684 writel(0, adc->base + LRADC_DELAY(0)); in mxs_lradc_adc_hw_stop()
689 struct device *dev = &pdev->dev; in mxs_lradc_adc_probe()
690 struct mxs_lradc *lradc = dev_get_drvdata(dev->parent); in mxs_lradc_adc_probe()
691 struct mxs_lradc_adc *adc; in mxs_lradc_adc_probe() local
699 iio = devm_iio_device_alloc(dev, sizeof(*adc)); in mxs_lradc_adc_probe()
702 return -ENOMEM; in mxs_lradc_adc_probe()
705 adc = iio_priv(iio); in mxs_lradc_adc_probe()
706 adc->lradc = lradc; in mxs_lradc_adc_probe()
707 adc->dev = dev; in mxs_lradc_adc_probe()
711 return -EINVAL; in mxs_lradc_adc_probe()
713 adc->base = devm_ioremap(dev, iores->start, resource_size(iores)); in mxs_lradc_adc_probe()
714 if (!adc->base) in mxs_lradc_adc_probe()
715 return -ENOMEM; in mxs_lradc_adc_probe()
717 init_completion(&adc->completion); in mxs_lradc_adc_probe()
718 spin_lock_init(&adc->lock); in mxs_lradc_adc_probe()
722 iio->name = pdev->name; in mxs_lradc_adc_probe()
723 iio->dev.of_node = dev->parent->of_node; in mxs_lradc_adc_probe()
724 iio->info = &mxs_lradc_adc_iio_info; in mxs_lradc_adc_probe()
725 iio->modes = INDIO_DIRECT_MODE; in mxs_lradc_adc_probe()
726 iio->masklength = LRADC_MAX_TOTAL_CHANS; in mxs_lradc_adc_probe()
728 if (lradc->soc == IMX23_LRADC) { in mxs_lradc_adc_probe()
729 iio->channels = mx23_lradc_chan_spec; in mxs_lradc_adc_probe()
730 iio->num_channels = ARRAY_SIZE(mx23_lradc_chan_spec); in mxs_lradc_adc_probe()
734 iio->channels = mx28_lradc_chan_spec; in mxs_lradc_adc_probe()
735 iio->num_channels = ARRAY_SIZE(mx28_lradc_chan_spec); in mxs_lradc_adc_probe()
740 ret = stmp_reset_block(adc->base); in mxs_lradc_adc_probe()
749 virq = irq_of_parse_and_map(dev->parent->of_node, irq); in mxs_lradc_adc_probe()
767 adc->vref_mv = mxs_lradc_adc_vref_mv[lradc->soc]; in mxs_lradc_adc_probe()
769 /* Populate available ADC input ranges */ in mxs_lradc_adc_probe()
771 for (s = 0; s < ARRAY_SIZE(adc->scale_avail[i]); s++) { in mxs_lradc_adc_probe()
777 * Vref >> (realbits - s) in mxs_lradc_adc_probe()
781 scale_uv = ((u64)adc->vref_mv[i] * 100000000) >> in mxs_lradc_adc_probe()
782 (LRADC_RESOLUTION - s); in mxs_lradc_adc_probe()
783 adc->scale_avail[i][s].nano = in mxs_lradc_adc_probe()
785 adc->scale_avail[i][s].integer = scale_uv; in mxs_lradc_adc_probe()
790 mxs_lradc_adc_hw_init(adc); in mxs_lradc_adc_probe()
802 mxs_lradc_adc_hw_stop(adc); in mxs_lradc_adc_probe()
812 struct mxs_lradc_adc *adc = iio_priv(iio); in mxs_lradc_adc_remove() local
815 mxs_lradc_adc_hw_stop(adc); in mxs_lradc_adc_remove()
824 .name = "mxs-lradc-adc",
832 MODULE_DESCRIPTION("Freescale MXS LRADC driver general purpose ADC driver");
834 MODULE_ALIAS("platform:mxs-lradc-adc");