* [PATCH 0/2] TSC2046 toucscreen support @ 2007-05-04 21:40 Kevin Hilman 2007-05-04 21:40 ` [PATCH 1/2] ARM: OMAP: add 24xx GPIO debounce support Kevin Hilman 2007-05-04 21:40 ` [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 Kevin Hilman 0 siblings, 2 replies; 11+ messages in thread From: Kevin Hilman @ 2007-05-04 21:40 UTC (permalink / raw) To: linux-omap-open-source Here is support for the TSC2046 touchscreen controller which is on the OMAP2430SDP board. It also includes a patch to add debounce support to the GPIO layer. Note that SPI driver-model hook-ups are done in the touchscreen driver instead of a separate tsc2046 layer in drivers/spi. It seemed overkill to have drivers/spi/tsc2046.c with only a probe and remove function, so I included them in drivers/input/touchscreen/tsc2046_ts.c. Kevin -- ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/2] ARM: OMAP: add 24xx GPIO debounce support 2007-05-04 21:40 [PATCH 0/2] TSC2046 toucscreen support Kevin Hilman @ 2007-05-04 21:40 ` Kevin Hilman 2007-05-04 21:40 ` [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 Kevin Hilman 1 sibling, 0 replies; 11+ messages in thread From: Kevin Hilman @ 2007-05-04 21:40 UTC (permalink / raw) To: linux-omap-open-source [-- Attachment #1: gpio-debounce.patch --] [-- Type: text/plain, Size: 2397 bytes --] Signed-off-by: Kevin Hilman <khilman@mvista.com> --- arch/arm/plat-omap/gpio.c | 39 +++++++++++++++++++++++++++++++++++++++ include/asm-arm/arch-omap/gpio.h | 5 +++++ 2 files changed, 44 insertions(+) Index: dev/arch/arm/plat-omap/gpio.c =================================================================== --- dev.orig/arch/arm/plat-omap/gpio.c +++ dev/arch/arm/plat-omap/gpio.c @@ -111,6 +111,8 @@ #define OMAP24XX_GPIO_LEVELDETECT1 0x0044 #define OMAP24XX_GPIO_RISINGDETECT 0x0048 #define OMAP24XX_GPIO_FALLINGDETECT 0x004c +#define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050 +#define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054 #define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060 #define OMAP24XX_GPIO_SETIRQENABLE1 0x0064 #define OMAP24XX_GPIO_CLEARWKUENA 0x0080 @@ -484,6 +486,43 @@ static inline void set_24xx_gpio_trigger /* FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only level * triggering requested. */ } + +void +omap_set_gpio_debounce(int gpio, int enable) +{ + struct gpio_bank *bank; + void __iomem *reg; + u32 val, l = 1 << get_gpio_index(gpio); + + bank = get_gpio_bank(gpio); + reg = bank->base; + + reg += OMAP24XX_GPIO_DEBOUNCE_EN; + val = __raw_readl(reg); + + if (enable) + val |= l; + else + val &= ~l; + + __raw_writel(val, reg); +} +EXPORT_SYMBOL(omap_set_gpio_debounce); + +void +omap_set_gpio_debounce_time(int gpio, int enc_time) +{ + struct gpio_bank *bank; + void __iomem *reg; + + bank = get_gpio_bank(gpio); + reg = bank->base; + + enc_time &= 0xff; + reg += OMAP24XX_GPIO_DEBOUNCE_VAL; + __raw_writel(enc_time, reg); +} +EXPORT_SYMBOL(omap_set_gpio_debounce_time); #endif static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) Index: dev/include/asm-arm/arch-omap/gpio.h =================================================================== --- dev.orig/include/asm-arm/arch-omap/gpio.h +++ dev/include/asm-arm/arch-omap/gpio.h @@ -78,6 +78,11 @@ extern int omap_get_gpio_datain(int gpio extern void omap2_gpio_prepare_for_retention(void); extern void omap2_gpio_resume_after_retention(void); +#ifdef CONFIG_ARCH_OMAP24XX +extern void omap_set_gpio_debounce(int gpio, int enable); +extern void omap_set_gpio_debounce_time(int gpio, int enable); +#endif + /*-------------------------------------------------------------------------*/ /* wrappers for "new style" GPIO calls. the old OMAP-specfic ones should -- ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 2007-05-04 21:40 [PATCH 0/2] TSC2046 toucscreen support Kevin Hilman 2007-05-04 21:40 ` [PATCH 1/2] ARM: OMAP: add 24xx GPIO debounce support Kevin Hilman @ 2007-05-04 21:40 ` Kevin Hilman 2007-05-04 21:53 ` Kevin Hilman 2007-05-05 8:28 ` Komal Shah 1 sibling, 2 replies; 11+ messages in thread From: Kevin Hilman @ 2007-05-04 21:40 UTC (permalink / raw) To: linux-omap-open-source [-- Attachment #1: touchscreen-tsc2046.patch --] [-- Type: text/plain, Size: 18531 bytes --] This is a rework of the tsc2046 driver from TI's tree, based on the tsc2301 driver and using the new SPI framework. Signed-off-by: Kevin Hilman <khilman@mvista.com> --- arch/arm/mach-omap2/board-2430sdp.c | 32 + drivers/input/touchscreen/Kconfig | 6 drivers/input/touchscreen/Makefile | 1 drivers/input/touchscreen/tsc2046_ts.c | 555 +++++++++++++++++++++++++++++++++ include/linux/spi/tsc2046.h | 60 +++ 5 files changed, 654 insertions(+) Index: dev/arch/arm/mach-omap2/board-2430sdp.c =================================================================== --- dev.orig/arch/arm/mach-omap2/board-2430sdp.c +++ dev/arch/arm/mach-omap2/board-2430sdp.c @@ -21,6 +21,8 @@ #include <linux/delay.h> #include <linux/err.h> #include <linux/clk.h> +#include <linux/spi/spi.h> +#include <linux/spi/tsc2046.h> #include <asm/hardware.h> #include <asm/mach-types.h> @@ -33,6 +35,7 @@ #include <asm/arch/board.h> #include <asm/arch/common.h> #include <asm/arch/gpmc.h> +#include <asm/arch/mcspi.h> #include "prcm-regs.h" #include <asm/io.h> @@ -40,6 +43,9 @@ #define SDP2430_FLASH_CS 0 #define SDP2430_SMC91X_CS 5 +/* TSC2046 (touchscreen) */ +#define TS_GPIO 24 + static struct mtd_partition sdp2430_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ { @@ -119,6 +125,29 @@ static struct platform_device *sdp2430_d &sdp2430_flash_device, }; +static struct tsc2046_platform_data tsc2046_config = { + .dav_gpio = TS_GPIO, + .gpio_debounce = 0xa, +}; + +static struct omap2_mcspi_device_config tsc2046_mcspi_config = { + .turbo_mode = 0, + .single_channel = 0, /* 0: slave, 1: master */ +}; + +static struct spi_board_info sdp2430_spi_board_info[] __initdata = { + [0] = { + /* TSC2046 operates at a max freqency of 2MHz, so + * operate slightly below at 1.5MHz */ + .modalias = "tsc2046", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data= &tsc2046_mcspi_config, + .platform_data = &tsc2046_config, + }, +}; + static inline void __init sdp2430_init_smc91x(void) { int eth_cs; @@ -198,6 +227,9 @@ static void __init omap_2430sdp_init(voi omap_board_config = sdp2430_config; omap_board_config_size = ARRAY_SIZE(sdp2430_config); omap_serial_init(); + + spi_register_board_info(sdp2430_spi_board_info, + ARRAY_SIZE(sdp2430_spi_board_info)); } static void __init omap_2430sdp_map_io(void) Index: dev/drivers/input/touchscreen/Kconfig =================================================================== --- dev.orig/drivers/input/touchscreen/Kconfig +++ dev/drivers/input/touchscreen/Kconfig @@ -165,4 +165,10 @@ config TOUCHSCREEN_TSC2301 help Say Y here for if you are using the touchscreen features of TSC2301. +config TOUCHSCREEN_TSC2046 + tristate "TSC2046 touchscreen support" + default MACH_OMAP2430SDP + help + Say Y here for if you are using the touchscreen features of TSC2046 + endif Index: dev/drivers/input/touchscreen/Makefile =================================================================== --- dev.orig/drivers/input/touchscreen/Makefile +++ dev/drivers/input/touchscreen/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb obj-$(CONFIG_TOUCHSCREEN_TSC2102) += tsc2102_ts.o obj-$(CONFIG_TOUCHSCREEN_OMAP) += omap/ obj-$(CONFIG_TOUCHSCREEN_TSC2301) += tsc2301_ts.o +obj-$(CONFIG_TOUCHSCREEN_TSC2046) += tsc2046_ts.o Index: dev/drivers/input/touchscreen/tsc2046_ts.c =================================================================== --- /dev/null +++ dev/drivers/input/touchscreen/tsc2046_ts.c @@ -0,0 +1,555 @@ +/* + * TSC2046 Touchscreen driver + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * + * Communication details from original TI driver + * Copyright (C) 2004-2005 Texas Instruments, Inc. + * + * Structure based heavily on TSC2301 driver + * Copyright (C) 2005-2006 Nokia Corporation + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/spi/spi.h> + +#ifdef CONFIG_ARCH_OMAP +#include <asm/arch/gpio.h> +#endif + +#include <linux/spi/tsc2046.h> + +/* TSC2046 commands */ +#define START_BYTE 0x8000 +#define X_CMDWD 0xd300 +#define Y_CMDWD 0x9300 +#define Z1_CMDWD 0xb300 +#define Z2_CMDWD 0xc300 + +#define TSC2046_TS_SCAN_TIME 1 +#define MAX_12BIT ((1 << 12) - 1) + +struct tsc2046_ts { + struct input_dev *idev; + char phys[32]; + struct timer_list timer; + spinlock_t lock; + + struct spi_transfer read_xfer[3]; + struct spi_message read_msg; + struct spi_message enable_msg; + u16 data[5]; + + u16 x; + u16 y; + u16 p; + int sample_cnt; + + int ignore_last : 1; + u16 x_plate_ohm; + int max_pressure; + int touch_pressure; + int pressure_limit; + + u16 irq_enabled:1; + u16 pen_down:1; + u16 disabled:1; + u16 pending:1; + + s16 dav_gpio; + int irq; +}; + +static const u16 tsc2046_ts_cmd_data[] = { + START_BYTE, X_CMDWD, Y_CMDWD, Z1_CMDWD, Z2_CMDWD, +}; + +static int device_suspended(struct device *dev) +{ + struct tsc2046 *tsc = dev_get_drvdata(dev); + return dev->power.power_state.event != PM_EVENT_ON || tsc->ts->disabled; +} + +static void update_pen_state(struct tsc2046 *tsc, int x, int y, int pressure) +{ + struct tsc2046_ts *ts = tsc->ts; + int sync = 0; + + if (pressure) { + input_report_abs(ts->idev, ABS_X, x); + input_report_abs(ts->idev, ABS_Y, y); + input_report_abs(ts->idev, ABS_PRESSURE, pressure); + if (!ts->pen_down) + input_report_key(ts->idev, BTN_TOUCH, 1); + sync = 1; + } else if (ts->pen_down) { + input_report_abs(ts->idev, ABS_PRESSURE, 0); + input_report_key(ts->idev, BTN_TOUCH, 0); + sync = 1; + } + + if (sync) + input_sync(ts->idev); + + ts->pen_down = pressure ? 1 : 0; + +#ifdef VERBOSE + dev_dbg(&tsc->spi->dev, "x %4d y %4d p %4d\n", x, y, pressure); +#endif +} + +#define CONV_DATA(d1, d2) \ + (((d1 & 0x7f) << 5) | ((d2 >> 11) & 0x1f)) + +/* + * This procedure is called by the SPI framework after the coordinates + * have been read from TSC2046 + */ +static void tsc2046_ts_rx(void *arg) +{ + struct tsc2046 *tsc = arg; + struct tsc2046_ts *ts = tsc->ts; + unsigned int x, y, z1, z2, pressure; + + x = CONV_DATA(ts->data[2], ts->data[3]); + y = CONV_DATA(ts->data[1], ts->data[2]); + z1 = CONV_DATA(ts->data[3], ts->data[4]); + z2 = CONV_DATA(ts->data[4], 0); + + if (z1) { + pressure = ts->x_plate_ohm * x; + pressure /= 4096; + pressure *= z2 - z1; + pressure /= z1; + } else + pressure = 0; + + /* If pressure value is above a preset limit (pen is barely + * touching the screen) we can't trust the coordinate values. + */ + if (pressure < ts->pressure_limit && x < MAX_12BIT && y < MAX_12BIT) { + ts->pressure_limit = ts->max_pressure; + if (ts->ignore_last) { + if (ts->sample_cnt) + update_pen_state(tsc, ts->x, ts->y, ts->p); + ts->x = x; + ts->y = y; + ts->p = pressure; + } else + update_pen_state(tsc, x, y, pressure); + ts->sample_cnt++; + } + + mod_timer(&ts->timer, + jiffies + msecs_to_jiffies(TSC2046_TS_SCAN_TIME)); +} + +static int is_pen_down(struct tsc2046_ts *ts) +{ + return ts->pen_down; +} + +/* + * Timer is called every TSC2046_TS_SCAN_TIME when the pen is down + */ +static void tsc2046_ts_timer(unsigned long arg) +{ + struct tsc2046 *tsc = (void *) arg; + struct tsc2046_ts *ts = tsc->ts; + unsigned long flags; + int ndav; + int r; + + spin_lock_irqsave(&ts->lock, flags); + ndav = omap_get_gpio_datain(ts->dav_gpio); + if (ndav || device_suspended(&tsc->spi->dev)) { + /* Pen has been lifted */ + if (!device_suspended(&tsc->spi->dev) && + !ts->irq_enabled) { + ts->irq_enabled = 1; + enable_irq(ts->irq); + } + update_pen_state(tsc, 0, 0, 0); + ts->pending = 0; + spin_unlock_irqrestore(&ts->lock, flags); + + } else { + ts->pen_down = 1; + spin_unlock_irqrestore(&ts->lock, flags); + + r = spi_async(tsc->spi, &ts->read_msg); + if (r) + dev_err(&tsc->spi->dev, "ts: spi_async() failed"); + } +} + +/* + * This interrupt is called when pen is down and first coordinates are + * available. That is indicated by a falling edge on DEV line. IRQ is + * disabled here because while the pen is down the coordinates are + * read by a timer. + */ +static irqreturn_t tsc2046_ts_irq_handler(int irq, void *dev_id) +{ + struct tsc2046 *tsc = dev_id; + struct tsc2046_ts *ts = tsc->ts; + unsigned long flags; + + spin_lock_irqsave(&ts->lock, flags); + if (ts->irq_enabled) { + ts->irq_enabled = 0; + disable_irq(ts->irq); + ts->pending = 1; + ts->pressure_limit = ts->touch_pressure; + ts->sample_cnt = 0; + mod_timer(&ts->timer, + jiffies + msecs_to_jiffies(TSC2046_TS_SCAN_TIME)); + } + spin_unlock_irqrestore(&ts->lock, flags); + + return IRQ_HANDLED; +} + +/* Must be called with ts->lock held */ +static void tsc2046_ts_disable(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + + if (ts->disabled) + return; + + ts->disabled = 1; + if (!ts->pending) { + ts->irq_enabled = 0; + disable_irq(ts->irq); + } else { + while (ts->pending) { + spin_unlock_irq(&ts->lock); + msleep(1); + spin_lock_irq(&ts->lock); + } + } +} + +static void tsc2046_ts_enable(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + + if (!ts->disabled) + return; + + ts->disabled = 0; + ts->irq_enabled = 1; + enable_irq(ts->irq); +} + +#ifdef CONFIG_PM +int tsc2046_ts_suspend(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + + spin_lock_irq(&ts->lock); + tsc2046_ts_disable(tsc); + spin_unlock_irq(&ts->lock); + + return 0; +} + +void tsc2046_ts_resume(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + + spin_lock_irq(&ts->lock); + tsc2046_ts_enable(tsc); + spin_unlock_irq(&ts->lock); +} +#endif + +static void tsc2046_ts_setup_spi_xfer(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + struct spi_message *m = &ts->read_msg; + struct spi_transfer *x = &ts->read_xfer[1]; + + spi_message_init(m); + + /* read and write data in one transaction */ + x->tx_buf = &tsc2046_ts_cmd_data; + x->rx_buf = &ts->data; + x->len = 10; + spi_message_add_tail(x, m); + + /* send another START_BYTE to (re)enable pen interrupts */ + x++; + x->tx_buf = &tsc2046_ts_cmd_data[0]; + x->len = 2; + spi_message_add_tail(x, m); + + m->complete = tsc2046_ts_rx; + m->context = tsc; +} + +static ssize_t tsc2046_ts_pen_down_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tsc2046 *tsc = dev_get_drvdata(dev); + + return sprintf(buf, "%u\n", is_pen_down(tsc->ts)); +} + +static DEVICE_ATTR(pen_down, S_IRUGO, tsc2046_ts_pen_down_show, NULL); + +static ssize_t tsc2046_ts_disable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsc2046 *tsc = dev_get_drvdata(dev); + struct tsc2046_ts *ts = tsc->ts; + + return sprintf(buf, "%u\n", ts->disabled); +} + +static ssize_t tsc2046_ts_disable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct tsc2046 *tsc = dev_get_drvdata(dev); + struct tsc2046_ts *ts = tsc->ts; + char *endp; + int i; + + i = simple_strtoul(buf, &endp, 10); + spin_lock_irq(&ts->lock); + + if (i) + tsc2046_ts_disable(tsc); + else + tsc2046_ts_enable(tsc); + + spin_unlock_irq(&ts->lock); + + return count; +} + +static DEVICE_ATTR(disable_ts, 0664, tsc2046_ts_disable_show, + tsc2046_ts_disable_store); + +int __devinit tsc2046_ts_init(struct tsc2046 *tsc, + struct tsc2046_platform_data *pdata) +{ + struct tsc2046_ts *ts; + struct input_dev *idev; + int dav_gpio, r; + + if (pdata->dav_gpio < 0) { + dev_err(&tsc->spi->dev, "need DAV GPIO"); + return -EINVAL; + } + dav_gpio = pdata->dav_gpio; + + ts = kzalloc(sizeof(*ts), GFP_KERNEL); + if (ts == NULL) + return -ENOMEM; + tsc->ts = ts; + + ts->dav_gpio = dav_gpio; +#ifdef CONFIG_ARCH_OMAP + r = omap_request_gpio(dav_gpio); + if (r < 0) { + dev_err(&tsc->spi->dev, "unable to get DAV GPIO"); + goto err1; + } + omap_set_gpio_direction(dav_gpio, 1); + if (pdata->gpio_debounce) { + omap_set_gpio_debounce(tsc->gpio, 1); + omap_set_gpio_debounce_time(tsc->gpio, pdata->gpio_debounce); + } + + ts->irq = OMAP_GPIO_IRQ(dav_gpio); +#endif + init_timer(&ts->timer); + ts->timer.data = (unsigned long) tsc; + ts->timer.function = tsc2046_ts_timer; + + spin_lock_init(&ts->lock); + + ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280; + ts->max_pressure= pdata->ts_max_pressure ? : MAX_12BIT; + ts->touch_pressure = pdata->ts_touch_pressure ? : ts->max_pressure; + ts->ignore_last = pdata->ts_ignore_last; + + idev = input_allocate_device(); + if (idev == NULL) { + r = -ENOMEM; + goto err2; + } + idev->name = "TSC2046 touchscreen"; + snprintf(ts->phys, sizeof(ts->phys), + "%s/input-ts", tsc->spi->dev.bus_id); + idev->phys = ts->phys; + + idev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); + idev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); + ts->idev = idev; + + tsc2046_ts_setup_spi_xfer(tsc); + + /* These parameters should perhaps be configurable? */ + input_set_abs_params(idev, ABS_X, 0, 4096, 0, 0); + input_set_abs_params(idev, ABS_Y, 0, 4096, 0, 0); + input_set_abs_params(idev, ABS_PRESSURE, 0, 1024, 0, 0); + + ts->irq_enabled = 1; + r = request_irq(ts->irq, tsc2046_ts_irq_handler, + SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, + "tsc2046-ts", tsc); + if (r < 0) { + dev_err(&tsc->spi->dev, "unable to get DAV IRQ"); + goto err3; + } + set_irq_wake(ts->irq, 1); + + if (device_create_file(&tsc->spi->dev, &dev_attr_pen_down) < 0) + goto err4; + if (device_create_file(&tsc->spi->dev, &dev_attr_disable_ts) < 0) + goto err5; + + r = input_register_device(idev); + if (r < 0) { + dev_err(&tsc->spi->dev, "can't register touchscreen device\n"); + goto err6; + } + + /* kick off a transaction to enable pen interrupts */ + spi_async(tsc->spi, &ts->read_msg); + + return 0; +err6: + device_remove_file(&tsc->spi->dev, &dev_attr_disable_ts); +err5: + device_remove_file(&tsc->spi->dev, &dev_attr_pen_down); +err4: + free_irq(ts->irq, tsc); +err3: + input_free_device(idev); +err2: +#ifdef CONFIG_ARCH_OMAP + omap_free_gpio(dav_gpio); +#endif + err1: + kfree(ts); + return r; +} +EXPORT_SYMBOL(tsc2046_ts_init); + +void __devexit tsc2046_ts_exit(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + unsigned long flags; + + spin_lock_irqsave(&ts->lock, flags); + tsc2046_ts_disable(tsc); + spin_unlock_irqrestore(&ts->lock, flags); + + device_remove_file(&tsc->spi->dev, &dev_attr_disable_ts); + device_remove_file(&tsc->spi->dev, &dev_attr_pen_down); + + free_irq(ts->irq, tsc); + input_unregister_device(ts->idev); + +#ifdef CONFIG_ARCH_OMAP + omap_free_gpio(ts->dav_gpio); +#endif + kfree(ts); +} +EXPORT_SYMBOL(tsc2046_ts_exit); + + +static int __devinit tsc2046_probe(struct spi_device *spi) +{ + struct tsc2046 *tsc; + struct tsc2046_platform_data *pdata = spi->dev.platform_data; + int r = -ENODEV; + + dev_dbg(&spi->dev, "%s\n", __FUNCTION__); + + if (!pdata) { + dev_dbg(&spi->dev, "no platform data?\n"); + return -ENODEV; + } + + tsc = kzalloc(sizeof(*tsc), GFP_KERNEL); + if (tsc == NULL) + return -ENOMEM; + + dev_set_drvdata(&spi->dev, tsc); + tsc->spi = spi; + spi->dev.power.power_state = PMSG_ON; + + spi->mode = SPI_MODE_1; + spi->bits_per_word = 16; + + /* The max speed might've been defined by the board-specific + * struct */ + if (!spi->max_speed_hz) + spi->max_speed_hz = TSC2046_HZ; + spi_setup(spi); + + r = tsc2046_ts_init(tsc, pdata); + if (r) + goto err1; + + return 0; + err1: + kfree(tsc); + return r; +} + +static int __devexit tsc2046_remove(struct spi_device *spi) +{ + struct tsc2046 *tsc = dev_get_drvdata(&spi->dev); + + dev_dbg(&tsc->spi->dev, "%s\n", __FUNCTION__); + + tsc2046_ts_exit(tsc); + kfree(tsc); + + return 0; +} + +static struct spi_driver tsc2046_driver = { + .driver = { + .name = "tsc2046", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = tsc2046_probe, + .remove = __devexit_p(tsc2046_remove), +}; + +static int __init tsc2046_init(void) +{ + printk("TSC2046 driver initializing\n"); + + return spi_register_driver(&tsc2046_driver); +} +module_init(tsc2046_init); + +static void __exit tsc2046_exit(void) +{ + spi_unregister_driver(&tsc2046_driver); +} +module_exit(tsc2046_exit); + +MODULE_AUTHOR("Kevin Hilman <khilman@mvista.com>"); +MODULE_LICENSE("GPL"); Index: dev/include/linux/spi/tsc2046.h =================================================================== --- /dev/null +++ dev/include/linux/spi/tsc2046.h @@ -0,0 +1,60 @@ +#ifndef _LINUX_SPI_TSC2046_H +#define _LINUX_SPI_TSC2046_H + +#include <linux/types.h> +#include <linux/timer.h> + +struct tsc2046_platform_data { + s16 dav_gpio; + s16 gpio_debounce; + u16 ts_x_plate_ohm; + u32 ts_max_pressure; /* Samples with bigger pressure value will + be ignored, since the corresponding X, Y + values are unreliable */ + u32 ts_touch_pressure;/* Pressure limit until we report a + touch event. After that we switch + to ts_max_pressure. */ + unsigned ts_ignore_last : 1; + +}; + +struct tsc2046_ts; + +struct tsc2046 { + struct spi_device *spi; + int gpio; + + struct tsc2046_ts *ts; +}; + +/* The TSC2046 operates at a maximum speed of 2MHz */ +#define TSC2046_HZ 2000000 + +#define TSC2046_DECL_MOD(module) \ +extern int tsc2046_##module##_init(struct tsc2046 *tsc, \ + struct tsc2046_platform_data *pdata); \ +extern void tsc2046_##module##_exit(struct tsc2046 *tsc); \ +extern int tsc2046_##module##_suspend(struct tsc2046 *tsc); \ +extern void tsc2046_##module##_resume(struct tsc2046 *tsc); + +#define TSC2046_DECL_EMPTY_MOD(module) \ +static inline int tsc2046_##module##_init(struct tsc2046 *tsc, \ + struct tsc2046_platform_data *pdata) \ +{ \ + return 0; \ +} \ +static inline void tsc2046_##module##_exit(struct tsc2046 *tsc) {} \ +static inline int tsc2046_##module##_suspend(struct tsc2046 *tsc) \ +{ \ + return 0; \ +} \ +static inline void tsc2046_##module##_resume(struct tsc2046 *tsc) {} + +#if defined(CONFIG_TOUCHSCREEN_TSC2046) || \ + defined(CONFIG_TOUCHSCREEN_TSC2046_MODULE) +TSC2046_DECL_MOD(ts) +#else +TSC2046_DECL_EMPTY_MOD(ts) +#endif + +#endif -- ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 2007-05-04 21:40 ` [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 Kevin Hilman @ 2007-05-04 21:53 ` Kevin Hilman 2007-05-04 23:36 ` Tony Lindgren 2007-05-05 8:28 ` Komal Shah 1 sibling, 1 reply; 11+ messages in thread From: Kevin Hilman @ 2007-05-04 21:53 UTC (permalink / raw) To: linux-omap-open-source [-- Attachment #1: Type: text/plain, Size: 91 bytes --] Tony, Here's a minor update so it applies on the (already pushed) onenand patch. Kevin [-- Attachment #2: touchscreen-tsc2046.patch --] [-- Type: text/x-patch, Size: 19253 bytes --] Subject: ARM: OMAP: TSC2046 touchscreen support for 2430 This is a rework of the tsc2046 driver from TI's tree, based on the tsc2301 driver and using the new SPI framework. Signed-off-by: Kevin Hilman <khilman@mvista.com> --- arch/arm/mach-omap2/board-2430sdp.c | 32 + drivers/input/touchscreen/Kconfig | 6 drivers/input/touchscreen/Makefile | 1 drivers/input/touchscreen/tsc2046_ts.c | 555 +++++++++++++++++++++++++++++++++ include/linux/spi/tsc2046.h | 60 +++ 5 files changed, 654 insertions(+) Index: dev/arch/arm/mach-omap2/board-2430sdp.c =================================================================== --- dev.orig/arch/arm/mach-omap2/board-2430sdp.c +++ dev/arch/arm/mach-omap2/board-2430sdp.c @@ -21,6 +21,8 @@ #include <linux/delay.h> #include <linux/err.h> #include <linux/clk.h> +#include <linux/spi/spi.h> +#include <linux/spi/tsc2046.h> #include <asm/hardware.h> #include <asm/mach-types.h> @@ -33,6 +35,7 @@ #include <asm/arch/board.h> #include <asm/arch/common.h> #include <asm/arch/gpmc.h> +#include <asm/arch/mcspi.h> #include "prcm-regs.h" #include <asm/io.h> @@ -40,6 +43,9 @@ #define SDP2430_FLASH_CS 0 #define SDP2430_SMC91X_CS 5 +/* TSC2046 (touchscreen) */ +#define TS_GPIO 24 + static struct mtd_partition sdp2430_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ { @@ -119,6 +125,29 @@ static struct platform_device *sdp2430_d &sdp2430_flash_device, }; +static struct tsc2046_platform_data tsc2046_config = { + .dav_gpio = TS_GPIO, + .gpio_debounce = 0xa, +}; + +static struct omap2_mcspi_device_config tsc2046_mcspi_config = { + .turbo_mode = 0, + .single_channel = 0, /* 0: slave, 1: master */ +}; + +static struct spi_board_info sdp2430_spi_board_info[] __initdata = { + [0] = { + /* TSC2046 operates at a max freqency of 2MHz, so + * operate slightly below at 1.5MHz */ + .modalias = "tsc2046", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data= &tsc2046_mcspi_config, + .platform_data = &tsc2046_config, + }, +}; + static inline void __init sdp2430_init_smc91x(void) { int eth_cs; @@ -202,6 +231,9 @@ static void __init omap_2430sdp_init(voi omap_serial_init(); sdp2430_flash_init(); + + spi_register_board_info(sdp2430_spi_board_info, + ARRAY_SIZE(sdp2430_spi_board_info)); } static void __init omap_2430sdp_map_io(void) Index: dev/drivers/input/touchscreen/Kconfig =================================================================== --- dev.orig/drivers/input/touchscreen/Kconfig +++ dev/drivers/input/touchscreen/Kconfig @@ -165,4 +165,10 @@ config TOUCHSCREEN_TSC2301 help Say Y here for if you are using the touchscreen features of TSC2301. +config TOUCHSCREEN_TSC2046 + tristate "TSC2046 touchscreen support" + default MACH_OMAP2430SDP + help + Say Y here for if you are using the touchscreen features of TSC2046 + endif Index: dev/drivers/input/touchscreen/Makefile =================================================================== --- dev.orig/drivers/input/touchscreen/Makefile +++ dev/drivers/input/touchscreen/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb obj-$(CONFIG_TOUCHSCREEN_TSC2102) += tsc2102_ts.o obj-$(CONFIG_TOUCHSCREEN_OMAP) += omap/ obj-$(CONFIG_TOUCHSCREEN_TSC2301) += tsc2301_ts.o +obj-$(CONFIG_TOUCHSCREEN_TSC2046) += tsc2046_ts.o Index: dev/drivers/input/touchscreen/tsc2046_ts.c =================================================================== --- /dev/null +++ dev/drivers/input/touchscreen/tsc2046_ts.c @@ -0,0 +1,555 @@ +/* + * TSC2046 Touchscreen driver + * + * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> + * + * Communication details from original TI driver + * Copyright (C) 2004-2005 Texas Instruments, Inc. + * + * Structure based heavily on TSC2301 driver + * Copyright (C) 2005-2006 Nokia Corporation + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/spi/spi.h> + +#ifdef CONFIG_ARCH_OMAP +#include <asm/arch/gpio.h> +#endif + +#include <linux/spi/tsc2046.h> + +/* TSC2046 commands */ +#define START_BYTE 0x8000 +#define X_CMDWD 0xd300 +#define Y_CMDWD 0x9300 +#define Z1_CMDWD 0xb300 +#define Z2_CMDWD 0xc300 + +#define TSC2046_TS_SCAN_TIME 1 +#define MAX_12BIT ((1 << 12) - 1) + +struct tsc2046_ts { + struct input_dev *idev; + char phys[32]; + struct timer_list timer; + spinlock_t lock; + + struct spi_transfer read_xfer[3]; + struct spi_message read_msg; + struct spi_message enable_msg; + u16 data[5]; + + u16 x; + u16 y; + u16 p; + int sample_cnt; + + int ignore_last : 1; + u16 x_plate_ohm; + int max_pressure; + int touch_pressure; + int pressure_limit; + + u16 irq_enabled:1; + u16 pen_down:1; + u16 disabled:1; + u16 pending:1; + + s16 dav_gpio; + int irq; +}; + +static const u16 tsc2046_ts_cmd_data[] = { + START_BYTE, X_CMDWD, Y_CMDWD, Z1_CMDWD, Z2_CMDWD, +}; + +static int device_suspended(struct device *dev) +{ + struct tsc2046 *tsc = dev_get_drvdata(dev); + return dev->power.power_state.event != PM_EVENT_ON || tsc->ts->disabled; +} + +static void update_pen_state(struct tsc2046 *tsc, int x, int y, int pressure) +{ + struct tsc2046_ts *ts = tsc->ts; + int sync = 0; + + if (pressure) { + input_report_abs(ts->idev, ABS_X, x); + input_report_abs(ts->idev, ABS_Y, y); + input_report_abs(ts->idev, ABS_PRESSURE, pressure); + if (!ts->pen_down) + input_report_key(ts->idev, BTN_TOUCH, 1); + sync = 1; + } else if (ts->pen_down) { + input_report_abs(ts->idev, ABS_PRESSURE, 0); + input_report_key(ts->idev, BTN_TOUCH, 0); + sync = 1; + } + + if (sync) + input_sync(ts->idev); + + ts->pen_down = pressure ? 1 : 0; + +#ifdef VERBOSE + dev_dbg(&tsc->spi->dev, "x %4d y %4d p %4d\n", x, y, pressure); +#endif +} + +#define CONV_DATA(d1, d2) \ + (((d1 & 0x7f) << 5) | ((d2 >> 11) & 0x1f)) + +/* + * This procedure is called by the SPI framework after the coordinates + * have been read from TSC2046 + */ +static void tsc2046_ts_rx(void *arg) +{ + struct tsc2046 *tsc = arg; + struct tsc2046_ts *ts = tsc->ts; + unsigned int x, y, z1, z2, pressure; + + x = CONV_DATA(ts->data[2], ts->data[3]); + y = CONV_DATA(ts->data[1], ts->data[2]); + z1 = CONV_DATA(ts->data[3], ts->data[4]); + z2 = CONV_DATA(ts->data[4], 0); + + if (z1) { + pressure = ts->x_plate_ohm * x; + pressure /= 4096; + pressure *= z2 - z1; + pressure /= z1; + } else + pressure = 0; + + /* If pressure value is above a preset limit (pen is barely + * touching the screen) we can't trust the coordinate values. + */ + if (pressure < ts->pressure_limit && x < MAX_12BIT && y < MAX_12BIT) { + ts->pressure_limit = ts->max_pressure; + if (ts->ignore_last) { + if (ts->sample_cnt) + update_pen_state(tsc, ts->x, ts->y, ts->p); + ts->x = x; + ts->y = y; + ts->p = pressure; + } else + update_pen_state(tsc, x, y, pressure); + ts->sample_cnt++; + } + + mod_timer(&ts->timer, + jiffies + msecs_to_jiffies(TSC2046_TS_SCAN_TIME)); +} + +static int is_pen_down(struct tsc2046_ts *ts) +{ + return ts->pen_down; +} + +/* + * Timer is called every TSC2046_TS_SCAN_TIME when the pen is down + */ +static void tsc2046_ts_timer(unsigned long arg) +{ + struct tsc2046 *tsc = (void *) arg; + struct tsc2046_ts *ts = tsc->ts; + unsigned long flags; + int ndav; + int r; + + spin_lock_irqsave(&ts->lock, flags); + ndav = omap_get_gpio_datain(ts->dav_gpio); + if (ndav || device_suspended(&tsc->spi->dev)) { + /* Pen has been lifted */ + if (!device_suspended(&tsc->spi->dev) && + !ts->irq_enabled) { + ts->irq_enabled = 1; + enable_irq(ts->irq); + } + update_pen_state(tsc, 0, 0, 0); + ts->pending = 0; + spin_unlock_irqrestore(&ts->lock, flags); + + } else { + ts->pen_down = 1; + spin_unlock_irqrestore(&ts->lock, flags); + + r = spi_async(tsc->spi, &ts->read_msg); + if (r) + dev_err(&tsc->spi->dev, "ts: spi_async() failed"); + } +} + +/* + * This interrupt is called when pen is down and first coordinates are + * available. That is indicated by a falling edge on DEV line. IRQ is + * disabled here because while the pen is down the coordinates are + * read by a timer. + */ +static irqreturn_t tsc2046_ts_irq_handler(int irq, void *dev_id) +{ + struct tsc2046 *tsc = dev_id; + struct tsc2046_ts *ts = tsc->ts; + unsigned long flags; + + spin_lock_irqsave(&ts->lock, flags); + if (ts->irq_enabled) { + ts->irq_enabled = 0; + disable_irq(ts->irq); + ts->pending = 1; + ts->pressure_limit = ts->touch_pressure; + ts->sample_cnt = 0; + mod_timer(&ts->timer, + jiffies + msecs_to_jiffies(TSC2046_TS_SCAN_TIME)); + } + spin_unlock_irqrestore(&ts->lock, flags); + + return IRQ_HANDLED; +} + +/* Must be called with ts->lock held */ +static void tsc2046_ts_disable(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + + if (ts->disabled) + return; + + ts->disabled = 1; + if (!ts->pending) { + ts->irq_enabled = 0; + disable_irq(ts->irq); + } else { + while (ts->pending) { + spin_unlock_irq(&ts->lock); + msleep(1); + spin_lock_irq(&ts->lock); + } + } +} + +static void tsc2046_ts_enable(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + + if (!ts->disabled) + return; + + ts->disabled = 0; + ts->irq_enabled = 1; + enable_irq(ts->irq); +} + +#ifdef CONFIG_PM +int tsc2046_ts_suspend(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + + spin_lock_irq(&ts->lock); + tsc2046_ts_disable(tsc); + spin_unlock_irq(&ts->lock); + + return 0; +} + +void tsc2046_ts_resume(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + + spin_lock_irq(&ts->lock); + tsc2046_ts_enable(tsc); + spin_unlock_irq(&ts->lock); +} +#endif + +static void tsc2046_ts_setup_spi_xfer(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + struct spi_message *m = &ts->read_msg; + struct spi_transfer *x = &ts->read_xfer[1]; + + spi_message_init(m); + + /* read and write data in one transaction */ + x->tx_buf = &tsc2046_ts_cmd_data; + x->rx_buf = &ts->data; + x->len = 10; + spi_message_add_tail(x, m); + + /* send another START_BYTE to (re)enable pen interrupts */ + x++; + x->tx_buf = &tsc2046_ts_cmd_data[0]; + x->len = 2; + spi_message_add_tail(x, m); + + m->complete = tsc2046_ts_rx; + m->context = tsc; +} + +static ssize_t tsc2046_ts_pen_down_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tsc2046 *tsc = dev_get_drvdata(dev); + + return sprintf(buf, "%u\n", is_pen_down(tsc->ts)); +} + +static DEVICE_ATTR(pen_down, S_IRUGO, tsc2046_ts_pen_down_show, NULL); + +static ssize_t tsc2046_ts_disable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsc2046 *tsc = dev_get_drvdata(dev); + struct tsc2046_ts *ts = tsc->ts; + + return sprintf(buf, "%u\n", ts->disabled); +} + +static ssize_t tsc2046_ts_disable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct tsc2046 *tsc = dev_get_drvdata(dev); + struct tsc2046_ts *ts = tsc->ts; + char *endp; + int i; + + i = simple_strtoul(buf, &endp, 10); + spin_lock_irq(&ts->lock); + + if (i) + tsc2046_ts_disable(tsc); + else + tsc2046_ts_enable(tsc); + + spin_unlock_irq(&ts->lock); + + return count; +} + +static DEVICE_ATTR(disable_ts, 0664, tsc2046_ts_disable_show, + tsc2046_ts_disable_store); + +int __devinit tsc2046_ts_init(struct tsc2046 *tsc, + struct tsc2046_platform_data *pdata) +{ + struct tsc2046_ts *ts; + struct input_dev *idev; + int dav_gpio, r; + + if (pdata->dav_gpio < 0) { + dev_err(&tsc->spi->dev, "need DAV GPIO"); + return -EINVAL; + } + dav_gpio = pdata->dav_gpio; + + ts = kzalloc(sizeof(*ts), GFP_KERNEL); + if (ts == NULL) + return -ENOMEM; + tsc->ts = ts; + + ts->dav_gpio = dav_gpio; +#ifdef CONFIG_ARCH_OMAP + r = omap_request_gpio(dav_gpio); + if (r < 0) { + dev_err(&tsc->spi->dev, "unable to get DAV GPIO"); + goto err1; + } + omap_set_gpio_direction(dav_gpio, 1); + if (pdata->gpio_debounce) { + omap_set_gpio_debounce(tsc->gpio, 1); + omap_set_gpio_debounce_time(tsc->gpio, pdata->gpio_debounce); + } + + ts->irq = OMAP_GPIO_IRQ(dav_gpio); +#endif + init_timer(&ts->timer); + ts->timer.data = (unsigned long) tsc; + ts->timer.function = tsc2046_ts_timer; + + spin_lock_init(&ts->lock); + + ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280; + ts->max_pressure= pdata->ts_max_pressure ? : MAX_12BIT; + ts->touch_pressure = pdata->ts_touch_pressure ? : ts->max_pressure; + ts->ignore_last = pdata->ts_ignore_last; + + idev = input_allocate_device(); + if (idev == NULL) { + r = -ENOMEM; + goto err2; + } + idev->name = "TSC2046 touchscreen"; + snprintf(ts->phys, sizeof(ts->phys), + "%s/input-ts", tsc->spi->dev.bus_id); + idev->phys = ts->phys; + + idev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); + idev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); + ts->idev = idev; + + tsc2046_ts_setup_spi_xfer(tsc); + + /* These parameters should perhaps be configurable? */ + input_set_abs_params(idev, ABS_X, 0, 4096, 0, 0); + input_set_abs_params(idev, ABS_Y, 0, 4096, 0, 0); + input_set_abs_params(idev, ABS_PRESSURE, 0, 1024, 0, 0); + + ts->irq_enabled = 1; + r = request_irq(ts->irq, tsc2046_ts_irq_handler, + SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, + "tsc2046-ts", tsc); + if (r < 0) { + dev_err(&tsc->spi->dev, "unable to get DAV IRQ"); + goto err3; + } + set_irq_wake(ts->irq, 1); + + if (device_create_file(&tsc->spi->dev, &dev_attr_pen_down) < 0) + goto err4; + if (device_create_file(&tsc->spi->dev, &dev_attr_disable_ts) < 0) + goto err5; + + r = input_register_device(idev); + if (r < 0) { + dev_err(&tsc->spi->dev, "can't register touchscreen device\n"); + goto err6; + } + + /* kick off a transaction to enable pen interrupts */ + spi_async(tsc->spi, &ts->read_msg); + + return 0; +err6: + device_remove_file(&tsc->spi->dev, &dev_attr_disable_ts); +err5: + device_remove_file(&tsc->spi->dev, &dev_attr_pen_down); +err4: + free_irq(ts->irq, tsc); +err3: + input_free_device(idev); +err2: +#ifdef CONFIG_ARCH_OMAP + omap_free_gpio(dav_gpio); +#endif + err1: + kfree(ts); + return r; +} +EXPORT_SYMBOL(tsc2046_ts_init); + +void __devexit tsc2046_ts_exit(struct tsc2046 *tsc) +{ + struct tsc2046_ts *ts = tsc->ts; + unsigned long flags; + + spin_lock_irqsave(&ts->lock, flags); + tsc2046_ts_disable(tsc); + spin_unlock_irqrestore(&ts->lock, flags); + + device_remove_file(&tsc->spi->dev, &dev_attr_disable_ts); + device_remove_file(&tsc->spi->dev, &dev_attr_pen_down); + + free_irq(ts->irq, tsc); + input_unregister_device(ts->idev); + +#ifdef CONFIG_ARCH_OMAP + omap_free_gpio(ts->dav_gpio); +#endif + kfree(ts); +} +EXPORT_SYMBOL(tsc2046_ts_exit); + + +static int __devinit tsc2046_probe(struct spi_device *spi) +{ + struct tsc2046 *tsc; + struct tsc2046_platform_data *pdata = spi->dev.platform_data; + int r = -ENODEV; + + dev_dbg(&spi->dev, "%s\n", __FUNCTION__); + + if (!pdata) { + dev_dbg(&spi->dev, "no platform data?\n"); + return -ENODEV; + } + + tsc = kzalloc(sizeof(*tsc), GFP_KERNEL); + if (tsc == NULL) + return -ENOMEM; + + dev_set_drvdata(&spi->dev, tsc); + tsc->spi = spi; + spi->dev.power.power_state = PMSG_ON; + + spi->mode = SPI_MODE_1; + spi->bits_per_word = 16; + + /* The max speed might've been defined by the board-specific + * struct */ + if (!spi->max_speed_hz) + spi->max_speed_hz = TSC2046_HZ; + spi_setup(spi); + + r = tsc2046_ts_init(tsc, pdata); + if (r) + goto err1; + + return 0; + err1: + kfree(tsc); + return r; +} + +static int __devexit tsc2046_remove(struct spi_device *spi) +{ + struct tsc2046 *tsc = dev_get_drvdata(&spi->dev); + + dev_dbg(&tsc->spi->dev, "%s\n", __FUNCTION__); + + tsc2046_ts_exit(tsc); + kfree(tsc); + + return 0; +} + +static struct spi_driver tsc2046_driver = { + .driver = { + .name = "tsc2046", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = tsc2046_probe, + .remove = __devexit_p(tsc2046_remove), +}; + +static int __init tsc2046_init(void) +{ + printk("TSC2046 driver initializing\n"); + + return spi_register_driver(&tsc2046_driver); +} +module_init(tsc2046_init); + +static void __exit tsc2046_exit(void) +{ + spi_unregister_driver(&tsc2046_driver); +} +module_exit(tsc2046_exit); + +MODULE_AUTHOR("Kevin Hilman <khilman@mvista.com>"); +MODULE_LICENSE("GPL"); Index: dev/include/linux/spi/tsc2046.h =================================================================== --- /dev/null +++ dev/include/linux/spi/tsc2046.h @@ -0,0 +1,60 @@ +#ifndef _LINUX_SPI_TSC2046_H +#define _LINUX_SPI_TSC2046_H + +#include <linux/types.h> +#include <linux/timer.h> + +struct tsc2046_platform_data { + s16 dav_gpio; + s16 gpio_debounce; + u16 ts_x_plate_ohm; + u32 ts_max_pressure; /* Samples with bigger pressure value will + be ignored, since the corresponding X, Y + values are unreliable */ + u32 ts_touch_pressure;/* Pressure limit until we report a + touch event. After that we switch + to ts_max_pressure. */ + unsigned ts_ignore_last : 1; + +}; + +struct tsc2046_ts; + +struct tsc2046 { + struct spi_device *spi; + int gpio; + + struct tsc2046_ts *ts; +}; + +/* The TSC2046 operates at a maximum speed of 2MHz */ +#define TSC2046_HZ 2000000 + +#define TSC2046_DECL_MOD(module) \ +extern int tsc2046_##module##_init(struct tsc2046 *tsc, \ + struct tsc2046_platform_data *pdata); \ +extern void tsc2046_##module##_exit(struct tsc2046 *tsc); \ +extern int tsc2046_##module##_suspend(struct tsc2046 *tsc); \ +extern void tsc2046_##module##_resume(struct tsc2046 *tsc); + +#define TSC2046_DECL_EMPTY_MOD(module) \ +static inline int tsc2046_##module##_init(struct tsc2046 *tsc, \ + struct tsc2046_platform_data *pdata) \ +{ \ + return 0; \ +} \ +static inline void tsc2046_##module##_exit(struct tsc2046 *tsc) {} \ +static inline int tsc2046_##module##_suspend(struct tsc2046 *tsc) \ +{ \ + return 0; \ +} \ +static inline void tsc2046_##module##_resume(struct tsc2046 *tsc) {} + +#if defined(CONFIG_TOUCHSCREEN_TSC2046) || \ + defined(CONFIG_TOUCHSCREEN_TSC2046_MODULE) +TSC2046_DECL_MOD(ts) +#else +TSC2046_DECL_EMPTY_MOD(ts) +#endif + +#endif [-- Attachment #3: Type: text/plain, Size: 0 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 2007-05-04 21:53 ` Kevin Hilman @ 2007-05-04 23:36 ` Tony Lindgren 0 siblings, 0 replies; 11+ messages in thread From: Tony Lindgren @ 2007-05-04 23:36 UTC (permalink / raw) To: Kevin Hilman; +Cc: linux-omap-open-source * Kevin Hilman <khilman@mvista.com> [070504 14:54]: > Tony, > > Here's a minor update so it applies on the (already pushed) onenand > patch. Thanks, I'll apply these too as they make 2430-sdp more usable. I've split the board update into a separate patch. Tony ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 2007-05-04 21:40 ` [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 Kevin Hilman 2007-05-04 21:53 ` Kevin Hilman @ 2007-05-05 8:28 ` Komal Shah 2007-05-07 9:02 ` Trilok Soni 1 sibling, 1 reply; 11+ messages in thread From: Komal Shah @ 2007-05-05 8:28 UTC (permalink / raw) To: Kevin Hilman; +Cc: linux-omap-open-source Kevin, On 5/5/07, Kevin Hilman <khilman@mvista.com> wrote: > This is a rework of the tsc2046 driver from TI's tree, based > on the tsc2301 driver and using the new SPI framework. > > Signed-off-by: Kevin Hilman <khilman@mvista.com> Very small changes required in order to confirm CodingStyle. ... > + > +static struct omap2_mcspi_device_config tsc2046_mcspi_config = { > + .turbo_mode = 0, > + .single_channel = 0, /* 0: slave, 1: master */ > +}; > + > +static struct spi_board_info sdp2430_spi_board_info[] __initdata = { > + [0] = { > + /* TSC2046 operates at a max freqency of 2MHz, so > + * operate slightly below at 1.5MHz */ multi-line comments block should be like this: /* * TSC2046 operates at a max freqency of 2MHz, so * operate slightly below at 1.5MHz */ > + .modalias = "tsc2046", > + .bus_num = 1, > + .chip_select = 0, > + .max_speed_hz = 1500000, > + .controller_data= &tsc2046_mcspi_config, Space before "=". > + .platform_data = &tsc2046_config, > + }, > +}; > + .... > +/* > + * This procedure is called by the SPI framework after the coordinates > + * have been read from TSC2046 > + */ > +static void tsc2046_ts_rx(void *arg) > +{ > + struct tsc2046 *tsc = arg; > + struct tsc2046_ts *ts = tsc->ts; > + unsigned int x, y, z1, z2, pressure; > + > + x = CONV_DATA(ts->data[2], ts->data[3]); > + y = CONV_DATA(ts->data[1], ts->data[2]); > + z1 = CONV_DATA(ts->data[3], ts->data[4]); > + z2 = CONV_DATA(ts->data[4], 0); > + > + if (z1) { > + pressure = ts->x_plate_ohm * x; > + pressure /= 4096; > + pressure *= z2 - z1; > + pressure /= z1; > + } else > + pressure = 0; > + > + /* If pressure value is above a preset limit (pen is barely > + * touching the screen) we can't trust the coordinate values. > + */ same here for multi-line comment block style. > + if (pressure < ts->pressure_limit && x < MAX_12BIT && y < MAX_12BIT) { > + ts->pressure_limit = ts->max_pressure; > + if (ts->ignore_last) { > + if (ts->sample_cnt) > + update_pen_state(tsc, ts->x, ts->y, ts->p); > + ts->x = x; > + ts->y = y; > + ts->p = pressure; > + } else > + update_pen_state(tsc, x, y, pressure); > + ts->sample_cnt++; > + } > + > + mod_timer(&ts->timer, > + jiffies + msecs_to_jiffies(TSC2046_TS_SCAN_TIME)); > +} > + .... > + > +int __devinit tsc2046_ts_init(struct tsc2046 *tsc, > + struct tsc2046_platform_data *pdata) > +{ > + struct tsc2046_ts *ts; > + struct input_dev *idev; > + int dav_gpio, r; > + > + if (pdata->dav_gpio < 0) { > + dev_err(&tsc->spi->dev, "need DAV GPIO"); > + return -EINVAL; > + } > + dav_gpio = pdata->dav_gpio; > + > + ts = kzalloc(sizeof(*ts), GFP_KERNEL); > + if (ts == NULL) > + return -ENOMEM; > + tsc->ts = ts; > + > + ts->dav_gpio = dav_gpio; > +#ifdef CONFIG_ARCH_OMAP > + r = omap_request_gpio(dav_gpio); > + if (r < 0) { > + dev_err(&tsc->spi->dev, "unable to get DAV GPIO"); > + goto err1; > + } > + omap_set_gpio_direction(dav_gpio, 1); > + if (pdata->gpio_debounce) { > + omap_set_gpio_debounce(tsc->gpio, 1); > + omap_set_gpio_debounce_time(tsc->gpio, pdata->gpio_debounce); > + } > + > + ts->irq = OMAP_GPIO_IRQ(dav_gpio); > +#endif > + init_timer(&ts->timer); > + ts->timer.data = (unsigned long) tsc; > + ts->timer.function = tsc2046_ts_timer; setup_timer ? > + > + spin_lock_init(&ts->lock); > + > + ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280; > + ts->max_pressure= pdata->ts_max_pressure ? : MAX_12BIT; space before "=". > + ts->touch_pressure = pdata->ts_touch_pressure ? : ts->max_pressure; > + ts->ignore_last = pdata->ts_ignore_last; > + > + idev = input_allocate_device(); > + if (idev == NULL) { > + r = -ENOMEM; > + goto err2; > + } > + idev->name = "TSC2046 touchscreen"; > + snprintf(ts->phys, sizeof(ts->phys), > + "%s/input-ts", tsc->spi->dev.bus_id); > + idev->phys = ts->phys; > + > + idev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); > + idev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); > + ts->idev = idev; > + > + tsc2046_ts_setup_spi_xfer(tsc); > + > + /* These parameters should perhaps be configurable? */ > + input_set_abs_params(idev, ABS_X, 0, 4096, 0, 0); > + input_set_abs_params(idev, ABS_Y, 0, 4096, 0, 0); > + input_set_abs_params(idev, ABS_PRESSURE, 0, 1024, 0, 0); > + > + ts->irq_enabled = 1; > + r = request_irq(ts->irq, tsc2046_ts_irq_handler, > + SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, > + "tsc2046-ts", tsc); deprecated SA_* flags. > + if (r < 0) { > + dev_err(&tsc->spi->dev, "unable to get DAV IRQ"); > + goto err3; > + } > + set_irq_wake(ts->irq, 1); > + > + if (device_create_file(&tsc->spi->dev, &dev_attr_pen_down) < 0) > + goto err4; > + if (device_create_file(&tsc->spi->dev, &dev_attr_disable_ts) < 0) > + goto err5; > + > + r = input_register_device(idev); > + if (r < 0) { > + dev_err(&tsc->spi->dev, "can't register touchscreen device\n"); > + goto err6; > + } > + > + /* kick off a transaction to enable pen interrupts */ > + spi_async(tsc->spi, &ts->read_msg); > + > + return 0; > +err6: > + device_remove_file(&tsc->spi->dev, &dev_attr_disable_ts); > +err5: > + device_remove_file(&tsc->spi->dev, &dev_attr_pen_down); > +err4: > + free_irq(ts->irq, tsc); > +err3: > + input_free_device(idev); > +err2: > +#ifdef CONFIG_ARCH_OMAP > + omap_free_gpio(dav_gpio); > +#endif > + err1: > + kfree(ts); > + return r; > +} > +EXPORT_SYMBOL(tsc2046_ts_init); > + > +void __devexit tsc2046_ts_exit(struct tsc2046 *tsc) > +{ > + struct tsc2046_ts *ts = tsc->ts; > + unsigned long flags; > + > + spin_lock_irqsave(&ts->lock, flags); > + tsc2046_ts_disable(tsc); > + spin_unlock_irqrestore(&ts->lock, flags); > + > + device_remove_file(&tsc->spi->dev, &dev_attr_disable_ts); > + device_remove_file(&tsc->spi->dev, &dev_attr_pen_down); > + > + free_irq(ts->irq, tsc); > + input_unregister_device(ts->idev); > + > +#ifdef CONFIG_ARCH_OMAP > + omap_free_gpio(ts->dav_gpio); > +#endif > + kfree(ts); > +} > +EXPORT_SYMBOL(tsc2046_ts_exit); > + > + > +static int __devinit tsc2046_probe(struct spi_device *spi) > +{ > + struct tsc2046 *tsc; > + struct tsc2046_platform_data *pdata = spi->dev.platform_data; > + int r = -ENODEV; > + > + dev_dbg(&spi->dev, "%s\n", __FUNCTION__); > + > + if (!pdata) { > + dev_dbg(&spi->dev, "no platform data?\n"); > + return -ENODEV; > + } > + > + tsc = kzalloc(sizeof(*tsc), GFP_KERNEL); > + if (tsc == NULL) > + return -ENOMEM; > + > + dev_set_drvdata(&spi->dev, tsc); > + tsc->spi = spi; > + spi->dev.power.power_state = PMSG_ON; > + > + spi->mode = SPI_MODE_1; > + spi->bits_per_word = 16; > + > + /* The max speed might've been defined by the board-specific > + * struct */ same comment for multi-line comments style as pointed earlier. > + if (!spi->max_speed_hz) > + spi->max_speed_hz = TSC2046_HZ; > + spi_setup(spi); > + > + r = tsc2046_ts_init(tsc, pdata); > + if (r) > + goto err1; > + > + return 0; > + err1: > + kfree(tsc); > + return r; > +} > + > +static int __devexit tsc2046_remove(struct spi_device *spi) > +{ > + struct tsc2046 *tsc = dev_get_drvdata(&spi->dev); > + > + dev_dbg(&tsc->spi->dev, "%s\n", __FUNCTION__); > + > + tsc2046_ts_exit(tsc); This doesn't look to me a tab. > + kfree(tsc); > + > + return 0; > +} -- ---Komal Shah http://komalshah.blogspot.com ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 2007-05-05 8:28 ` Komal Shah @ 2007-05-07 9:02 ` Trilok Soni 2007-05-07 10:23 ` Trilok Soni 0 siblings, 1 reply; 11+ messages in thread From: Trilok Soni @ 2007-05-07 9:02 UTC (permalink / raw) To: Tony Lindgren; +Cc: linux-omap-open-source [-- Attachment #1: Type: text/plain, Size: 500 bytes --] Tony, On 5/5/07, Komal Shah <komal.shah802003@gmail.com> wrote: > Kevin, > > On 5/5/07, Kevin Hilman <khilman@mvista.com> wrote: > > This is a rework of the tsc2046 driver from TI's tree, based > > on the tsc2301 driver and using the new SPI framework. > > > > Signed-off-by: Kevin Hilman <khilman@mvista.com> > > Very small changes required in order to confirm CodingStyle. > I have attached two patches implementing changes as suggested by Komal. They are compile tested only. -- --Trilok Soni [-- Attachment #2: 0001-ARM-OMAP-TSC2046-CodingStyle-cleanup.patch --] [-- Type: text/x-patch, Size: 1328 bytes --] From f34fac46abd0e3c6f9f7760a83e91b64ab602d21 Mon Sep 17 00:00:00 2001 From: Trilok Soni <soni.trilok@gmail.com> Date: Mon, 7 May 2007 17:50:49 +0530 Subject: [PATCH] ARM: OMAP: TSC2046 CodingStyle cleanup. Signed-off-by: Trilok Soni <soni.trilok@gmail.com> --- arch/arm/mach-omap2/board-2430sdp.c | 18 ++++++++++-------- 1 files changed, 10 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 5ee970b..ebd2630 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -137,14 +137,16 @@ static struct omap2_mcspi_device_config tsc2046_mcspi_config = { static struct spi_board_info sdp2430_spi_board_info[] __initdata = { [0] = { - /* TSC2046 operates at a max freqency of 2MHz, so - * operate slightly below at 1.5MHz */ - .modalias = "tsc2046", - .bus_num = 1, - .chip_select = 0, - .max_speed_hz = 1500000, - .controller_data= &tsc2046_mcspi_config, - .platform_data = &tsc2046_config, + /* + * TSC2046 operates at a max freqency of 2MHz, so + * operate slightly below at 1.5MHz + */ + .modalias = "tsc2046", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &tsc2046_mcspi_config, + .platform_data = &tsc2046_config, }, }; -- 1.5.0 [-- Attachment #3: 0002-SPI-TSC2046-driver-CodingStyle-cleanup.patch --] [-- Type: text/x-patch, Size: 2781 bytes --] From 29d67e3821b3f5e27de5d8247a6fc39f5bad06db Mon Sep 17 00:00:00 2001 From: Trilok Soni <soni.trilok@gmail.com> Date: Mon, 7 May 2007 18:13:43 +0530 Subject: [PATCH] SPI: TSC2046 driver CodingStyle cleanup. Signed-off-by: Trilok Soni <soni.trilok@gmail.com> --- drivers/input/touchscreen/tsc2046_ts.c | 23 ++++++++++++----------- 1 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/input/touchscreen/tsc2046_ts.c b/drivers/input/touchscreen/tsc2046_ts.c index a56ae5a..a509986 100644 --- a/drivers/input/touchscreen/tsc2046_ts.c +++ b/drivers/input/touchscreen/tsc2046_ts.c @@ -134,7 +134,8 @@ static void tsc2046_ts_rx(void *arg) } else pressure = 0; - /* If pressure value is above a preset limit (pen is barely + /* + * If pressure value is above a preset limit (pen is barely * touching the screen) we can't trust the coordinate values. */ if (pressure < ts->pressure_limit && x < MAX_12BIT && y < MAX_12BIT) { @@ -377,14 +378,12 @@ int __devinit tsc2046_ts_init(struct tsc2046 *tsc, ts->irq = OMAP_GPIO_IRQ(dav_gpio); #endif - init_timer(&ts->timer); - ts->timer.data = (unsigned long) tsc; - ts->timer.function = tsc2046_ts_timer; + setup_timer(&ts->timer, tsc2046_ts_timer, (unsigned long)tsc); spin_lock_init(&ts->lock); ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280; - ts->max_pressure= pdata->ts_max_pressure ? : MAX_12BIT; + ts->max_pressure = pdata->ts_max_pressure ? : MAX_12BIT; ts->touch_pressure = pdata->ts_touch_pressure ? : ts->max_pressure; ts->ignore_last = pdata->ts_ignore_last; @@ -411,7 +410,7 @@ int __devinit tsc2046_ts_init(struct tsc2046 *tsc, ts->irq_enabled = 1; r = request_irq(ts->irq, tsc2046_ts_irq_handler, - SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING, + IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING, "tsc2046-ts", tsc); if (r < 0) { dev_err(&tsc->spi->dev, "unable to get DAV IRQ"); @@ -446,7 +445,7 @@ err2: #ifdef CONFIG_ARCH_OMAP omap_free_gpio(dav_gpio); #endif - err1: +err1: kfree(ts); return r; } @@ -499,8 +498,10 @@ static int __devinit tsc2046_probe(struct spi_device *spi) spi->mode = SPI_MODE_1; spi->bits_per_word = 16; - /* The max speed might've been defined by the board-specific - * struct */ + /* + * The max speed might've been defined by the board-specific + * struct + */ if (!spi->max_speed_hz) spi->max_speed_hz = TSC2046_HZ; spi_setup(spi); @@ -510,7 +511,7 @@ static int __devinit tsc2046_probe(struct spi_device *spi) goto err1; return 0; - err1: +err1: kfree(tsc); return r; } @@ -521,7 +522,7 @@ static int __devexit tsc2046_remove(struct spi_device *spi) dev_dbg(&tsc->spi->dev, "%s\n", __FUNCTION__); - tsc2046_ts_exit(tsc); + tsc2046_ts_exit(tsc); kfree(tsc); return 0; -- 1.5.0 [-- Attachment #4: Type: text/plain, Size: 0 bytes --] ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 2007-05-07 9:02 ` Trilok Soni @ 2007-05-07 10:23 ` Trilok Soni 2007-05-07 17:02 ` Kevin Hilman 0 siblings, 1 reply; 11+ messages in thread From: Trilok Soni @ 2007-05-07 10:23 UTC (permalink / raw) To: Tony Lindgren; +Cc: linux-omap-open-source [-- Attachment #1: Type: text/plain, Size: 869 bytes --] On 5/7/07, Trilok Soni <soni.trilok@gmail.com> wrote: > Tony, > > On 5/5/07, Komal Shah <komal.shah802003@gmail.com> wrote: > > Kevin, > > > > On 5/5/07, Kevin Hilman <khilman@mvista.com> wrote: > > > This is a rework of the tsc2046 driver from TI's tree, based > > > on the tsc2301 driver and using the new SPI framework. > > > > > > Signed-off-by: Kevin Hilman <khilman@mvista.com> > > > > Very small changes required in order to confirm CodingStyle. > > > > I have attached two patches implementing changes as suggested by > Komal. They are compile tested only. > Attached 3rd patch fixes suspend/resume functions, as TSC2046 is TS only device not like TSC2301, so we don't need to make non-static functions like TSC2301_TS which gets called from it's core driver on suspend/resume. This patch is also compile-tested only. Kevin please test it. -- --Trilok Soni [-- Attachment #2: 0003-SPI-TSC2046-Fix-supend-resume-functions.patch --] [-- Type: text/x-patch, Size: 1739 bytes --] From 77d4ae193bdd275bffacd6e446768764c7902dd8 Mon Sep 17 00:00:00 2001 From: Trilok Soni <soni.trilok@gmail.com> Date: Mon, 7 May 2007 21:21:15 +0530 Subject: [PATCH] SPI: TSC2046 Fix supend/resume functions - Add suspend, resume function to tsc2046 device driver. - Change tsc2046_suspend/resume function accoradingly, as tsc2046 is TS only device not like TSC2301. Signed-off-by: Trilok Soni <soni.trilok@gmail.com> --- drivers/input/touchscreen/tsc2046_ts.c | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/tsc2046_ts.c b/drivers/input/touchscreen/tsc2046_ts.c index a509986..4689fb6 100644 --- a/drivers/input/touchscreen/tsc2046_ts.c +++ b/drivers/input/touchscreen/tsc2046_ts.c @@ -255,8 +255,9 @@ static void tsc2046_ts_enable(struct tsc2046 *tsc) } #ifdef CONFIG_PM -int tsc2046_ts_suspend(struct tsc2046 *tsc) +static int tsc2046_suspend(struct spi_device *spi, pm_message_t mesg) { + struct tsc2046 *tsc = dev_get_drvdata(&spi->dev); struct tsc2046_ts *ts = tsc->ts; spin_lock_irq(&ts->lock); @@ -266,13 +267,16 @@ int tsc2046_ts_suspend(struct tsc2046 *tsc) return 0; } -void tsc2046_ts_resume(struct tsc2046 *tsc) +static int tsc2046_resume(struct spi_device *spi) { + struct tsc2046 *tsc = dev_get_drvdata(&spi->dev); struct tsc2046_ts *ts = tsc->ts; spin_lock_irq(&ts->lock); tsc2046_ts_enable(tsc); spin_unlock_irq(&ts->lock); + + return 0; } #endif @@ -536,6 +540,10 @@ static struct spi_driver tsc2046_driver = { }, .probe = tsc2046_probe, .remove = __devexit_p(tsc2046_remove), +#ifdef CONFIG_PM + .suspend = tsc2046_suspend, + .resume = tsc2046_resume, +#endif }; static int __init tsc2046_init(void) -- 1.5.0 [-- Attachment #3: Type: text/plain, Size: 0 bytes --] ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 2007-05-07 10:23 ` Trilok Soni @ 2007-05-07 17:02 ` Kevin Hilman [not found] ` <20070507172440.GA31968@atomide.com> 0 siblings, 1 reply; 11+ messages in thread From: Kevin Hilman @ 2007-05-07 17:02 UTC (permalink / raw) To: Trilok Soni; +Cc: linux-omap-open-source On Mon, 2007-05-07 at 15:53 +0530, Trilok Soni wrote: > On 5/7/07, Trilok Soni <soni.trilok@gmail.com> wrote: > > Tony, > > > > On 5/5/07, Komal Shah <komal.shah802003@gmail.com> wrote: > > > Kevin, > > > > > > On 5/5/07, Kevin Hilman <khilman@mvista.com> wrote: > > > > This is a rework of the tsc2046 driver from TI's tree, based > > > > on the tsc2301 driver and using the new SPI framework. > > > > > > > > Signed-off-by: Kevin Hilman <khilman@mvista.com> > > > > > > Very small changes required in order to confirm CodingStyle. > > > > > > > I have attached two patches implementing changes as suggested by > > Komal. They are compile tested only. > > > > Attached 3rd patch fixes suspend/resume functions, as TSC2046 is TS > only device not like TSC2301, so we don't need to make non-static > functions like TSC2301_TS which gets called from it's core driver on > suspend/resume. > > This patch is also compile-tested only. Kevin please test it. Trilok, Thanks for the cleanups and PM support. I have tested all 3 patches and the driver is still working well. Thanks, Kevin ^ permalink raw reply [flat|nested] 11+ messages in thread
[parent not found: <20070507172440.GA31968@atomide.com>]
* Re: [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 [not found] ` <20070507172440.GA31968@atomide.com> @ 2007-05-08 5:24 ` Trilok Soni 2007-05-08 16:54 ` tony 0 siblings, 1 reply; 11+ messages in thread From: Trilok Soni @ 2007-05-08 5:24 UTC (permalink / raw) To: Tony Lindgren; +Cc: linux-omap-open-source On 5/7/07, Tony Lindgren <tony@atomide.com> wrote: > * Kevin Hilman <khilman@mvista.com> [070507 10:03]: > > On Mon, 2007-05-07 at 15:53 +0530, Trilok Soni wrote: > > > On 5/7/07, Trilok Soni <soni.trilok@gmail.com> wrote: > > > > Tony, > > > > > > > > On 5/5/07, Komal Shah <komal.shah802003@gmail.com> wrote: > > > > > Kevin, > > > > > > > > > > On 5/5/07, Kevin Hilman <khilman@mvista.com> wrote: > > > > > > This is a rework of the tsc2046 driver from TI's tree, based > > > > > > on the tsc2301 driver and using the new SPI framework. > > > > > > > > > > > > Signed-off-by: Kevin Hilman <khilman@mvista.com> > > > > > > > > > > Very small changes required in order to confirm CodingStyle. > > > > > > > > > > > > > I have attached two patches implementing changes as suggested by > > > > Komal. They are compile tested only. > > > > > > > > > > Attached 3rd patch fixes suspend/resume functions, as TSC2046 is TS > > > only device not like TSC2301, so we don't need to make non-static > > > functions like TSC2301_TS which gets called from it's core driver on > > > suspend/resume. > > > > > > This patch is also compile-tested only. Kevin please test it. > > > > Trilok, > > > > Thanks for the cleanups and PM support. I have tested all 3 patches and > > the driver is still working well. > > Cool, will push today. > Have you applied first two cleanup patches? I can only see PM patch (3rd patch) on master branch. -- --Trilok Soni ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 2007-05-08 5:24 ` Trilok Soni @ 2007-05-08 16:54 ` tony 0 siblings, 0 replies; 11+ messages in thread From: tony @ 2007-05-08 16:54 UTC (permalink / raw) To: Trilok Soni; +Cc: linux-omap-open-source * Trilok Soni <soni.trilok@gmail.com> [070507 22:25]: > On 5/7/07, Tony Lindgren <tony@atomide.com> wrote: > >* Kevin Hilman <khilman@mvista.com> [070507 10:03]: > >> On Mon, 2007-05-07 at 15:53 +0530, Trilok Soni wrote: > >> > On 5/7/07, Trilok Soni <soni.trilok@gmail.com> wrote: > >> > > Tony, > >> > > > >> > > On 5/5/07, Komal Shah <komal.shah802003@gmail.com> wrote: > >> > > > Kevin, > >> > > > > >> > > > On 5/5/07, Kevin Hilman <khilman@mvista.com> wrote: > >> > > > > This is a rework of the tsc2046 driver from TI's tree, based > >> > > > > on the tsc2301 driver and using the new SPI framework. > >> > > > > > >> > > > > Signed-off-by: Kevin Hilman <khilman@mvista.com> > >> > > > > >> > > > Very small changes required in order to confirm CodingStyle. > >> > > > > >> > > > >> > > I have attached two patches implementing changes as suggested by > >> > > Komal. They are compile tested only. > >> > > > >> > > >> > Attached 3rd patch fixes suspend/resume functions, as TSC2046 is TS > >> > only device not like TSC2301, so we don't need to make non-static > >> > functions like TSC2301_TS which gets called from it's core driver on > >> > suspend/resume. > >> > > >> > This patch is also compile-tested only. Kevin please test it. > >> > >> Trilok, > >> > >> Thanks for the cleanups and PM support. I have tested all 3 patches and > >> the driver is still working well. > > > >Cool, will push today. > > > > Have you applied first two cleanup patches? I can only see PM patch > (3rd patch) on master branch. Oops, sorry. I've applied and pushed, can you please check? Regards, Tony ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2007-05-08 16:54 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-04 21:40 [PATCH 0/2] TSC2046 toucscreen support Kevin Hilman
2007-05-04 21:40 ` [PATCH 1/2] ARM: OMAP: add 24xx GPIO debounce support Kevin Hilman
2007-05-04 21:40 ` [PATCH 2/2] ARM: OMAP: TSC2046 touchscreen support for 2430 Kevin Hilman
2007-05-04 21:53 ` Kevin Hilman
2007-05-04 23:36 ` Tony Lindgren
2007-05-05 8:28 ` Komal Shah
2007-05-07 9:02 ` Trilok Soni
2007-05-07 10:23 ` Trilok Soni
2007-05-07 17:02 ` Kevin Hilman
[not found] ` <20070507172440.GA31968@atomide.com>
2007-05-08 5:24 ` Trilok Soni
2007-05-08 16:54 ` tony
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox