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