summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Fan <r01011@freescale.com>2008-04-08 16:20:27 +0800
committerDaniel Schaeffer <daniel.schaeffer@timesys.com>2008-08-25 15:20:59 -0400
commitec46dcf0ef8a41810620736511f0b48e3c8061c5 (patch)
tree63df7ef393ff49b9a4d0b4f0e26e8d6be3a908da
parentd9c80f8205c38c53d230f91400ebe884010dadfe (diff)
ENGR00058719 i.MX35 3stack supports touchscreen tsc2007
Add close interface to input device. And change the wait_for_complete to wait_for_complete_interruptible_timeout, because driver can not get the event about singals. So thread can not terminate. Signed-off-by: Fred Fan <r01011@freescale.com>
-rw-r--r--arch/arm/configs/imx35_3stack_defconfig31
-rw-r--r--arch/arm/mach-mx35/board-mx35_3stack.h2
-rw-r--r--arch/arm/mach-mx35/mx35_3stack.c12
-rw-r--r--arch/arm/mach-mx35/mx35_3stack_gpio.c19
-rw-r--r--drivers/input/touchscreen/Kconfig2
-rw-r--r--drivers/input/touchscreen/tsc2007.c53
-rw-r--r--include/asm-arm/arch-mxc/mxc.h10
7 files changed, 115 insertions, 14 deletions
diff --git a/arch/arm/configs/imx35_3stack_defconfig b/arch/arm/configs/imx35_3stack_defconfig
index 64b7ea94b0d8..0e44528fdd76 100644
--- a/arch/arm/configs/imx35_3stack_defconfig
+++ b/arch/arm/configs/imx35_3stack_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.24
-# Thu Mar 27 00:55:50 2008
+# Tue Apr 8 14:04:22 2008
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -446,6 +446,8 @@ CONFIG_MTD_MXC=y
#
# Self-contained MTD device drivers
#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -638,7 +640,7 @@ CONFIG_INPUT=y
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
@@ -648,7 +650,19 @@ CONFIG_INPUT=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+CONFIG_TOUCHSCREEN_TSC2007=y
# CONFIG_INPUT_MISC is not set
#
@@ -753,6 +767,13 @@ CONFIG_SPI_MXC=y
# CONFIG_SPI_MXC_TEST_LOOPBACK is not set
CONFIG_SPI_MXC_SELECT1=y
# CONFIG_SPI_MXC_SELECT2 is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
@@ -845,6 +866,7 @@ CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL=y
# CONFIG_FB_VIRTUAL is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LTV350QV is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_CORGI is not set
CONFIG_BACKLIGHT_MXC=y
@@ -939,6 +961,8 @@ CONFIG_RTC_INTF_DEV=y
#
# SPI RTC drivers
#
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
#
# Platform RTC drivers
@@ -977,6 +1001,7 @@ CONFIG_MXC_IPU_PF=y
#
# MXC PMIC support
#
+# CONFIG_MXC_SPI_PMIC_CORE is not set
CONFIG_MXC_I2C_MCU_PMIC_CORE=y
CONFIG_MXC_PMIC=y
CONFIG_MXC_PMIC_CHARDEV=y
diff --git a/arch/arm/mach-mx35/board-mx35_3stack.h b/arch/arm/mach-mx35/board-mx35_3stack.h
index a402fedd4e35..ececa519e667 100644
--- a/arch/arm/mach-mx35/board-mx35_3stack.h
+++ b/arch/arm/mach-mx35/board-mx35_3stack.h
@@ -167,6 +167,8 @@ extern struct sys_timer mxc_timer;
extern void mxc_cpu_common_init(void);
extern int mxc_clocks_init(void);
extern void __init early_console_setup(char *);
+extern void gpio_tsc_active(void);
+extern void gpio_tsc_inactive(void);
#endif /* CONFIG_MACH_MX35_3DS */
#endif /* __ASM_ARCH_MXC_BOARD_MX35_3STACK_H__ */
diff --git a/arch/arm/mach-mx35/mx35_3stack.c b/arch/arm/mach-mx35/mx35_3stack.c
index 202f56ae3773..61444de96a87 100644
--- a/arch/arm/mach-mx35/mx35_3stack.c
+++ b/arch/arm/mach-mx35/mx35_3stack.c
@@ -253,6 +253,12 @@ static inline void mxc_init_bl(void)
}
#endif
+static struct mxc_tsc_platform_data tsc2007_data = {
+ .vdd_reg = "SW1",
+ .active = gpio_tsc_active,
+ .inactive = gpio_tsc_inactive,
+};
+
static struct i2c_board_info mxc_i2c_board_info[] __initdata = {
{
.driver_name = "mc9sdz60",
@@ -262,6 +268,12 @@ static struct i2c_board_info mxc_i2c_board_info[] __initdata = {
.driver_name = "max8660",
.addr = 0x34,
},
+ {
+ .driver_name = "TSC2007",
+ .addr = 0x48,
+ .platform_data = &tsc2007_data,
+ .irq = IOMUX_TO_IRQ(MX35_PIN_CAPTURE),
+ },
};
#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
diff --git a/arch/arm/mach-mx35/mx35_3stack_gpio.c b/arch/arm/mach-mx35/mx35_3stack_gpio.c
index bc98a0954320..711e1f6d1a4d 100644
--- a/arch/arm/mach-mx35/mx35_3stack_gpio.c
+++ b/arch/arm/mach-mx35/mx35_3stack_gpio.c
@@ -378,3 +378,22 @@ void gpio_lcd_inactive(void)
}
EXPORT_SYMBOL(gpio_lcd_inactive);
+
+/*!
+ * Setup pin for touchscreen
+ */
+void gpio_tsc_active(void)
+{
+ unsigned int pad_val = PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU;
+ mxc_request_iomux(MX35_PIN_CAPTURE, MUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX35_PIN_CAPTURE, pad_val);
+ mxc_set_gpio_direction(MX35_PIN_CAPTURE, 1);
+}
+
+/*!
+ * Release pin for touchscreen
+ */
+void gpio_tsc_inactive(void)
+{
+ mxc_free_iomux(MX35_PIN_CAPTURE, MUX_CONFIG_GPIO);
+}
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 9e49ffc55d6f..82565379a41f 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -277,7 +277,7 @@ config TOUCHSCREEN_USB_GOTOP
config TOUCHSCREEN_TSC2007
tristate "TI Touch Screen Controller Chip TSC2007"
- depends on ARCH_MX37
+ depends on ARCH_MX37 || MACH_MX35_3DS
help
If you say yes here you get support for TSC2007 touch screen controller chip.
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index f59fcff2b6f4..04be406d700f 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -35,6 +35,7 @@
#include <linux/kthread.h>
#include <linux/input.h>
#include <linux/delay.h>
+#include <linux/regulator/regulator.h>
#include <asm/mach/irq.h>
#define DRIVER_NAME "TSC2007"
@@ -76,6 +77,7 @@ struct tsc2007_data {
struct completion penup_completion;
enum tsc2007_m m;
int penirq;
+ struct regulator *vdd_reg;
};
static int tsc2007_read(struct tsc2007_data *data,
@@ -105,7 +107,7 @@ static int tsc2007_read(struct tsc2007_data *data,
}
return 0;
-err:
+ err:
return -ENODEV;
}
@@ -169,8 +171,13 @@ static int tsc2007ts_thread(void *v)
while (1) {
unsigned int x = 0, y = 0, p = 0;
+ if (kthread_should_stop())
+ break;
/* Wait for an Pen down interrupt */
- wait_for_completion(&d->penirq_completion);
+ if (wait_for_completion_interruptible_timeout
+ (&d->penirq_completion, HZ) <= 0)
+ continue;
+
tsc2007_read_xpos(d, PD_PENIRQ_DISARM, &x);
tsc2007_read_ypos(d, PD_PENIRQ_DISARM, &y);
tsc2007_read_pressure(d, PD_PENIRQ_DISARM, &p);
@@ -204,8 +211,6 @@ static int tsc2007ts_thread(void *v)
tsc2007_read(d, MEAS_TEMP0, PD_PENIRQ_ARM, 0);
enable_irq(d->penirq);
- if (kthread_should_stop())
- break;
}
d->ts_thread_cnt = 0;
@@ -220,6 +225,8 @@ static int tsc2007_idev_open(struct input_dev *idev)
d->penirq_timer.data = (unsigned long)d;
d->penirq_timer.function = tsc2007_pen_up;
+ init_completion(&d->penup_completion);
+
d->tstask = kthread_run(tsc2007ts_thread, d, DRIVER_NAME "tsd");
if (IS_ERR(d->tstask))
ret = PTR_ERR(d->tstask);
@@ -227,6 +234,15 @@ static int tsc2007_idev_open(struct input_dev *idev)
return ret;
}
+static void tsc2007_idev_close(struct input_dev *idev)
+{
+ struct tsc2007_data *d = idev->private;
+ if (!IS_ERR(d->tstask))
+ kthread_stop(d->tstask);
+
+ del_timer_sync(&d->penirq_timer);
+}
+
static int tsc2007_driver_register(struct tsc2007_data *data)
{
struct input_dev *idev;
@@ -236,6 +252,8 @@ static int tsc2007_driver_register(struct tsc2007_data *data)
data->penirq_timer.data = (unsigned long)data;
data->penirq_timer.function = tsc2007_pen_up;
+ init_completion(&data->penirq_completion);
+
if (data->penirq) {
ret =
request_irq(data->penirq, tsc2007_penirq, IRQT_LOW,
@@ -243,8 +261,6 @@ static int tsc2007_driver_register(struct tsc2007_data *data)
if (!ret) {
printk(KERN_INFO "%s: Registering Touchscreen device\n",
__func__);
- init_completion(&data->penirq_completion);
- init_completion(&data->penup_completion);
} else {
printk(KERN_ERR "%s: Cannot grab irq %d\n",
__func__, data->penirq);
@@ -256,6 +272,7 @@ static int tsc2007_driver_register(struct tsc2007_data *data)
idev->name = DRIVER_NAME;
idev->evbit[0] = BIT(EV_ABS);
idev->open = tsc2007_idev_open;
+ idev->close = tsc2007_idev_close;
idev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
input_set_abs_params(idev, ABS_X, 0, ADC_MAX, 0, 0);
input_set_abs_params(idev, ABS_Y, 0, ADC_MAX, 0, 0);
@@ -271,8 +288,8 @@ static int tsc2007_i2c_remove(struct i2c_client *client)
{
int err;
struct tsc2007_data *d = i2c_get_clientdata(client);
+ struct mxc_tsc_platform_data *tsc_data;
- kthread_stop(d->tstask);
free_irq(d->penirq, d);
input_unregister_device(d->idev);
@@ -283,12 +300,22 @@ static int tsc2007_i2c_remove(struct i2c_client *client)
return err;
}
+ tsc_data = (struct mxc_tsc_platform_data *)(client->dev).platform_data;
+ if (tsc_data && tsc_data->inactive)
+ tsc_data->inactive();
+
+ if (d->vdd_reg) {
+ regulator_disable(d->vdd_reg);
+ regulator_put(d->vdd_reg, &client->dev);
+ d->vdd_reg = NULL;
+ }
return 0;
}
static int tsc2007_i2c_probe(struct i2c_client *client)
{
struct tsc2007_data *data;
+ struct mxc_tsc_platform_data *tsc_data;
int err = 0;
data = kzalloc(sizeof(struct tsc2007_data), GFP_KERNEL);
@@ -299,6 +326,16 @@ static int tsc2007_i2c_probe(struct i2c_client *client)
data->client = client;
data->penirq = client->irq;
+ tsc_data = (struct mxc_tsc_platform_data *)(client->dev).platform_data;
+ if (tsc_data && tsc_data->vdd_reg) {
+ data->vdd_reg = regulator_get(&client->dev, tsc_data->vdd_reg);
+ if (data->vdd_reg)
+ regulator_enable(data->vdd_reg);
+ if (tsc_data->active)
+ tsc_data->active();
+ } else
+ data->vdd_reg = NULL;
+
err = tsc2007_powerdown(data);
if (err >= 0) {
data->m = M_12BIT;
@@ -310,7 +347,7 @@ static int tsc2007_i2c_probe(struct i2c_client *client)
return 0;
}
-exit:
+ exit:
return err;
}
diff --git a/include/asm-arm/arch-mxc/mxc.h b/include/asm-arm/arch-mxc/mxc.h
index f2645552fa9a..d901cc92e984 100644
--- a/include/asm-arm/arch-mxc/mxc.h
+++ b/include/asm-arm/arch-mxc/mxc.h
@@ -101,6 +101,12 @@ struct mxc_lcd_platform_data {
void (*reset) (void);
};
+struct mxc_tsc_platform_data {
+ char *vdd_reg;
+ void (*active) (void);
+ void (*inactive) (void);
+};
+
struct mxc_tvout_platform_data {
char *io_reg;
char *core_reg;
@@ -150,7 +156,7 @@ unsigned long board_get_ckih_rate(void);
int mxc_snoop_set_config(u32 num, unsigned long base, int size);
int mxc_snoop_get_status(u32 num, u32 * statl, u32 * stath);
-#endif /* __ASSEMBLY__ */
+#endif /* __ASSEMBLY__ */
#define IOMUX_TO_GPIO(pin) ((((unsigned int)pin >> MUX_IO_P) * GPIO_NUM_PIN) + ((pin >> MUX_IO_I) & ((1 << (MUX_IO_P - MUX_IO_I)) -1)))
#define IOMUX_TO_IRQ(pin) (MXC_GPIO_INT_BASE + IOMUX_TO_GPIO(pin))
@@ -257,4 +263,4 @@ int tzic_enable_wake(int is_idle);
#endif
-#endif /* __ASM_ARCH_MXC_H__ */
+#endif /* __ASM_ARCH_MXC_H__ */