linux/drivers/input/touchscreen/pixcir_i2c_ts.c
<<
>>
Prefs
   1/*
   2 * Driver for Pixcir I2C touchscreen controllers.
   3 *
   4 * Copyright (C) 2010-2011 Pixcir, Inc.
   5 *
   6 * This software is licensed under the terms of the GNU General Public
   7 * License version 2, as published by the Free Software Foundation, and
   8 * may be copied, distributed, and modified under those terms.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public
  16 * License along with this library; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18 */
  19
  20#include <linux/delay.h>
  21#include <linux/module.h>
  22#include <linux/interrupt.h>
  23#include <linux/slab.h>
  24#include <linux/i2c.h>
  25#include <linux/input.h>
  26#include <linux/input/pixcir_ts.h>
  27#include <linux/gpio.h>
  28
  29struct pixcir_i2c_ts_data {
  30        struct i2c_client *client;
  31        struct input_dev *input;
  32        const struct pixcir_ts_platform_data *chip;
  33        bool running;
  34};
  35
  36static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data)
  37{
  38        struct pixcir_i2c_ts_data *tsdata = data;
  39        u8 rdbuf[10], wrbuf[1] = { 0 };
  40        u8 touch;
  41        int ret;
  42
  43        ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf));
  44        if (ret != sizeof(wrbuf)) {
  45                dev_err(&tsdata->client->dev,
  46                        "%s: i2c_master_send failed(), ret=%d\n",
  47                        __func__, ret);
  48                return;
  49        }
  50
  51        ret = i2c_master_recv(tsdata->client, rdbuf, sizeof(rdbuf));
  52        if (ret != sizeof(rdbuf)) {
  53                dev_err(&tsdata->client->dev,
  54                        "%s: i2c_master_recv failed(), ret=%d\n",
  55                        __func__, ret);
  56                return;
  57        }
  58
  59        touch = rdbuf[0];
  60        if (touch) {
  61                u16 posx1 = (rdbuf[3] << 8) | rdbuf[2];
  62                u16 posy1 = (rdbuf[5] << 8) | rdbuf[4];
  63                u16 posx2 = (rdbuf[7] << 8) | rdbuf[6];
  64                u16 posy2 = (rdbuf[9] << 8) | rdbuf[8];
  65
  66                input_report_key(tsdata->input, BTN_TOUCH, 1);
  67                input_report_abs(tsdata->input, ABS_X, posx1);
  68                input_report_abs(tsdata->input, ABS_Y, posy1);
  69
  70                input_report_abs(tsdata->input, ABS_MT_POSITION_X, posx1);
  71                input_report_abs(tsdata->input, ABS_MT_POSITION_Y, posy1);
  72                input_mt_sync(tsdata->input);
  73
  74                if (touch == 2) {
  75                        input_report_abs(tsdata->input,
  76                                         ABS_MT_POSITION_X, posx2);
  77                        input_report_abs(tsdata->input,
  78                                         ABS_MT_POSITION_Y, posy2);
  79                        input_mt_sync(tsdata->input);
  80                }
  81        } else {
  82                input_report_key(tsdata->input, BTN_TOUCH, 0);
  83        }
  84
  85        input_sync(tsdata->input);
  86}
  87
  88static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
  89{
  90        struct pixcir_i2c_ts_data *tsdata = dev_id;
  91        const struct pixcir_ts_platform_data *pdata = tsdata->chip;
  92
  93        while (tsdata->running) {
  94                pixcir_ts_poscheck(tsdata);
  95
  96                if (gpio_get_value(pdata->gpio_attb))
  97                        break;
  98
  99                msleep(20);
 100        }
 101
 102        return IRQ_HANDLED;
 103}
 104
 105static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts,
 106                                 enum pixcir_power_mode mode)
 107{
 108        struct device *dev = &ts->client->dev;
 109        int ret;
 110
 111        ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_POWER_MODE);
 112        if (ret < 0) {
 113                dev_err(dev, "%s: can't read reg 0x%x : %d\n",
 114                        __func__, PIXCIR_REG_POWER_MODE, ret);
 115                return ret;
 116        }
 117
 118        ret &= ~PIXCIR_POWER_MODE_MASK;
 119        ret |= mode;
 120
 121        /* Always AUTO_IDLE */
 122        ret |= PIXCIR_POWER_ALLOW_IDLE;
 123
 124        ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_POWER_MODE, ret);
 125        if (ret < 0) {
 126                dev_err(dev, "%s: can't write reg 0x%x : %d\n",
 127                        __func__, PIXCIR_REG_POWER_MODE, ret);
 128                return ret;
 129        }
 130
 131        return 0;
 132}
 133
 134/*
 135 * Set the interrupt mode for the device i.e. ATTB line behaviour
 136 *
 137 * @polarity : 1 for active high, 0 for active low.
 138 */
 139static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts,
 140                               enum pixcir_int_mode mode, bool polarity)
 141{
 142        struct device *dev = &ts->client->dev;
 143        int ret;
 144
 145        ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE);
 146        if (ret < 0) {
 147                dev_err(dev, "%s: can't read reg 0x%x : %d\n",
 148                        __func__, PIXCIR_REG_INT_MODE, ret);
 149                return ret;
 150        }
 151
 152        ret &= ~PIXCIR_INT_MODE_MASK;
 153        ret |= mode;
 154
 155        if (polarity)
 156                ret |= PIXCIR_INT_POL_HIGH;
 157        else
 158                ret &= ~PIXCIR_INT_POL_HIGH;
 159
 160        ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret);
 161        if (ret < 0) {
 162                dev_err(dev, "%s: can't write reg 0x%x : %d\n",
 163                        __func__, PIXCIR_REG_INT_MODE, ret);
 164                return ret;
 165        }
 166
 167        return 0;
 168}
 169
 170/*
 171 * Enable/disable interrupt generation
 172 */
 173static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable)
 174{
 175        struct device *dev = &ts->client->dev;
 176        int ret;
 177
 178        ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE);
 179        if (ret < 0) {
 180                dev_err(dev, "%s: can't read reg 0x%x : %d\n",
 181                        __func__, PIXCIR_REG_INT_MODE, ret);
 182                return ret;
 183        }
 184
 185        if (enable)
 186                ret |= PIXCIR_INT_ENABLE;
 187        else
 188                ret &= ~PIXCIR_INT_ENABLE;
 189
 190        ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret);
 191        if (ret < 0) {
 192                dev_err(dev, "%s: can't write reg 0x%x : %d\n",
 193                        __func__, PIXCIR_REG_INT_MODE, ret);
 194                return ret;
 195        }
 196
 197        return 0;
 198}
 199
 200static int pixcir_start(struct pixcir_i2c_ts_data *ts)
 201{
 202        struct device *dev = &ts->client->dev;
 203        int error;
 204
 205        /* LEVEL_TOUCH interrupt with active low polarity */
 206        error = pixcir_set_int_mode(ts, PIXCIR_INT_LEVEL_TOUCH, 0);
 207        if (error) {
 208                dev_err(dev, "Failed to set interrupt mode: %d\n", error);
 209                return error;
 210        }
 211
 212        ts->running = true;
 213        mb();   /* Update status before IRQ can fire */
 214
 215        /* enable interrupt generation */
 216        error = pixcir_int_enable(ts, true);
 217        if (error) {
 218                dev_err(dev, "Failed to enable interrupt generation: %d\n",
 219                        error);
 220                return error;
 221        }
 222
 223        return 0;
 224}
 225
 226static int pixcir_stop(struct pixcir_i2c_ts_data *ts)
 227{
 228        int error;
 229
 230        /* Disable interrupt generation */
 231        error = pixcir_int_enable(ts, false);
 232        if (error) {
 233                dev_err(&ts->client->dev,
 234                        "Failed to disable interrupt generation: %d\n",
 235                        error);
 236                return error;
 237        }
 238
 239        /* Exit ISR if running, no more report parsing */
 240        ts->running = false;
 241        mb();   /* update status before we synchronize irq */
 242
 243        /* Wait till running ISR is complete */
 244        synchronize_irq(ts->client->irq);
 245
 246        return 0;
 247}
 248
 249static int pixcir_input_open(struct input_dev *dev)
 250{
 251        struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev);
 252
 253        return pixcir_start(ts);
 254}
 255
 256static void pixcir_input_close(struct input_dev *dev)
 257{
 258        struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev);
 259
 260        pixcir_stop(ts);
 261}
 262
 263#ifdef CONFIG_PM_SLEEP
 264static int pixcir_i2c_ts_suspend(struct device *dev)
 265{
 266        struct i2c_client *client = to_i2c_client(dev);
 267        struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
 268        struct input_dev *input = ts->input;
 269        int ret = 0;
 270
 271        mutex_lock(&input->mutex);
 272
 273        if (device_may_wakeup(&client->dev)) {
 274                if (!input->users) {
 275                        ret = pixcir_start(ts);
 276                        if (ret) {
 277                                dev_err(dev, "Failed to start\n");
 278                                goto unlock;
 279                        }
 280                }
 281
 282                enable_irq_wake(client->irq);
 283        } else if (input->users) {
 284                ret = pixcir_stop(ts);
 285        }
 286
 287unlock:
 288        mutex_unlock(&input->mutex);
 289
 290        return ret;
 291}
 292
 293static int pixcir_i2c_ts_resume(struct device *dev)
 294{
 295        struct i2c_client *client = to_i2c_client(dev);
 296        struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
 297        struct input_dev *input = ts->input;
 298        int ret = 0;
 299
 300        mutex_lock(&input->mutex);
 301
 302        if (device_may_wakeup(&client->dev)) {
 303                disable_irq_wake(client->irq);
 304
 305                if (!input->users) {
 306                        ret = pixcir_stop(ts);
 307                        if (ret) {
 308                                dev_err(dev, "Failed to stop\n");
 309                                goto unlock;
 310                        }
 311                }
 312        } else if (input->users) {
 313                ret = pixcir_start(ts);
 314        }
 315
 316unlock:
 317        mutex_unlock(&input->mutex);
 318
 319        return ret;
 320}
 321#endif
 322
 323static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops,
 324                         pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume);
 325
 326static int pixcir_i2c_ts_probe(struct i2c_client *client,
 327                                         const struct i2c_device_id *id)
 328{
 329        const struct pixcir_ts_platform_data *pdata =
 330                        dev_get_platdata(&client->dev);
 331        struct device *dev = &client->dev;
 332        struct pixcir_i2c_ts_data *tsdata;
 333        struct input_dev *input;
 334        int error;
 335
 336        if (!pdata) {
 337                dev_err(&client->dev, "platform data not defined\n");
 338                return -EINVAL;
 339        }
 340
 341        if (!gpio_is_valid(pdata->gpio_attb)) {
 342                dev_err(dev, "Invalid gpio_attb in pdata\n");
 343                return -EINVAL;
 344        }
 345
 346        tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL);
 347        if (!tsdata)
 348                return -ENOMEM;
 349
 350        input = devm_input_allocate_device(dev);
 351        if (!input) {
 352                dev_err(dev, "Failed to allocate input device\n");
 353                return -ENOMEM;
 354        }
 355
 356        tsdata->client = client;
 357        tsdata->input = input;
 358        tsdata->chip = pdata;
 359
 360        input->name = client->name;
 361        input->id.bustype = BUS_I2C;
 362        input->open = pixcir_input_open;
 363        input->close = pixcir_input_close;
 364        input->dev.parent = &client->dev;
 365
 366        __set_bit(EV_KEY, input->evbit);
 367        __set_bit(EV_ABS, input->evbit);
 368        __set_bit(BTN_TOUCH, input->keybit);
 369        input_set_abs_params(input, ABS_X, 0, pdata->x_max, 0, 0);
 370        input_set_abs_params(input, ABS_Y, 0, pdata->y_max, 0, 0);
 371        input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0);
 372        input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0);
 373
 374        input_set_drvdata(input, tsdata);
 375
 376        error = devm_gpio_request_one(dev, pdata->gpio_attb,
 377                                      GPIOF_DIR_IN, "pixcir_i2c_attb");
 378        if (error) {
 379                dev_err(dev, "Failed to request ATTB gpio\n");
 380                return error;
 381        }
 382
 383        error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr,
 384                                          IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 385                                          client->name, tsdata);
 386        if (error) {
 387                dev_err(dev, "failed to request irq %d\n", client->irq);
 388                return error;
 389        }
 390
 391        /* Always be in IDLE mode to save power, device supports auto wake */
 392        error = pixcir_set_power_mode(tsdata, PIXCIR_POWER_IDLE);
 393        if (error) {
 394                dev_err(dev, "Failed to set IDLE mode\n");
 395                return error;
 396        }
 397
 398        /* Stop device till opened */
 399        error = pixcir_stop(tsdata);
 400        if (error)
 401                return error;
 402
 403        error = input_register_device(input);
 404        if (error)
 405                return error;
 406
 407        i2c_set_clientdata(client, tsdata);
 408        device_init_wakeup(&client->dev, 1);
 409
 410        return 0;
 411}
 412
 413static int pixcir_i2c_ts_remove(struct i2c_client *client)
 414{
 415        device_init_wakeup(&client->dev, 0);
 416
 417        return 0;
 418}
 419
 420static const struct i2c_device_id pixcir_i2c_ts_id[] = {
 421        { "pixcir_ts", 0 },
 422        { }
 423};
 424MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id);
 425
 426static struct i2c_driver pixcir_i2c_ts_driver = {
 427        .driver = {
 428                .owner  = THIS_MODULE,
 429                .name   = "pixcir_ts",
 430                .pm     = &pixcir_dev_pm_ops,
 431        },
 432        .probe          = pixcir_i2c_ts_probe,
 433        .remove         = pixcir_i2c_ts_remove,
 434        .id_table       = pixcir_i2c_ts_id,
 435};
 436
 437module_i2c_driver(pixcir_i2c_ts_driver);
 438
 439MODULE_AUTHOR("Jianchun Bian <jcbian@pixcir.com.cn>, Dequan Meng <dqmeng@pixcir.com.cn>");
 440MODULE_DESCRIPTION("Pixcir I2C Touchscreen Driver");
 441MODULE_LICENSE("GPL");
 442
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.