| From 86bf7f3ef7e961e91e16dceb31ae0f583483b204 Mon Sep 17 00:00:00 2001 |
| From: Kristina Martšenko <kristina.martsenko@gmail.com> |
| Date: Sun, 25 Jan 2015 18:28:20 +0200 |
| Subject: iio: mxs-lradc: make ADC reads not disable touchscreen interrupts |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Kristina Martšenko <kristina.martsenko@gmail.com> |
| |
| 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 | 20 +++++++++++++++----- |
| 1 file changed, 15 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/staging/iio/adc/mxs-lradc.c |
| +++ b/drivers/staging/iio/adc/mxs-lradc.c |
| @@ -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 |
| * 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(st |
| } |
| |
| 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( |
| |
| 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 platfo |
| |
| 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); |