2  * drivers/input/touchscreen/tsc2007.c
 
   4  * Copyright (c) 2008 MtekVision Co., Ltd.
 
   5  *      Kwangwoo Lee <kwlee@mtekvision.com>
 
   9  *      Copyright (c) 2005 David Brownell
 
  10  *      Copyright (c) 2006 Nokia Corporation
 
  12  *      Copyright (C) 2004-2005 Richard Purdie
 
  13  *  - omap_ts.[hc], ads7846.h, ts_osk.c
 
  14  *      Copyright (C) 2002 MontaVista Software
 
  15  *      Copyright (C) 2004 Texas Instruments
 
  16  *      Copyright (C) 2005 Dirk Behme
 
  18  *  This program is free software; you can redistribute it and/or modify
 
  19  *  it under the terms of the GNU General Public License version 2 as
 
  20  *  published by the Free Software Foundation.
 
  23 #include <linux/module.h>
 
  24 #include <linux/hrtimer.h>
 
  25 #include <linux/slab.h>
 
  26 #include <linux/input.h>
 
  27 #include <linux/interrupt.h>
 
  28 #include <linux/i2c.h>
 
  29 #include <linux/i2c/tsc2007.h>
 
  31 #define TS_POLL_DELAY   (10 * 1000)     /* ns delay before the first sample */
 
  32 #define TS_POLL_PERIOD  (5 * 1000)      /* ns delay between samples */
 
  34 #define TSC2007_MEASURE_TEMP0           (0x0 << 4)
 
  35 #define TSC2007_MEASURE_AUX             (0x2 << 4)
 
  36 #define TSC2007_MEASURE_TEMP1           (0x4 << 4)
 
  37 #define TSC2007_ACTIVATE_XN             (0x8 << 4)
 
  38 #define TSC2007_ACTIVATE_YN             (0x9 << 4)
 
  39 #define TSC2007_ACTIVATE_YP_XN          (0xa << 4)
 
  40 #define TSC2007_SETUP                   (0xb << 4)
 
  41 #define TSC2007_MEASURE_X               (0xc << 4)
 
  42 #define TSC2007_MEASURE_Y               (0xd << 4)
 
  43 #define TSC2007_MEASURE_Z1              (0xe << 4)
 
  44 #define TSC2007_MEASURE_Z2              (0xf << 4)
 
  46 #define TSC2007_POWER_OFF_IRQ_EN        (0x0 << 2)
 
  47 #define TSC2007_ADC_ON_IRQ_DIS0         (0x1 << 2)
 
  48 #define TSC2007_ADC_OFF_IRQ_EN          (0x2 << 2)
 
  49 #define TSC2007_ADC_ON_IRQ_DIS1         (0x3 << 2)
 
  51 #define TSC2007_12BIT                   (0x0 << 1)
 
  52 #define TSC2007_8BIT                    (0x1 << 1)
 
  54 #define MAX_12BIT                       ((1 << 12) - 1)
 
  56 #define ADC_ON_12BIT    (TSC2007_12BIT | TSC2007_ADC_ON_IRQ_DIS0)
 
  58 #define READ_Y          (ADC_ON_12BIT | TSC2007_MEASURE_Y)
 
  59 #define READ_Z1         (ADC_ON_12BIT | TSC2007_MEASURE_Z1)
 
  60 #define READ_Z2         (ADC_ON_12BIT | TSC2007_MEASURE_Z2)
 
  61 #define READ_X          (ADC_ON_12BIT | TSC2007_MEASURE_X)
 
  62 #define PWRDOWN         (TSC2007_12BIT | TSC2007_POWER_OFF_IRQ_EN)
 
  71         struct input_dev        *input;
 
  76         struct i2c_client       *client;
 
  86         int                     (*get_pendown_state)(void);
 
  87         void                    (*clear_penirq)(void);
 
  90 static inline int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
 
  95         data = i2c_smbus_read_word_data(tsc->client, cmd);
 
  97                 dev_err(&tsc->client->dev, "i2c io error: %d\n", data);
 
 101         /* The protocol and raw data format from i2c interface:
 
 102          * S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
 
 103          * Where DataLow has [D11-D4], DataHigh has [D3-D0 << 4 | Dummy 4bit].
 
 105         val = swab16(data) >> 4;
 
 107         dev_dbg(&tsc->client->dev, "data: 0x%x, val: 0x%x\n", data, val);
 
 112 static void tsc2007_send_event(void *tsc)
 
 114         struct tsc2007  *ts = tsc;
 
 123         /* range filtering */
 
 127         if (likely(x && z1)) {
 
 128                 /* compute touch pressure resistance using equation #1 */
 
 132                 rt *= ts->x_plate_ohms;
 
 134                 rt = (rt + 2047) >> 12;
 
 138         /* Sample found inconsistent by debouncing or pressure is beyond
 
 139          * the maximum. Don't report it to user space, repeat at least
 
 140          * once more the measurement
 
 142         if (rt > MAX_12BIT) {
 
 143                 dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt);
 
 145                 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
 
 150         /* NOTE: We can't rely on the pressure to determine the pen down
 
 151          * state, even this controller has a pressure sensor.  The pressure
 
 152          * value can fluctuate for quite a while after lifting the pen and
 
 153          * in some cases may not even settle at the expected value.
 
 155          * The only safe way to check for the pen up condition is in the
 
 156          * timer by reading the pen signal state (it's a GPIO _and_ IRQ).
 
 159                 struct input_dev *input = ts->input;
 
 162                         dev_dbg(&ts->client->dev, "DOWN\n");
 
 164                         input_report_key(input, BTN_TOUCH, 1);
 
 168                 input_report_abs(input, ABS_X, x);
 
 169                 input_report_abs(input, ABS_Y, y);
 
 170                 input_report_abs(input, ABS_PRESSURE, rt);
 
 174                 dev_dbg(&ts->client->dev, "point(%4d,%4d), pressure (%4u)\n",
 
 178         hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
 
 182 static int tsc2007_read_values(struct tsc2007 *tsc)
 
 184         /* y- still on; turn on only y+ (and ADC) */
 
 185         tsc->tc.y = tsc2007_xfer(tsc, READ_Y);
 
 187         /* turn y- off, x+ on, then leave in lowpower */
 
 188         tsc->tc.x = tsc2007_xfer(tsc, READ_X);
 
 190         /* turn y+ off, x- on; we'll use formula #1 */
 
 191         tsc->tc.z1 = tsc2007_xfer(tsc, READ_Z1);
 
 192         tsc->tc.z2 = tsc2007_xfer(tsc, READ_Z2);
 
 195         tsc2007_xfer(tsc, PWRDOWN);
 
 200 static enum hrtimer_restart tsc2007_timer(struct hrtimer *handle)
 
 202         struct tsc2007 *ts = container_of(handle, struct tsc2007, timer);
 
 204         spin_lock_irq(&ts->lock);
 
 206         if (unlikely(!ts->get_pendown_state() && ts->pendown)) {
 
 207                 struct input_dev *input = ts->input;
 
 209                 dev_dbg(&ts->client->dev, "UP\n");
 
 211                 input_report_key(input, BTN_TOUCH, 0);
 
 212                 input_report_abs(input, ABS_PRESSURE, 0);
 
 218                 /* pen is still down, continue with the measurement */
 
 219                 dev_dbg(&ts->client->dev, "pen is still down\n");
 
 221                 tsc2007_read_values(ts);
 
 222                 tsc2007_send_event(ts);
 
 225         spin_unlock_irq(&ts->lock);
 
 227         return HRTIMER_NORESTART;
 
 230 static irqreturn_t tsc2007_irq(int irq, void *handle)
 
 232         struct tsc2007 *ts = handle;
 
 235         spin_lock_irqsave(&ts->lock, flags);
 
 237         if (likely(ts->get_pendown_state())) {
 
 238                 disable_irq(ts->irq);
 
 239                 hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
 
 243         if (ts->clear_penirq)
 
 246         spin_unlock_irqrestore(&ts->lock, flags);
 
 251 static int tsc2007_probe(struct i2c_client *client,
 
 252                         const struct i2c_device_id *id)
 
 255         struct tsc2007_platform_data *pdata = pdata = client->dev.platform_data;
 
 256         struct input_dev *input_dev;
 
 260                 dev_err(&client->dev, "platform data is required!\n");
 
 264         if (!i2c_check_functionality(client->adapter,
 
 265                                      I2C_FUNC_SMBUS_READ_WORD_DATA))
 
 268         ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL);
 
 269         input_dev = input_allocate_device();
 
 270         if (!ts || !input_dev) {
 
 276         i2c_set_clientdata(client, ts);
 
 278         ts->input = input_dev;
 
 280         hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 
 281         ts->timer.function = tsc2007_timer;
 
 283         spin_lock_init(&ts->lock);
 
 285         ts->model             = pdata->model;
 
 286         ts->x_plate_ohms      = pdata->x_plate_ohms;
 
 287         ts->get_pendown_state = pdata->get_pendown_state;
 
 288         ts->clear_penirq      = pdata->clear_penirq;
 
 290         pdata->init_platform_hw();
 
 292         snprintf(ts->phys, sizeof(ts->phys), "%s/input0", client->dev.bus_id);
 
 294         input_dev->name = "TSC2007 Touchscreen";
 
 295         input_dev->phys = ts->phys;
 
 296         input_dev->id.bustype = BUS_I2C;
 
 298         input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 
 299         input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
 301         input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
 
 302         input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
 
 303         input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
 
 305         tsc2007_read_values(ts);
 
 307         ts->irq = client->irq;
 
 309         err = request_irq(ts->irq, tsc2007_irq, 0,
 
 310                         client->dev.driver->name, ts);
 
 312                 dev_err(&client->dev, "irq %d busy?\n", ts->irq);
 
 316         err = input_register_device(input_dev);
 
 320         dev_info(&client->dev, "registered with irq (%d)\n", ts->irq);
 
 325         free_irq(ts->irq, ts);
 
 326         hrtimer_cancel(&ts->timer);
 
 328         input_free_device(input_dev);
 
 333 static int tsc2007_remove(struct i2c_client *client)
 
 335         struct tsc2007  *ts = i2c_get_clientdata(client);
 
 336         struct tsc2007_platform_data *pdata;
 
 338         pdata = client->dev.platform_data;
 
 339         pdata->exit_platform_hw();
 
 341         free_irq(ts->irq, ts);
 
 342         hrtimer_cancel(&ts->timer);
 
 343         input_unregister_device(ts->input);
 
 349 static struct i2c_device_id tsc2007_idtable[] = {
 
 354 MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);
 
 356 static struct i2c_driver tsc2007_driver = {
 
 358                 .owner  = THIS_MODULE,
 
 361         .id_table       = tsc2007_idtable,
 
 362         .probe          = tsc2007_probe,
 
 363         .remove         = tsc2007_remove,
 
 366 static int __init tsc2007_init(void)
 
 368         return i2c_add_driver(&tsc2007_driver);
 
 371 static void __exit tsc2007_exit(void)
 
 373         i2c_del_driver(&tsc2007_driver);
 
 376 module_init(tsc2007_init);
 
 377 module_exit(tsc2007_exit);
 
 379 MODULE_AUTHOR("Kwangwoo Lee <kwlee@mtekvision.com>");
 
 380 MODULE_DESCRIPTION("TSC2007 TouchScreen Driver");
 
 381 MODULE_LICENSE("GPL");