aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristina Martšenko <kristina.martsenko@gmail.com>2015-01-25 11:28:19 -0500
committerJonathan Cameron <jic23@kernel.org>2015-01-26 15:57:37 -0500
commitf81197b8a31b8fb287ae57f597b5b6841e1ece92 (patch)
tree1f429f871d970e4d9f5cab5ffdc3521c87ac22b3
parent4f33fbae555000bf73aaacbc4f5b24668afc8c7a (diff)
iio: mxs-lradc: separate touchscreen and buffer virtual channels
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> Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c166
1 files 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 {
214 unsigned long is_divided; 214 unsigned long is_divided;
215 215
216 /* 216 /*
217 * Touchscreen LRADC channels receives a private slot in the CTRL4 217 * When the touchscreen is enabled, we give it two private virtual
218 * register, the slot #7. Therefore only 7 slots instead of 8 in the 218 * channels: #6 and #7. This means that only 6 virtual channels (instead
219 * CTRL4 register can be mapped to LRADC channels when using the 219 * of 8) will be available for buffered capture.
220 * touchscreen. 220 */
221 * 221#define TOUCHSCREEN_VCHANNEL1 7
222#define TOUCHSCREEN_VCHANNEL2 6
223
224 /*
222 * Furthermore, certain LRADC channels are shared between touchscreen 225 * Furthermore, certain LRADC channels are shared between touchscreen
223 * and/or touch-buttons and generic LRADC block. Therefore when using 226 * and/or touch-buttons and generic LRADC block. Therefore when using
224 * either of these, these channels are not available for the regular 227 * either of these, these channels are not available for the regular
@@ -342,6 +345,9 @@ struct mxs_lradc {
342#define LRADC_CTRL4 0x140 345#define LRADC_CTRL4 0x140
343#define LRADC_CTRL4_LRADCSELECT_MASK(n) (0xf << ((n) * 4)) 346#define LRADC_CTRL4_LRADCSELECT_MASK(n) (0xf << ((n) * 4))
344#define LRADC_CTRL4_LRADCSELECT_OFFSET(n) ((n) * 4) 347#define LRADC_CTRL4_LRADCSELECT_OFFSET(n) ((n) * 4)
348#define LRADC_CTRL4_LRADCSELECT(n, x) \
349 (((x) << LRADC_CTRL4_LRADCSELECT_OFFSET(n)) & \
350 LRADC_CTRL4_LRADCSELECT_MASK(n))
345 351
346#define LRADC_RESOLUTION 12 352#define LRADC_RESOLUTION 12
347#define LRADC_SINGLE_SAMPLE_MASK ((1 << LRADC_RESOLUTION) - 1) 353#define LRADC_SINGLE_SAMPLE_MASK ((1 << LRADC_RESOLUTION) - 1)
@@ -416,6 +422,14 @@ static bool mxs_lradc_check_touch_event(struct mxs_lradc *lradc)
416 LRADC_STATUS_TOUCH_DETECT_RAW); 422 LRADC_STATUS_TOUCH_DETECT_RAW);
417} 423}
418 424
425static void mxs_lradc_map_channel(struct mxs_lradc *lradc, unsigned vch,
426 unsigned ch)
427{
428 mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(vch),
429 LRADC_CTRL4);
430 mxs_lradc_reg_set(lradc, LRADC_CTRL4_LRADCSELECT(vch, ch), LRADC_CTRL4);
431}
432
419static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch) 433static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
420{ 434{
421 /* 435 /*
@@ -443,12 +457,8 @@ static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
443 LRADC_DELAY_DELAY(lradc->over_sample_delay - 1), 457 LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
444 LRADC_DELAY(3)); 458 LRADC_DELAY(3));
445 459
446 mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) | 460 mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(ch), LRADC_CTRL1);
447 LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
448 LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
449 461
450 /* wake us again, when the complete conversion is done */
451 mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch), LRADC_CTRL1);
452 /* 462 /*
453 * after changing the touchscreen plates setting 463 * after changing the touchscreen plates setting
454 * the signals need some initial time to settle. Start the 464 * 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,
502 LRADC_DELAY_DELAY(lradc->over_sample_delay - 1), 512 LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
503 LRADC_DELAY(3)); 513 LRADC_DELAY(3));
504 514
505 mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) | 515 mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(ch2), LRADC_CTRL1);
506 LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
507 LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
508 516
509 /* wake us again, when the conversions are done */
510 mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch2), LRADC_CTRL1);
511 /* 517 /*
512 * after changing the touchscreen plates setting 518 * after changing the touchscreen plates setting
513 * the signals need some initial time to settle. Start the 519 * 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,
573#define TS_CH_XM 4 579#define TS_CH_XM 4
574#define TS_CH_YM 5 580#define TS_CH_YM 5
575 581
576static int mxs_lradc_read_ts_channel(struct mxs_lradc *lradc)
577{
578 u32 reg;
579 int val;
580
581 reg = readl(lradc->base + LRADC_CTRL1);
582
583 /* only channels 3 to 5 are of interest here */
584 if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YP)) {
585 mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YP) |
586 LRADC_CTRL1_LRADC_IRQ(TS_CH_YP), LRADC_CTRL1);
587 val = mxs_lradc_read_raw_channel(lradc, TS_CH_YP);
588 } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_XM)) {
589 mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_XM) |
590 LRADC_CTRL1_LRADC_IRQ(TS_CH_XM), LRADC_CTRL1);
591 val = mxs_lradc_read_raw_channel(lradc, TS_CH_XM);
592 } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YM)) {
593 mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YM) |
594 LRADC_CTRL1_LRADC_IRQ(TS_CH_YM), LRADC_CTRL1);
595 val = mxs_lradc_read_raw_channel(lradc, TS_CH_YM);
596 } else {
597 return -EIO;
598 }
599
600 mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
601 mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
602
603 return val;
604}
605
606/* 582/*
607 * YP(open)--+-------------+ 583 * YP(open)--+-------------+
608 * | |--+ 584 * | |--+
@@ -646,7 +622,8 @@ static void mxs_lradc_prepare_x_pos(struct mxs_lradc *lradc)
646 mxs_lradc_reg_set(lradc, mxs_lradc_drive_x_plate(lradc), LRADC_CTRL0); 622 mxs_lradc_reg_set(lradc, mxs_lradc_drive_x_plate(lradc), LRADC_CTRL0);
647 623
648 lradc->cur_plate = LRADC_SAMPLE_X; 624 lradc->cur_plate = LRADC_SAMPLE_X;
649 mxs_lradc_setup_ts_channel(lradc, TS_CH_YP); 625 mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_YP);
626 mxs_lradc_setup_ts_channel(lradc, TOUCHSCREEN_VCHANNEL1);
650} 627}
651 628
652/* 629/*
@@ -667,7 +644,8 @@ static void mxs_lradc_prepare_y_pos(struct mxs_lradc *lradc)
667 mxs_lradc_reg_set(lradc, mxs_lradc_drive_y_plate(lradc), LRADC_CTRL0); 644 mxs_lradc_reg_set(lradc, mxs_lradc_drive_y_plate(lradc), LRADC_CTRL0);
668 645
669 lradc->cur_plate = LRADC_SAMPLE_Y; 646 lradc->cur_plate = LRADC_SAMPLE_Y;
670 mxs_lradc_setup_ts_channel(lradc, TS_CH_XM); 647 mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_XM);
648 mxs_lradc_setup_ts_channel(lradc, TOUCHSCREEN_VCHANNEL1);
671} 649}
672 650
673/* 651/*
@@ -688,7 +666,10 @@ static void mxs_lradc_prepare_pressure(struct mxs_lradc *lradc)
688 mxs_lradc_reg_set(lradc, mxs_lradc_drive_pressure(lradc), LRADC_CTRL0); 666 mxs_lradc_reg_set(lradc, mxs_lradc_drive_pressure(lradc), LRADC_CTRL0);
689 667
690 lradc->cur_plate = LRADC_SAMPLE_PRESSURE; 668 lradc->cur_plate = LRADC_SAMPLE_PRESSURE;
691 mxs_lradc_setup_ts_pressure(lradc, TS_CH_XP, TS_CH_YM); 669 mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL1, TS_CH_YM);
670 mxs_lradc_map_channel(lradc, TOUCHSCREEN_VCHANNEL2, TS_CH_XP);
671 mxs_lradc_setup_ts_pressure(lradc, TOUCHSCREEN_VCHANNEL2,
672 TOUCHSCREEN_VCHANNEL1);
692} 673}
693 674
694static void mxs_lradc_enable_touch_detection(struct mxs_lradc *lradc) 675static 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)
701 mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1); 682 mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
702} 683}
703 684
685static void mxs_lradc_start_touch_event(struct mxs_lradc *lradc)
686{
687 mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
688 LRADC_CTRL1);
689 mxs_lradc_reg_set(lradc,
690 LRADC_CTRL1_LRADC_IRQ_EN(TOUCHSCREEN_VCHANNEL1), LRADC_CTRL1);
691 /*
692 * start with the Y-pos, because it uses nearly the same plate
693 * settings like the touch detection
694 */