public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [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

* 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