Input: imx6ul_tsc - add support for sample averaging
authorGuy Shapiro <guy.shapiro@mobi-wize.com>
Mon, 28 Nov 2016 04:40:39 +0000 (20:40 -0800)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 28 Nov 2016 04:45:14 +0000 (20:45 -0800)
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>
Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
drivers/input/touchscreen/imx6ul_tsc.c

index 853dff96dd9f7650f6d6b9787266d001a9ded047..a66069f6db666dc4fb5c8300c306329450be859d 100644 (file)
@@ -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 {
@@ -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";
        };
index 8275267eac25441f308e6103e82d48830d1feb71..00b336f37fb30312bcd4a5efd8c1ff2c4078d593 100644 (file)
@@ -25,6 +25,7 @@
 /* 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)
@@ -32,6 +33,7 @@
 #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)
@@ -86,6 +88,7 @@ struct imx6ul_tsc {
 
        int measure_delay_time;
        int pre_charge_time;
+       int average_samples;
 
        struct completion completion;
 };
@@ -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);
 
@@ -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
@@ -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,