summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt24
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c54
2 files changed, 72 insertions, 6 deletions
diff --git a/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt b/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
index 6c4fb34823d3..b1163bf97146 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
@@ -42,6 +42,27 @@ Optional properties:
hardware knob for adjusting the amount of "settling
time".
+- child "adc"
+ ti,chan-step-opendelay: List of open delays for each channel of
+ ADC in the order of ti,adc-channels. The
+ value corresponds to the number of ADC
+ clock cycles to wait after applying the
+ step configuration registers and before
+ sending the start of ADC conversion.
+ Maximum value is 0x3FFFF.
+ ti,chan-step-sampledelay: List of sample delays for each channel
+ of ADC in the order of ti,adc-channels.
+ The value corresponds to the number of
+ ADC clock cycles to sample (to hold
+ start of conversion high).
+ Maximum value is 0xFF.
+ ti,chan-step-avg: Number of averages to be performed for each
+ channel of ADC. If average is 16 then input
+ is sampled 16 times and averaged to get more
+ accurate value. This increases the time taken
+ by ADC to generate a sample. Valid range is 0
+ average to 16 averages. Maximum value is 16.
+
Example:
tscadc: tscadc@44e0d000 {
compatible = "ti,am3359-tscadc";
@@ -55,5 +76,8 @@ Example:
adc {
ti,adc-channels = <4 5 6 7>;
+ ti,chan-step-opendelay = <0x098 0x3ffff 0x098 0x0>;
+ ti,chan-step-sampledelay = <0xff 0x0 0xf 0x0>;
+ ti,chan-step-avg = <16 2 4 8>;
};
}
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index 42e444044ea5..942320e32753 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -37,6 +37,7 @@ struct tiadc_device {
u8 channel_step[8];
int buffer_en_ch_steps;
u16 data[8];
+ u32 open_delay[8], sample_delay[8], step_avg[8];
};
static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
@@ -85,6 +86,7 @@ static u32 get_adc_step_bit(struct tiadc_device *adc_dev, int chan)
static void tiadc_step_config(struct iio_dev *indio_dev)
{
struct tiadc_device *adc_dev = iio_priv(indio_dev);
+ struct device *dev = adc_dev->mfd_tscadc->dev;
unsigned int stepconfig;
int i, steps = 0;
@@ -98,20 +100,47 @@ static void tiadc_step_config(struct iio_dev *indio_dev)
* needs to be given to ADC to digitalize data.
*/
- if (iio_buffer_enabled(indio_dev))
- stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1
- | STEPCONFIG_MODE_SWCNT;
- else
- stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
for (i = 0; i < adc_dev->channels; i++) {
int chan;
chan = adc_dev->channel_line[i];
+
+ if (adc_dev->step_avg[i] > STEPCONFIG_AVG_16) {
+ dev_warn(dev, "chan %d step_avg truncating to %d\n",
+ chan, STEPCONFIG_AVG_16);
+ adc_dev->step_avg[i] = STEPCONFIG_AVG_16;
+ }
+
+ if (adc_dev->step_avg[i])
+ stepconfig =
+ STEPCONFIG_AVG(ffs(adc_dev->step_avg[i]) - 1) |
+ STEPCONFIG_FIFO1;
+ else
+ stepconfig = STEPCONFIG_FIFO1;
+
+ if (iio_buffer_enabled(indio_dev))
+ stepconfig |= STEPCONFIG_MODE_SWCNT;
+
tiadc_writel(adc_dev, REG_STEPCONFIG(steps),
stepconfig | STEPCONFIG_INP(chan));
+
+ if (adc_dev->open_delay[i] > STEPDELAY_OPEN_MASK) {
+ dev_warn(dev, "chan %d open delay truncating to 0x3FFFF\n",
+ chan);
+ adc_dev->open_delay[i] = STEPDELAY_OPEN_MASK;
+ }
+
+ if (adc_dev->sample_delay[i] > 0xFF) {
+ dev_warn(dev, "chan %d sample delay truncating to 0xFF\n",
+ chan);
+ adc_dev->sample_delay[i] = 0xFF;
+ }
+
tiadc_writel(adc_dev, REG_STEPDELAY(steps),
- STEPCONFIG_OPENDLY);
+ STEPDELAY_OPEN(adc_dev->open_delay[i]) |
+ STEPDELAY_SAMPLE(adc_dev->sample_delay[i]));
+
adc_dev->channel_step[i] = steps;
steps++;
}
@@ -406,9 +435,22 @@ static int tiadc_parse_dt(struct platform_device *pdev,
of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
adc_dev->channel_line[channels] = val;
+
+ /* Set Default values for optional DT parameters */
+ adc_dev->open_delay[channels] = STEPCONFIG_OPENDLY;
+ adc_dev->sample_delay[channels] = STEPCONFIG_SAMPLEDLY;
+ adc_dev->step_avg[channels] = 16;
+
channels++;
}
+ of_property_read_u32_array(node, "ti,chan-step-avg",
+ adc_dev->step_avg, channels);
+ of_property_read_u32_array(node, "ti,chan-step-opendelay",
+ adc_dev->open_delay, channels);
+ of_property_read_u32_array(node, "ti,chan-step-sampledelay",
+ adc_dev->sample_delay, channels);
+
adc_dev->channels = channels;
return 0;
}