]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 11 Mar 2015 14:54:59 +0000 (15:54 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 11 Mar 2015 14:54:59 +0000 (15:54 +0100)
added patches:
iio-ad5686-fix-optional-reference-voltage-declaration.patch
iio-adc-mcp3422-fix-incorrect-scales-table.patch
iio-imu-adis16400-fix-sign-extension.patch
iio-mxs-lradc-fix-iio-channel-map-regression.patch
iio-mxs-lradc-make-adc-reads-not-disable-touchscreen-interrupts.patch
iio-mxs-lradc-make-adc-reads-not-unschedule-touchscreen-conversions.patch
iio-mxs-lradc-only-update-the-buffer-when-its-conversions-have-finished.patch
iio-mxs-lradc-separate-touchscreen-and-buffer-virtual-channels.patch

queue-3.14/iio-ad5686-fix-optional-reference-voltage-declaration.patch [new file with mode: 0644]
queue-3.14/iio-adc-mcp3422-fix-incorrect-scales-table.patch [new file with mode: 0644]
queue-3.14/iio-imu-adis16400-fix-sign-extension.patch [new file with mode: 0644]
queue-3.14/iio-mxs-lradc-fix-iio-channel-map-regression.patch [new file with mode: 0644]
queue-3.14/iio-mxs-lradc-make-adc-reads-not-disable-touchscreen-interrupts.patch [new file with mode: 0644]
queue-3.14/iio-mxs-lradc-make-adc-reads-not-unschedule-touchscreen-conversions.patch [new file with mode: 0644]
queue-3.14/iio-mxs-lradc-only-update-the-buffer-when-its-conversions-have-finished.patch [new file with mode: 0644]
queue-3.14/iio-mxs-lradc-separate-touchscreen-and-buffer-virtual-channels.patch [new file with mode: 0644]
queue-3.14/series

diff --git a/queue-3.14/iio-ad5686-fix-optional-reference-voltage-declaration.patch b/queue-3.14/iio-ad5686-fix-optional-reference-voltage-declaration.patch
new file mode 100644 (file)
index 0000000..997af79
--- /dev/null
@@ -0,0 +1,35 @@
+From da019f59cb16570e78feaf10380ac65a3a06861e Mon Sep 17 00:00:00 2001
+From: Urs Fässler <urs.fassler@bytesatwork.ch>
+Date: Mon, 2 Feb 2015 17:12:23 +0100
+Subject: iio: ad5686: fix optional reference voltage declaration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Urs Fässler <urs.fassler@bytesatwork.ch>
+
+commit da019f59cb16570e78feaf10380ac65a3a06861e upstream.
+
+When not using the "_optional" function, a dummy regulator is returned
+and the driver fails to initialize.
+
+Signed-off-by: Urs Fässler <urs.fassler@bytesatwork.ch>
+Acked-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/dac/ad5686.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/dac/ad5686.c
++++ b/drivers/iio/dac/ad5686.c
+@@ -322,7 +322,7 @@ static int ad5686_probe(struct spi_devic
+       st = iio_priv(indio_dev);
+       spi_set_drvdata(spi, indio_dev);
+-      st->reg = devm_regulator_get(&spi->dev, "vcc");
++      st->reg = devm_regulator_get_optional(&spi->dev, "vcc");
+       if (!IS_ERR(st->reg)) {
+               ret = regulator_enable(st->reg);
+               if (ret)
diff --git a/queue-3.14/iio-adc-mcp3422-fix-incorrect-scales-table.patch b/queue-3.14/iio-adc-mcp3422-fix-incorrect-scales-table.patch
new file mode 100644 (file)
index 0000000..f3d1bce
--- /dev/null
@@ -0,0 +1,48 @@
+From 9e128ced3851d2802b6db870f6b2e93f449ce013 Mon Sep 17 00:00:00 2001
+From: Angelo Compagnucci <angelo.compagnucci@gmail.com>
+Date: Wed, 4 Feb 2015 15:14:26 +0100
+Subject: iio:adc:mcp3422 Fix incorrect scales table
+
+From: Angelo Compagnucci <angelo.compagnucci@gmail.com>
+
+commit 9e128ced3851d2802b6db870f6b2e93f449ce013 upstream.
+
+This patch fixes uncorrect order of mcp3422_scales table, the values
+was erroneously transposed.
+It removes also an unused array and a wrong comment.
+
+Signed-off-by: Angelo Compagnucci <angelo.compagnucci@gmail.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/mcp3422.c |   17 ++++-------------
+ 1 file changed, 4 insertions(+), 13 deletions(-)
+
+--- a/drivers/iio/adc/mcp3422.c
++++ b/drivers/iio/adc/mcp3422.c
+@@ -57,20 +57,11 @@
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+       }
+-/* LSB is in nV to eliminate floating point */
+-static const u32 rates_to_lsb[] = {1000000, 250000, 62500, 15625};
+-
+-/*
+- *  scales calculated as:
+- *  rates_to_lsb[sample_rate] / (1 << pga);
+- *  pga is 1 for 0, 2
+- */
+-
+ static const int mcp3422_scales[4][4] = {
+-      { 1000000, 250000, 62500, 15625 },
+-      { 500000 , 125000, 31250, 7812 },
+-      { 250000 , 62500 , 15625, 3906 },
+-      { 125000 , 31250 , 7812 , 1953 } };
++      { 1000000, 500000, 250000, 125000 },
++      { 250000 , 125000, 62500 , 31250  },
++      { 62500  , 31250 , 15625 , 7812   },
++      { 15625  , 7812  , 3906  , 1953   } };
+ /* Constant msleep times for data acquisitions */
+ static const int mcp3422_read_times[4] = {
diff --git a/queue-3.14/iio-imu-adis16400-fix-sign-extension.patch b/queue-3.14/iio-imu-adis16400-fix-sign-extension.patch
new file mode 100644 (file)
index 0000000..16c1c8a
--- /dev/null
@@ -0,0 +1,41 @@
+From 19e353f2b344ad86cea6ebbc0002e5f903480a90 Mon Sep 17 00:00:00 2001
+From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Date: Fri, 23 Jan 2015 00:34:02 +0100
+Subject: iio: imu: adis16400: Fix sign extension
+
+From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+
+commit 19e353f2b344ad86cea6ebbc0002e5f903480a90 upstream.
+
+The intention is obviously to sign-extend a 12 bit quantity. But
+because of C's promotion rules, the assignment is equivalent to "val16
+&= 0xfff;". Use the proper API for this.
+
+Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
+Acked-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/imu/adis16400_core.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/imu/adis16400_core.c
++++ b/drivers/iio/imu/adis16400_core.c
+@@ -26,6 +26,7 @@
+ #include <linux/list.h>
+ #include <linux/module.h>
+ #include <linux/debugfs.h>
++#include <linux/bitops.h>
+ #include <linux/iio/iio.h>
+ #include <linux/iio/sysfs.h>
+@@ -447,7 +448,7 @@ static int adis16400_read_raw(struct iio
+               mutex_unlock(&indio_dev->mlock);
+               if (ret)
+                       return ret;
+-              val16 = ((val16 & 0xFFF) << 4) >> 4;
++              val16 = sign_extend32(val16, 11);
+               *val = val16;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_OFFSET:
diff --git a/queue-3.14/iio-mxs-lradc-fix-iio-channel-map-regression.patch b/queue-3.14/iio-mxs-lradc-fix-iio-channel-map-regression.patch
new file mode 100644 (file)
index 0000000..ce00eaf
--- /dev/null
@@ -0,0 +1,42 @@
+From 03305e535cd5cdc1079b32909bf4b2dd67d46f7f Mon Sep 17 00:00:00 2001
+From: Stefan Wahren <stefan.wahren@i2se.com>
+Date: Sat, 3 Jan 2015 20:34:12 +0000
+Subject: iio: mxs-lradc: fix iio channel map regression
+
+From: Stefan Wahren <stefan.wahren@i2se.com>
+
+commit 03305e535cd5cdc1079b32909bf4b2dd67d46f7f upstream.
+
+Since commit c8231a9af8147f8a ("iio: mxs-lradc: compute temperature
+from channel 8 and 9") with the removal of adc channel 9 there is
+no 1-1 mapping in the channel spec.
+
+All hwmon channel values above 9 are accessible via there index minus
+one. So add a hidden iio channel 9 to fix this issue.
+
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.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 |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/staging/iio/adc/mxs-lradc.c
++++ b/drivers/staging/iio/adc/mxs-lradc.c
+@@ -1412,6 +1412,13 @@ static const struct iio_chan_spec mxs_lr
+               .channel = 8,
+               .scan_type = {.sign = 'u', .realbits = 18, .storagebits = 32,},
+       },
++      /* Hidden channel to keep indexes */
++      {
++              .type = IIO_TEMP,
++              .indexed = 1,
++              .scan_index = -1,
++              .channel = 9,
++      },
+       MXS_ADC_CHAN(10, IIO_VOLTAGE),  /* VDDIO */
+       MXS_ADC_CHAN(11, IIO_VOLTAGE),  /* VTH */
+       MXS_ADC_CHAN(12, IIO_VOLTAGE),  /* VDDA */
diff --git a/queue-3.14/iio-mxs-lradc-make-adc-reads-not-disable-touchscreen-interrupts.patch b/queue-3.14/iio-mxs-lradc-make-adc-reads-not-disable-touchscreen-interrupts.patch
new file mode 100644 (file)
index 0000000..5eb9763
--- /dev/null
@@ -0,0 +1,90 @@
+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
+@@ -824,7 +827,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);
+@@ -1272,8 +1275,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) {
+@@ -1309,8 +1313,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);
+@@ -1554,6 +1559,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);
diff --git a/queue-3.14/iio-mxs-lradc-make-adc-reads-not-unschedule-touchscreen-conversions.patch b/queue-3.14/iio-mxs-lradc-make-adc-reads-not-unschedule-touchscreen-conversions.patch
new file mode 100644 (file)
index 0000000..a09c71f
--- /dev/null
@@ -0,0 +1,75 @@
+From 6abe0300a1d5242f4ff89257197f284679af1a06 Mon Sep 17 00:00:00 2001
+From: Kristina Martšenko <kristina.martsenko@gmail.com>
+Date: Sun, 25 Jan 2015 18:28:21 +0200
+Subject: iio: mxs-lradc: make ADC reads not unschedule touchscreen conversions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kristina Martšenko <kristina.martsenko@gmail.com>
+
+commit 6abe0300a1d5242f4ff89257197f284679af1a06 upstream.
+
+Reading a channel through sysfs, or starting a buffered capture, can
+occasionally turn off the touchscreen.
+
+This is because the read_raw() and buffer preenable()/postdisable()
+callbacks unschedule current conversions on all channels. If a delay
+channel happens to schedule a touchscreen conversion at the same time,
+the conversion gets cancelled and the touchscreen sequence stops.
+
+This is probably related to this note from the reference manual:
+
+       "If a delay group schedules channels to be sampled and a manual
+       write to the schedule field in CTRL0 occurs while the block is
+       discarding samples, the LRADC will switch to the new schedule
+       and will not sample the channels that were previously scheduled.
+       The time window for this to happen is very small and lasts only
+       while the LRADC is discarding samples."
+
+So make the callbacks only unschedule conversions 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.
+
+This is tested and fixes the issue on i.MX28, but hasn't been tested on
+i.MX23.
+
+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 |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/iio/adc/mxs-lradc.c
++++ b/drivers/staging/iio/adc/mxs-lradc.c
+@@ -829,7 +829,7 @@ static int mxs_lradc_read_single(struct
+       if (lradc->soc == IMX28_LRADC)
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0),
+                       LRADC_CTRL1);
+-      mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
++      mxs_lradc_reg_clear(lradc, 0x1, LRADC_CTRL0);
+       /* Enable / disable the divider per requirement */
+       if (test_bit(chan, &lradc->is_divided))
+@@ -1278,7 +1278,7 @@ static int mxs_lradc_buffer_preenable(st
+               mxs_lradc_reg_clear(lradc,
+                       lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET,
+                       LRADC_CTRL1);
+-      mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
++      mxs_lradc_reg_clear(lradc, lradc->buffer_vchans, LRADC_CTRL0);
+       for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
+               ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
+@@ -1311,7 +1311,7 @@ static int mxs_lradc_buffer_postdisable(
+       mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
+                                       LRADC_DELAY_KICK, LRADC_DELAY(0));
+-      mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
++      mxs_lradc_reg_clear(lradc, lradc->buffer_vchans, LRADC_CTRL0);
+       if (lradc->soc == IMX28_LRADC)
+               mxs_lradc_reg_clear(lradc,
+                       lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET,
diff --git a/queue-3.14/iio-mxs-lradc-only-update-the-buffer-when-its-conversions-have-finished.patch b/queue-3.14/iio-mxs-lradc-only-update-the-buffer-when-its-conversions-have-finished.patch
new file mode 100644 (file)
index 0000000..8028ee1
--- /dev/null
@@ -0,0 +1,45 @@
+From 89bb35e200bee745c539a96666e0792301ca40f1 Mon Sep 17 00:00:00 2001
+From: Kristina Martšenko <kristina.martsenko@gmail.com>
+Date: Sun, 25 Jan 2015 18:28:22 +0200
+Subject: iio: mxs-lradc: only update the buffer when its conversions have finished
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kristina Martšenko <kristina.martsenko@gmail.com>
+
+commit 89bb35e200bee745c539a96666e0792301ca40f1 upstream.
+
+Using the touchscreen while running buffered capture results in the
+buffer reporting lots of wrong values, often just zeros. This is because
+we push readings to the buffer every time a touchscreen interrupt
+arrives, including when the buffer's own conversions have not yet
+finished. So let's only push to the buffer when its conversions are
+ready.
+
+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 |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/iio/adc/mxs-lradc.c
++++ b/drivers/staging/iio/adc/mxs-lradc.c
+@@ -1160,9 +1160,12 @@ static irqreturn_t mxs_lradc_handle_irq(
+       }
+       if (iio_buffer_enabled(iio))
+-              iio_trigger_poll(iio->trig, iio_get_time_ns());
+-      else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
++      if (iio_buffer_enabled(iio)) {
++              if (reg & lradc->buffer_vchans)
++                      iio_trigger_poll(iio->trig, iio_get_time_ns());
++      } else if (reg & LRADC_CTRL1_LRADC_IRQ(0)) {
+               complete(&lradc->completion);
++      }
+       mxs_lradc_reg_clear(lradc, reg & clr_irq, LRADC_CTRL1);
diff --git a/queue-3.14/iio-mxs-lradc-separate-touchscreen-and-buffer-virtual-channels.patch b/queue-3.14/iio-mxs-lradc-separate-touchscreen-and-buffer-virtual-channels.patch
new file mode 100644 (file)
index 0000000..fc013c6
--- /dev/null
@@ -0,0 +1,355 @@
+From f81197b8a31b8fb287ae57f597b5b6841e1ece92 Mon Sep 17 00:00:00 2001
+From: Kristina Martšenko <kristina.martsenko@gmail.com>
+Date: Sun, 25 Jan 2015 18:28:19 +0200
+Subject: iio: mxs-lradc: separate touchscreen and buffer virtual channels
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kristina Martšenko <kristina.martsenko@gmail.com>
+
+commit f81197b8a31b8fb287ae57f597b5b6841e1ece92 upstream.
+
+The touchscreen was initially designed [1] to map all of its physical
+channels to one virtual channel, leaving buffered capture to use the
+remaining 7 virtual channels. When the touchscreen was reimplemented
+[2], it was made to use four virtual channels, which overlap and
+conflict with the channels the buffer uses.
+
+As a result, when the buffer is enabled, the touchscreen's virtual
+channels are remapped to whichever physical channels the buffer was
+configured with, causing the touchscreen to read those instead of the
+touch measurement channels. Effectively the touchscreen stops working.
+
+So here we separate the channels again, giving the touchscreen 2 virtual
+channels and the buffer 6. We can't give the touchscreen just 1 channel
+as before, as the current pressure calculation requires 2 channels to be
+read at the same time.
+
+This makes the touchscreen continue to work during buffered capture. It
+has been tested on i.MX28, but not on i.MX23.
+
+[1] 06ddd353f5c8 ("iio: mxs: Implement support for touchscreen")
+[2] dee05308f602 ("Staging/iio/adc/touchscreen/MXS: add interrupt driven
+touch detection")
+
+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 |  164 ++++++++++++++++--------------------
+ 1 file changed, 74 insertions(+), 90 deletions(-)
+
+--- a/drivers/staging/iio/adc/mxs-lradc.c
++++ b/drivers/staging/iio/adc/mxs-lradc.c
+@@ -214,11 +214,14 @@ struct mxs_lradc {
+       unsigned long           is_divided;
+       /*
+-       * Touchscreen LRADC channels receives a private slot in the CTRL4
+-       * register, the slot #7. Therefore only 7 slots instead of 8 in the
+-       * CTRL4 register can be mapped to LRADC channels when using the
+-       * touchscreen.
+-       *
++       * When the touchscreen is enabled, we give it two private virtual
++       * channels: #6 and #7. This means that only 6 virtual channels (instead
++       * of 8) will be available for buffered capture.
++       */
++#define TOUCHSCREEN_VCHANNEL1         7
++#define TOUCHSCREEN_VCHANNEL2         6
++
++      /*
+        * Furthermore, certain LRADC channels are shared between touchscreen
+        * and/or touch-buttons and generic LRADC block. Therefore when using
+        * either of these, these channels are not available for the regular
+@@ -342,6 +345,9 @@ struct mxs_lradc {
+ #define       LRADC_CTRL4                             0x140
+ #define       LRADC_CTRL4_LRADCSELECT_MASK(n)         (0xf << ((n) * 4))
+ #define       LRADC_CTRL4_LRADCSELECT_OFFSET(n)       ((n) * 4)
++#define       LRADC_CTRL4_LRADCSELECT(n, x) \
++                              (((x) << LRADC_CTRL4_LRADCSELECT_OFFSET(n)) & \
++                              LRADC_CTRL4_LRADCSELECT_MASK(n))
+ #define LRADC_RESOLUTION                      12
+ #define LRADC_SINGLE_SAMPLE_MASK              ((1 << LRADC_RESOLUTION) - 1)
+@@ -423,6 +429,14 @@ static bool mxs_lradc_check_touch_event(
+                                       LRADC_STATUS_TOUCH_DETECT_RAW);
+ }
++static void mxs_lradc_map_channel(struct mxs_lradc *lradc, unsigned vch,
++                                unsigned ch)
++{
++      mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(vch),
++                              LRADC_CTRL4);
++      mxs_lradc_reg_set(lradc, LRADC_CTRL4_LRADCSELECT(vch, ch), LRADC_CTRL4);
++}
++
+ static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
+ {
+       /*
+@@ -450,12 +464,8 @@ static void mxs_lradc_setup_ts_channel(s
+               LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
+                       LRADC_DELAY(3));
+-      mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
+-                      LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
+-                      LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
++      mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(ch), LRADC_CTRL1);
+-      /* wake us again, when the complete conversion is done */
+-      mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch), LRADC_CTRL1);
+       /*
+        * after changing the touchscreen plates setting
+        * the signals need some initial time to settle. Start the
+@@ -508,12 +518,8 @@ static void mxs_lradc_setup_ts_pressure(
+               LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
+                                       LRADC_DELAY(3));
+-      mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
+-                      LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
+-                      LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
++      mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(ch2), LRADC_CTRL1);
+-      /* wake us again, when the conversions are done */
+-      mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch2), LRADC_CTRL1);
+       /*
+        * after changing the touchscreen plates setting
+        * the signals need some initial time to settle. Start the
+@@ -578,36 +584,6 @@ static unsigned mxs_lradc_read_ts_pressu
+ #define TS_CH_XM 4
+ #define TS_CH_YM 5
+-static int mxs_lradc_read_ts_channel(struct mxs_lradc *lradc)
+-{
+-      u32 reg;
+-      int val;
+-
+-      reg = readl(lradc->base + LRADC_CTRL1);
+-
+-      /* only channels 3 to 5 are of interest here */
+-      if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YP)) {
+-              mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YP) |
+-                      LRADC_CTRL1_LRADC_IRQ(TS_CH_YP), LRADC_CTRL1);
+-              val = mxs_lradc_read_raw_channel(lradc, TS_CH_YP);
+-      } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_XM)) {
+-              mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_XM) |
+-                      LRADC_CTRL1_LRADC_IRQ(TS_CH_XM), LRADC_CTRL1);
+-              val = mxs_lradc_read_raw_channel(lradc, TS_CH_XM);
+-      } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YM)) {
+-              mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YM) |
+-                      LRADC_CTRL1_LRADC_IRQ(TS_CH_YM), LRADC_CTRL1);
+-              val = mxs_lradc_read_raw_channel(lradc, TS_CH_YM);
+-      } else {
+-              return -EIO;
+-      }
+-
+-      mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
+-      mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
+-
+-      return val;
+-}
+-
+ /*
+  * YP(open)--+-------------+
+  *           |             |--+
+@@ -651,7 +627,8 @@ static void mxs_lradc_prepare_x_pos(stru
+       mxs_lradc_reg_set(lradc, mxs_lradc_drive_x_plate(lradc), LRADC_CTRL0);
+       lradc->cur_plate = LRADC_SAMPLE_X;
+-      mxs_lradc_setup_ts_channel(lradc, TS_CH_YP);
++      mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_YP);
++      mxs_lradc_setup_ts_channel(lradc, TOUCHSCREEN_VCHANNEL1);
+ }
+ /*
+@@ -672,7 +649,8 @@ static void mxs_lradc_prepare_y_pos(stru
+       mxs_lradc_reg_set(lradc, mxs_lradc_drive_y_plate(lradc), LRADC_CTRL0);
+       lradc->cur_plate = LRADC_SAMPLE_Y;
+-      mxs_lradc_setup_ts_channel(lradc, TS_CH_XM);
++      mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_XM);
++      mxs_lradc_setup_ts_channel(lradc, TOUCHSCREEN_VCHANNEL1);
+ }
+ /*
+@@ -693,7 +671,10 @@ static void mxs_lradc_prepare_pressure(s
+       mxs_lradc_reg_set(lradc, mxs_lradc_drive_pressure(lradc), LRADC_CTRL0);
+       lradc->cur_plate = LRADC_SAMPLE_PRESSURE;
+-      mxs_lradc_setup_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
++      mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_YM);
++      mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL2, TS_CH_XP);
++      mxs_lradc_setup_ts_pressure(lradc, TOUCHSCREEN_VCHANNEL2,
++                                              TOUCHSCREEN_VCHANNEL1);
+ }
+ static void mxs_lradc_enable_touch_detection(struct mxs_lradc *lradc)
+@@ -706,6 +687,19 @@ static void mxs_lradc_enable_touch_detec
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+ }
++static void mxs_lradc_start_touch_event(struct mxs_lradc *lradc)
++{
++      mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
++                              LRADC_CTRL1);
++      mxs_lradc_reg_set(lradc,
++              LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1), LRADC_CTRL1);
++      /*
++       * start with the Y-pos, because it uses nearly the same plate
++       * settings like the touch detection
++       */
++      mxs_lradc_prepare_y_pos(lradc);
++}
++
+ static void mxs_lradc_report_ts_event(struct mxs_lradc *lradc)
+ {
+       input_report_abs(lradc->ts_input, ABS_X, lradc->ts_x_pos);
+@@ -723,10 +717,12 @@ static void mxs_lradc_complete_touch_eve
+        * start a dummy conversion to burn time to settle the signals
+        * note: we are not interested in the conversion's value
+        */
+-      mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(5));
+-      mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
+-      mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(5), LRADC_CTRL1);
+-      mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << 5) |
++      mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(TOUCHSCREEN_VCHANNEL1));
++      mxs_lradc_reg_clear(lradc,
++              LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) |
++              LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2), LRADC_CTRL1);
++      mxs_lradc_reg_wrt(lradc,
++              LRADC_DELAY_TRIGGER(1 << TOUCHSCREEN_VCHANNEL1) |
+               LRADC_DELAY_KICK | LRADC_DELAY_DELAY(10), /* waste 5 ms */
+                       LRADC_DELAY(2));
+ }
+@@ -758,59 +754,45 @@ static void mxs_lradc_finish_touch_event
+       /* if it is released, wait for the next touch via IRQ */
+       lradc->cur_plate = LRADC_TOUCH;
+-      mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1);
++      mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
++      mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
++      mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ |
++              LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1) |
++              LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1), LRADC_CTRL1);
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+ }
+ /* touchscreen's state machine */
+ static void mxs_lradc_handle_touch(struct mxs_lradc *lradc)
+ {
+-      int val;
+-
+       switch (lradc->cur_plate) {
+       case LRADC_TOUCH:
+-              /*
+-               * start with the Y-pos, because it uses nearly the same plate
+-               * settings like the touch detection
+-               */
+-              if (mxs_lradc_check_touch_event(lradc)) {
+-                      mxs_lradc_reg_clear(lradc,
+-                                      LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
+-                                      LRADC_CTRL1);
+-                      mxs_lradc_prepare_y_pos(lradc);
+-              }
++              if (mxs_lradc_check_touch_event(lradc))
++                      mxs_lradc_start_touch_event(lradc);
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ,
+                                       LRADC_CTRL1);
+               return;
+       case LRADC_SAMPLE_Y:
+-              val = mxs_lradc_read_ts_channel(lradc);
+-              if (val < 0) {
+-                      mxs_lradc_enable_touch_detection(lradc); /* re-start */
+-                      return;
+-              }
+-              lradc->ts_y_pos = val;
++              lradc->ts_y_pos = mxs_lradc_read_raw_channel(lradc,
++                                                      TOUCHSCREEN_VCHANNEL1);
+               mxs_lradc_prepare_x_pos(lradc);
+               return;
+       case LRADC_SAMPLE_X:
+-              val = mxs_lradc_read_ts_channel(lradc);
+-              if (val < 0) {
+-                      mxs_lradc_enable_touch_detection(lradc); /* re-start */
+-                      return;
+-              }
+-              lradc->ts_x_pos = val;
++              lradc->ts_x_pos = mxs_lradc_read_raw_channel(lradc,
++                                                      TOUCHSCREEN_VCHANNEL1);
+               mxs_lradc_prepare_pressure(lradc);
+               return;
+       case LRADC_SAMPLE_PRESSURE:
+-              lradc->ts_pressure =
+-                      mxs_lradc_read_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
++              lradc->ts_pressure = mxs_lradc_read_ts_pressure(lradc,
++                                                      TOUCHSCREEN_VCHANNEL2,
++                                                      TOUCHSCREEN_VCHANNEL1);
+               mxs_lradc_complete_touch_event(lradc);
+               return;
+       case LRADC_SAMPLE_VALID:
+-              val = mxs_lradc_read_ts_channel(lradc); /* ignore the value */
+               mxs_lradc_finish_touch_event(lradc, 1);
+               break;
+       }
+@@ -1091,9 +1073,8 @@ static void mxs_lradc_disable_ts(struct
+ {
+       /* stop all interrupts from firing */
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
+-              LRADC_CTRL1_LRADC_IRQ_EN(2) | LRADC_CTRL1_LRADC_IRQ_EN(3) |
+-              LRADC_CTRL1_LRADC_IRQ_EN(4) | LRADC_CTRL1_LRADC_IRQ_EN(5),
+-              LRADC_CTRL1);
++              LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1) |
++              LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL2), LRADC_CTRL1);
+       /* Power-down touchscreen touch-detect circuitry. */
+       mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+@@ -1159,25 +1140,28 @@ static irqreturn_t mxs_lradc_handle_irq(
+       struct iio_dev *iio = data;
+       struct mxs_lradc *lradc = iio_priv(iio);
+       unsigned long reg = readl(lradc->base + LRADC_CTRL1);
++      uint32_t clr_irq = mxs_lradc_irq_mask(lradc);
+       const uint32_t ts_irq_mask =
+               LRADC_CTRL1_TOUCH_DETECT_IRQ |
+-              LRADC_CTRL1_LRADC_IRQ(2) |
+-              LRADC_CTRL1_LRADC_IRQ(3) |
+-              LRADC_CTRL1_LRADC_IRQ(4) |
+-              LRADC_CTRL1_LRADC_IRQ(5);
++              LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) |
++              LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2);
+       if (!(reg & mxs_lradc_irq_mask(lradc)))
+               return IRQ_NONE;
+-      if (lradc->use_touchscreen && (reg & ts_irq_mask))
++      if (lradc->use_touchscreen && (reg & ts_irq_mask)) {
+               mxs_lradc_handle_touch(lradc);
++              /* Make sure we don't clear the next conversion's interrupt. */
++              clr_irq &= ~(LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) |
++                              LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2));
++      }
+       if (iio_buffer_enabled(iio))
+               iio_trigger_poll(iio->trig, iio_get_time_ns());
+       else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
+               complete(&lradc->completion);
+-      mxs_lradc_reg_clear(lradc, reg & mxs_lradc_irq_mask(lradc), LRADC_CTRL1);
++      mxs_lradc_reg_clear(lradc, reg & clr_irq, LRADC_CTRL1);
+       return IRQ_HANDLED;
+ }
+@@ -1352,7 +1336,7 @@ static bool mxs_lradc_validate_scan_mask
+       if (lradc->use_touchbutton)
+               rsvd_chans++;
+       if (lradc->use_touchscreen)
+-              rsvd_chans++;
++              rsvd_chans += 2;
+       /* Test for attempts to map channels with special mode of operation. */
+       if (bitmap_intersects(mask, &rsvd_mask, LRADC_MAX_TOTAL_CHANS))
index a7b2cca9eb64fb95de471adf69358385332a2adc..1e6cf08b1d92f35b32e3c492a0a66948fcc41a77 100644 (file)
@@ -29,3 +29,11 @@ target-fix-pr_aptpl_buf_len-buffer-size-limitation.patch
 target-add-missing-write_same-end-of-device-sanity-check.patch
 target-check-for-lba-sectors-wrap-around-in-sbc_parse_cdb.patch
 x86-asm-entry-64-remove-a-bogus-ret_from_fork-optimization.patch
+iio-mxs-lradc-fix-iio-channel-map-regression.patch
+iio-imu-adis16400-fix-sign-extension.patch
+iio-mxs-lradc-separate-touchscreen-and-buffer-virtual-channels.patch
+iio-mxs-lradc-make-adc-reads-not-disable-touchscreen-interrupts.patch
+iio-mxs-lradc-make-adc-reads-not-unschedule-touchscreen-conversions.patch
+iio-mxs-lradc-only-update-the-buffer-when-its-conversions-have-finished.patch
+iio-ad5686-fix-optional-reference-voltage-declaration.patch
+iio-adc-mcp3422-fix-incorrect-scales-table.patch