From: "Hiremath, Vaibhav" <hvaibhav@ti.com>
To: "Hiremath, Vaibhav" <hvaibhav@ti.com>,
"linux-input@vger.kernel.org" <linux-input@vger.kernel.org>
Cc: "linux-omap@vger.kernel.org" <linux-omap@vger.kernel.org>,
Dmitry Torokhov <dmitry.torokhov@gmail.com>,
"dtor@mail.ru" <dtor@mail.ru>
Subject: RE: [PATCH 2/3] Input:TouchScreen: Introduce TSC2004 driver support
Date: Mon, 11 Jan 2010 11:54:05 +0530 [thread overview]
Message-ID: <19F8576C6E063C45BE387C64729E7394044A3982AE@dbde02.ent.ti.com> (raw)
In-Reply-To: <1258642000-2271-1-git-send-email-hvaibhav@ti.com>
> -----Original Message-----
> From: Hiremath, Vaibhav
> Sent: Thursday, November 19, 2009 8:17 PM
> To: linux-input@vger.kernel.org
> Cc: linux-omap@vger.kernel.org; Hiremath, Vaibhav
> Subject: [PATCH 2/3] Input:TouchScreen: Introduce TSC2004 driver
> support
>
> From: Vaibhav Hiremath <hvaibhav@ti.com>
>
> Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
> drivers/input/touchscreen/Kconfig | 11 +
> drivers/input/touchscreen/Makefile | 1 +
> drivers/input/touchscreen/tsc2004.c | 525
> +++++++++++++++++++++++++++++++++++
> include/linux/i2c/tsc2004.h | 17 ++
> 4 files changed, 554 insertions(+), 0 deletions(-)
> create mode 100644 drivers/input/touchscreen/tsc2004.c
> create mode 100644 include/linux/i2c/tsc2004.h
>
[Hiremath, Vaibhav] Dmitry,
Any update on this? This driver support is important for AM3517EVM, can we merge this patch?
Thanks,
Vaibhav
> diff --git a/drivers/input/touchscreen/Kconfig
> b/drivers/input/touchscreen/Kconfig
> index 8cc453c..08aba0b 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -512,6 +512,17 @@ config TOUCHSCREEN_TSC2007
> To compile this driver as a module, choose M here: the
> module will be called tsc2007.
>
> +config TOUCHSCREEN_TSC2004
> + tristate "TSC2004 based touchscreens"
> + depends on I2C
> + help
> + Say Y here if you have a TSC2004 based touchscreen.
> +
> + If unsure, say N.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called tsc2004.
> +
> config TOUCHSCREEN_W90X900
> tristate "W90P910 touchscreen driver"
> depends on HAVE_CLK
> diff --git a/drivers/input/touchscreen/Makefile
> b/drivers/input/touchscreen/Makefile
> index 15fa62c..4ac5b81 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -30,6 +30,7 @@ obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) +=
> touchit213.o
> obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
> obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
> obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o
> +obj-$(CONFIG_TOUCHSCREEN_TSC2004) += tsc2004.o
> obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
> obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o
> obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
> diff --git a/drivers/input/touchscreen/tsc2004.c
> b/drivers/input/touchscreen/tsc2004.c
> new file mode 100644
> index 0000000..0bba2e6
> --- /dev/null
> +++ b/drivers/input/touchscreen/tsc2004.c
> @@ -0,0 +1,525 @@
> +/*
> + * drivers/input/touchscreen/tsc2004.c
> + *
> + * Copyright (C) 2009 Texas Instruments Inc
> + * Author: Vaibhav Hiremath <hvaibhav@ti.com>
> + *
> + * Using code from:
> + * - tsc2007.c
> + *
> + * This package is free software; you can redistribute it and/or
> modify
> + * it under the terms of the GNU General Public License version 2
> as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public
> License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/i2c.h>
> +#include <linux/i2c/tsc2004.h>
> +
> +
> +#define TS_POLL_DELAY 1 /* ms delay between samples */
> +#define TS_POLL_PERIOD 1 /* ms delay between samples */
> +
> +/* Control byte 0 */
> +#define TSC2004_CMD0(addr, pnd, rw) ((addr<<3)|(pnd<<1)|rw)
> +/* Control byte 1 */
> +#define TSC2004_CMD1(cmd, mode, rst)
> ((1<<7)|(cmd<<4)|(mode<<2)|(rst<<1))
> +
> +/* Command Bits */
> +#define READ_REG 1
> +#define WRITE_REG 0
> +#define SWRST_TRUE 1
> +#define SWRST_FALSE 0
> +#define PND0_TRUE 1
> +#define PND0_FALSE 0
> +
> +/* Converter function mapping */
> +enum convertor_function {
> + MEAS_X_Y_Z1_Z2, /* Measure X,Y,z1 and Z2: 0x0 */
> + MEAS_X_Y, /* Measure X and Y only: 0x1 */
> + MEAS_X, /* Measure X only: 0x2 */
> + MEAS_Y, /* Measure Y only: 0x3 */
> + MEAS_Z1_Z2, /* Measure Z1 and Z2 only: 0x4 */
> + MEAS_AUX, /* Measure Auxillary input: 0x5 */
> + MEAS_TEMP1, /* Measure Temparature1: 0x6 */
> + MEAS_TEMP2, /* Measure Temparature2: 0x7 */
> + MEAS_AUX_CONT, /* Continuously measure Auxillary input: 0x8
> */
> + X_DRV_TEST, /* X-Axis drivers tested 0x9 */
> + Y_DRV_TEST, /* Y-Axis drivers tested 0xA */
> + /*Command Reserved*/
> + SHORT_CKT_TST = 0xC, /* Short circuit test: 0xC */
> + XP_XN_DRV_STAT, /* X+,Y- drivers status: 0xD */
> + YP_YN_DRV_STAT, /* X+,Y- drivers status: 0xE */
> + YP_XN_DRV_STAT /* Y+,X- drivers status: 0xF */
> +};
> +
> +/* Register address mapping */
> +enum register_address {
> + X_REG, /* X register: 0x0 */
> + Y_REG, /* Y register: 0x1 */
> + Z1_REG, /* Z1 register: 0x2 */
> + Z2_REG, /* Z2 register: 0x3 */
> + AUX_REG, /* AUX register: 0x4 */
> + TEMP1_REG, /* Temp1 register: 0x5 */
> + TEMP2_REG, /* Temp2 register: 0x6 */
> + STAT_REG, /* Status Register: 0x7 */
> + AUX_HGH_TH_REG, /* AUX high threshold register: 0x8 */
> + AUX_LOW_TH_REG, /* AUX low threshold register: 0x9 */
> + TMP_HGH_TH_REG, /* Temp high threshold register:0xA */
> + TMP_LOW_TH_REG, /* Temp low threshold register: 0xB */
> + CFR0_REG, /* Configuration register 0: 0xC */
> + CFR1_REG, /* Configuration register 1: 0xD */
> + CFR2_REG, /* Configuration register 2: 0xE */
> + CONV_FN_SEL_STAT /* Convertor function select register:
> 0xF */
> +};
> +
> +/* Supported Resolution modes */
> +enum resolution_mode {
> + MODE_10BIT, /* 10 bit resolution */
> + MODE_12BIT /* 12 bit resolution */
> +};
> +
> +/* Configuraton register bit fields */
> +/* CFR0 */
> +#define PEN_STS_CTRL_MODE (1<<15)
> +#define ADC_STS (1<<14)
> +#define RES_CTRL (1<<13)
> +#define ADC_CLK_4MHZ (0<<11)
> +#define ADC_CLK_2MHZ (1<<11)
> +#define ADC_CLK_1MHZ (2<<11)
> +#define PANEL_VLTG_STB_TIME_0US (0<<8)
> +#define PANEL_VLTG_STB_TIME_100US (1<<8)
> +#define PANEL_VLTG_STB_TIME_500US (2<<8)
> +#define PANEL_VLTG_STB_TIME_1MS (3<<8)
> +#define PANEL_VLTG_STB_TIME_5MS (4<<8)
> +#define PANEL_VLTG_STB_TIME_10MS (5<<8)
> +#define PANEL_VLTG_STB_TIME_50MS (6<<8)
> +#define PANEL_VLTG_STB_TIME_100MS (7<<8)
> +
> +/* CFR2 */
> +#define PINTS1 (1<<15)
> +#define PINTS0 (1<<14)
> +#define MEDIAN_VAL_FLTR_SIZE_1 (0<<12)
> +#define MEDIAN_VAL_FLTR_SIZE_3 (1<<12)
> +#define MEDIAN_VAL_FLTR_SIZE_7 (2<<12)
> +#define MEDIAN_VAL_FLTR_SIZE_15 (3<<12)
> +#define AVRG_VAL_FLTR_SIZE_1 (0<<10)
> +#define AVRG_VAL_FLTR_SIZE_3_4 (1<<10)
> +#define AVRG_VAL_FLTR_SIZE_7_8 (2<<10)
> +#define AVRG_VAL_FLTR_SIZE_16 (3<<10)
> +#define MAV_FLTR_EN_X (1<<4)
> +#define MAV_FLTR_EN_Y (1<<3)
> +#define MAV_FLTR_EN_Z (1<<2)
> +
> +#define MAX_12BIT ((1 << 12) - 1)
> +#define MEAS_MASK 0xFFF
> +
> +struct ts_event {
> + u16 x;
> + u16 y;
> + u16 z1, z2;
> +};
> +
> +struct tsc2004 {
> + struct input_dev *input;
> + char phys[32];
> + struct delayed_work work;
> +
> + struct i2c_client *client;
> +
> + u16 model;
> + u16 x_plate_ohms;
> +
> + bool pendown;
> + int irq;
> +
> + int (*get_pendown_state)(void);
> + void (*clear_penirq)(void);
> +};
> +
> +static inline int tsc2004_read_word_data(struct tsc2004 *tsc, u8
> cmd)
> +{
> + s32 data;
> + u16 val;
> +
> + data = i2c_smbus_read_word_data(tsc->client, cmd);
> + if (data < 0) {
> + dev_err(&tsc->client->dev, "i2c io (read) error: %d\n",
> data);
> + return data;
> + }
> +
> + /* The protocol and raw data format from i2c interface:
> + * S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh]
> NA P
> + * Where DataLow has [D11-D4], DataHigh has [D3-D0 << 4 |
> Dummy 4bit].
> + */
> + val = swab16(data) >> 4;
> +
> + dev_dbg(&tsc->client->dev, "data: 0x%x, val: 0x%x\n", data,
> val);
> +
> + return val;
> +}
> +
> +static inline int tsc2004_write_word_data(struct tsc2004 *tsc, u8
> cmd, u16 data)
> +{
> + u16 val;
> +
> + val = swab16(data);
> + return i2c_smbus_write_word_data(tsc->client, cmd, val);
> +}
> +
> +static inline int tsc2004_write_cmd(struct tsc2004 *tsc, u8 value)
> +{
> + return i2c_smbus_write_byte(tsc->client, value);
> +}
> +
> +static int tsc2004_prepare_for_reading(struct tsc2004 *ts)
> +{
> + int err;
> + int cmd, data;
> +
> + /* Reset the TSC, configure for 12 bit */
> + cmd = TSC2004_CMD1(MEAS_X_Y_Z1_Z2, MODE_12BIT, SWRST_TRUE);
> + err = tsc2004_write_cmd(ts, cmd);
> + if (err < 0)
> + return err;
> +
> + /* Enable interrupt for PENIRQ and DAV */
> + cmd = TSC2004_CMD0(CFR2_REG, PND0_FALSE, WRITE_REG);
> + data = PINTS1 | PINTS0 | MEDIAN_VAL_FLTR_SIZE_15 |
> + AVRG_VAL_FLTR_SIZE_7_8 | MAV_FLTR_EN_X | MAV_FLTR_EN_Y |
> + MAV_FLTR_EN_Z;
> + err = tsc2004_write_word_data(ts, cmd, data);
> + if (err < 0)
> + return err;
> +
> + /* Configure the TSC in TSMode 1 */
> + cmd = TSC2004_CMD0(CFR0_REG, PND0_FALSE, WRITE_REG);
> + data = PEN_STS_CTRL_MODE | ADC_CLK_2MHZ |
> PANEL_VLTG_STB_TIME_1MS;
> + err = tsc2004_write_word_data(ts, cmd, data);
> + if (err < 0)
> + return err;
> +
> + /* Enable x, y, z1 and z2 conversion functions */
> + cmd = TSC2004_CMD1(MEAS_X_Y_Z1_Z2, MODE_12BIT, SWRST_FALSE);
> + err = tsc2004_write_cmd(ts, cmd);
> + if (err < 0)
> + return err;
> +
> + return 0;
> +}
> +
> +static void tsc2004_read_values(struct tsc2004 *tsc, struct
> ts_event *tc)
> +{
> + int cmd;
> +
> + /* Read X Measurement */
> + cmd = TSC2004_CMD0(X_REG, PND0_FALSE, READ_REG);
> + tc->x = tsc2004_read_word_data(tsc, cmd);
> +
> + /* Read Y Measurement */
> + cmd = TSC2004_CMD0(Y_REG, PND0_FALSE, READ_REG);
> + tc->y = tsc2004_read_word_data(tsc, cmd);
> +
> + /* Read Z1 Measurement */
> + cmd = TSC2004_CMD0(Z1_REG, PND0_FALSE, READ_REG);
> + tc->z1 = tsc2004_read_word_data(tsc, cmd);
> +
> + /* Read Z2 Measurement */
> + cmd = TSC2004_CMD0(Z2_REG, PND0_FALSE, READ_REG);
> + tc->z2 = tsc2004_read_word_data(tsc, cmd);
> +
> +
> + tc->x &= MEAS_MASK;
> + tc->y &= MEAS_MASK;
> + tc->z1 &= MEAS_MASK;
> + tc->z2 &= MEAS_MASK;
> +
> + /* Prepare for touch readings */
> + if (tsc2004_prepare_for_reading(tsc) < 0)
> + dev_dbg(&tsc->client->dev, "Failed to prepare TSC for
> next"
> + "reading\n");
> +}
> +
> +static u32 tsc2004_calculate_pressure(struct tsc2004 *tsc, struct
> ts_event *tc)
> +{
> + u32 rt = 0;
> +
> + /* range filtering */
> + if (tc->x == MAX_12BIT)
> + tc->x = 0;
> +
> + if (likely(tc->x && tc->z1)) {
> + /* compute touch pressure resistance using equation #1
> */
> + rt = tc->z2 - tc->z1;
> + rt *= tc->x;
> + rt *= tsc->x_plate_ohms;
> + rt /= tc->z1;
> + rt = (rt + 2047) >> 12;
> + }
> +
> + return rt;
> +}
> +
> +static void tsc2004_send_up_event(struct tsc2004 *tsc)
> +{
> + struct input_dev *input = tsc->input;
> +
> + dev_dbg(&tsc->client->dev, "UP\n");
> +
> + input_report_key(input, BTN_TOUCH, 0);
> + input_report_abs(input, ABS_PRESSURE, 0);
> + input_sync(input);
> +}
> +
> +static void tsc2004_work(struct work_struct *work)
> +{
> + struct tsc2004 *ts =
> + container_of(to_delayed_work(work), struct tsc2004,
> work);
> + struct ts_event tc;
> + u32 rt;
> +
> + /*
> + * NOTE: We can't rely on the pressure to determine the pen
> down
> + * state, even though this controller has a pressure sensor.
> + * The pressure value can fluctuate for quite a while after
> + * lifting the pen and in some cases may not even settle at
> the
> + * expected value.
> + *
> + * The only safe way to check for the pen up condition is in
> the
> + * work function by reading the pen signal state (it's a GPIO
> + * and IRQ). Unfortunately such callback is not always
> available,
> + * in that case we have rely on the pressure anyway.
> + */
> + if (ts->get_pendown_state) {
> + if (unlikely(!ts->get_pendown_state())) {
> + tsc2004_send_up_event(ts);
> + ts->pendown = false;
> + goto out;
> + }
> +
> + dev_dbg(&ts->client->dev, "pen is still down\n");
> + }
> +
> + tsc2004_read_values(ts, &tc);
> +
> + rt = tsc2004_calculate_pressure(ts, &tc);
> + if (rt > MAX_12BIT) {
> + /*
> + * Sample found inconsistent by debouncing or pressure
> is
> + * beyond the maximum. Don't report it to user space,
> + * repeat at least once more the measurement.
> + */
> + dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt);
> + goto out;
> +
> + }
> +
> + if (rt) {
> + struct input_dev *input = ts->input;
> +
> + if (!ts->pendown) {
> + dev_dbg(&ts->client->dev, "DOWN\n");
> +
> + input_report_key(input, BTN_TOUCH, 1);
> + ts->pendown = true;
> + }
> +
> + input_report_abs(input, ABS_X, tc.x);
> + input_report_abs(input, ABS_Y, tc.y);
> + input_report_abs(input, ABS_PRESSURE, rt);
> +
> + input_sync(input);
> +
> + dev_dbg(&ts->client->dev, "point(%4d,%4d), pressure
> (%4u)\n",
> + tc.x, tc.y, rt);
> +
> + } else if (!ts->get_pendown_state && ts->pendown) {
> + /*
> + * We don't have callback to check pendown state, so we
> + * have to assume that since pressure reported is 0 the
> + * pen was lifted up.
> + */
> + tsc2004_send_up_event(ts);
> + ts->pendown = false;
> + }
> +
> + out:
> + if (ts->pendown)
> + schedule_delayed_work(&ts->work,
> + msecs_to_jiffies(TS_POLL_PERIOD));
> + else
> + enable_irq(ts->irq);
> +}
> +
> +static irqreturn_t tsc2004_irq(int irq, void *handle)
> +{
> + struct tsc2004 *ts = handle;
> +
> + if (!ts->get_pendown_state || likely(ts->get_pendown_state()))
> {
> + disable_irq_nosync(ts->irq);
> + schedule_delayed_work(&ts->work,
> + msecs_to_jiffies(TS_POLL_DELAY));
> + }
> +
> + if (ts->clear_penirq)
> + ts->clear_penirq();
> +
> + return IRQ_HANDLED;
> +}
> +
> +static void tsc2004_free_irq(struct tsc2004 *ts)
> +{
> + free_irq(ts->irq, ts);
> + if (cancel_delayed_work_sync(&ts->work)) {
> + /*
> + * Work was pending, therefore we need to enable
> + * IRQ here to balance the disable_irq() done in the
> + * interrupt handler.
> + */
> + enable_irq(ts->irq);
> + }
> +}
> +
> +static int __devinit tsc2004_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + struct tsc2004 *ts;
> + struct tsc2004_platform_data *pdata = pdata = client-
> >dev.platform_data;
> + struct input_dev *input_dev;
> + int err;
> +
> + if (!pdata) {
> + dev_err(&client->dev, "platform data is required!\n");
> + return -EINVAL;
> + }
> +
> + if (!i2c_check_functionality(client->adapter,
> + I2C_FUNC_SMBUS_READ_WORD_DATA))
> + return -EIO;
> +
> + ts = kzalloc(sizeof(struct tsc2004), GFP_KERNEL);
> + input_dev = input_allocate_device();
> + if (!ts || !input_dev) {
> + err = -ENOMEM;
> + goto err_free_mem;
> + }
> +
> + ts->client = client;
> + ts->irq = client->irq;
> + ts->input = input_dev;
> + INIT_DELAYED_WORK(&ts->work, tsc2004_work);
> +
> + ts->model = pdata->model;
> + ts->x_plate_ohms = pdata->x_plate_ohms;
> + ts->get_pendown_state = pdata->get_pendown_state;
> + ts->clear_penirq = pdata->clear_penirq;
> +
> + snprintf(ts->phys, sizeof(ts->phys),
> + "%s/input0", dev_name(&client->dev));
> +
> + input_dev->name = "TSC2004 Touchscreen";
> + input_dev->phys = ts->phys;
> + input_dev->id.bustype = BUS_I2C;
> +
> + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
> + input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
> +
> + input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
> + input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
> + input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0,
> 0);
> +
> + if (pdata->init_platform_hw)
> + pdata->init_platform_hw();
> +
> + err = request_irq(ts->irq, tsc2004_irq, IRQF_TRIGGER_FALLING,
> + client->dev.driver->name, ts);
> + if (err < 0) {
> + dev_err(&client->dev, "irq %d busy?\n", ts->irq);
> + goto err_free_mem;
> + }
> +
> + /* Prepare for touch readings */
> + err = tsc2004_prepare_for_reading(ts);
> + if (err < 0)
> + goto err_free_irq;
> +
> + err = input_register_device(input_dev);
> + if (err)
> + goto err_free_irq;
> +
> + i2c_set_clientdata(client, ts);
> +
> + return 0;
> +
> + err_free_irq:
> + tsc2004_free_irq(ts);
> + if (pdata->exit_platform_hw)
> + pdata->exit_platform_hw();
> + err_free_mem:
> + input_free_device(input_dev);
> + kfree(ts);
> + return err;
> +}
> +
> +static int __devexit tsc2004_remove(struct i2c_client *client)
> +{
> + struct tsc2004 *ts = i2c_get_clientdata(client);
> + struct tsc2004_platform_data *pdata = client-
> >dev.platform_data;
> +
> + tsc2004_free_irq(ts);
> +
> + if (pdata->exit_platform_hw)
> + pdata->exit_platform_hw();
> +
> + input_unregister_device(ts->input);
> + kfree(ts);
> +
> + return 0;
> +}
> +
> +static struct i2c_device_id tsc2004_idtable[] = {
> + { "tsc2004", 0 },
> + { }
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, tsc2004_idtable);
> +
> +static struct i2c_driver tsc2004_driver = {
> + .driver = {
> + .owner = THIS_MODULE,
> + .name = "tsc2004"
> + },
> + .id_table = tsc2004_idtable,
> + .probe = tsc2004_probe,
> + .remove = __devexit_p(tsc2004_remove),
> +};
> +
> +static int __init tsc2004_init(void)
> +{
> + return i2c_add_driver(&tsc2004_driver);
> +}
> +
> +static void __exit tsc2004_exit(void)
> +{
> + i2c_del_driver(&tsc2004_driver);
> +}
> +
> +module_init(tsc2004_init);
> +module_exit(tsc2004_exit);
> +
> +MODULE_AUTHOR("Vaibhav Hiremath <hvaibhav@ti.com>");
> +MODULE_DESCRIPTION("TSC2004 TouchScreen Driver");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/i2c/tsc2004.h
> b/include/linux/i2c/tsc2004.h
> new file mode 100644
> index 0000000..044c36f
> --- /dev/null
> +++ b/include/linux/i2c/tsc2004.h
> @@ -0,0 +1,17 @@
> +#ifndef __LINUX_I2C_TSC2004_H
> +#define __LINUX_I2C_TSC2004_H
> +
> +/* linux/i2c/tsc2004.h */
> +
> +struct tsc2004_platform_data {
> + u16 model; /* 2004. */
> + u16 x_plate_ohms;
> +
> + int (*get_pendown_state)(void);
> + void (*clear_penirq)(void); /* If needed, clear 2nd
> level
> + interrupt source */
> + int (*init_platform_hw)(void);
> + void (*exit_platform_hw)(void);
> +};
> +
> +#endif
> --
> 1.6.2.4
next prev parent reply other threads:[~2010-01-11 6:24 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-11-19 14:46 [PATCH 2/3] Input:TouchScreen: Introduce TSC2004 driver support hvaibhav
2009-11-20 17:02 ` Dmitry Torokhov
2009-11-23 10:15 ` Hiremath, Vaibhav
2010-01-11 6:24 ` Hiremath, Vaibhav [this message]
2010-01-12 8:37 ` Dmitry Torokhov
2010-01-30 10:58 ` Hiremath, Vaibhav
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=19F8576C6E063C45BE387C64729E7394044A3982AE@dbde02.ent.ti.com \
--to=hvaibhav@ti.com \
--cc=dmitry.torokhov@gmail.com \
--cc=dtor@mail.ru \
--cc=linux-input@vger.kernel.org \
--cc=linux-omap@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).