[Armadeus-commitlog] armadeus branch, master, updated. armadeus-4.1-263-g9caf476
Brought to you by:
sszy
|
From: Nicolas <th...@us...> - 2012-04-16 09:07:38
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "armadeus".
The branch, master has been updated
via 9caf476cd8b63d4648cdcc16a7dfc1bcd9670cf0 (commit)
from 6da2a097fe3e5452b4d04aabaaeb6c76c0a3d089 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 9caf476cd8b63d4648cdcc16a7dfc1bcd9670cf0
Author: nicolas <nicolas@nicolas-Studio-1558.(none)>
Date: Mon Apr 16 11:06:31 2012 +0200
[LINUX] fix sequencer of iMX28 touchscreen driver
-----------------------------------------------------------------------
Summary of changes:
.../linux/2.6.35/453-armadeus-mxs-ts-fixes.patch | 382 ++++++++++++++++++++
1 files changed, 382 insertions(+), 0 deletions(-)
create mode 100644 patches/linux/2.6.35/453-armadeus-mxs-ts-fixes.patch
diff --git a/patches/linux/2.6.35/453-armadeus-mxs-ts-fixes.patch b/patches/linux/2.6.35/453-armadeus-mxs-ts-fixes.patch
new file mode 100644
index 0000000..979ad1f
--- /dev/null
+++ b/patches/linux/2.6.35/453-armadeus-mxs-ts-fixes.patch
@@ -0,0 +1,382 @@
+Fix APF28 touchscreen driver
+
+Signed-off-by: Nicolas Colombain <nic...@ar...>
+
+Index: linux-2.6.35.3/drivers/input/touchscreen/mxs-ts.c
+===================================================================
+--- linux-2.6.35.3.orig/drivers/input/touchscreen/mxs-ts.c 2012-01-31 14:27:22.000000000 +0100
++++ linux-2.6.35.3/drivers/input/touchscreen/mxs-ts.c 2012-02-03 17:42:26.000000000 +0100
+@@ -1,8 +1,9 @@
+ /*
+- * Freesclae MXS Touchscreen driver
++ * Freescale MXS Touchscreen driver
+ *
+ * Author: Vitaly Wool <vi...@em...>
+ *
++ * Copyright (C) 2012 Armadeus systems
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+@@ -30,7 +31,7 @@
+ #include <mach/device.h>
+ #include <mach/regs-lradc.h>
+
+-#define TOUCH_DEBOUNCE_TOLERANCE 100
++#define FILTER_SIZE 4 /* must be a power of 2 */
+
+ struct mxs_ts_info {
+ int touch_irq;
+@@ -50,6 +51,8 @@ struct mxs_ts_info {
+ unsigned int y_plus_mask;
+ unsigned int y_minus_mask;
+
++ struct delayed_work activate_touch_detect;
++
+ struct input_dev *idev;
+ enum {
+ TS_STATE_DISABLED,
+@@ -60,161 +63,142 @@ struct mxs_ts_info {
+ } state;
+ u16 x;
+ u16 y;
++ int pressure;
+ int sample_count;
+ };
+
+-static inline void enter_state_touch_detect(struct mxs_ts_info *info)
++static inline void enter_state_x_plane(struct mxs_ts_info *info)
+ {
+- __raw_writel(0xFFFFFFFF,
+- info->base + HW_LRADC_CHn_CLR(info->x_plus_chan));
+- __raw_writel(0xFFFFFFFF,
+- info->base + HW_LRADC_CHn_CLR(info->y_plus_chan));
+- __raw_writel(0xFFFFFFFF,
+- info->base + HW_LRADC_CHn_CLR(info->x_minus_chan));
+- __raw_writel(0xFFFFFFFF,
+- info->base + HW_LRADC_CHn_CLR(info->y_minus_chan));
+-
+- __raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ << info->y_minus_chan,
+- info->base + HW_LRADC_CTRL1_CLR);
+- __raw_writel(BM_LRADC_CTRL1_TOUCH_DETECT_IRQ,
+- info->base + HW_LRADC_CTRL1_CLR);
+- /*
+- * turn off the yplus and yminus pullup and pulldown, and turn off touch
+- * detect (enables yminus, and xplus through a resistor.On a press,
+- * xplus is pulled down)
+- */
+- __raw_writel(info->y_plus_mask, info->base + HW_LRADC_CTRL0_CLR);
+- __raw_writel(info->y_minus_mask, info->base + HW_LRADC_CTRL0_CLR);
++ __raw_writel(BM_LRADC_CTRL0_TOUCH_DETECT_ENABLE,
++ info->base + HW_LRADC_CTRL0_CLR);
++ __raw_writel(info->y_plus_val, info->base + HW_LRADC_CTRL0_SET);
++ __raw_writel(info->y_minus_val, info->base + HW_LRADC_CTRL0_SET);
+ __raw_writel(info->x_plus_mask, info->base + HW_LRADC_CTRL0_CLR);
+ __raw_writel(info->x_minus_mask, info->base + HW_LRADC_CTRL0_CLR);
+- __raw_writel(BM_LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+- info->base + HW_LRADC_CTRL0_SET);
+- hw_lradc_set_delay_trigger_kick(LRADC_DELAY_TRIGGER_TOUCHSCREEN, 0);
+- info->state = TS_STATE_TOUCH_DETECT;
++
++ info->state = TS_STATE_X_PLANE;
+ info->sample_count = 0;
++ info->x = 0;
++ info->y = 0;
++
++ hw_lradc_set_delay_trigger_kick(LRADC_DELAY_TRIGGER_TOUCHSCREEN, 1);
+ }
+
+-static inline void enter_state_disabled(struct mxs_ts_info *info)
++static inline void enter_state_y_plane(struct mxs_ts_info *info)
+ {
+- __raw_writel(info->y_plus_mask, info->base + HW_LRADC_CTRL0_CLR);
+- __raw_writel(info->y_minus_mask, info->base + HW_LRADC_CTRL0_CLR);
+- __raw_writel(info->x_plus_mask, info->base + HW_LRADC_CTRL0_CLR);
+- __raw_writel(info->x_minus_mask, info->base + HW_LRADC_CTRL0_CLR);
+ __raw_writel(BM_LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+ info->base + HW_LRADC_CTRL0_CLR);
+- hw_lradc_set_delay_trigger_kick(LRADC_DELAY_TRIGGER_TOUCHSCREEN, 0);
+- info->state = TS_STATE_DISABLED;
++ __raw_writel(info->y_plus_mask, info->base + HW_LRADC_CTRL0_CLR);
++ __raw_writel(info->y_minus_mask, info->base + HW_LRADC_CTRL0_CLR);
++ __raw_writel(info->x_plus_val, info->base + HW_LRADC_CTRL0_SET);
++ __raw_writel(info->x_minus_val, info->base + HW_LRADC_CTRL0_SET);
++ info->state = TS_STATE_Y_PLANE;
+ info->sample_count = 0;
++ hw_lradc_set_delay_trigger_kick(LRADC_DELAY_TRIGGER_TOUCHSCREEN, 1);
+ }
+
+-
+-static inline void enter_state_x_plane(struct mxs_ts_info *info)
++static void activate_touch_detect(struct work_struct *work)
+ {
+- __raw_writel(info->y_plus_val, info->base + HW_LRADC_CTRL0_SET);
+- __raw_writel(info->y_minus_val, info->base + HW_LRADC_CTRL0_SET);
+- __raw_writel(info->x_plus_mask, info->base + HW_LRADC_CTRL0_CLR);
+- __raw_writel(info->x_minus_mask, info->base + HW_LRADC_CTRL0_CLR);
+- __raw_writel(BM_LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+- info->base + HW_LRADC_CTRL0_CLR);
+- hw_lradc_set_delay_trigger_kick(LRADC_DELAY_TRIGGER_TOUCHSCREEN, 1);
++ struct mxs_ts_info *info =
++ container_of(to_delayed_work(work), struct mxs_ts_info, activate_touch_detect);
+
+ info->state = TS_STATE_X_PLANE;
+- info->sample_count = 0;
++
++ /* check if the pen is always down */
++ if( __raw_readl(info->base + HW_LRADC_STATUS) & BM_LRADC_STATUS_TOUCH_DETECT_RAW ){
++ info->pressure = 1;
++ /* if yes, start a new scan */
++ enter_state_x_plane(info);
++ }
++ else{
++ if (info->pressure){
++ info->pressure = 0;
++ /* report touch pen up */
++ input_report_key(info->idev, BTN_TOUCH, 0);
++ input_report_abs(info->idev, ABS_PRESSURE, 0);
++ input_sync(info->idev);
++ }
++ /* enable touch detect IRQ */
++ __raw_writel(BM_LRADC_CTRL1_TOUCH_DETECT_IRQ,
++ info->base + HW_LRADC_CTRL1_CLR);
++ __raw_writel(BM_LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
++ info->base + HW_LRADC_CTRL1_SET);
++ }
+ }
+
+-static inline void enter_state_y_plane(struct mxs_ts_info *info)
++static inline void enter_state_touch_detect(struct mxs_ts_info *info)
+ {
++ __raw_writel(info->x_plus_mask, info->base + HW_LRADC_CTRL0_CLR);
+ __raw_writel(info->y_plus_mask, info->base + HW_LRADC_CTRL0_CLR);
+ __raw_writel(info->y_minus_mask, info->base + HW_LRADC_CTRL0_CLR);
+- __raw_writel(info->x_plus_val, info->base + HW_LRADC_CTRL0_SET);
+- __raw_writel(info->x_minus_val, info->base + HW_LRADC_CTRL0_SET);
++ __raw_writel(info->x_minus_mask, info->base + HW_LRADC_CTRL0_CLR);
++
++ __raw_writel(0xFFFFFFFF,
++ info->base + HW_LRADC_CHn_CLR(info->x_plus_chan));
++ __raw_writel(0xFFFFFFFF,
++ info->base + HW_LRADC_CHn_CLR(info->y_plus_chan));
++ __raw_writel(0xFFFFFFFF,
++ info->base + HW_LRADC_CHn_CLR(info->x_minus_chan));
++ __raw_writel(0xFFFFFFFF,
++ info->base + HW_LRADC_CHn_CLR(info->y_minus_chan));
++
++ __raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ << info->y_minus_chan,
++ info->base + HW_LRADC_CTRL1_CLR);
++
++ hw_lradc_set_delay_trigger_kick(LRADC_DELAY_TRIGGER_TOUCHSCREEN, 0);
++
+ __raw_writel(BM_LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+- info->base + HW_LRADC_CTRL0_CLR);
+- hw_lradc_set_delay_trigger_kick(LRADC_DELAY_TRIGGER_TOUCHSCREEN, 1);
+- info->state = TS_STATE_Y_PLANE;
+- info->sample_count = 0;
++ info->base + HW_LRADC_CTRL0_SET);
++ /* delay touch detect interrupt enable due to touch capacitance and imx28 bug */
++ schedule_delayed_work(&info->activate_touch_detect, msecs_to_jiffies(5));
+ }
+
+-static inline void enter_state_touch_verify(struct mxs_ts_info *info)
++static inline void enter_state_disabled(struct mxs_ts_info *info)
+ {
+ __raw_writel(info->y_plus_mask, info->base + HW_LRADC_CTRL0_CLR);
+ __raw_writel(info->y_minus_mask, info->base + HW_LRADC_CTRL0_CLR);
+ __raw_writel(info->x_plus_mask, info->base + HW_LRADC_CTRL0_CLR);
+ __raw_writel(info->x_minus_mask, info->base + HW_LRADC_CTRL0_CLR);
+ __raw_writel(BM_LRADC_CTRL0_TOUCH_DETECT_ENABLE,
+- info->base + HW_LRADC_CTRL0_SET);
+- info->state = TS_STATE_TOUCH_VERIFY;
+- hw_lradc_set_delay_trigger_kick(LRADC_DELAY_TRIGGER_TOUCHSCREEN, 1);
++ info->base + HW_LRADC_CTRL0_CLR);
++ hw_lradc_set_delay_trigger_kick(LRADC_DELAY_TRIGGER_TOUCHSCREEN, 0);
++ info->state = TS_STATE_DISABLED;
+ info->sample_count = 0;
+ }
+
+-static void process_lradc(struct mxs_ts_info *info, u16 x, u16 y,
+- int pressure)
++static void process_lradc(struct mxs_ts_info *info, u16 x, u16 y)
+ {
+ switch (info->state) {
++
+ case TS_STATE_X_PLANE:
+- pr_debug("%s: x plane state, sample_count %d\n", __func__,
+- info->sample_count);
+- if (info->sample_count < 2) {
+- info->x = x;
+- info->sample_count++;
+- } else {
+- if (abs(info->x - x) > TOUCH_DEBOUNCE_TOLERANCE)
+- info->sample_count = 1;
+- else {
+- u16 x_c = info->x * (info->sample_count - 1);
+- info->x = (x_c + x) / info->sample_count;
+- info->sample_count++;
+- }
+- }
+- if (info->sample_count > 4)
++ info->x += x;
++ info->sample_count++;
++ if (info->sample_count >= FILTER_SIZE){
++ info->x = info->x >> FILTER_SIZE;
+ enter_state_y_plane(info);
+- else
++ }
++ else{
+ hw_lradc_set_delay_trigger_kick(
+ LRADC_DELAY_TRIGGER_TOUCHSCREEN, 1);
++ }
+ break;
+
+ case TS_STATE_Y_PLANE:
+- pr_debug("%s: y plane state, sample_count %d\n", __func__,
+- info->sample_count);
+- if (info->sample_count < 2) {
+- info->y = y;
+- info->sample_count++;
+- } else {
+- if (abs(info->y - y) > TOUCH_DEBOUNCE_TOLERANCE)
+- info->sample_count = 1;
+- else {
+- u16 y_c = info->y * (info->sample_count - 1);
+- info->y = (y_c + y) / info->sample_count;
+- info->sample_count++;
+- }
+- }
+- if (info->sample_count > 4)
+- enter_state_touch_verify(info);
+- else
+- hw_lradc_set_delay_trigger_kick(
+- LRADC_DELAY_TRIGGER_TOUCHSCREEN, 1);
+- break;
++ info->y += y;
++ info->sample_count++;
++ if (info->sample_count >= FILTER_SIZE){
++ info->y = info->y >> FILTER_SIZE;
++ input_report_abs(info->idev, ABS_X, info->x);
++ input_report_abs(info->idev, ABS_Y, info->y);
++ input_report_abs(info->idev, ABS_PRESSURE, 100);
++ input_sync(info->idev);
+
+- case TS_STATE_TOUCH_VERIFY:
+- pr_debug("%s: touch verify state, sample_count %d\n", __func__,
+- info->sample_count);
+- pr_debug("%s: x %d, y %d\n", __func__, info->x, info->y);
+- input_report_abs(info->idev, ABS_X, info->x);
+- input_report_abs(info->idev, ABS_Y, info->y);
+- input_report_abs(info->idev, ABS_PRESSURE, pressure);
+- input_sync(info->idev);
+- /* fall through */
+- case TS_STATE_TOUCH_DETECT:
+- pr_debug("%s: touch detect state, sample_count %d\n", __func__,
+- info->sample_count);
+- if (pressure) {
+- input_report_abs(info->idev, ABS_PRESSURE, pressure);
+- enter_state_x_plane(info);
++ enter_state_touch_detect(info);
++ }
++ else{
+ hw_lradc_set_delay_trigger_kick(
+ LRADC_DELAY_TRIGGER_TOUCHSCREEN, 1);
+- } else
+- enter_state_touch_detect(info);
++ }
+ break;
+
+ default:
+@@ -227,30 +211,29 @@ static irqreturn_t ts_handler(int irq, v
+ {
+ struct mxs_ts_info *info = dev_id;
+ u16 x_plus, y_plus;
+- int pressure = 0;
++ u32 status;
+
+- if (irq == info->touch_irq)
++ if (irq == info->touch_irq){
+ __raw_writel(BM_LRADC_CTRL1_TOUCH_DETECT_IRQ,
+ info->base + HW_LRADC_CTRL1_CLR);
+- else if (irq == info->device_irq)
++ info->pressure = __raw_readl(info->base + HW_LRADC_STATUS) & BM_LRADC_STATUS_TOUCH_DETECT_RAW;
++ /* if pen down, disable touch IRQ and start touch scanning */
++ if (info->pressure){
++ __raw_writel(BM_LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
++ info->base + HW_LRADC_CTRL1_CLR);
++ enter_state_x_plane(info);
++ }
++ }
++ else if (irq == info->device_irq){
+ __raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ << info->y_minus_chan,
+ info->base + HW_LRADC_CTRL1_CLR);
++ x_plus = __raw_readl(info->base + HW_LRADC_CHn(info->x_plus_chan)) &
++ BM_LRADC_CHn_VALUE;
++ y_plus = __raw_readl(info->base + HW_LRADC_CHn(info->y_plus_chan)) &
++ BM_LRADC_CHn_VALUE;
+
+- /* get x, y values */
+- x_plus = __raw_readl(info->base + HW_LRADC_CHn(info->x_plus_chan)) &
+- BM_LRADC_CHn_VALUE;
+- y_plus = __raw_readl(info->base + HW_LRADC_CHn(info->y_plus_chan)) &
+- BM_LRADC_CHn_VALUE;
+-
+- /* pressed? */
+- if (__raw_readl(info->base + HW_LRADC_STATUS) &
+- BM_LRADC_STATUS_TOUCH_DETECT_RAW)
+- pressure = 1;
+-
+- pr_debug("%s: irq %d, x_plus %d, y_plus %d, pressure %d\n",
+- __func__, irq, x_plus, y_plus, pressure);
+-
+- process_lradc(info, x_plus, y_plus, pressure);
++ process_lradc(info, x_plus, y_plus);
++ }
+
+ return IRQ_HANDLED;
+ }
+@@ -278,7 +261,8 @@ static int __devinit mxs_ts_probe(struct
+ }
+
+ idev->name = "MXS touchscreen";
+- idev->evbit[0] = BIT(EV_ABS);
++ idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
++ idev->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);
+ input_set_abs_params(idev, ABS_X, 0, 0xFFF, 0, 0);
+ input_set_abs_params(idev, ABS_Y, 0, 0xFFF, 0, 0);
+ input_set_abs_params(idev, ABS_PRESSURE, 0, 1, 0, 0);
+@@ -301,6 +285,8 @@ static int __devinit mxs_ts_probe(struct
+ info->y_plus_mask = plat_data->y_plus_mask;
+ info->y_minus_mask = plat_data->y_minus_mask;
+
++ INIT_DELAYED_WORK(&info->activate_touch_detect, activate_touch_detect);
++
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ printk(KERN_ERR "%s: couldn't get MEM resource\n", __func__);
+@@ -335,7 +321,6 @@ static int __devinit mxs_ts_probe(struct
+ free_irq(info->touch_irq, info);
+ goto out_nodev;
+ }
+- enter_state_touch_detect(info);
+
+ hw_lradc_use_channel(info->x_plus_chan);
+ hw_lradc_use_channel(info->x_minus_chan);
+@@ -366,8 +351,8 @@ static int __devinit mxs_ts_probe(struct
+
+ __raw_writel(BM_LRADC_CTRL1_LRADC0_IRQ_EN << info->y_minus_chan,
+ info->base + HW_LRADC_CTRL1_SET);
+- __raw_writel(BM_LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
+- info->base + HW_LRADC_CTRL1_SET);
++
++ enter_state_touch_detect(info);
+
+ platform_set_drvdata(pdev, info);
+ device_init_wakeup(&pdev->dev, 1);
+@@ -401,6 +386,7 @@ static int __devexit mxs_ts_remove(struc
+
+ free_irq(info->device_irq, info);
+ free_irq(info->touch_irq, info);
++ cancel_delayed_work_sync(&info->activate_touch_detect);
+ input_free_device(info->idev);
+
+ enter_state_disabled(info);
hooks/post-receive
--
armadeus
|