* [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC
@ 2015-01-25 16:28 Kristina Martšenko
2015-01-25 16:28 ` [PATCH v2 1/4] iio: mxs-lradc: separate touchscreen and buffer virtual channels Kristina Martšenko
` (4 more replies)
0 siblings, 5 replies; 9+ messages in thread
From: Kristina Martšenko @ 2015-01-25 16:28 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Marek Vasut,
Juergen Beisert, Alexandre Belloni, Fabio Estevam, Stefan Wahren,
Greg Kroah-Hartman, linux-iio, devel, Kristina Martšenko
These patches fix some issues with using the touchscreen and reading
other ADC channels at the same time.
The main issue is that the "virtual" channels the touchscreen uses can
overlap with the channels that the iio buffer is configured to read,
causing the touchscreen to read those channels instead, and report wrong
values. Patch #1 fixes that by separating the channels they use.
Patches #2 and #3 stop buffered mode and sysfs reads from disabling the
touchscreen. Patch #4 keeps the buffer from reporting wrong values when
the touchscreen is in use.
Note that I've only tested these patches on i.MX28. I checked the i.MX23
reference manual, and there don't seem to be any differences in the
parts I changed, but it would still be nice if someone could test on
i.MX23 as well.
Changes in v2:
- renamed TS_VCHn macros to TOUCHSCREEN_VCHANNELn
- removed indentation changes from patch #2
Kristina Martšenko (4):
iio: mxs-lradc: separate touchscreen and buffer virtual channels
iio: mxs-lradc: make ADC reads not disable touchscreen interrupts
iio: mxs-lradc: make ADC reads not unschedule touchscreen conversions
iio: mxs-lradc: only update the buffer when its conversions have
finished
drivers/staging/iio/adc/mxs-lradc.c | 200 ++++++++++++++++++------------------
1 file changed, 98 insertions(+), 102 deletions(-)
--
2.2.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/4] iio: mxs-lradc: separate touchscreen and buffer virtual channels
2015-01-25 16:28 [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC Kristina Martšenko
@ 2015-01-25 16:28 ` Kristina Martšenko
2015-01-25 16:28 ` [PATCH v2 2/4] iio: mxs-lradc: make ADC reads not disable touchscreen interrupts Kristina Martšenko
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Kristina Martšenko @ 2015-01-25 16:28 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Marek Vasut,
Juergen Beisert, Alexandre Belloni, Fabio Estevam, Stefan Wahren,
Greg Kroah-Hartman, linux-iio, devel, Kristina Martšenko
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>
---
Note that this patch alone isn't very useful, as another bug causes buffered
capture to disable the touchscreen entirely (on i.MX28). Patch #2 in this
series fixes the other issue.
drivers/staging/iio/adc/mxs-lradc.c | 166 ++++++++++++++++--------------------
1 file changed, 75 insertions(+), 91 deletions(-)
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index f053535385bf..4e574b76ead0 100644
--- 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)
@@ -416,6 +422,14 @@ static bool mxs_lradc_check_touch_event(struct mxs_lradc *lradc)
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)
{
/*
@@ -443,12 +457,8 @@ static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
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
@@ -502,12 +512,8 @@ static void mxs_lradc_setup_ts_pressure(struct mxs_lradc *lradc, unsigned ch1,
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
@@ -573,36 +579,6 @@ static unsigned mxs_lradc_read_ts_pressure(struct mxs_lradc *lradc,
#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)--+-------------+
* | |--+
@@ -646,7 +622,8 @@ static void mxs_lradc_prepare_x_pos(struct mxs_lradc *lradc)
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);
}
/*
@@ -667,7 +644,8 @@ static void mxs_lradc_prepare_y_pos(struct mxs_lradc *lradc)
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);
}
/*
@@ -688,7 +666,10 @@ static void mxs_lradc_prepare_pressure(struct mxs_lradc *lradc)
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)
@@ -701,6 +682,19 @@ static void mxs_lradc_enable_touch_detection(struct mxs_lradc *lradc)
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);
@@ -718,10 +712,12 @@ static void mxs_lradc_complete_touch_event(struct mxs_lradc *lradc)
* 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));
}
@@ -753,59 +749,45 @@ static void mxs_lradc_finish_touch_event(struct mxs_lradc *lradc, bool valid)
/* 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;
}
@@ -1083,9 +1065,8 @@ static void mxs_lradc_disable_ts(struct mxs_lradc *lradc)
{
/* 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);
@@ -1151,26 +1132,29 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
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);
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;
}
@@ -1346,7 +1330,7 @@ static bool mxs_lradc_validate_scan_mask(struct iio_dev *iio,
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))
--
2.2.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/4] iio: mxs-lradc: make ADC reads not disable touchscreen interrupts
2015-01-25 16:28 [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC Kristina Martšenko
2015-01-25 16:28 ` [PATCH v2 1/4] iio: mxs-lradc: separate touchscreen and buffer virtual channels Kristina Martšenko
@ 2015-01-25 16:28 ` Kristina Martšenko
2015-01-25 16:28 ` [PATCH v2 3/4] iio: mxs-lradc: make ADC reads not unschedule touchscreen conversions Kristina Martšenko
` (2 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Kristina Martšenko @ 2015-01-25 16:28 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Marek Vasut,
Juergen Beisert, Alexandre Belloni, Fabio Estevam, Stefan Wahren,
Greg Kroah-Hartman, linux-iio, devel, Kristina Martšenko
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>
---
drivers/staging/iio/adc/mxs-lradc.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index 4e574b76ead0..653af03bc69d 100644
--- 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 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);
@@ -1542,6 +1547,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);
--
2.2.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/4] iio: mxs-lradc: make ADC reads not unschedule touchscreen conversions
2015-01-25 16:28 [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC Kristina Martšenko
2015-01-25 16:28 ` [PATCH v2 1/4] iio: mxs-lradc: separate touchscreen and buffer virtual channels Kristina Martšenko
2015-01-25 16:28 ` [PATCH v2 2/4] iio: mxs-lradc: make ADC reads not disable touchscreen interrupts Kristina Martšenko
@ 2015-01-25 16:28 ` Kristina Martšenko
2015-01-25 16:28 ` [PATCH v2 4/4] iio: mxs-lradc: only update the buffer when its conversions have finished Kristina Martšenko
2015-01-25 18:47 ` [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC Marek Vasut
4 siblings, 0 replies; 9+ messages in thread
From: Kristina Martšenko @ 2015-01-25 16:28 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Marek Vasut,
Juergen Beisert, Alexandre Belloni, Fabio Estevam, Stefan Wahren,
Greg Kroah-Hartman, linux-iio, devel, Kristina Martšenko
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>
---
drivers/staging/iio/adc/mxs-lradc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index 653af03bc69d..d2e0c275bf4d 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -824,7 +824,7 @@ static int mxs_lradc_read_single(struct iio_dev *iio_dev, int chan, int *val)
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))
@@ -1272,7 +1272,7 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
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);
@@ -1305,7 +1305,7 @@ static int mxs_lradc_buffer_postdisable(struct iio_dev *iio)
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,
--
2.2.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 4/4] iio: mxs-lradc: only update the buffer when its conversions have finished
2015-01-25 16:28 [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC Kristina Martšenko
` (2 preceding siblings ...)
2015-01-25 16:28 ` [PATCH v2 3/4] iio: mxs-lradc: make ADC reads not unschedule touchscreen conversions Kristina Martšenko
@ 2015-01-25 16:28 ` Kristina Martšenko
2015-01-25 18:47 ` [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC Marek Vasut
4 siblings, 0 replies; 9+ messages in thread
From: Kristina Martšenko @ 2015-01-25 16:28 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald, Marek Vasut,
Juergen Beisert, Alexandre Belloni, Fabio Estevam, Stefan Wahren,
Greg Kroah-Hartman, linux-iio, devel, Kristina Martšenko
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>
---
drivers/staging/iio/adc/mxs-lradc.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index d2e0c275bf4d..ebcbd12d48b9 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -1152,10 +1152,12 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2));
}
- if (iio_buffer_enabled(iio))
- iio_trigger_poll(iio->trig);
- else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
+ if (iio_buffer_enabled(iio)) {
+ if (reg & lradc->buffer_vchans)
+ iio_trigger_poll(iio->trig);
+ } else if (reg & LRADC_CTRL1_LRADC_IRQ(0)) {
complete(&lradc->completion);
+ }
mxs_lradc_reg_clear(lradc, reg & clr_irq, LRADC_CTRL1);
--
2.2.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC
2015-01-25 16:28 [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC Kristina Martšenko
` (3 preceding siblings ...)
2015-01-25 16:28 ` [PATCH v2 4/4] iio: mxs-lradc: only update the buffer when its conversions have finished Kristina Martšenko
@ 2015-01-25 18:47 ` Marek Vasut
2015-01-26 21:01 ` Jonathan Cameron
4 siblings, 1 reply; 9+ messages in thread
From: Marek Vasut @ 2015-01-25 18:47 UTC (permalink / raw)
To: Kristina Martšenko
Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald, Juergen Beisert, Alexandre Belloni, Fabio Estevam,
Stefan Wahren, Greg Kroah-Hartman, linux-iio, devel
On Sunday, January 25, 2015 at 05:28:18 PM, Kristina Martšenko wrote:
> These patches fix some issues with using the touchscreen and reading
> other ADC channels at the same time.
[...]
Hi!
Thanks!
Entire series
Reviewed-by: Marek Vasut <marex@denx.de>
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC
2015-01-25 18:47 ` [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC Marek Vasut
@ 2015-01-26 21:01 ` Jonathan Cameron
2015-01-27 14:19 ` Kristina Martšenko
0 siblings, 1 reply; 9+ messages in thread
From: Jonathan Cameron @ 2015-01-26 21:01 UTC (permalink / raw)
To: Marek Vasut, Kristina Martšenko
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald,
Juergen Beisert, Alexandre Belloni, Fabio Estevam, Stefan Wahren,
Greg Kroah-Hartman, linux-iio, devel
On 25/01/15 18:47, Marek Vasut wrote:
> On Sunday, January 25, 2015 at 05:28:18 PM, Kristina Martšenko wrote:
>> These patches fix some issues with using the touchscreen and reading
>> other ADC channels at the same time.
>
> [...]
>
> Hi!
>
> Thanks!
>
> Entire series
>
> Reviewed-by: Marek Vasut <marex@denx.de>
All 4 applied to the fixes-togreg branch of iio.git and cc'd to
stable.
Thanks
Jonathan
>
> Best regards,
> Marek Vasut
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC
2015-01-26 21:01 ` Jonathan Cameron
@ 2015-01-27 14:19 ` Kristina Martšenko
2015-01-27 17:17 ` Jonathan Cameron
0 siblings, 1 reply; 9+ messages in thread
From: Kristina Martšenko @ 2015-01-27 14:19 UTC (permalink / raw)
To: Jonathan Cameron, Marek Vasut
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald,
Juergen Beisert, Alexandre Belloni, Fabio Estevam, Stefan Wahren,
Greg Kroah-Hartman, linux-iio, devel
On 26/01/15 23:01, Jonathan Cameron wrote:
> On 25/01/15 18:47, Marek Vasut wrote:
>> On Sunday, January 25, 2015 at 05:28:18 PM, Kristina Martšenko wrote:
>>> These patches fix some issues with using the touchscreen and reading
>>> other ADC channels at the same time.
>>
>> Entire series
>>
>> Reviewed-by: Marek Vasut <marex@denx.de>
Thanks again!
> All 4 applied to the fixes-togreg branch of iio.git and cc'd to
> stable.
Thanks, Jonathan! I'm not entirely sure if these are critical enough to
go in stable, but alright.
Kristina
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC
2015-01-27 14:19 ` Kristina Martšenko
@ 2015-01-27 17:17 ` Jonathan Cameron
0 siblings, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2015-01-27 17:17 UTC (permalink / raw)
To: Kristina Martšenko, Jonathan Cameron, Marek Vasut
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald,
Juergen Beisert, Alexandre Belloni, Fabio Estevam, Stefan Wahren,
Greg Kroah-Hartman, linux-iio, devel
[-- Attachment #1: Type: text/plain, Size: 944 bytes --]
On 27 January 2015 14:19:17 GMT+00:00, "Kristina Martšenko" <kristina.martsenko@gmail.com> wrote:
>On 26/01/15 23:01, Jonathan Cameron wrote:
>> On 25/01/15 18:47, Marek Vasut wrote:
>>> On Sunday, January 25, 2015 at 05:28:18 PM, Kristina Martšenko
>wrote:
>>>> These patches fix some issues with using the touchscreen and
>reading
>>>> other ADC channels at the same time.
>>>
>>> Entire series
>>>
>>> Reviewed-by: Marek Vasut <marex@denx.de>
>
>Thanks again!
>
>> All 4 applied to the fixes-togreg branch of iio.git and cc'd to
>> stable.
>
>Thanks, Jonathan! I'm not entirely sure if these are critical enough to
>go in stable, but alright.
>
>Kristina
It's broken and the fix doesn't effect anyone without the hardware so definitely
stable material!
Chances are someone will release hardware based on an old kernel so best
to drive these fixes backwards.
J
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
[-- Attachment #2: Type: text/html, Size: 1835 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2015-01-27 17:17 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-25 16:28 [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC Kristina Martšenko
2015-01-25 16:28 ` [PATCH v2 1/4] iio: mxs-lradc: separate touchscreen and buffer virtual channels Kristina Martšenko
2015-01-25 16:28 ` [PATCH v2 2/4] iio: mxs-lradc: make ADC reads not disable touchscreen interrupts Kristina Martšenko
2015-01-25 16:28 ` [PATCH v2 3/4] iio: mxs-lradc: make ADC reads not unschedule touchscreen conversions Kristina Martšenko
2015-01-25 16:28 ` [PATCH v2 4/4] iio: mxs-lradc: only update the buffer when its conversions have finished Kristina Martšenko
2015-01-25 18:47 ` [PATCH v2 0/4] iio: mxs-lradc: fix interactions between the touchscreen and the ADC Marek Vasut
2015-01-26 21:01 ` Jonathan Cameron
2015-01-27 14:19 ` Kristina Martšenko
2015-01-27 17:17 ` Jonathan Cameron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).