]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
mfd: Add pdata to set mc13783-ts conversion delay
authorMichael Thalmeier <michael.thalmeier@hale.at>
Mon, 20 Feb 2012 11:18:13 +0000 (12:18 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Tue, 6 Mar 2012 17:46:30 +0000 (18:46 +0100)
MC13783 can be programmed to wait some clock cycles between the
touchscreen polarization and the resistance conversion. This is
needed to adjust for touchscreens with high capacitance between
plates.

Signed-off-by: Michael Thalmeier <michael.thalmeier@hale.at>
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
drivers/hwmon/mc13783-adc.c
drivers/input/touchscreen/mc13783_ts.c
drivers/mfd/mc13xxx-core.c
include/linux/mfd/mc13xxx.h

index ef65ab56b0948a23da0d797c01c321fee45fba4f..6acd04427723fcadac1088e0197f6f8d2700ec84 100644 (file)
@@ -53,7 +53,7 @@ static int mc13783_adc_read(struct device *dev,
 
        ret = mc13xxx_adc_do_conversion(priv->mc13xxx,
                        MC13XXX_ADC_MODE_MULT_CHAN,
-                       channel, sample);
+                       channel, 0, 0, sample);
        if (ret)
                return ret;
 
index ede02743eac1997b426a7970f96429a486ea4059..48dc5b0d26f1a0b59039532318967ec5c500b862 100644 (file)
@@ -39,6 +39,7 @@ struct mc13783_ts_priv {
        struct delayed_work work;
        struct workqueue_struct *workq;
        unsigned int sample[4];
+       struct mc13xxx_ts_platform_data *touch;
 };
 
 static irqreturn_t mc13783_ts_handler(int irq, void *data)
@@ -125,7 +126,9 @@ static void mc13783_ts_work(struct work_struct *work)
        unsigned int channel = 12;
 
        if (mc13xxx_adc_do_conversion(priv->mc13xxx,
-                               mode, channel, priv->sample) == 0)
+                               mode, channel,
+                               priv->touch->ato, priv->touch->atox,
+                               priv->sample) == 0)
                mc13783_ts_report_sample(priv);
 }
 
@@ -179,6 +182,12 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
        INIT_DELAYED_WORK(&priv->work, mc13783_ts_work);
        priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
        priv->idev = idev;
+       priv->touch = dev_get_platdata(&pdev->dev);
+       if (!priv->touch) {
+               dev_err(&pdev->dev, "missing platform data\n");
+               ret = -ENODEV;
+               goto err_free_mem;
+       }
 
        /*
         * We need separate workqueue because mc13783_adc_do_conversion
index 7122386b4e3cf1830dbb3cab2f552efefeb43834..9fd4f63c45cc18b2e60dc41085425ff3d35f04b8 100644 (file)
@@ -560,6 +560,8 @@ EXPORT_SYMBOL(mc13xxx_get_flags);
 
 #define MC13XXX_ADC1_CHAN0_SHIFT       5
 #define MC13XXX_ADC1_CHAN1_SHIFT       8
+#define MC13783_ADC1_ATO_SHIFT         11
+#define MC13783_ADC1_ATOX              (1 << 19)
 
 struct mc13xxx_adcdone_data {
        struct mc13xxx *mc13xxx;
@@ -580,7 +582,8 @@ static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data)
 #define MC13XXX_ADC_WORKING (1 << 0)
 
 int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
-               unsigned int channel, unsigned int *sample)
+               unsigned int channel, u8 ato, bool atox,
+               unsigned int *sample)
 {
        u32 adc0, adc1, old_adc0;
        int i, ret;
@@ -631,6 +634,9 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
                return -EINVAL;
        }
 
+       adc1 |= ato << MC13783_ADC1_ATO_SHIFT;
+       if (atox)
+               adc1 |= MC13783_ADC1_ATOX;
        dev_dbg(&mc13xxx->spidev->dev, "%s: request irq\n", __func__);
        mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE,
                        mc13xxx_handler_adcdone, __func__, &adcdone_data);
@@ -813,7 +819,8 @@ err_revision:
                mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
 
        if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN)
-               mc13xxx_add_subdevice(mc13xxx, "%s-ts");
+               mc13xxx_add_subdevice_pdata(mc13xxx, "%s-ts",
+                               &pdata->touch, sizeof(pdata->touch));
 
        if (pdata) {
                mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
index b86ee45c8b03fc1b57f233543bbd0f0859167532..10e038bac8dd106f742dc283aa69e7f5cbc495e7 100644 (file)
@@ -38,7 +38,8 @@ int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq);
 int mc13xxx_get_flags(struct mc13xxx *mc13xxx);
 
 int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx,
-               unsigned int mode, unsigned int channel, unsigned int *sample);
+               unsigned int mode, unsigned int channel,
+               u8 ato, bool atox, unsigned int *sample);
 
 #define MC13XXX_IRQ_ADCDONE    0
 #define MC13XXX_IRQ_ADCBISDONE 1
@@ -157,6 +158,18 @@ struct mc13xxx_buttons_platform_data {
        unsigned short b3on_key;
 };
 
+struct mc13xxx_ts_platform_data {
+       /* Delay between Touchscreen polarization and ADC Conversion.
+        * Given in clock ticks of a 32 kHz clock which gives a granularity of
+        * about 30.5ms */
+       u8 ato;
+
+#define MC13783_TS_ATO_FIRST false
+#define MC13783_TS_ATO_EACH  true
+       /* Use the ATO delay only for the first conversion or for each one */
+       bool atox;
+};
+
 struct mc13xxx_platform_data {
 #define MC13XXX_USE_TOUCHSCREEN (1 << 0)
 #define MC13XXX_USE_CODEC      (1 << 1)
@@ -167,6 +180,7 @@ struct mc13xxx_platform_data {
        struct mc13xxx_regulator_platform_data regulators;
        struct mc13xxx_leds_platform_data *leds;
        struct mc13xxx_buttons_platform_data *buttons;
+       struct mc13xxx_ts_platform_data touch;
 };
 
 #define MC13XXX_ADC_MODE_TS            1