linux/drivers/input/touchscreen/st1232.c
<<
>>
Prefs
   1/*
   2 * ST1232 Touchscreen Controller Driver
   3 *
   4 * Copyright (C) 2010 Renesas Solutions Corp.
   5 *      Tony SIM <chinyeow.sim.xt@renesas.com>
   6 *
   7 * Using code from:
   8 *  - android.git.kernel.org: projects/kernel/common.git: synaptics_i2c_rmi.c
   9 *      Copyright (C) 2007 Google, Inc.
  10 *
  11 * This software is licensed under the terms of the GNU General Public
  12 * License version 2, as published by the Free Software Foundation, and
  13 * may be copied, distributed, and modified under those terms.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 */
  20
  21#include <linux/delay.h>
  22#include <linux/i2c.h>
  23#include <linux/input.h>
  24#include <linux/interrupt.h>
  25#include <linux/module.h>
  26#include <linux/pm_qos.h>
  27#include <linux/slab.h>
  28#include <linux/types.h>
  29
  30#define ST1232_TS_NAME  "st1232-ts"
  31
  32#define MIN_X           0x00
  33#define MIN_Y           0x00
  34#define MAX_X           0x31f   /* (800 - 1) */
  35#define MAX_Y           0x1df   /* (480 - 1) */
  36#define MAX_AREA        0xff
  37#define MAX_FINGERS     2
  38
  39struct st1232_ts_finger {
  40        u16 x;
  41        u16 y;
  42        u8 t;
  43        bool is_valid;
  44};
  45
  46struct st1232_ts_data {
  47        struct i2c_client *client;
  48        struct input_dev *input_dev;
  49        struct st1232_ts_finger finger[MAX_FINGERS];
  50        struct dev_pm_qos_request low_latency_req;
  51};
  52
  53static int st1232_ts_read_data(struct st1232_ts_data *ts)
  54{
  55        struct st1232_ts_finger *finger = ts->finger;
  56        struct i2c_client *client = ts->client;
  57        struct i2c_msg msg[2];
  58        int error;
  59        u8 start_reg;
  60        u8 buf[10];
  61
  62        /* read touchscreen data from ST1232 */
  63        msg[0].addr = client->addr;
  64        msg[0].flags = 0;
  65        msg[0].len = 1;
  66        msg[0].buf = &start_reg;
  67        start_reg = 0x10;
  68
  69        msg[1].addr = ts->client->addr;
  70        msg[1].flags = I2C_M_RD;
  71        msg[1].len = sizeof(buf);
  72        msg[1].buf = buf;
  73
  74        error = i2c_transfer(client->adapter, msg, 2);
  75        if (error < 0)
  76                return error;
  77
  78        /* get "valid" bits */
  79        finger[0].is_valid = buf[2] >> 7;
  80        finger[1].is_valid = buf[5] >> 7;
  81
  82        /* get xy coordinate */
  83        if (finger[0].is_valid) {
  84                finger[0].x = ((buf[2] & 0x0070) << 4) | buf[3];
  85                finger[0].y = ((buf[2] & 0x0007) << 8) | buf[4];
  86                finger[0].t = buf[8];
  87        }
  88
  89        if (finger[1].is_valid) {
  90                finger[1].x = ((buf[5] & 0x0070) << 4) | buf[6];
  91                finger[1].y = ((buf[5] & 0x0007) << 8) | buf[7];
  92                finger[1].t = buf[9];
  93        }
  94
  95        return 0;
  96}
  97
  98static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id)
  99{
 100        struct st1232_ts_data *ts = dev_id;
 101        struct st1232_ts_finger *finger = ts->finger;
 102        struct input_dev *input_dev = ts->input_dev;
 103        int count = 0;
 104        int i, ret;
 105
 106        ret = st1232_ts_read_data(ts);
 107        if (ret < 0)
 108                goto end;
 109
 110        /* multi touch protocol */
 111        for (i = 0; i < MAX_FINGERS; i++) {
 112                if (!finger[i].is_valid)
 113                        continue;
 114
 115                input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, finger[i].t);
 116                input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x);
 117                input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].y);
 118                input_mt_sync(input_dev);
 119                count++;
 120        }
 121
 122        /* SYN_MT_REPORT only if no contact */
 123        if (!count) {
 124                input_mt_sync(input_dev);
 125                if (ts->low_latency_req.dev) {
 126                        dev_pm_qos_remove_request(&ts->low_latency_req);
 127                        ts->low_latency_req.dev = NULL;
 128                }
 129        } else if (!ts->low_latency_req.dev) {
 130                /* First contact, request 100 us latency. */
 131                dev_pm_qos_add_ancestor_request(&ts->client->dev,
 132                                                &ts->low_latency_req, 100);
 133        }
 134
 135        /* SYN_REPORT */
 136        input_sync(input_dev);
 137
 138end:
 139        return IRQ_HANDLED;
 140}
 141
 142static int st1232_ts_probe(struct i2c_client *client,
 143                                        const struct i2c_device_id *id)
 144{
 145        struct st1232_ts_data *ts;
 146        struct input_dev *input_dev;
 147        int error;
 148
 149        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 150                dev_err(&client->dev, "need I2C_FUNC_I2C\n");
 151                return -EIO;
 152        }
 153
 154        if (!client->irq) {
 155                dev_err(&client->dev, "no IRQ?\n");
 156                return -EINVAL;
 157        }
 158
 159
 160        ts = kzalloc(sizeof(struct st1232_ts_data), GFP_KERNEL);
 161        input_dev = input_allocate_device();
 162        if (!ts || !input_dev) {
 163                error = -ENOMEM;
 164                goto err_free_mem;
 165        }
 166
 167        ts->client = client;
 168        ts->input_dev = input_dev;
 169
 170        input_dev->name = "st1232-touchscreen";
 171        input_dev->id.bustype = BUS_I2C;
 172        input_dev->dev.parent = &client->dev;
 173
 174        __set_bit(EV_SYN, input_dev->evbit);
 175        __set_bit(EV_KEY, input_dev->evbit);
 176        __set_bit(EV_ABS, input_dev->evbit);
 177
 178        input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MAX_AREA, 0, 0);
 179        input_set_abs_params(input_dev, ABS_MT_POSITION_X, MIN_X, MAX_X, 0, 0);
 180        input_set_abs_params(input_dev, ABS_MT_POSITION_Y, MIN_Y, MAX_Y, 0, 0);
 181
 182        error = request_threaded_irq(client->irq, NULL, st1232_ts_irq_handler,
 183                                     IRQF_ONESHOT, client->name, ts);
 184        if (error) {
 185                dev_err(&client->dev, "Failed to register interrupt\n");
 186                goto err_free_mem;
 187        }
 188
 189        error = input_register_device(ts->input_dev);
 190        if (error) {
 191                dev_err(&client->dev, "Unable to register %s input device\n",
 192                        input_dev->name);
 193                goto err_free_irq;
 194        }
 195
 196        i2c_set_clientdata(client, ts);
 197        device_init_wakeup(&client->dev, 1);
 198
 199        return 0;
 200
 201err_free_irq:
 202        free_irq(client->irq, ts);
 203err_free_mem:
 204        input_free_device(input_dev);
 205        kfree(ts);
 206        return error;
 207}
 208
 209static int st1232_ts_remove(struct i2c_client *client)
 210{
 211        struct st1232_ts_data *ts = i2c_get_clientdata(client);
 212
 213        device_init_wakeup(&client->dev, 0);
 214        free_irq(client->irq, ts);
 215        input_unregister_device(ts->input_dev);
 216        kfree(ts);
 217
 218        return 0;
 219}
 220
 221#ifdef CONFIG_PM_SLEEP
 222static int st1232_ts_suspend(struct device *dev)
 223{
 224        struct i2c_client *client = to_i2c_client(dev);
 225
 226        if (device_may_wakeup(&client->dev))
 227                enable_irq_wake(client->irq);
 228        else
 229                disable_irq(client->irq);
 230
 231        return 0;
 232}
 233
 234static int st1232_ts_resume(struct device *dev)
 235{
 236        struct i2c_client *client = to_i2c_client(dev);
 237
 238        if (device_may_wakeup(&client->dev))
 239                disable_irq_wake(client->irq);
 240        else
 241                enable_irq(client->irq);
 242
 243        return 0;
 244}
 245
 246#endif
 247
 248static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops,
 249                         st1232_ts_suspend, st1232_ts_resume);
 250
 251static const struct i2c_device_id st1232_ts_id[] = {
 252        { ST1232_TS_NAME, 0 },
 253        { }
 254};
 255MODULE_DEVICE_TABLE(i2c, st1232_ts_id);
 256
 257#ifdef CONFIG_OF
 258static const struct of_device_id st1232_ts_dt_ids[] = {
 259        { .compatible = "sitronix,st1232", },
 260        { }
 261};
 262MODULE_DEVICE_TABLE(of, st1232_ts_dt_ids);
 263#endif
 264
 265static struct i2c_driver st1232_ts_driver = {
 266        .probe          = st1232_ts_probe,
 267        .remove         = st1232_ts_remove,
 268        .id_table       = st1232_ts_id,
 269        .driver = {
 270                .name   = ST1232_TS_NAME,
 271                .owner  = THIS_MODULE,
 272                .of_match_table = of_match_ptr(st1232_ts_dt_ids),
 273                .pm     = &st1232_ts_pm_ops,
 274        },
 275};
 276
 277module_i2c_driver(st1232_ts_driver);
 278
 279MODULE_AUTHOR("Tony SIM <chinyeow.sim.xt@renesas.com>");
 280MODULE_DESCRIPTION("SITRONIX ST1232 Touchscreen Controller Driver");
 281MODULE_LICENSE("GPL");
 282
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.