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>
This commit is contained in:
Родитель
feca56ff40
Коммит
5dc11e8106
|
@ -42,6 +42,27 @@ Optional properties:
|
||||||
hardware knob for adjusting the amount of "settling
|
hardware knob for adjusting the amount of "settling
|
||||||
time".
|
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:
|
Example:
|
||||||
tscadc: tscadc@44e0d000 {
|
tscadc: tscadc@44e0d000 {
|
||||||
compatible = "ti,am3359-tscadc";
|
compatible = "ti,am3359-tscadc";
|
||||||
|
@ -55,5 +76,8 @@ Example:
|
||||||
|
|
||||||
adc {
|
adc {
|
||||||
ti,adc-channels = <4 5 6 7>;
|
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>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ struct tiadc_device {
|
||||||
u8 channel_step[8];
|
u8 channel_step[8];
|
||||||
int buffer_en_ch_steps;
|
int buffer_en_ch_steps;
|
||||||
u16 data[8];
|
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)
|
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)
|
static void tiadc_step_config(struct iio_dev *indio_dev)
|
||||||
{
|
{
|
||||||
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||||
|
struct device *dev = adc_dev->mfd_tscadc->dev;
|
||||||
unsigned int stepconfig;
|
unsigned int stepconfig;
|
||||||
int i, steps = 0;
|
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.
|
* 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++) {
|
for (i = 0; i < adc_dev->channels; i++) {
|
||||||
int chan;
|
int chan;
|
||||||
|
|
||||||
chan = adc_dev->channel_line[i];
|
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),
|
tiadc_writel(adc_dev, REG_STEPCONFIG(steps),
|
||||||
stepconfig | STEPCONFIG_INP(chan));
|
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),
|
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;
|
adc_dev->channel_step[i] = steps;
|
||||||
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) {
|
of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
|
||||||
adc_dev->channel_line[channels] = 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++;
|
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;
|
adc_dev->channels = channels;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче