RE: [PATCH v4] input: add support for TI Touchscreen controller.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Shubhrajyoti,

Sorry about the late reply. I was stuck with some other work.

I have also received the real hardware for the respective driver.
There are some changes. I will soon apply a patch for the same.


On Thu, Aug 11, 2011 at 19:22:01, Shubhrajyoti Datta wrote:
>
> Hi Rachna,
>
>
> On Thu, Aug 11, 2011 at 6:01 PM, Patil, Rachna <rachna@xxxxxx> wrote:
>
>
>       This patch adds support for TI's touchscreen
>       controller for a 4/5/8 wire resistive panel
>       that is directly fed to the ADC.
>
>       This touchscreen controller will be part of
>       an upcoming TI SoC and has been tested on
>       an emulation platform.
>
>       ChangeLog:
>       v2: fixed comments from Dimitry
>       v3: made the driver depend on HAVE_CLK for build
>       v4: error handling added
>
>       Signed-off-by: Patil, Rachna <rachna@xxxxxx>
>       ---
>        drivers/input/touchscreen/Kconfig     |   12 +
>        drivers/input/touchscreen/Makefile    |    1 +
>        drivers/input/touchscreen/ti_tscadc.c |  432
> +++++++++++++++++++++++++++++++++
>        include/linux/input/ti_tscadc.h       |   10 +
>        4 files changed, 455 insertions(+), 0 deletions(-)
>        create mode 100644 drivers/input/touchscreen/ti_tscadc.c
>        create mode 100644 include/linux/input/ti_tscadc.h
>
>       diff --git a/drivers/input/touchscreen/Kconfig
> b/drivers/input/touchscreen/Kconfig
>       index 44589f5..69d367a 100644
>       --- a/drivers/input/touchscreen/Kconfig
>       +++ b/drivers/input/touchscreen/Kconfig
>       @@ -395,6 +395,18 @@ config TOUCHSCREEN_TOUCHWIN
>                To compile this driver as a module, choose M here: the
>                module will be called touchwin.
>
>       +config TOUCHSCREEN_TI_TSCADC
>       +       tristate "TI Touchscreen Interface"
>       +       depends on HAVE_CLK
>       +       help
>       +         Say Y here if you have 4/5/8 wire touchscreen
> controller
>       +         to be connected to the ADC controller on your TI SoC.
>       +
>       +         If unsure, say N.
>       +
>       +         To compile this driver as a module, choose M here: the
>       +         module will be called ti_tscadc.
>       +
>        config TOUCHSCREEN_ATMEL_TSADCC
>              tristate "Atmel Touchscreen Interface"
>              depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
>       diff --git a/drivers/input/touchscreen/Makefile
> b/drivers/input/touchscreen/Makefile
>       index 51b08b0..86b7ab6 100644
>       --- a/drivers/input/touchscreen/Makefile
>       +++ b/drivers/input/touchscreen/Makefile
>       @@ -41,6 +41,7 @@ obj-$(CONFIG_TOUCHSCREEN_QT602240)    +=
> qt602240_ts.o
>        obj-$(CONFIG_TOUCHSCREEN_S3C2410)      += s3c2410_ts.o
>        obj-$(CONFIG_TOUCHSCREEN_ST1232)       += st1232.o
>        obj-$(CONFIG_TOUCHSCREEN_STMPE)                += stmpe-ts.o
>       +obj-$(CONFIG_TOUCHSCREEN_TI_TSCADC)     += ti_tscadc.o
>        obj-$(CONFIG_TOUCHSCREEN_TNETV107X)    += tnetv107x-ts.o
>        obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213)   += touchit213.o
>        obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT)   += touchright.o
>       diff --git a/drivers/input/touchscreen/ti_tscadc.c
> b/drivers/input/touchscreen/ti_tscadc.c
>       new file mode 100644
>       index 0000000..4f935a0
>       --- /dev/null
>       +++ b/drivers/input/touchscreen/ti_tscadc.c
>       @@ -0,0 +1,432 @@
>       +/*
>       + * TI Touch Screen driver
>       + *
>       + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
>       + *
>       + * This program is free software; you can redistribute it and/or
>       + * modify it under the terms of the GNU General Public License as
>       + * published by the Free Software Foundation version 2.
>       + *
>       + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
>       + * kind, whether express or implied; without even the implied warranty
>       + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>       + * GNU General Public License for more details.
>       + */
>       +
>       +
>       +#include <linux/init.h>
>       +#include <linux/kernel.h>
>       +#include <linux/err.h>
>       +#include <linux/module.h>
>       +#include <linux/input.h>
>       +#include <linux/slab.h>
>       +#include <linux/interrupt.h>
>       +#include <linux/clk.h>
>       +#include <linux/platform_device.h>
>       +#include <linux/io.h>
>       +#include <linux/input/ti_tscadc.h>
>       +
>       +#define TSCADC_REG_IRQEOI              0x020
>       +#define TSCADC_REG_IRQSTATUS           0x028
>       +#define TSCADC_REG_IRQENABLE           0x02C
>       +#define TSCADC_REG_IRQWAKEUP           0x034
>       +#define TSCADC_REG_CTRL                        0x040
>       +#define TSCADC_REG_ADCFSM              0x044
>       +#define TSCADC_REG_CLKDIV              0x04C
>       +#define TSCADC_REG_SE                  0x054
>       +#define TSCADC_REG_IDLECONFIG          0x058
>       +#define TSCADC_REG_CHARGECONFIG                0x05C
>       +#define TSCADC_REG_STEPCONFIG1         0x064
>       +#define TSCADC_REG_STEPDELAY1          0x068
>       +#define TSCADC_REG_STEPCONFIG2         0x06C
>       +#define TSCADC_REG_STEPDELAY2          0x070
>       +#define TSCADC_REG_FIFO0               0x100
>       +
>       +/*     Register Bitfields      */
>       +#define TSCADC_IRQWKUP_ENB             BIT(0)
>       +#define TSCADC_STPENB_STEPENB          (7 << 0)
>       +#define TSCADC_IRQENB_IRQHWPEN         BIT(10)
>       +#define TSCADC_IRQENB_IRQEOS           BIT(1)
>       +#define TSCADC_IRQENB_FIFO_OVERFLOW    BIT(3)
>       +#define TSCADC_IRQENB_PENUP            BIT(9)
>       +#define TSCADC_STEPCONFIG_MODE_HWSYNC  0x3
>       +#define TSCADC_STEPCONFIG_2SAMPLES_AVG BIT(2)
>       +#define TSCADC_STEPCONFIG_XPP          BIT(5)
>       +#define TSCADC_STEPCONFIG_XNN          BIT(6)
>       +#define TSCADC_STEPCONFIG_YPP          BIT(7)
>       +#define TSCADC_STEPCONFIG_YNN          BIT(8)
>       +#define TSCADC_STEPCONFIG_XNP          BIT(9)
>       +#define TSCADC_STEPCONFIG_YPN          BIT(10)
>
>
>
> Any particular reason for having some as BIT and some as  1 << xx

