Skip to content

Commit

Permalink
Input: imx6ul_tsc - add support for sample averaging
Browse files Browse the repository at this point in the history
The i.MX6UL internal touchscreen controller contains an option to
average upon samples. This feature reduces noise from the produced
touch locations.

This patch adds sample averaging support to the imx6ul_tsc device
driver.

Signed-off-by: Guy Shapiro <guy.shapiro@mobi-wize.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
  • Loading branch information
Guy Shapiro authored and Dmitry Torokhov committed Nov 28, 2016
1 parent ae3b446 commit 031bfed
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ Optional properties:
This value depends on the touch screen.
- pre-charge-time: the touch screen need some time to precharge.
This value depends on the touch screen.
- average-samples: Number of data samples which are averaged for each read.
Valid values 0-4
0 = 1 sample
1 = 4 samples
2 = 8 samples
3 = 16 samples
4 = 32 samples

Example:
tsc: tsc@02040000 {
Expand All @@ -32,5 +39,6 @@ Example:
xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
measure-delay-time = <0xfff>;
pre-charge-time = <0xffff>;
average-samples = <4>;
status = "okay";
};
18 changes: 18 additions & 0 deletions drivers/input/touchscreen/imx6ul_tsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
/* ADC configuration registers field define */
#define ADC_AIEN (0x1 << 7)
#define ADC_CONV_DISABLE 0x1F
#define ADC_AVGE (0x1 << 5)
#define ADC_CAL (0x1 << 7)
#define ADC_CALF 0x2
#define ADC_12BIT_MODE (0x2 << 2)
#define ADC_IPG_CLK 0x00
#define ADC_CLK_DIV_8 (0x03 << 5)
#define ADC_SHORT_SAMPLE_MODE (0x0 << 4)
#define ADC_HARDWARE_TRIGGER (0x1 << 13)
#define ADC_AVGS_SHIFT 14
#define SELECT_CHANNEL_4 0x04
#define SELECT_CHANNEL_1 0x01
#define DISABLE_CONVERSION_INT (0x0 << 7)
Expand Down Expand Up @@ -86,6 +88,7 @@ struct imx6ul_tsc {

int measure_delay_time;
int pre_charge_time;
int average_samples;

struct completion completion;
};
Expand All @@ -107,6 +110,8 @@ static int imx6ul_adc_init(struct imx6ul_tsc *tsc)
adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
adc_cfg |= ADC_12BIT_MODE | ADC_IPG_CLK;
adc_cfg |= ADC_CLK_DIV_8 | ADC_SHORT_SAMPLE_MODE;
if (tsc->average_samples)
adc_cfg |= (tsc->average_samples - 1) << ADC_AVGS_SHIFT;
adc_cfg &= ~ADC_HARDWARE_TRIGGER;
writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG);

Expand All @@ -118,6 +123,8 @@ static int imx6ul_adc_init(struct imx6ul_tsc *tsc)
/* start ADC calibration */
adc_gc = readl(tsc->adc_regs + REG_ADC_GC);
adc_gc |= ADC_CAL;
if (tsc->average_samples)
adc_gc |= ADC_AVGE;
writel(adc_gc, tsc->adc_regs + REG_ADC_GC);

timeout = wait_for_completion_timeout
Expand Down Expand Up @@ -450,6 +457,17 @@ static int imx6ul_tsc_probe(struct platform_device *pdev)
if (err)
tsc->pre_charge_time = 0xfff;

err = of_property_read_u32(np, "average-samples",
&tsc->average_samples);
if (err)
tsc->average_samples = 0;

if (tsc->average_samples > 4) {
dev_err(&pdev->dev, "average-samples (%u) must be [0-4]\n",
tsc->average_samples);
return -EINVAL;
}

err = input_register_device(tsc->input);
if (err) {
dev_err(&pdev->dev,
Expand Down

0 comments on commit 031bfed

Please sign in to comment.