root/drivers/input/touchscreen/sx8654.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sx865x_penrelease
  2. sx865x_penrelease_timer_handler
  3. sx8650_irq
  4. sx8654_irq
  5. sx8654_reset
  6. sx8654_open
  7. sx8654_close
  8. sx8654_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Driver for Semtech SX8654 I2C touchscreen controller.
   4  *
   5  * Copyright (c) 2015 Armadeus Systems
   6  *      Sébastien Szymanski <sebastien.szymanski@armadeus.com>
   7  *
   8  * Using code from:
   9  *  - sx865x.c
  10  *      Copyright (c) 2013 U-MoBo Srl
  11  *      Pierluigi Passaro <p.passaro@u-mobo.com>
  12  *  - sx8650.c
  13  *      Copyright (c) 2009 Wayne Roberts
  14  *  - tsc2007.c
  15  *      Copyright (c) 2008 Kwangwoo Lee
  16  *  - ads7846.c
  17  *      Copyright (c) 2005 David Brownell
  18  *      Copyright (c) 2006 Nokia Corporation
  19  *  - corgi_ts.c
  20  *      Copyright (C) 2004-2005 Richard Purdie
  21  *  - omap_ts.[hc], ads7846.h, ts_osk.c
  22  *      Copyright (C) 2002 MontaVista Software
  23  *      Copyright (C) 2004 Texas Instruments
  24  *      Copyright (C) 2005 Dirk Behme
  25  */
  26 
  27 #include <linux/bitops.h>
  28 #include <linux/delay.h>
  29 #include <linux/gpio/consumer.h>
  30 #include <linux/i2c.h>
  31 #include <linux/input.h>
  32 #include <linux/input/touchscreen.h>
  33 #include <linux/interrupt.h>
  34 #include <linux/irq.h>
  35 #include <linux/module.h>
  36 #include <linux/of.h>
  37 
  38 /* register addresses */
  39 #define I2C_REG_TOUCH0                  0x00
  40 #define I2C_REG_TOUCH1                  0x01
  41 #define I2C_REG_CHANMASK                0x04
  42 #define I2C_REG_IRQMASK                 0x22
  43 #define I2C_REG_IRQSRC                  0x23
  44 #define I2C_REG_SOFTRESET               0x3f
  45 
  46 #define I2C_REG_SX8650_STAT             0x05
  47 #define SX8650_STAT_CONVIRQ             BIT(7)
  48 
  49 /* commands */
  50 #define CMD_READ_REGISTER               0x40
  51 #define CMD_PENTRG                      0xe0
  52 
  53 /* value for I2C_REG_SOFTRESET */
  54 #define SOFTRESET_VALUE                 0xde
  55 
  56 /* bits for I2C_REG_IRQSRC */
  57 #define IRQ_PENTOUCH_TOUCHCONVDONE      BIT(3)
  58 #define IRQ_PENRELEASE                  BIT(2)
  59 
  60 /* bits for RegTouch1 */
  61 #define CONDIRQ                         0x20
  62 #define RPDNT_100K                      0x00
  63 #define FILT_7SA                        0x03
  64 
  65 /* bits for I2C_REG_CHANMASK */
  66 #define CONV_X                          BIT(7)
  67 #define CONV_Y                          BIT(6)
  68 
  69 /* coordinates rate: higher nibble of CTRL0 register */
  70 #define RATE_MANUAL                     0x00
  71 #define RATE_5000CPS                    0xf0
  72 
  73 /* power delay: lower nibble of CTRL0 register */
  74 #define POWDLY_1_1MS                    0x0b
  75 
  76 /* for sx8650, as we have no pen release IRQ there: timeout in ns following the
  77  * last PENIRQ after which we assume the pen is lifted.
  78  */
  79 #define SX8650_PENIRQ_TIMEOUT           msecs_to_jiffies(10)
  80 
  81 #define MAX_12BIT                       ((1 << 12) - 1)
  82 #define MAX_I2C_READ_LEN                10 /* see datasheet section 5.1.5 */
  83 
  84 /* channel definition */
  85 #define CH_X                            0x00
  86 #define CH_Y                            0x01
  87 
  88 struct sx865x_data {
  89         u8 cmd_manual;
  90         u8 chan_mask;
  91         bool has_irq_penrelease;
  92         bool has_reg_irqmask;
  93         irq_handler_t irqh;
  94 };
  95 
  96 struct sx8654 {
  97         struct input_dev *input;
  98         struct i2c_client *client;
  99         struct gpio_desc *gpio_reset;
 100 
 101         spinlock_t lock;        /* for input reporting from irq/timer */
 102         struct timer_list timer;
 103 
 104         struct touchscreen_properties props;
 105 
 106         const struct sx865x_data *data;
 107 };
 108 
 109 static inline void sx865x_penrelease(struct sx8654 *ts)
 110 {
 111         struct input_dev *input_dev = ts->input;
 112 
 113         input_report_key(input_dev, BTN_TOUCH, 0);
 114         input_sync(input_dev);
 115 }
 116 
 117 static void sx865x_penrelease_timer_handler(struct timer_list *t)
 118 {
 119         struct sx8654 *ts = from_timer(ts, t, timer);
 120         unsigned long flags;
 121 
 122         spin_lock_irqsave(&ts->lock, flags);
 123         sx865x_penrelease(ts);
 124         spin_unlock_irqrestore(&ts->lock, flags);
 125         dev_dbg(&ts->client->dev, "penrelease by timer\n");
 126 }
 127 
 128 static irqreturn_t sx8650_irq(int irq, void *handle)
 129 {
 130         struct sx8654 *ts = handle;
 131         struct device *dev = &ts->client->dev;
 132         int len, i;
 133         unsigned long flags;
 134         u8 stat;
 135         u16 x, y;
 136         u16 ch;
 137         u16 chdata;
 138         __be16 data[MAX_I2C_READ_LEN / sizeof(__be16)];
 139         u8 nchan = hweight32(ts->data->chan_mask);
 140         u8 readlen = nchan * sizeof(*data);
 141 
 142         stat = i2c_smbus_read_byte_data(ts->client, CMD_READ_REGISTER
 143                                                     | I2C_REG_SX8650_STAT);
 144 
 145         if (!(stat & SX8650_STAT_CONVIRQ)) {
 146                 dev_dbg(dev, "%s ignore stat [0x%02x]", __func__, stat);
 147                 return IRQ_HANDLED;
 148         }
 149 
 150         len = i2c_master_recv(ts->client, (u8 *)data, readlen);
 151         if (len != readlen) {
 152                 dev_dbg(dev, "ignore short recv (%d)\n", len);
 153                 return IRQ_HANDLED;
 154         }
 155 
 156         spin_lock_irqsave(&ts->lock, flags);
 157 
 158         x = 0;
 159         y = 0;
 160         for (i = 0; i < nchan; i++) {
 161                 chdata = be16_to_cpu(data[i]);
 162 
 163                 if (unlikely(chdata == 0xFFFF)) {
 164                         dev_dbg(dev, "invalid qualified data @ %d\n", i);
 165                         continue;
 166                 } else if (unlikely(chdata & 0x8000)) {
 167                         dev_warn(dev, "hibit @ %d [0x%04x]\n", i, chdata);
 168                         continue;
 169                 }
 170 
 171                 ch = chdata >> 12;
 172                 if (ch == CH_X)
 173                         x = chdata & MAX_12BIT;
 174                 else if (ch == CH_Y)
 175                         y = chdata & MAX_12BIT;
 176                 else
 177                         dev_warn(dev, "unknown channel %d [0x%04x]\n", ch,
 178                                  chdata);
 179         }
 180 
 181         touchscreen_report_pos(ts->input, &ts->props, x, y, false);
 182         input_report_key(ts->input, BTN_TOUCH, 1);
 183         input_sync(ts->input);
 184         dev_dbg(dev, "point(%4d,%4d)\n", x, y);
 185 
 186         mod_timer(&ts->timer, jiffies + SX8650_PENIRQ_TIMEOUT);
 187         spin_unlock_irqrestore(&ts->lock, flags);
 188 
 189         return IRQ_HANDLED;
 190 }
 191 
 192 static irqreturn_t sx8654_irq(int irq, void *handle)
 193 {
 194         struct sx8654 *sx8654 = handle;
 195         int irqsrc;
 196         u8 data[4];
 197         unsigned int x, y;
 198         int retval;
 199 
 200         irqsrc = i2c_smbus_read_byte_data(sx8654->client,
 201                                           CMD_READ_REGISTER | I2C_REG_IRQSRC);
 202         dev_dbg(&sx8654->client->dev, "irqsrc = 0x%x", irqsrc);
 203 
 204         if (irqsrc < 0)
 205                 goto out;
 206 
 207         if (irqsrc & IRQ_PENRELEASE) {
 208                 dev_dbg(&sx8654->client->dev, "pen release interrupt");
 209 
 210                 input_report_key(sx8654->input, BTN_TOUCH, 0);
 211                 input_sync(sx8654->input);
 212         }
 213 
 214         if (irqsrc & IRQ_PENTOUCH_TOUCHCONVDONE) {
 215                 dev_dbg(&sx8654->client->dev, "pen touch interrupt");
 216 
 217                 retval = i2c_master_recv(sx8654->client, data, sizeof(data));
 218                 if (retval != sizeof(data))
 219                         goto out;
 220 
 221                 /* invalid data */
 222                 if (unlikely(data[0] & 0x80 || data[2] & 0x80))
 223                         goto out;
 224 
 225                 x = ((data[0] & 0xf) << 8) | (data[1]);
 226                 y = ((data[2] & 0xf) << 8) | (data[3]);
 227 
 228                 touchscreen_report_pos(sx8654->input, &sx8654->props, x, y,
 229                                        false);
 230                 input_report_key(sx8654->input, BTN_TOUCH, 1);
 231                 input_sync(sx8654->input);
 232 
 233                 dev_dbg(&sx8654->client->dev, "point(%4d,%4d)\n", x, y);
 234         }
 235 
 236 out:
 237         return IRQ_HANDLED;
 238 }
 239 
 240 static int sx8654_reset(struct sx8654 *ts)
 241 {
 242         int err;
 243 
 244         if (ts->gpio_reset) {
 245                 gpiod_set_value_cansleep(ts->gpio_reset, 1);
 246                 udelay(2); /* Tpulse > 1µs */
 247                 gpiod_set_value_cansleep(ts->gpio_reset, 0);
 248         } else {
 249                 dev_dbg(&ts->client->dev, "NRST unavailable, try softreset\n");
 250                 err = i2c_smbus_write_byte_data(ts->client, I2C_REG_SOFTRESET,
 251                                                 SOFTRESET_VALUE);
 252                 if (err)
 253                         return err;
 254         }
 255 
 256         return 0;
 257 }
 258 
 259 static int sx8654_open(struct input_dev *dev)
 260 {
 261         struct sx8654 *sx8654 = input_get_drvdata(dev);
 262         struct i2c_client *client = sx8654->client;
 263         int error;
 264 
 265         /* enable pen trigger mode */
 266         error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH0,
 267                                           RATE_5000CPS | POWDLY_1_1MS);
 268         if (error) {
 269                 dev_err(&client->dev, "writing to I2C_REG_TOUCH0 failed");
 270                 return error;
 271         }
 272 
 273         error = i2c_smbus_write_byte(client, CMD_PENTRG);
 274         if (error) {
 275                 dev_err(&client->dev, "writing command CMD_PENTRG failed");
 276                 return error;
 277         }
 278 
 279         enable_irq(client->irq);
 280 
 281         return 0;
 282 }
 283 
 284 static void sx8654_close(struct input_dev *dev)
 285 {
 286         struct sx8654 *sx8654 = input_get_drvdata(dev);
 287         struct i2c_client *client = sx8654->client;
 288         int error;
 289 
 290         disable_irq(client->irq);
 291 
 292         if (!sx8654->data->has_irq_penrelease)
 293                 del_timer_sync(&sx8654->timer);
 294 
 295         /* enable manual mode mode */
 296         error = i2c_smbus_write_byte(client, sx8654->data->cmd_manual);
 297         if (error) {
 298                 dev_err(&client->dev, "writing command CMD_MANUAL failed");
 299                 return;
 300         }
 301 
 302         error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH0, RATE_MANUAL);
 303         if (error) {
 304                 dev_err(&client->dev, "writing to I2C_REG_TOUCH0 failed");
 305                 return;
 306         }
 307 }
 308 
 309 static int sx8654_probe(struct i2c_client *client,
 310                         const struct i2c_device_id *id)
 311 {
 312         struct sx8654 *sx8654;
 313         struct input_dev *input;
 314         int error;
 315 
 316         if (!i2c_check_functionality(client->adapter,
 317                                      I2C_FUNC_SMBUS_READ_WORD_DATA))
 318                 return -ENXIO;
 319 
 320         sx8654 = devm_kzalloc(&client->dev, sizeof(*sx8654), GFP_KERNEL);
 321         if (!sx8654)
 322                 return -ENOMEM;
 323 
 324         sx8654->gpio_reset = devm_gpiod_get_optional(&client->dev, "reset",
 325                                                      GPIOD_OUT_HIGH);
 326         if (IS_ERR(sx8654->gpio_reset)) {
 327                 error = PTR_ERR(sx8654->gpio_reset);
 328                 if (error != -EPROBE_DEFER)
 329                         dev_err(&client->dev, "unable to get reset-gpio: %d\n",
 330                                 error);
 331                 return error;
 332         }
 333         dev_dbg(&client->dev, "got GPIO reset pin\n");
 334 
 335         sx8654->data = device_get_match_data(&client->dev);
 336         if (!sx8654->data)
 337                 sx8654->data = (const struct sx865x_data *)id->driver_data;
 338         if (!sx8654->data) {
 339                 dev_err(&client->dev, "invalid or missing device data\n");
 340                 return -EINVAL;
 341         }
 342 
 343         if (!sx8654->data->has_irq_penrelease) {
 344                 dev_dbg(&client->dev, "use timer for penrelease\n");
 345                 timer_setup(&sx8654->timer, sx865x_penrelease_timer_handler, 0);
 346                 spin_lock_init(&sx8654->lock);
 347         }
 348 
 349         input = devm_input_allocate_device(&client->dev);
 350         if (!input)
 351                 return -ENOMEM;
 352 
 353         input->name = "SX8654 I2C Touchscreen";
 354         input->id.bustype = BUS_I2C;
 355         input->dev.parent = &client->dev;
 356         input->open = sx8654_open;
 357         input->close = sx8654_close;
 358 
 359         __set_bit(INPUT_PROP_DIRECT, input->propbit);
 360         input_set_capability(input, EV_KEY, BTN_TOUCH);
 361         input_set_abs_params(input, ABS_X, 0, MAX_12BIT, 0, 0);
 362         input_set_abs_params(input, ABS_Y, 0, MAX_12BIT, 0, 0);
 363 
 364         touchscreen_parse_properties(input, false, &sx8654->props);
 365 
 366         sx8654->client = client;
 367         sx8654->input = input;
 368 
 369         input_set_drvdata(sx8654->input, sx8654);
 370 
 371         error = sx8654_reset(sx8654);
 372         if (error) {
 373                 dev_err(&client->dev, "reset failed");
 374                 return error;
 375         }
 376 
 377         error = i2c_smbus_write_byte_data(client, I2C_REG_CHANMASK,
 378                                           sx8654->data->chan_mask);
 379         if (error) {
 380                 dev_err(&client->dev, "writing to I2C_REG_CHANMASK failed");
 381                 return error;
 382         }
 383 
 384         if (sx8654->data->has_reg_irqmask) {
 385                 error = i2c_smbus_write_byte_data(client, I2C_REG_IRQMASK,
 386                                                   IRQ_PENTOUCH_TOUCHCONVDONE |
 387                                                         IRQ_PENRELEASE);
 388                 if (error) {
 389                         dev_err(&client->dev, "writing I2C_REG_IRQMASK failed");
 390                         return error;
 391                 }
 392         }
 393 
 394         error = i2c_smbus_write_byte_data(client, I2C_REG_TOUCH1,
 395                                           CONDIRQ | RPDNT_100K | FILT_7SA);
 396         if (error) {
 397                 dev_err(&client->dev, "writing to I2C_REG_TOUCH1 failed");
 398                 return error;
 399         }
 400 
 401         error = devm_request_threaded_irq(&client->dev, client->irq,
 402                                           NULL, sx8654->data->irqh,
 403                                           IRQF_ONESHOT,
 404                                           client->name, sx8654);
 405         if (error) {
 406                 dev_err(&client->dev,
 407                         "Failed to enable IRQ %d, error: %d\n",
 408                         client->irq, error);
 409                 return error;
 410         }
 411 
 412         /* Disable the IRQ, we'll enable it in sx8654_open() */
 413         disable_irq(client->irq);
 414 
 415         error = input_register_device(sx8654->input);
 416         if (error)
 417                 return error;
 418 
 419         return 0;
 420 }
 421 
 422 static const struct sx865x_data sx8650_data = {
 423         .cmd_manual             = 0xb0,
 424         .has_irq_penrelease     = false,
 425         .has_reg_irqmask        = false,
 426         .chan_mask              = (CONV_X | CONV_Y),
 427         .irqh                   = sx8650_irq,
 428 };
 429 
 430 static const struct sx865x_data sx8654_data = {
 431         .cmd_manual             = 0xc0,
 432         .has_irq_penrelease     = true,
 433         .has_reg_irqmask        = true,
 434         .chan_mask              = (CONV_X | CONV_Y),
 435         .irqh                   = sx8654_irq,
 436 };
 437 
 438 #ifdef CONFIG_OF
 439 static const struct of_device_id sx8654_of_match[] = {
 440         {
 441                 .compatible = "semtech,sx8650",
 442                 .data = &sx8650_data,
 443         }, {
 444                 .compatible = "semtech,sx8654",
 445                 .data = &sx8654_data,
 446         }, {
 447                 .compatible = "semtech,sx8655",
 448                 .data = &sx8654_data,
 449         }, {
 450                 .compatible = "semtech,sx8656",
 451                 .data = &sx8654_data,
 452         },
 453         { }
 454 };
 455 MODULE_DEVICE_TABLE(of, sx8654_of_match);
 456 #endif
 457 
 458 static const struct i2c_device_id sx8654_id_table[] = {
 459         { .name = "semtech_sx8650", .driver_data = (long)&sx8650_data },
 460         { .name = "semtech_sx8654", .driver_data = (long)&sx8654_data },
 461         { .name = "semtech_sx8655", .driver_data = (long)&sx8654_data },
 462         { .name = "semtech_sx8656", .driver_data = (long)&sx8654_data },
 463         { }
 464 };
 465 MODULE_DEVICE_TABLE(i2c, sx8654_id_table);
 466 
 467 static struct i2c_driver sx8654_driver = {
 468         .driver = {
 469                 .name = "sx8654",
 470                 .of_match_table = of_match_ptr(sx8654_of_match),
 471         },
 472         .id_table = sx8654_id_table,
 473         .probe = sx8654_probe,
 474 };
 475 module_i2c_driver(sx8654_driver);
 476 
 477 MODULE_AUTHOR("Sébastien Szymanski <sebastien.szymanski@armadeus.com>");
 478 MODULE_DESCRIPTION("Semtech SX8654 I2C Touchscreen Driver");
 479 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */