Lines Matching +full:iio +full:- +full:aux
1 // SPDX-License-Identifier: GPL-2.0
18 #include <linux/iio/buffer.h>
19 #include <linux/iio/trigger_consumer.h>
20 #include <linux/iio/triggered_buffer.h>
21 #include <linux/iio/trigger.h>
29 * - rate limiting:
31 * - hrtimer:
61 * conversion has 12-bit resolution, whereas with this bit high, the next
62 * conversion has 8-bit resolution. This driver is optimized for 12-bit mode.
68 * SER/DFR - The SER/DFR bit controls the reference mode, either single-ended
75 * auto-wake/suspend mode. In most case this bits should stay zero.
210 TI_TSC2046_V_CHAN(6, bits, AUX), \
231 bit_count = DIV_ROUND_UP(time * NSEC_PER_USEC, priv->time_per_bit_ns); in tsc2046_adc_time_to_count()
234 …dev_dbg(&priv->spi->dev, "Effective speed %u, time per bit: %u, count bits: %u, count samples: %u\… in tsc2046_adc_time_to_count()
235 priv->effective_speed_hz, priv->time_per_bit_ns, in tsc2046_adc_time_to_count()
261 if (priv->internal_vref) in tsc2046_adc_get_cmd()
270 return FIELD_GET(TI_TSC2046_DATA_12BIT, get_unaligned_be16(&buf->data)); in tsc2046_adc_get_value()
276 struct tsc2046_adc_ch_cfg *ch = &priv->ch_cfg[ch_idx]; in tsc2046_adc_read_one()
284 count_skip = tsc2046_adc_time_to_count(priv, ch->settling_time_us); in tsc2046_adc_read_one()
285 max_count = count_skip + ch->oversampling_ratio; in tsc2046_adc_read_one()
291 return -ENOSPC; in tsc2046_adc_read_one()
297 return -ENOMEM; in tsc2046_adc_read_one()
303 return -ENOMEM; in tsc2046_adc_read_one()
311 for (i = 0; i < max_count - 1; i++) in tsc2046_adc_read_one()
327 ret = spi_sync(priv->spi, &msg); in tsc2046_adc_read_one()
329 dev_err_ratelimited(&priv->spi->dev, "SPI transfer failed %pe\n", in tsc2046_adc_read_one()
337 for (i = 0; i < max_count - count_skip; i++) { in tsc2046_adc_read_one()
342 return DIV_ROUND_UP(val_normalized, max_count - count_skip); in tsc2046_adc_read_one()
349 struct tsc2046_adc_ch_cfg *ch = &priv->ch_cfg[ch_idx]; in tsc2046_adc_group_set_layout()
355 offset = priv->l[group - 1].offset + priv->l[group - 1].count; in tsc2046_adc_group_set_layout()
357 count_skip = tsc2046_adc_time_to_count(priv, ch->settling_time_us); in tsc2046_adc_group_set_layout()
358 max_count = count_skip + ch->oversampling_ratio; in tsc2046_adc_group_set_layout()
360 cur = &priv->l[group]; in tsc2046_adc_group_set_layout()
361 cur->offset = offset; in tsc2046_adc_group_set_layout()
362 cur->count = max_count; in tsc2046_adc_group_set_layout()
363 cur->skip = count_skip; in tsc2046_adc_group_set_layout()
365 return sizeof(*priv->tx) * max_count; in tsc2046_adc_group_set_layout()
371 struct tsc2046_adc_group_layout *l = &priv->l[group]; in tsc2046_adc_group_set_cmd()
381 for (i = 0; i < l->count - 1; i++) in tsc2046_adc_group_set_cmd()
382 priv->tx[l->offset + i].cmd = cmd; in tsc2046_adc_group_set_cmd()
385 priv->tx[l->offset + i].cmd = tsc2046_adc_get_cmd(priv, ch_idx, false); in tsc2046_adc_group_set_cmd()
394 l = &priv->l[group]; in tsc2046_adc_get_val()
395 valid_count = l->count - l->skip; in tsc2046_adc_get_val()
398 val = tsc2046_adc_get_value(&priv->rx[l->offset + l->skip + i]); in tsc2046_adc_get_val()
408 struct device *dev = &priv->spi->dev; in tsc2046_adc_scan()
412 ret = spi_sync(priv->spi, &priv->msg); in tsc2046_adc_scan()
418 for (group = 0; group < priv->groups; group++) in tsc2046_adc_scan()
419 priv->scan_buf.data[group] = tsc2046_adc_get_val(priv, group); in tsc2046_adc_scan()
421 ret = iio_push_to_buffers_with_timestamp(indio_dev, &priv->scan_buf, in tsc2046_adc_scan()
423 /* If the consumer is kfifo, we may get a EBUSY here - ignore it. */ in tsc2046_adc_scan()
424 if (ret < 0 && ret != -EBUSY) { in tsc2046_adc_scan()
437 struct iio_dev *indio_dev = pf->indio_dev; in tsc2046_adc_trigger_handler()
440 mutex_lock(&priv->slock); in tsc2046_adc_trigger_handler()
442 mutex_unlock(&priv->slock); in tsc2046_adc_trigger_handler()
444 iio_trigger_notify_done(indio_dev->trig); in tsc2046_adc_trigger_handler()
458 ret = tsc2046_adc_read_one(priv, chan->channel, NULL); in tsc2046_adc_read_raw()
469 * So, it is better to use external voltage-divider driver in tsc2046_adc_read_raw()
472 *val = priv->vref_mv; in tsc2046_adc_read_raw()
473 *val2 = chan->scan_type.realbits; in tsc2046_adc_read_raw()
477 return -EINVAL; in tsc2046_adc_read_raw()
487 mutex_lock(&priv->slock); in tsc2046_adc_update_scan_mode()
490 for_each_set_bit(ch_idx, active_scan_mask, ARRAY_SIZE(priv->l)) { in tsc2046_adc_update_scan_mode()
496 priv->groups = group; in tsc2046_adc_update_scan_mode()
497 priv->xfer.len = size; in tsc2046_adc_update_scan_mode()
498 priv->time_per_scan_us = size * 8 * priv->time_per_bit_ns / NSEC_PER_USEC; in tsc2046_adc_update_scan_mode()
500 if (priv->scan_interval_us < priv->time_per_scan_us) in tsc2046_adc_update_scan_mode()
501 dev_warn(&priv->spi->dev, "The scan interval (%d) is less then calculated scan time (%d)\n", in tsc2046_adc_update_scan_mode()
502 priv->scan_interval_us, priv->time_per_scan_us); in tsc2046_adc_update_scan_mode()
504 mutex_unlock(&priv->slock); in tsc2046_adc_update_scan_mode()
523 * - the interrupt source is based on level shifter attached to the X in tsc2046_adc_timer()
527 * - we should do iio_trigger_poll() at some reduced sample rate in tsc2046_adc_timer()
528 * - we should still trigger for some amount of time after last in tsc2046_adc_timer()
532 spin_lock_irqsave(&priv->state_lock, flags); in tsc2046_adc_timer()
533 switch (priv->state) { in tsc2046_adc_timer()
535 if (priv->poll_cnt < TI_TSC2046_POLL_CNT) { in tsc2046_adc_timer()
536 priv->poll_cnt++; in tsc2046_adc_timer()
537 hrtimer_start(&priv->trig_timer, in tsc2046_adc_timer()
538 ns_to_ktime(priv->scan_interval_us * in tsc2046_adc_timer()
542 if (priv->poll_cnt >= TI_TSC2046_MIN_POLL_CNT) { in tsc2046_adc_timer()
543 priv->state = TSC2046_STATE_POLL_IRQ_DISABLE; in tsc2046_adc_timer()
544 enable_irq(priv->spi->irq); in tsc2046_adc_timer()
546 priv->state = TSC2046_STATE_POLL; in tsc2046_adc_timer()
549 priv->state = TSC2046_STATE_STANDBY; in tsc2046_adc_timer()
550 enable_irq(priv->spi->irq); in tsc2046_adc_timer()
554 disable_irq_nosync(priv->spi->irq); in tsc2046_adc_timer()
557 priv->state = TSC2046_STATE_ENABLE_IRQ; in tsc2046_adc_timer()
559 iio_trigger_poll(priv->trig); in tsc2046_adc_timer()
566 dev_warn(&priv->spi->dev, "Got unexpected state: %i\n", in tsc2046_adc_timer()
567 priv->state); in tsc2046_adc_timer()
570 spin_unlock_irqrestore(&priv->state_lock, flags); in tsc2046_adc_timer()
581 hrtimer_try_to_cancel(&priv->trig_timer); in tsc2046_adc_irq()
583 spin_lock_irqsave(&priv->state_lock, flags); in tsc2046_adc_irq()
584 if (priv->state != TSC2046_STATE_SHUTDOWN) { in tsc2046_adc_irq()
585 priv->state = TSC2046_STATE_ENABLE_IRQ; in tsc2046_adc_irq()
586 priv->poll_cnt = 0; in tsc2046_adc_irq()
589 disable_irq_nosync(priv->spi->irq); in tsc2046_adc_irq()
590 iio_trigger_poll(priv->trig); in tsc2046_adc_irq()
592 spin_unlock_irqrestore(&priv->state_lock, flags); in tsc2046_adc_irq()
608 tim = ns_to_ktime((priv->scan_interval_us - priv->time_per_scan_us) * in tsc2046_adc_reenable_trigger()
610 hrtimer_start(&priv->trig_timer, tim, HRTIMER_MODE_REL_SOFT); in tsc2046_adc_reenable_trigger()
620 spin_lock_irqsave(&priv->state_lock, flags); in tsc2046_adc_set_trigger_state()
621 if (priv->state == TSC2046_STATE_SHUTDOWN) { in tsc2046_adc_set_trigger_state()
622 priv->state = TSC2046_STATE_STANDBY; in tsc2046_adc_set_trigger_state()
623 enable_irq(priv->spi->irq); in tsc2046_adc_set_trigger_state()
625 spin_unlock_irqrestore(&priv->state_lock, flags); in tsc2046_adc_set_trigger_state()
627 spin_lock_irqsave(&priv->state_lock, flags); in tsc2046_adc_set_trigger_state()
629 if (priv->state == TSC2046_STATE_STANDBY || in tsc2046_adc_set_trigger_state()
630 priv->state == TSC2046_STATE_POLL_IRQ_DISABLE) in tsc2046_adc_set_trigger_state()
631 disable_irq_nosync(priv->spi->irq); in tsc2046_adc_set_trigger_state()
633 priv->state = TSC2046_STATE_SHUTDOWN; in tsc2046_adc_set_trigger_state()
634 spin_unlock_irqrestore(&priv->state_lock, flags); in tsc2046_adc_set_trigger_state()
636 hrtimer_cancel(&priv->trig_timer); in tsc2046_adc_set_trigger_state()
659 &priv->effective_speed_hz); in tsc2046_adc_setup_spi_msg()
667 if (!priv->effective_speed_hz) in tsc2046_adc_setup_spi_msg()
668 priv->effective_speed_hz = priv->spi->max_speed_hz; in tsc2046_adc_setup_spi_msg()
671 priv->scan_interval_us = TI_TSC2046_SAMPLE_INTERVAL_US; in tsc2046_adc_setup_spi_msg()
672 priv->time_per_bit_ns = DIV_ROUND_UP(NSEC_PER_SEC, in tsc2046_adc_setup_spi_msg()
673 priv->effective_speed_hz); in tsc2046_adc_setup_spi_msg()
680 for (ch_idx = 0; ch_idx < ARRAY_SIZE(priv->l); ch_idx++) in tsc2046_adc_setup_spi_msg()
684 dev_err(&priv->spi->dev, in tsc2046_adc_setup_spi_msg()
685 …Calculated scan buffer is too big. Try to reduce spi-max-frequency, settling-time-us or oversampli… in tsc2046_adc_setup_spi_msg()
686 return -ENOSPC; in tsc2046_adc_setup_spi_msg()
689 priv->tx = devm_kzalloc(&priv->spi->dev, size, GFP_KERNEL); in tsc2046_adc_setup_spi_msg()
690 if (!priv->tx) in tsc2046_adc_setup_spi_msg()
691 return -ENOMEM; in tsc2046_adc_setup_spi_msg()
693 priv->rx = devm_kzalloc(&priv->spi->dev, size, GFP_KERNEL); in tsc2046_adc_setup_spi_msg()
694 if (!priv->rx) in tsc2046_adc_setup_spi_msg()
695 return -ENOMEM; in tsc2046_adc_setup_spi_msg()
697 priv->xfer.tx_buf = priv->tx; in tsc2046_adc_setup_spi_msg()
698 priv->xfer.rx_buf = priv->rx; in tsc2046_adc_setup_spi_msg()
699 priv->xfer.len = size; in tsc2046_adc_setup_spi_msg()
700 spi_message_init_with_transfers(&priv->msg, &priv->xfer, 1); in tsc2046_adc_setup_spi_msg()
708 struct device *dev = &priv->spi->dev; in tsc2046_adc_parse_fwnode()
711 for (i = 0; i < ARRAY_SIZE(priv->ch_cfg); i++) { in tsc2046_adc_parse_fwnode()
712 priv->ch_cfg[i].settling_time_us = 1; in tsc2046_adc_parse_fwnode()
713 priv->ch_cfg[i].oversampling_ratio = 1; in tsc2046_adc_parse_fwnode()
727 if (reg >= ARRAY_SIZE(priv->ch_cfg)) { in tsc2046_adc_parse_fwnode()
729 child, reg, ARRAY_SIZE(priv->ch_cfg)); in tsc2046_adc_parse_fwnode()
733 ret = fwnode_property_read_u32(child, "settling-time-us", &stl); in tsc2046_adc_parse_fwnode()
735 priv->ch_cfg[reg].settling_time_us = stl; in tsc2046_adc_parse_fwnode()
737 ret = fwnode_property_read_u32(child, "oversampling-ratio", in tsc2046_adc_parse_fwnode()
740 priv->ch_cfg[reg].oversampling_ratio = overs; in tsc2046_adc_parse_fwnode()
747 struct device *dev = &spi->dev; in tsc2046_adc_probe()
753 if (spi->max_speed_hz > TI_TSC2046_MAX_CLK_FREQ) { in tsc2046_adc_probe()
755 spi->max_speed_hz, TI_TSC2046_MAX_CLK_FREQ); in tsc2046_adc_probe()
756 return -EINVAL; in tsc2046_adc_probe()
761 return -EINVAL; in tsc2046_adc_probe()
763 spi->bits_per_word = 8; in tsc2046_adc_probe()
764 spi->mode &= ~SPI_MODE_X_MASK; in tsc2046_adc_probe()
765 spi->mode |= SPI_MODE_0; in tsc2046_adc_probe()
772 return -ENOMEM; in tsc2046_adc_probe()
775 priv->dcfg = dcfg; in tsc2046_adc_probe()
777 priv->spi = spi; in tsc2046_adc_probe()
779 indio_dev->name = TI_TSC2046_NAME; in tsc2046_adc_probe()
780 indio_dev->modes = INDIO_DIRECT_MODE; in tsc2046_adc_probe()
781 indio_dev->channels = dcfg->channels; in tsc2046_adc_probe()
782 indio_dev->num_channels = dcfg->num_channels; in tsc2046_adc_probe()
783 indio_dev->info = &tsc2046_adc_info; in tsc2046_adc_probe()
786 if (ret < 0 && ret != -ENODEV) in tsc2046_adc_probe()
789 priv->internal_vref = ret == -ENODEV; in tsc2046_adc_probe()
790 priv->vref_mv = priv->internal_vref ? TI_TSC2046_INT_VREF : ret / MILLI; in tsc2046_adc_probe()
798 mutex_init(&priv->slock); in tsc2046_adc_probe()
800 ret = devm_request_irq(dev, spi->irq, &tsc2046_adc_irq, in tsc2046_adc_probe()
801 IRQF_NO_AUTOEN, indio_dev->name, indio_dev); in tsc2046_adc_probe()
805 trig = devm_iio_trigger_alloc(dev, "touchscreen-%s", indio_dev->name); in tsc2046_adc_probe()
807 return -ENOMEM; in tsc2046_adc_probe()
809 priv->trig = trig; in tsc2046_adc_probe()
811 trig->ops = &tsc2046_adc_trigger_ops; in tsc2046_adc_probe()
813 spin_lock_init(&priv->state_lock); in tsc2046_adc_probe()
814 priv->state = TSC2046_STATE_SHUTDOWN; in tsc2046_adc_probe()
815 hrtimer_init(&priv->trig_timer, CLOCK_MONOTONIC, in tsc2046_adc_probe()
817 priv->trig_timer.function = tsc2046_adc_timer; in tsc2046_adc_probe()
833 indio_dev->trig = iio_trigger_get(priv->trig); in tsc2046_adc_probe()
839 { .compatible = "ti,tsc2046e-adc", .data = &tsc2046_adc_dcfg_tsc2046e },
845 { "tsc2046e-adc", (unsigned long)&tsc2046_adc_dcfg_tsc2046e },