No particular reason. I will fix this.

>
>
>
>       +#define TSCADC_STEPCONFIG_RFP_X                (1 << 12)
>       +#define TSCADC_STEPCONFIG_RFP_4_Y      (1 << 13)
>       +#define TSCADC_STEPCONFIG_RFP_5_Y      (1 << 12)
>       +#define TSCADC_STEPCONFIG_RFP_8_Y      (1 << 13)
>       +#define TSCADC_STEPCONFIG_INM          (1 << 18)
>       +#define TSCADC_STEPCONFIG_INP_4                (1 << 20)
>       +#define TSCADC_STEPCONFIG_INP_5                (1 << 21)
>       +#define TSCADC_STEPCONFIG_INP_8_X      (3 << 20)
>       +#define TSCADC_STEPCONFIG_INP_8_Y      (1 << 21)
>       +#define TSCADC_STEPCONFIG_RFM_4_X      (1 << 23)
>       +#define TSCADC_STEPCONFIG_RFM_5_X      (1 << 24)
>       +#define TSCADC_STEPCONFIG_RFM_8_X      (1 << 23)
>       +#define TSCADC_STEPCONFIG_RFM_Y                (1 << 24)
>       +#define TSCADC_STEPCONFIG_OPENDLY      (0xf << 0)
>       +#define TSCADC_STEPCONFIG_SAMPLEDLY    BIT(25)
>       +#define TSCADC_STEPCHARGE_INM          BIT(18)
>       +#define TSCADC_STEPCHARGE_RFM          (3 << 23)
>       +#define TSCADC_CNTRLREG_TSCSSENB       BIT(0)
>       +#define TSCADC_CNTRLREG_STEPID         BIT(1)
>       +#define TSCADC_CNTRLREG_STEPCONFIGWRT  BIT(2)
>       +#define TSCADC_CNTRLREG_TSCENB         BIT(7)
>       +#define TSCADC_CNTRLREG_4WIRE          (0x1 << 5)
>       +#define TSCADC_CNTRLREG_5WIRE          (0x1 << 6)
>       +#define TSCADC_CNTRLREG_8WIRE          (0x3 << 5)
>       +#define TSCADC_ADCFSM_STEPID           0x10
>       +#define TSCADC_ADCFSM_FSM              BIT(5)
>       +
>       +#define ADC_CLK                                3000000
>       +
>       +#define MAX_12BIT                       ((1 << 12) - 1)
>       +
>       +struct tscadc {
>       +       struct input_dev        *input;
>       +       int                     wires;
>       +       struct clk              *clk;
>       +       int                     irq;
>       +       void __iomem            *tsc_base;
>       +};
>       +
>       +static unsigned int tscadc_readl(struct tscadc *ts, unsigned int reg)
>       +{
>       +       return readl(ts->tsc_base + reg);
>       +}
>       +
>       +static void tscadc_writel(struct tscadc *tsc, unsigned int reg,
>       +                                       unsigned int val)
>       +{
>       +       writel(val, tsc->tsc_base + reg);
>       +}
>       +
>       +static void tsc_step_config(struct tscadc *ts_dev)
>       +{
>       +       int     stepconfig1, stepconfig2, delay;
>       +
>       +       /* Configure the Step registers */
>       +       stepconfig1 = TSCADC_STEPCONFIG_MODE_HWSYNC |
>       +                       TSCADC_STEPCONFIG_2SAMPLES_AVG |
> TSCADC_STEPCONFIG_XPP |
>       +                       TSCADC_STEPCONFIG_XNN |
> TSCADC_STEPCONFIG_INM |
>       +                       TSCADC_STEPCONFIG_RFP_X;
>       +
>       +       stepconfig2 = TSCADC_STEPCONFIG_MODE_HWSYNC |
>       +                       TSCADC_STEPCONFIG_2SAMPLES_AVG |
> TSCADC_STEPCONFIG_YNN |
>       +                       TSCADC_STEPCONFIG_INM |
> TSCADC_STEPCONFIG_RFM_Y;
>       +       switch (ts_dev->wires) {
>       +       case 4:
>       +               stepconfig1 |= TSCADC_STEPCONFIG_INP_4 |
>       +                               TSCADC_STEPCONFIG_RFM_4_X;
>       +
>       +               stepconfig2 |= TSCADC_STEPCONFIG_YPP |
>       +                               TSCADC_STEPCONFIG_RFP_4_Y;
>       +               break;
>       +       case 5:
>       +               stepconfig1 |= TSCADC_STEPCONFIG_YPP |
>       +                               TSCADC_STEPCONFIG_YNN |
>       +                               TSCADC_STEPCONFIG_INP_5 |
>       +                               TSCADC_STEPCONFIG_RFM_5_X;
>       +
>       +               stepconfig2 |= TSCADC_STEPCONFIG_XPP |
>       +                               TSCADC_STEPCONFIG_XNP |
>       +                               TSCADC_STEPCONFIG_YPN |
>       +                               TSCADC_STEPCONFIG_RFP_5_Y |
>       +                               TSCADC_STEPCONFIG_INP_5;
>       +               break;
>       +       case 8:
>       +               stepconfig1 |= TSCADC_STEPCONFIG_INP_8_X |
>       +                               TSCADC_STEPCONFIG_RFM_8_X;
>       +
>       +               stepconfig2 |= TSCADC_STEPCONFIG_YPP |
>       +                               TSCADC_STEPCONFIG_RFP_8_Y |
>       +                               TSCADC_STEPCONFIG_INP_8_Y;
>       +               break;
>       +       }
>       +       delay = TSCADC_STEPCONFIG_OPENDLY |
> TSCADC_STEPCONFIG_SAMPLEDLY;
>       +
>       +       tscadc_writel(ts_dev, TSCADC_REG_STEPCONFIG1,
> stepconfig1);
>       +       tscadc_writel(ts_dev, TSCADC_REG_STEPDELAY1, delay);
>       +       tscadc_writel(ts_dev, TSCADC_REG_STEPCONFIG2,
> stepconfig2);
>       +       tscadc_writel(ts_dev, TSCADC_REG_STEPDELAY2, delay);
>       +
>       +       tscadc_writel(ts_dev, TSCADC_REG_SE,
> TSCADC_STPENB_STEPENB);
>       +}
>       +
>       +static void tsc_idle_config(struct tscadc *ts_config)
>       +{
>       +       /* Idle mode touch screen config */
>       +       unsigned int     idleconfig;
>       +
>       +       idleconfig = TSCADC_STEPCONFIG_YNN |
>       +                               TSCADC_STEPCONFIG_RFP_X |
>       +                               TSCADC_STEPCONFIG_INM ;
>       +
>       +       switch (ts_config->wires) {
>       +       case 4:
>       +               idleconfig |= TSCADC_STEPCONFIG_INP_4 |
>       +                       TSCADC_STEPCONFIG_RFM_4_X;
>       +               break;
>       +       case 5:
>       +               idleconfig |= TSCADC_STEPCONFIG_INP_5 |
>       +                       TSCADC_STEPCONFIG_RFM_5_X;
>       +               break;
>       +       case 8:
>       +               idleconfig |= TSCADC_STEPCONFIG_INP_4 |
>       +                       TSCADC_STEPCONFIG_RFM_8_X;
>       +               break;
>       +       }
>       +       tscadc_writel(ts_config, TSCADC_REG_IDLECONFIG,
> idleconfig);
>       +}
>       +
>       +static irqreturn_t tscadc_interrupt(int irq, void *dev)
>       +{
>       +       struct tscadc           *ts_dev = (struct tscadc *)dev;
>       +       struct input_dev        *input_dev = ts_dev->input;
>       +       unsigned int            status, store, cntrlreg, irqclr
> = 0;
>       +       int                     absx, absy;
>       +       int                     charge, fsm;
>       +
>       +       status = tscadc_readl(ts_dev, TSCADC_REG_IRQSTATUS);
>       +       tscadc_writel(ts_dev, TSCADC_REG_SE, 0x0);
>       +
>       +       /* Pen touch event */
>       +       if (status & TSCADC_IRQENB_IRQHWPEN)
>       +               irqclr = TSCADC_IRQENB_IRQHWPEN;
>       +
>       +       if (status & TSCADC_IRQENB_PENUP) {
>       +               /* Pen up event */
>       +               charge = TSCADC_STEPCHARGE_INM |
> TSCADC_STEPCHARGE_RFM;
>       +               tscadc_writel(ts_dev, TSCADC_REG_CHARGECONFIG,
> charge);
>       +               input_report_key(input_dev, BTN_TOUCH, 0);
>       +               input_sync(input_dev);
>       +               tsc_idle_config(ts_dev);
>       +               irqclr |= TSCADC_IRQENB_PENUP;
>       +
>       +       }
>       +       if (status & TSCADC_IRQENB_IRQEOS) {
>       +               /* ADC is done with sampling, ready to read the
> data */
>       +               absx = tscadc_readl(ts_dev, TSCADC_REG_FIFO0);
>       +               absy = tscadc_readl(ts_dev, TSCADC_REG_FIFO0);
>       +
>       +               input_report_abs(input_dev, ABS_X, absx);
>       +               input_report_abs(input_dev, ABS_Y, absy);
>       +               input_report_key(input_dev, BTN_TOUCH, 1);
>       +               input_sync(input_dev);
>       +
>       +               irqclr |= TSCADC_IRQENB_IRQEOS;
>       +
>       +       }
>       +       if (status & TSCADC_IRQENB_FIFO_OVERFLOW) {
>       +               /* FIFO overflow condition */
>       +               cntrlreg = tscadc_readl(ts_dev,
> TSCADC_REG_CTRL);
>       +               cntrlreg &= ~TSCADC_CNTRLREG_TSCSSENB;
>       +               tscadc_writel(ts_dev, TSCADC_REG_CTRL,
> cntrlreg);
>       +
>       +               irqclr |= TSCADC_IRQENB_FIFO_OVERFLOW;
>       +       }
>       +
>       +       tscadc_writel(ts_dev, TSCADC_REG_IRQSTATUS, irqclr);
>       +       fsm = tscadc_readl(ts_dev, TSCADC_REG_ADCFSM);
>       +       if ((fsm & TSCADC_ADCFSM_FSM) &&
>       +                       (fsm & TSCADC_ADCFSM_STEPID)) {
>       +               store = tscadc_readl(ts_dev, TSCADC_REG_CTRL);
>       +               store |= TSCADC_CNTRLREG_TSCSSENB;
>       +               tscadc_writel(ts_dev, TSCADC_REG_CTRL, store);
>       +       }
>       +
>       +        /* check pending interrupts */
>       +       tscadc_writel(ts_dev, TSCADC_REG_IRQEOI, 0x0);
>       +
>       +       tscadc_writel(ts_dev, TSCADC_REG_SE,
> TSCADC_STPENB_STEPENB);
>       +       return IRQ_HANDLED;
>       +}
>       +
>       +/*
>       +* The functions for inserting/removing driver as a module.
>       +*/
>       +
>       +static int __devinit tscadc_probe(struct platform_device *pdev)
>       +{
>       +       struct tscadc                   *ts_dev;
>       +       struct input_dev                *input_dev;
>       +       int                             err;
>       +       int                             clk_value;
>       +       int                             clock_rate, irqenable,
> ctrl;
>       +       struct  tsc_data                *pdata =
> pdev->dev.platform_data;
>       +       struct resource                 *res;
>       +
>       +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>       +       if (!res) {
>       +               dev_err(&pdev->dev, "no memory resource
> defined.\n");
>       +               return -EINVAL;
>       +       }
>       +
>       +       /* Allocate memory for device */
>       +       ts_dev = kzalloc(sizeof(struct tscadc), GFP_KERNEL);
>       +       if (!ts_dev) {
>       +               dev_err(&pdev->dev, "failed to allocate
> memory.\n");
>       +               return -ENOMEM;
>       +       }
>       +
>       +       ts_dev->irq = platform_get_irq(pdev, 0);
>       +       if (ts_dev->irq < 0) {
>       +               dev_err(&pdev->dev, "no irq ID is
> specified.\n");
>       +               err = -ENODEV;
>       +               goto err_free_mem;
>       +       }
>       +
>       +       input_dev = input_allocate_device();
>       +       if (!input_dev) {
>       +               dev_err(&pdev->dev, "failed to allocate input
> device.\n");
>       +               err = -ENOMEM;
>       +               goto err_free_mem;
>       +       }
>       +       ts_dev->input = input_dev;
>       +
>       +       ts_dev->tsc_base = ioremap(res->start,
> resource_size(res));
>       +       if (!ts_dev->tsc_base) {
>       +               dev_err(&pdev->dev, "failed to map
> registers.\n");
>       +               err = -ENOMEM;
>       +               goto err_release_mem;
>       +       }
>       +
>       +       err = request_irq(ts_dev->irq, tscadc_interrupt,
> IRQF_DISABLED,
>       +                               pdev->dev.driver->name, ts_dev);
>
>
>
> Why not use threaded irq instead?

I didn't see a lot of interrupt load, but I can do this.

>
>
>
>       +       if (err) {
>       +               dev_err(&pdev->dev, "failed to allocate
> irq.\n");
>       +               goto err_unmap_regs;
>       +       }
>       +
>       +       ts_dev->clk = clk_get(&pdev->dev, "tsc_clk");
>       +       if (IS_ERR(ts_dev->clk)) {
>       +               dev_err(&pdev->dev, "failed to get ts_clk\n");
>       +               err = PTR_ERR(ts_dev->clk);
>       +               goto err_free_irq;
>       +       }
>       +       clk_enable(ts_dev->clk);
>
>
>
> Could we use runtime apis?

We haven't really done power management on this
driver yet. Will add it in future. Hope this is
not really a must for the driver to get in.

>
>
>
>       +
>       +       clock_rate = clk_get_rate(ts_dev->clk);
>       +       clk_value = clock_rate / ADC_CLK;
>       +       if (clk_value < 7) {
>       +               dev_err(&pdev->dev, "clock input less than min
> clock requirement\n");
>       +               goto err_fail;
>       +       }
>       +       /* TSCADC_CLKDIV needs to be configured to the value
> minus 1 */
>       +       clk_value = clk_value - 1;
>       +       tscadc_writel(ts_dev, TSCADC_REG_CLKDIV, clk_value);
>       +
>       +        /* Enable wake-up of the SoC using touchscreen */
>       +       tscadc_writel(ts_dev, TSCADC_REG_IRQWAKEUP,
> TSCADC_IRQWKUP_ENB);
>       +
>       +       ts_dev->wires = pdata->wires;
>       +
>       +       /* Set the control register bits */
>       +       ctrl = TSCADC_CNTRLREG_STEPCONFIGWRT |
>       +                       TSCADC_CNTRLREG_TSCENB |
>       +                       TSCADC_CNTRLREG_STEPID;
>       +       switch (ts_dev->wires) {
>       +       case 4:
>       +               ctrl |= TSCADC_CNTRLREG_4WIRE;
>       +               break;
>       +       case 5:
>       +               ctrl |= TSCADC_CNTRLREG_5WIRE;
>       +               break;
>       +       case 8:
>       +               ctrl |= TSCADC_CNTRLREG_8WIRE;
>       +               break;
>       +       }
>       +       tscadc_writel(ts_dev, TSCADC_REG_CTRL, ctrl);
>       +
>       +       /* Set register bits for Idel Config Mode */
>       +       tsc_idle_config(ts_dev);
>       +
>       +       /* IRQ Enable */
>       +       irqenable = TSCADC_IRQENB_IRQHWPEN |
>       +                       TSCADC_IRQENB_IRQEOS |
>       +                       TSCADC_IRQENB_PENUP |
> TSCADC_IRQENB_FIFO_OVERFLOW;
>       +       tscadc_writel(ts_dev, TSCADC_REG_IRQENABLE, irqenable);
>       +
>       +       tsc_step_config(ts_dev);
>       +
>       +       ctrl |= TSCADC_CNTRLREG_TSCSSENB;
>       +       tscadc_writel(ts_dev, TSCADC_REG_CTRL, ctrl);
>       +
>       +       input_dev->name = "ti-tsc-adcc";
>       +       input_dev->dev.parent = &pdev->dev;
>       +
>       +       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);
>       +
>       +       /* register to the input system */
>       +       err = input_register_device(input_dev);
>       +       if (err)
>       +               goto err_fail;
>       +
>       +       return 0;
>       +
>       +err_fail:
>       +       clk_disable(ts_dev->clk);
>       +       clk_put(ts_dev->clk);
>       +err_free_irq:
>       +       free_irq(ts_dev->irq, ts_dev);
>       +err_unmap_regs:
>       +       iounmap(ts_dev->tsc_base);
>       +err_release_mem:
>       +       release_mem_region(res->start, resource_size(res));
>       +       input_free_device(ts_dev->input);
>       +err_free_mem:
>       +       kfree(ts_dev);
>       +       return err;
>       +}
>       +
>       +static int __devexit tscadc_remove(struct platform_device
> *pdev)
>       +{
>       +       struct tscadc           *ts_dev =
> dev_get_drvdata(&pdev->dev);
>       +       struct resource         *res;
>       +
>       +       free_irq(ts_dev->irq, ts_dev);
>       +
>       +       input_unregister_device(ts_dev->input);
>       +
>       +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>       +       iounmap(ts_dev->tsc_base);
>       +       release_mem_region(res->start, resource_size(res));
>       +
>       +       clk_disable(ts_dev->clk);
>       +       clk_put(ts_dev->clk);
>       +
>       +       kfree(ts_dev);
>       +
>       +       return 0;
>       +}
>       +
>       +static struct platform_driver ti_tsc_driver = {
>       +       .probe    = tscadc_probe,
>       +       .remove  = __devexit_p(tscadc_remove),
>       +       .driver  = {
>       +               .name   = "tsc",
>       +       },
>       +};
>       +
>       +static int __init ti_tsc_init(void)
>       +{
>       +       return platform_driver_register(&ti_tsc_driver);
>       +}
>       +
>       +static void __exit ti_tsc_exit(void)
>       +{
>       +       platform_driver_unregister(&ti_tsc_driver);
>       +}
>       +
>       +module_init(ti_tsc_init);
>       +module_exit(ti_tsc_exit);
>       diff --git a/include/linux/input/ti_tscadc.h b/include/linux/input/ti_tscadc.h
>       new file mode 100644
>       index 0000000..29f87db
>       --- /dev/null
>       +++ b/include/linux/input/ti_tscadc.h
>       @@ -0,0 +1,10 @@
>       +/**
>       + * struct tsc_data     Touchscreen wire configuration
>       + * @wires:             Wires refer to application modes
>       + *                     i.e. 4/5/8 wire touchscreen support
>       + *                     on the platform
>       + */
>       +
>       +struct tsc_data {
>       +       int wires;
>       +};
>       --
>       1.6.2.4
>
>       --
>       To unsubscribe from this list: send the line "unsubscribe linux-input" in
>       the body of a message to majordomo@xxxxxxxxxxxxxxx
>       More majordomo info at
> http://vger.kernel.org/majordomo-info.html
>

Regards,
Rachna.
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux