Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: adc: ti_am335x_adc: make sample delay, open delay, averaging DT parameters

Add optional DT properties to set open delay, sample delay and number
of averages per sample for each adc step. Open delay, sample delay
and averaging are some of the parameters that affect the sampling rate
and accuracy of the sample. Making these parameters configurable via
DT will help in balancing speed vs accuracy.

Signed-off-by: Vignesh R <vigneshr@ti.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Vignesh R and committed by
Jonathan Cameron
5dc11e81 feca56ff

+72 -6
+24
Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
··· 42 42 hardware knob for adjusting the amount of "settling 43 43 time". 44 44 45 + - child "adc" 46 + ti,chan-step-opendelay: List of open delays for each channel of 47 + ADC in the order of ti,adc-channels. The 48 + value corresponds to the number of ADC 49 + clock cycles to wait after applying the 50 + step configuration registers and before 51 + sending the start of ADC conversion. 52 + Maximum value is 0x3FFFF. 53 + ti,chan-step-sampledelay: List of sample delays for each channel 54 + of ADC in the order of ti,adc-channels. 55 + The value corresponds to the number of 56 + ADC clock cycles to sample (to hold 57 + start of conversion high). 58 + Maximum value is 0xFF. 59 + ti,chan-step-avg: Number of averages to be performed for each 60 + channel of ADC. If average is 16 then input 61 + is sampled 16 times and averaged to get more 62 + accurate value. This increases the time taken 63 + by ADC to generate a sample. Valid range is 0 64 + average to 16 averages. Maximum value is 16. 65 + 45 66 Example: 46 67 tscadc: tscadc@44e0d000 { 47 68 compatible = "ti,am3359-tscadc"; ··· 76 55 77 56 adc { 78 57 ti,adc-channels = <4 5 6 7>; 58 + ti,chan-step-opendelay = <0x098 0x3ffff 0x098 0x0>; 59 + ti,chan-step-sampledelay = <0xff 0x0 0xf 0x0>; 60 + ti,chan-step-avg = <16 2 4 8>; 79 61 }; 80 62 }
+48 -6
drivers/iio/adc/ti_am335x_adc.c
··· 37 37 u8 channel_step[8]; 38 38 int buffer_en_ch_steps; 39 39 u16 data[8]; 40 + u32 open_delay[8], sample_delay[8], step_avg[8]; 40 41 }; 41 42 42 43 static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg) ··· 86 85 static void tiadc_step_config(struct iio_dev *indio_dev) 87 86 { 88 87 struct tiadc_device *adc_dev = iio_priv(indio_dev); 88 + struct device *dev = adc_dev->mfd_tscadc->dev; 89 89 unsigned int stepconfig; 90 90 int i, steps = 0; 91 91 ··· 100 98 * needs to be given to ADC to digitalize data. 101 99 */ 102 100 103 - if (iio_buffer_enabled(indio_dev)) 104 - stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1 105 - | STEPCONFIG_MODE_SWCNT; 106 - else 107 - stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1; 108 101 109 102 for (i = 0; i < adc_dev->channels; i++) { 110 103 int chan; 111 104 112 105 chan = adc_dev->channel_line[i]; 106 + 107 + if (adc_dev->step_avg[i] > STEPCONFIG_AVG_16) { 108 + dev_warn(dev, "chan %d step_avg truncating to %d\n", 109 + chan, STEPCONFIG_AVG_16); 110 + adc_dev->step_avg[i] = STEPCONFIG_AVG_16; 111 + } 112 + 113 + if (adc_dev->step_avg[i]) 114 + stepconfig = 115 + STEPCONFIG_AVG(ffs(adc_dev->step_avg[i]) - 1) | 116 + STEPCONFIG_FIFO1; 117 + else 118 + stepconfig = STEPCONFIG_FIFO1; 119 + 120 + if (iio_buffer_enabled(indio_dev)) 121 + stepconfig |= STEPCONFIG_MODE_SWCNT; 122 + 113 123 tiadc_writel(adc_dev, REG_STEPCONFIG(steps), 114 124 stepconfig | STEPCONFIG_INP(chan)); 125 + 126 + if (adc_dev->open_delay[i] > STEPDELAY_OPEN_MASK) { 127 + dev_warn(dev, "chan %d open delay truncating to 0x3FFFF\n", 128 + chan); 129 + adc_dev->open_delay[i] = STEPDELAY_OPEN_MASK; 130 + } 131 + 132 + if (adc_dev->sample_delay[i] > 0xFF) { 133 + dev_warn(dev, "chan %d sample delay truncating to 0xFF\n", 134 + chan); 135 + adc_dev->sample_delay[i] = 0xFF; 136 + } 137 + 115 138 tiadc_writel(adc_dev, REG_STEPDELAY(steps), 116 - STEPCONFIG_OPENDLY); 139 + STEPDELAY_OPEN(adc_dev->open_delay[i]) | 140 + STEPDELAY_SAMPLE(adc_dev->sample_delay[i])); 141 + 117 142 adc_dev->channel_step[i] = steps; 118 143 steps++; 119 144 } ··· 435 406 436 407 of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) { 437 408 adc_dev->channel_line[channels] = val; 409 + 410 + /* Set Default values for optional DT parameters */ 411 + adc_dev->open_delay[channels] = STEPCONFIG_OPENDLY; 412 + adc_dev->sample_delay[channels] = STEPCONFIG_SAMPLEDLY; 413 + adc_dev->step_avg[channels] = 16; 414 + 438 415 channels++; 439 416 } 417 + 418 + of_property_read_u32_array(node, "ti,chan-step-avg", 419 + adc_dev->step_avg, channels); 420 + of_property_read_u32_array(node, "ti,chan-step-opendelay", 421 + adc_dev->open_delay, channels); 422 + of_property_read_u32_array(node, "ti,chan-step-sampledelay", 423 + adc_dev->sample_delay, channels); 440 424 441 425 adc_dev->channels = channels; 442 426 return 0;