sx8654.c (11890B)
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 88struct 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 96struct 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 109static 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 117static 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 128static 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 192static 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 236out: 237 return IRQ_HANDLED; 238} 239 240static 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 259static 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 284static 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 309static 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 422static 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 430static 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 439static 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}; 455MODULE_DEVICE_TABLE(of, sx8654_of_match); 456#endif 457 458static 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}; 465MODULE_DEVICE_TABLE(i2c, sx8654_id_table); 466 467static 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}; 475module_i2c_driver(sx8654_driver); 476 477MODULE_AUTHOR("Sébastien Szymanski <sebastien.szymanski@armadeus.com>"); 478MODULE_DESCRIPTION("Semtech SX8654 I2C Touchscreen Driver"); 479MODULE_LICENSE("GPL");