Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.6 698 lines 16 kB view raw
1/* 2 * Core Source for: 3 * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers. 4 * For use with Cypress Txx3xx parts. 5 * Supported parts include: 6 * CY8CTST341 7 * CY8CTMA340 8 * 9 * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. 10 * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org> 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * version 2, and only version 2, as published by the 15 * Free Software Foundation. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License along 23 * with this program; if not, write to the Free Software Foundation, Inc., 24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 25 * 26 * Contact Cypress Semiconductor at www.cypress.com <kev@cypress.com> 27 * 28 */ 29 30#include <linux/delay.h> 31#include <linux/input.h> 32#include <linux/input/mt.h> 33#include <linux/input/touchscreen.h> 34#include <linux/gpio.h> 35#include <linux/interrupt.h> 36#include <linux/slab.h> 37#include <linux/property.h> 38#include <linux/gpio/consumer.h> 39 40#include "cyttsp_core.h" 41 42/* Bootloader number of command keys */ 43#define CY_NUM_BL_KEYS 8 44 45/* helpers */ 46#define GET_NUM_TOUCHES(x) ((x) & 0x0F) 47#define IS_LARGE_AREA(x) (((x) & 0x10) >> 4) 48#define IS_BAD_PKT(x) ((x) & 0x20) 49#define IS_VALID_APP(x) ((x) & 0x01) 50#define IS_OPERATIONAL_ERR(x) ((x) & 0x3F) 51#define GET_HSTMODE(reg) (((reg) & 0x70) >> 4) 52#define GET_BOOTLOADERMODE(reg) (((reg) & 0x10) >> 4) 53 54#define CY_REG_BASE 0x00 55#define CY_REG_ACT_DIST 0x1E 56#define CY_REG_ACT_INTRVL 0x1D 57#define CY_REG_TCH_TMOUT (CY_REG_ACT_INTRVL + 1) 58#define CY_REG_LP_INTRVL (CY_REG_TCH_TMOUT + 1) 59#define CY_MAXZ 255 60#define CY_DELAY_DFLT 20 /* ms */ 61#define CY_DELAY_MAX 500 62#define CY_ACT_DIST_DFLT 0xF8 63#define CY_ACT_DIST_MASK 0x0F 64#define CY_HNDSHK_BIT 0x80 65/* device mode bits */ 66#define CY_OPERATE_MODE 0x00 67#define CY_SYSINFO_MODE 0x10 68/* power mode select bits */ 69#define CY_SOFT_RESET_MODE 0x01 /* return to Bootloader mode */ 70#define CY_DEEP_SLEEP_MODE 0x02 71#define CY_LOW_POWER_MODE 0x04 72 73/* Slots management */ 74#define CY_MAX_FINGER 4 75#define CY_MAX_ID 16 76 77static const u8 bl_command[] = { 78 0x00, /* file offset */ 79 0xFF, /* command */ 80 0xA5, /* exit bootloader command */ 81 0, 1, 2, 3, 4, 5, 6, 7 /* default keys */ 82}; 83 84static int ttsp_read_block_data(struct cyttsp *ts, u8 command, 85 u8 length, void *buf) 86{ 87 int error; 88 int tries; 89 90 for (tries = 0; tries < CY_NUM_RETRY; tries++) { 91 error = ts->bus_ops->read(ts->dev, ts->xfer_buf, command, 92 length, buf); 93 if (!error) 94 return 0; 95 96 msleep(CY_DELAY_DFLT); 97 } 98 99 return -EIO; 100} 101 102static int ttsp_write_block_data(struct cyttsp *ts, u8 command, 103 u8 length, void *buf) 104{ 105 int error; 106 int tries; 107 108 for (tries = 0; tries < CY_NUM_RETRY; tries++) { 109 error = ts->bus_ops->write(ts->dev, ts->xfer_buf, command, 110 length, buf); 111 if (!error) 112 return 0; 113 114 msleep(CY_DELAY_DFLT); 115 } 116 117 return -EIO; 118} 119 120static int ttsp_send_command(struct cyttsp *ts, u8 cmd) 121{ 122 return ttsp_write_block_data(ts, CY_REG_BASE, sizeof(cmd), &cmd); 123} 124 125static int cyttsp_handshake(struct cyttsp *ts) 126{ 127 if (ts->use_hndshk) 128 return ttsp_send_command(ts, 129 ts->xy_data.hst_mode ^ CY_HNDSHK_BIT); 130 131 return 0; 132} 133 134static int cyttsp_load_bl_regs(struct cyttsp *ts) 135{ 136 memset(&ts->bl_data, 0, sizeof(ts->bl_data)); 137 ts->bl_data.bl_status = 0x10; 138 139 return ttsp_read_block_data(ts, CY_REG_BASE, 140 sizeof(ts->bl_data), &ts->bl_data); 141} 142 143static int cyttsp_exit_bl_mode(struct cyttsp *ts) 144{ 145 int error; 146 u8 bl_cmd[sizeof(bl_command)]; 147 148 memcpy(bl_cmd, bl_command, sizeof(bl_command)); 149 if (ts->bl_keys) 150 memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS], 151 ts->bl_keys, CY_NUM_BL_KEYS); 152 153 error = ttsp_write_block_data(ts, CY_REG_BASE, 154 sizeof(bl_cmd), bl_cmd); 155 if (error) 156 return error; 157 158 /* wait for TTSP Device to complete the operation */ 159 msleep(CY_DELAY_DFLT); 160 161 error = cyttsp_load_bl_regs(ts); 162 if (error) 163 return error; 164 165 if (GET_BOOTLOADERMODE(ts->bl_data.bl_status)) 166 return -EIO; 167 168 return 0; 169} 170 171static int cyttsp_set_operational_mode(struct cyttsp *ts) 172{ 173 int error; 174 175 error = ttsp_send_command(ts, CY_OPERATE_MODE); 176 if (error) 177 return error; 178 179 /* wait for TTSP Device to complete switch to Operational mode */ 180 error = ttsp_read_block_data(ts, CY_REG_BASE, 181 sizeof(ts->xy_data), &ts->xy_data); 182 if (error) 183 return error; 184 185 error = cyttsp_handshake(ts); 186 if (error) 187 return error; 188 189 return ts->xy_data.act_dist == CY_ACT_DIST_DFLT ? -EIO : 0; 190} 191 192static int cyttsp_set_sysinfo_mode(struct cyttsp *ts) 193{ 194 int error; 195 196 memset(&ts->sysinfo_data, 0, sizeof(ts->sysinfo_data)); 197 198 /* switch to sysinfo mode */ 199 error = ttsp_send_command(ts, CY_SYSINFO_MODE); 200 if (error) 201 return error; 202 203 /* read sysinfo registers */ 204 msleep(CY_DELAY_DFLT); 205 error = ttsp_read_block_data(ts, CY_REG_BASE, sizeof(ts->sysinfo_data), 206 &ts->sysinfo_data); 207 if (error) 208 return error; 209 210 error = cyttsp_handshake(ts); 211 if (error) 212 return error; 213 214 if (!ts->sysinfo_data.tts_verh && !ts->sysinfo_data.tts_verl) 215 return -EIO; 216 217 return 0; 218} 219 220static int cyttsp_set_sysinfo_regs(struct cyttsp *ts) 221{ 222 int retval = 0; 223 224 if (ts->act_intrvl != CY_ACT_INTRVL_DFLT || 225 ts->tch_tmout != CY_TCH_TMOUT_DFLT || 226 ts->lp_intrvl != CY_LP_INTRVL_DFLT) { 227 228 u8 intrvl_ray[] = { 229 ts->act_intrvl, 230 ts->tch_tmout, 231 ts->lp_intrvl 232 }; 233 234 /* set intrvl registers */ 235 retval = ttsp_write_block_data(ts, CY_REG_ACT_INTRVL, 236 sizeof(intrvl_ray), intrvl_ray); 237 msleep(CY_DELAY_DFLT); 238 } 239 240 return retval; 241} 242 243static void cyttsp_hard_reset(struct cyttsp *ts) 244{ 245 if (ts->reset_gpio) { 246 gpiod_set_value_cansleep(ts->reset_gpio, 1); 247 msleep(CY_DELAY_DFLT); 248 gpiod_set_value_cansleep(ts->reset_gpio, 0); 249 msleep(CY_DELAY_DFLT); 250 } 251} 252 253static int cyttsp_soft_reset(struct cyttsp *ts) 254{ 255 unsigned long timeout; 256 int retval; 257 258 /* wait for interrupt to set ready completion */ 259 reinit_completion(&ts->bl_ready); 260 ts->state = CY_BL_STATE; 261 262 enable_irq(ts->irq); 263 264 retval = ttsp_send_command(ts, CY_SOFT_RESET_MODE); 265 if (retval) 266 goto out; 267 268 timeout = wait_for_completion_timeout(&ts->bl_ready, 269 msecs_to_jiffies(CY_DELAY_DFLT * CY_DELAY_MAX)); 270 retval = timeout ? 0 : -EIO; 271 272out: 273 ts->state = CY_IDLE_STATE; 274 disable_irq(ts->irq); 275 return retval; 276} 277 278static int cyttsp_act_dist_setup(struct cyttsp *ts) 279{ 280 u8 act_dist_setup = ts->act_dist; 281 282 /* Init gesture; active distance setup */ 283 return ttsp_write_block_data(ts, CY_REG_ACT_DIST, 284 sizeof(act_dist_setup), &act_dist_setup); 285} 286 287static void cyttsp_extract_track_ids(struct cyttsp_xydata *xy_data, int *ids) 288{ 289 ids[0] = xy_data->touch12_id >> 4; 290 ids[1] = xy_data->touch12_id & 0xF; 291 ids[2] = xy_data->touch34_id >> 4; 292 ids[3] = xy_data->touch34_id & 0xF; 293} 294 295static const struct cyttsp_tch *cyttsp_get_tch(struct cyttsp_xydata *xy_data, 296 int idx) 297{ 298 switch (idx) { 299 case 0: 300 return &xy_data->tch1; 301 case 1: 302 return &xy_data->tch2; 303 case 2: 304 return &xy_data->tch3; 305 case 3: 306 return &xy_data->tch4; 307 default: 308 return NULL; 309 } 310} 311 312static void cyttsp_report_tchdata(struct cyttsp *ts) 313{ 314 struct cyttsp_xydata *xy_data = &ts->xy_data; 315 struct input_dev *input = ts->input; 316 int num_tch = GET_NUM_TOUCHES(xy_data->tt_stat); 317 const struct cyttsp_tch *tch; 318 int ids[CY_MAX_ID]; 319 int i; 320 DECLARE_BITMAP(used, CY_MAX_ID); 321 322 if (IS_LARGE_AREA(xy_data->tt_stat) == 1) { 323 /* terminate all active tracks */ 324 num_tch = 0; 325 dev_dbg(ts->dev, "%s: Large area detected\n", __func__); 326 } else if (num_tch > CY_MAX_FINGER) { 327 /* terminate all active tracks */ 328 num_tch = 0; 329 dev_dbg(ts->dev, "%s: Num touch error detected\n", __func__); 330 } else if (IS_BAD_PKT(xy_data->tt_mode)) { 331 /* terminate all active tracks */ 332 num_tch = 0; 333 dev_dbg(ts->dev, "%s: Invalid buffer detected\n", __func__); 334 } 335 336 cyttsp_extract_track_ids(xy_data, ids); 337 338 bitmap_zero(used, CY_MAX_ID); 339 340 for (i = 0; i < num_tch; i++) { 341 tch = cyttsp_get_tch(xy_data, i); 342 343 input_mt_slot(input, ids[i]); 344 input_mt_report_slot_state(input, MT_TOOL_FINGER, true); 345 input_report_abs(input, ABS_MT_POSITION_X, be16_to_cpu(tch->x)); 346 input_report_abs(input, ABS_MT_POSITION_Y, be16_to_cpu(tch->y)); 347 input_report_abs(input, ABS_MT_TOUCH_MAJOR, tch->z); 348 349 __set_bit(ids[i], used); 350 } 351 352 for (i = 0; i < CY_MAX_ID; i++) { 353 if (test_bit(i, used)) 354 continue; 355 356 input_mt_slot(input, i); 357 input_mt_report_slot_state(input, MT_TOOL_FINGER, false); 358 } 359 360 input_sync(input); 361} 362 363static irqreturn_t cyttsp_irq(int irq, void *handle) 364{ 365 struct cyttsp *ts = handle; 366 int error; 367 368 if (unlikely(ts->state == CY_BL_STATE)) { 369 complete(&ts->bl_ready); 370 goto out; 371 } 372 373 /* Get touch data from CYTTSP device */ 374 error = ttsp_read_block_data(ts, CY_REG_BASE, 375 sizeof(struct cyttsp_xydata), &ts->xy_data); 376 if (error) 377 goto out; 378 379 /* provide flow control handshake */ 380 error = cyttsp_handshake(ts); 381 if (error) 382 goto out; 383 384 if (unlikely(ts->state == CY_IDLE_STATE)) 385 goto out; 386 387 if (GET_BOOTLOADERMODE(ts->xy_data.tt_mode)) { 388 /* 389 * TTSP device has reset back to bootloader mode. 390 * Restore to operational mode. 391 */ 392 error = cyttsp_exit_bl_mode(ts); 393 if (error) { 394 dev_err(ts->dev, 395 "Could not return to operational mode, err: %d\n", 396 error); 397 ts->state = CY_IDLE_STATE; 398 } 399 } else { 400 cyttsp_report_tchdata(ts); 401 } 402 403out: 404 return IRQ_HANDLED; 405} 406 407static int cyttsp_power_on(struct cyttsp *ts) 408{ 409 int error; 410 411 error = cyttsp_soft_reset(ts); 412 if (error) 413 return error; 414 415 error = cyttsp_load_bl_regs(ts); 416 if (error) 417 return error; 418 419 if (GET_BOOTLOADERMODE(ts->bl_data.bl_status) && 420 IS_VALID_APP(ts->bl_data.bl_status)) { 421 error = cyttsp_exit_bl_mode(ts); 422 if (error) 423 return error; 424 } 425 426 if (GET_HSTMODE(ts->bl_data.bl_file) != CY_OPERATE_MODE || 427 IS_OPERATIONAL_ERR(ts->bl_data.bl_status)) { 428 return -ENODEV; 429 } 430 431 error = cyttsp_set_sysinfo_mode(ts); 432 if (error) 433 return error; 434 435 error = cyttsp_set_sysinfo_regs(ts); 436 if (error) 437 return error; 438 439 error = cyttsp_set_operational_mode(ts); 440 if (error) 441 return error; 442 443 /* init active distance */ 444 error = cyttsp_act_dist_setup(ts); 445 if (error) 446 return error; 447 448 ts->state = CY_ACTIVE_STATE; 449 450 return 0; 451} 452 453static int cyttsp_enable(struct cyttsp *ts) 454{ 455 int error; 456 457 /* 458 * The device firmware can wake on an I2C or SPI memory slave 459 * address match. So just reading a register is sufficient to 460 * wake up the device. The first read attempt will fail but it 461 * will wake it up making the second read attempt successful. 462 */ 463 error = ttsp_read_block_data(ts, CY_REG_BASE, 464 sizeof(ts->xy_data), &ts->xy_data); 465 if (error) 466 return error; 467 468 if (GET_HSTMODE(ts->xy_data.hst_mode)) 469 return -EIO; 470 471 enable_irq(ts->irq); 472 473 return 0; 474} 475 476static int cyttsp_disable(struct cyttsp *ts) 477{ 478 int error; 479 480 error = ttsp_send_command(ts, CY_LOW_POWER_MODE); 481 if (error) 482 return error; 483 484 disable_irq(ts->irq); 485 486 return 0; 487} 488 489static int __maybe_unused cyttsp_suspend(struct device *dev) 490{ 491 struct cyttsp *ts = dev_get_drvdata(dev); 492 int retval = 0; 493 494 mutex_lock(&ts->input->mutex); 495 496 if (ts->input->users) { 497 retval = cyttsp_disable(ts); 498 if (retval == 0) 499 ts->suspended = true; 500 } 501 502 mutex_unlock(&ts->input->mutex); 503 504 return retval; 505} 506 507static int __maybe_unused cyttsp_resume(struct device *dev) 508{ 509 struct cyttsp *ts = dev_get_drvdata(dev); 510 511 mutex_lock(&ts->input->mutex); 512 513 if (ts->input->users) 514 cyttsp_enable(ts); 515 516 ts->suspended = false; 517 518 mutex_unlock(&ts->input->mutex); 519 520 return 0; 521} 522 523SIMPLE_DEV_PM_OPS(cyttsp_pm_ops, cyttsp_suspend, cyttsp_resume); 524EXPORT_SYMBOL_GPL(cyttsp_pm_ops); 525 526static int cyttsp_open(struct input_dev *dev) 527{ 528 struct cyttsp *ts = input_get_drvdata(dev); 529 int retval = 0; 530 531 if (!ts->suspended) 532 retval = cyttsp_enable(ts); 533 534 return retval; 535} 536 537static void cyttsp_close(struct input_dev *dev) 538{ 539 struct cyttsp *ts = input_get_drvdata(dev); 540 541 if (!ts->suspended) 542 cyttsp_disable(ts); 543} 544 545static int cyttsp_parse_properties(struct cyttsp *ts) 546{ 547 struct device *dev = ts->dev; 548 u32 dt_value; 549 int ret; 550 551 ts->bl_keys = devm_kzalloc(dev, CY_NUM_BL_KEYS, GFP_KERNEL); 552 if (!ts->bl_keys) 553 return -ENOMEM; 554 555 /* Set some default values */ 556 ts->use_hndshk = false; 557 ts->act_dist = CY_ACT_DIST_DFLT; 558 ts->act_intrvl = CY_ACT_INTRVL_DFLT; 559 ts->tch_tmout = CY_TCH_TMOUT_DFLT; 560 ts->lp_intrvl = CY_LP_INTRVL_DFLT; 561 562 ret = device_property_read_u8_array(dev, "bootloader-key", 563 ts->bl_keys, CY_NUM_BL_KEYS); 564 if (ret) { 565 dev_err(dev, 566 "bootloader-key property could not be retrieved\n"); 567 return ret; 568 } 569 570 ts->use_hndshk = device_property_present(dev, "use-handshake"); 571 572 if (!device_property_read_u32(dev, "active-distance", &dt_value)) { 573 if (dt_value > 15) { 574 dev_err(dev, "active-distance (%u) must be [0-15]\n", 575 dt_value); 576 return -EINVAL; 577 } 578 ts->act_dist &= ~CY_ACT_DIST_MASK; 579 ts->act_dist |= dt_value; 580 } 581 582 if (!device_property_read_u32(dev, "active-interval-ms", &dt_value)) { 583 if (dt_value > 255) { 584 dev_err(dev, "active-interval-ms (%u) must be [0-255]\n", 585 dt_value); 586 return -EINVAL; 587 } 588 ts->act_intrvl = dt_value; 589 } 590 591 if (!device_property_read_u32(dev, "lowpower-interval-ms", &dt_value)) { 592 if (dt_value > 2550) { 593 dev_err(dev, "lowpower-interval-ms (%u) must be [0-2550]\n", 594 dt_value); 595 return -EINVAL; 596 } 597 /* Register value is expressed in 0.01s / bit */ 598 ts->lp_intrvl = dt_value / 10; 599 } 600 601 if (!device_property_read_u32(dev, "touch-timeout-ms", &dt_value)) { 602 if (dt_value > 2550) { 603 dev_err(dev, "touch-timeout-ms (%u) must be [0-2550]\n", 604 dt_value); 605 return -EINVAL; 606 } 607 /* Register value is expressed in 0.01s / bit */ 608 ts->tch_tmout = dt_value / 10; 609 } 610 611 return 0; 612} 613 614struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops, 615 struct device *dev, int irq, size_t xfer_buf_size) 616{ 617 struct cyttsp *ts; 618 struct input_dev *input_dev; 619 int error; 620 621 ts = devm_kzalloc(dev, sizeof(*ts) + xfer_buf_size, GFP_KERNEL); 622 if (!ts) 623 return ERR_PTR(-ENOMEM); 624 625 input_dev = devm_input_allocate_device(dev); 626 if (!input_dev) 627 return ERR_PTR(-ENOMEM); 628 629 ts->dev = dev; 630 ts->input = input_dev; 631 ts->bus_ops = bus_ops; 632 ts->irq = irq; 633 634 ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 635 if (IS_ERR(ts->reset_gpio)) { 636 error = PTR_ERR(ts->reset_gpio); 637 dev_err(dev, "Failed to request reset gpio, error %d\n", error); 638 return ERR_PTR(error); 639 } 640 641 error = cyttsp_parse_properties(ts); 642 if (error) 643 return ERR_PTR(error); 644 645 init_completion(&ts->bl_ready); 646 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev)); 647 648 input_dev->name = "Cypress TTSP TouchScreen"; 649 input_dev->phys = ts->phys; 650 input_dev->id.bustype = bus_ops->bustype; 651 input_dev->dev.parent = ts->dev; 652 653 input_dev->open = cyttsp_open; 654 input_dev->close = cyttsp_close; 655 656 input_set_drvdata(input_dev, ts); 657 658 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X); 659 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y); 660 touchscreen_parse_properties(input_dev, true); 661 662 error = input_mt_init_slots(input_dev, CY_MAX_ID, 0); 663 if (error) { 664 dev_err(dev, "Unable to init MT slots.\n"); 665 return ERR_PTR(error); 666 } 667 668 error = devm_request_threaded_irq(dev, ts->irq, NULL, cyttsp_irq, 669 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 670 "cyttsp", ts); 671 if (error) { 672 dev_err(ts->dev, "failed to request IRQ %d, err: %d\n", 673 ts->irq, error); 674 return ERR_PTR(error); 675 } 676 677 disable_irq(ts->irq); 678 679 cyttsp_hard_reset(ts); 680 681 error = cyttsp_power_on(ts); 682 if (error) 683 return ERR_PTR(error); 684 685 error = input_register_device(input_dev); 686 if (error) { 687 dev_err(ts->dev, "failed to register input device: %d\n", 688 error); 689 return ERR_PTR(error); 690 } 691 692 return ts; 693} 694EXPORT_SYMBOL_GPL(cyttsp_probe); 695 696MODULE_LICENSE("GPL"); 697MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard touchscreen driver core"); 698MODULE_AUTHOR("Cypress");