]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iio: mxs-lradc: make ADC reads not disable touchscreen interrupts
authorKristina Martšenko <kristina.martsenko@gmail.com>
Sun, 25 Jan 2015 16:28:20 +0000 (18:28 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Mar 2015 13:10:58 +0000 (14:10 +0100)
commit 86bf7f3ef7e961e91e16dceb31ae0f583483b204 upstream.

Reading a channel through sysfs, or starting a buffered capture, will
currently turn off the touchscreen. This is because the read_raw() and
buffer preenable()/postdisable() callbacks disable interrupts for all
LRADC channels, including those the touchscreen uses.

So make the callbacks only disable interrupts for the channels they use.
This means channel 0 for read_raw() and channels 0-5 for the buffer (if
the touchscreen is enabled). Since the touchscreen uses different
channels (6 and 7), it no longer gets turned off.

Note that only i.MX28 is affected by this issue, i.MX23 should be fine.

Signed-off-by: Kristina Martšenko <kristina.martsenko@gmail.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/iio/adc/mxs-lradc.c

index cce3cb2ee26ebd68ccde8c0b65c745ac7e44c7a3..9a9b1a73aa86900caffc2e1af3994376b8eab4ca 100644 (file)
@@ -220,6 +220,9 @@ struct mxs_lradc {
         */
 #define TOUCHSCREEN_VCHANNEL1          7
 #define TOUCHSCREEN_VCHANNEL2          6
+#define BUFFER_VCHANS_LIMITED          0x3f
+#define BUFFER_VCHANS_ALL              0xff
+       u8                      buffer_vchans;
 
        /*
         * Furthermore, certain LRADC channels are shared between touchscreen
@@ -819,7 +822,7 @@ static int mxs_lradc_read_single(struct iio_dev *iio_dev, int chan, int *val)
         * used if doing raw sampling.
         */
        if (lradc->soc == IMX28_LRADC)
-               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0),
                        LRADC_CTRL1);
        mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
 
@@ -1266,8 +1269,9 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
        }
 
        if (lradc->soc == IMX28_LRADC)
-               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
-                                                       LRADC_CTRL1);
+               mxs_lradc_reg_clear(lradc,
+                       lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET,
+                       LRADC_CTRL1);
        mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
 
        for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
@@ -1303,8 +1307,9 @@ static int mxs_lradc_buffer_postdisable(struct iio_dev *iio)
 
        mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
        if (lradc->soc == IMX28_LRADC)
-               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
-                                       LRADC_CTRL1);
+               mxs_lradc_reg_clear(lradc,
+                       lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET,
+                       LRADC_CTRL1);
 
        kfree(lradc->buffer);
        mutex_unlock(&lradc->lock);
@@ -1549,6 +1554,11 @@ static int mxs_lradc_probe(struct platform_device *pdev)
 
        touch_ret = mxs_lradc_probe_touchscreen(lradc, node);
 
+       if (touch_ret == 0)
+               lradc->buffer_vchans = BUFFER_VCHANS_LIMITED;
+       else
+               lradc->buffer_vchans = BUFFER_VCHANS_ALL;
+
        /* Grab all IRQ sources */
        for (i = 0; i < of_cfg->irq_count; i++) {
                lradc->irq[i] = platform_get_irq(pdev, i);