diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/input/touchscreen | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/input/touchscreen')
38 files changed, 6376 insertions, 2102 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 0069d9703fda..cabd9e54863f 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -86,6 +86,18 @@ config TOUCHSCREEN_AD7879_SPI | |||
86 | To compile this driver as a module, choose M here: the | 86 | To compile this driver as a module, choose M here: the |
87 | module will be called ad7879-spi. | 87 | module will be called ad7879-spi. |
88 | 88 | ||
89 | config TOUCHSCREEN_ATMEL_MXT | ||
90 | tristate "Atmel mXT I2C Touchscreen" | ||
91 | depends on I2C | ||
92 | help | ||
93 | Say Y here if you have Atmel mXT series I2C touchscreen, | ||
94 | such as AT42QT602240/ATMXT224, connected to your system. | ||
95 | |||
96 | If unsure, say N. | ||
97 | |||
98 | To compile this driver as a module, choose M here: the | ||
99 | module will be called atmel_mxt_ts. | ||
100 | |||
89 | config TOUCHSCREEN_BITSY | 101 | config TOUCHSCREEN_BITSY |
90 | tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" | 102 | tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" |
91 | depends on SA1100_BITSY | 103 | depends on SA1100_BITSY |
@@ -98,6 +110,18 @@ config TOUCHSCREEN_BITSY | |||
98 | To compile this driver as a module, choose M here: the | 110 | To compile this driver as a module, choose M here: the |
99 | module will be called h3600_ts_input. | 111 | module will be called h3600_ts_input. |
100 | 112 | ||
113 | config TOUCHSCREEN_BU21013 | ||
114 | tristate "BU21013 based touch panel controllers" | ||
115 | depends on I2C | ||
116 | help | ||
117 | Say Y here if you have a bu21013 touchscreen connected to | ||
118 | your system. | ||
119 | |||
120 | If unsure, say N. | ||
121 | |||
122 | To compile this driver as a module, choose M here: the | ||
123 | module will be called bu21013_ts. | ||
124 | |||
101 | config TOUCHSCREEN_CY8CTMG110 | 125 | config TOUCHSCREEN_CY8CTMG110 |
102 | tristate "cy8ctmg110 touchscreen" | 126 | tristate "cy8ctmg110 touchscreen" |
103 | depends on I2C | 127 | depends on I2C |
@@ -214,6 +238,28 @@ config TOUCHSCREEN_WACOM_W8001 | |||
214 | To compile this driver as a module, choose M here: the | 238 | To compile this driver as a module, choose M here: the |
215 | module will be called wacom_w8001. | 239 | module will be called wacom_w8001. |
216 | 240 | ||
241 | config TOUCHSCREEN_LPC32XX | ||
242 | tristate "LPC32XX touchscreen controller" | ||
243 | depends on ARCH_LPC32XX | ||
244 | help | ||
245 | Say Y here if you have a LPC32XX device and want | ||
246 | to support the built-in touchscreen. | ||
247 | |||
248 | To compile this driver as a module, choose M here: the | ||
249 | module will be called lpc32xx_ts. | ||
250 | |||
251 | config TOUCHSCREEN_MAX11801 | ||
252 | tristate "MAX11801 based touchscreens" | ||
253 | depends on I2C | ||
254 | help | ||
255 | Say Y here if you have a MAX11801 based touchscreen | ||
256 | controller. | ||
257 | |||
258 | If unsure, say N. | ||
259 | |||
260 | To compile this driver as a module, choose M here: the | ||
261 | module will be called max11801_ts. | ||
262 | |||
217 | config TOUCHSCREEN_MCS5000 | 263 | config TOUCHSCREEN_MCS5000 |
218 | tristate "MELFAS MCS-5000 touchscreen" | 264 | tristate "MELFAS MCS-5000 touchscreen" |
219 | depends on I2C | 265 | depends on I2C |
@@ -250,6 +296,18 @@ config TOUCHSCREEN_INEXIO | |||
250 | To compile this driver as a module, choose M here: the | 296 | To compile this driver as a module, choose M here: the |
251 | module will be called inexio. | 297 | module will be called inexio. |
252 | 298 | ||
299 | config TOUCHSCREEN_INTEL_MID | ||
300 | tristate "Intel MID platform resistive touchscreen" | ||
301 | depends on INTEL_SCU_IPC | ||
302 | help | ||
303 | Say Y here if you have a Intel MID based touchscreen in | ||
304 | your system. | ||
305 | |||
306 | If unsure, say N. | ||
307 | |||
308 | To compile this driver as a module, choose M here: the | ||
309 | module will be called intel_mid_touch. | ||
310 | |||
253 | config TOUCHSCREEN_MK712 | 311 | config TOUCHSCREEN_MK712 |
254 | tristate "ICS MicroClock MK712 touchscreen" | 312 | tristate "ICS MicroClock MK712 touchscreen" |
255 | help | 313 | help |
@@ -305,18 +363,6 @@ config TOUCHSCREEN_PENMOUNT | |||
305 | To compile this driver as a module, choose M here: the | 363 | To compile this driver as a module, choose M here: the |
306 | module will be called penmount. | 364 | module will be called penmount. |
307 | 365 | ||
308 | config TOUCHSCREEN_QT602240 | ||
309 | tristate "QT602240 I2C Touchscreen" | ||
310 | depends on I2C | ||
311 | help | ||
312 | Say Y here if you have the AT42QT602240/ATMXT224 I2C touchscreen | ||
313 | connected to your system. | ||
314 | |||
315 | If unsure, say N. | ||
316 | |||
317 | To compile this driver as a module, choose M here: the | ||
318 | module will be called qt602240_ts. | ||
319 | |||
320 | config TOUCHSCREEN_MIGOR | 366 | config TOUCHSCREEN_MIGOR |
321 | tristate "Renesas MIGO-R touchscreen" | 367 | tristate "Renesas MIGO-R touchscreen" |
322 | depends on SH_MIGOR && I2C | 368 | depends on SH_MIGOR && I2C |
@@ -328,6 +374,15 @@ config TOUCHSCREEN_MIGOR | |||
328 | To compile this driver as a module, choose M here: the | 374 | To compile this driver as a module, choose M here: the |
329 | module will be called migor_ts. | 375 | module will be called migor_ts. |
330 | 376 | ||
377 | config TOUCHSCREEN_TNETV107X | ||
378 | tristate "TI TNETV107X touchscreen support" | ||
379 | depends on ARCH_DAVINCI_TNETV107X | ||
380 | help | ||
381 | Say Y here if you want to use the TNETV107X touchscreen. | ||
382 | |||
383 | To compile this driver as a module, choose M here: the | ||
384 | module will be called tnetv107x-ts. | ||
385 | |||
331 | config TOUCHSCREEN_TOUCHRIGHT | 386 | config TOUCHSCREEN_TOUCHRIGHT |
332 | tristate "Touchright serial touchscreen" | 387 | tristate "Touchright serial touchscreen" |
333 | select SERIO | 388 | select SERIO |
@@ -380,6 +435,16 @@ config TOUCHSCREEN_UCB1400 | |||
380 | To compile this driver as a module, choose M here: the | 435 | To compile this driver as a module, choose M here: the |
381 | module will be called ucb1400_ts. | 436 | module will be called ucb1400_ts. |
382 | 437 | ||
438 | config TOUCHSCREEN_WM831X | ||
439 | tristate "Support for WM831x touchscreen controllers" | ||
440 | depends on MFD_WM831X | ||
441 | help | ||
442 | This enables support for the touchscreen controller on the WM831x | ||
443 | series of PMICs. | ||
444 | |||
445 | To compile this driver as a module, choose M here: the | ||
446 | module will be called wm831x-ts. | ||
447 | |||
383 | config TOUCHSCREEN_WM97XX | 448 | config TOUCHSCREEN_WM97XX |
384 | tristate "Support for WM97xx AC97 touchscreen controllers" | 449 | tristate "Support for WM97xx AC97 touchscreen controllers" |
385 | depends on AC97_BUS | 450 | depends on AC97_BUS |
@@ -497,62 +562,62 @@ config TOUCHSCREEN_MC13783 | |||
497 | 562 | ||
498 | config TOUCHSCREEN_USB_EGALAX | 563 | config TOUCHSCREEN_USB_EGALAX |
499 | default y | 564 | default y |
500 | bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED | 565 | bool "eGalax, eTurboTouch CT-410/510/700 device support" if EXPERT |
501 | depends on TOUCHSCREEN_USB_COMPOSITE | 566 | depends on TOUCHSCREEN_USB_COMPOSITE |
502 | 567 | ||
503 | config TOUCHSCREEN_USB_PANJIT | 568 | config TOUCHSCREEN_USB_PANJIT |
504 | default y | 569 | default y |
505 | bool "PanJit device support" if EMBEDDED | 570 | bool "PanJit device support" if EXPERT |
506 | depends on TOUCHSCREEN_USB_COMPOSITE | 571 | depends on TOUCHSCREEN_USB_COMPOSITE |
507 | 572 | ||
508 | config TOUCHSCREEN_USB_3M | 573 | config TOUCHSCREEN_USB_3M |
509 | default y | 574 | default y |
510 | bool "3M/Microtouch EX II series device support" if EMBEDDED | 575 | bool "3M/Microtouch EX II series device support" if EXPERT |
511 | depends on TOUCHSCREEN_USB_COMPOSITE | 576 | depends on TOUCHSCREEN_USB_COMPOSITE |
512 | 577 | ||
513 | config TOUCHSCREEN_USB_ITM | 578 | config TOUCHSCREEN_USB_ITM |
514 | default y | 579 | default y |
515 | bool "ITM device support" if EMBEDDED | 580 | bool "ITM device support" if EXPERT |
516 | depends on TOUCHSCREEN_USB_COMPOSITE | 581 | depends on TOUCHSCREEN_USB_COMPOSITE |
517 | 582 | ||
518 | config TOUCHSCREEN_USB_ETURBO | 583 | config TOUCHSCREEN_USB_ETURBO |
519 | default y | 584 | default y |
520 | bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED | 585 | bool "eTurboTouch (non-eGalax compatible) device support" if EXPERT |
521 | depends on TOUCHSCREEN_USB_COMPOSITE | 586 | depends on TOUCHSCREEN_USB_COMPOSITE |
522 | 587 | ||
523 | config TOUCHSCREEN_USB_GUNZE | 588 | config TOUCHSCREEN_USB_GUNZE |
524 | default y | 589 | default y |
525 | bool "Gunze AHL61 device support" if EMBEDDED | 590 | bool "Gunze AHL61 device support" if EXPERT |
526 | depends on TOUCHSCREEN_USB_COMPOSITE | 591 | depends on TOUCHSCREEN_USB_COMPOSITE |
527 | 592 | ||
528 | config TOUCHSCREEN_USB_DMC_TSC10 | 593 | config TOUCHSCREEN_USB_DMC_TSC10 |
529 | default y | 594 | default y |
530 | bool "DMC TSC-10/25 device support" if EMBEDDED | 595 | bool "DMC TSC-10/25 device support" if EXPERT |
531 | depends on TOUCHSCREEN_USB_COMPOSITE | 596 | depends on TOUCHSCREEN_USB_COMPOSITE |
532 | 597 | ||
533 | config TOUCHSCREEN_USB_IRTOUCH | 598 | config TOUCHSCREEN_USB_IRTOUCH |
534 | default y | 599 | default y |
535 | bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED | 600 | bool "IRTOUCHSYSTEMS/UNITOP device support" if EXPERT |
536 | depends on TOUCHSCREEN_USB_COMPOSITE | 601 | depends on TOUCHSCREEN_USB_COMPOSITE |
537 | 602 | ||
538 | config TOUCHSCREEN_USB_IDEALTEK | 603 | config TOUCHSCREEN_USB_IDEALTEK |
539 | default y | 604 | default y |
540 | bool "IdealTEK URTC1000 device support" if EMBEDDED | 605 | bool "IdealTEK URTC1000 device support" if EXPERT |
541 | depends on TOUCHSCREEN_USB_COMPOSITE | 606 | depends on TOUCHSCREEN_USB_COMPOSITE |
542 | 607 | ||
543 | config TOUCHSCREEN_USB_GENERAL_TOUCH | 608 | config TOUCHSCREEN_USB_GENERAL_TOUCH |
544 | default y | 609 | default y |
545 | bool "GeneralTouch Touchscreen device support" if EMBEDDED | 610 | bool "GeneralTouch Touchscreen device support" if EXPERT |
546 | depends on TOUCHSCREEN_USB_COMPOSITE | 611 | depends on TOUCHSCREEN_USB_COMPOSITE |
547 | 612 | ||
548 | config TOUCHSCREEN_USB_GOTOP | 613 | config TOUCHSCREEN_USB_GOTOP |
549 | default y | 614 | default y |
550 | bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED | 615 | bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EXPERT |
551 | depends on TOUCHSCREEN_USB_COMPOSITE | 616 | depends on TOUCHSCREEN_USB_COMPOSITE |
552 | 617 | ||
553 | config TOUCHSCREEN_USB_JASTEC | 618 | config TOUCHSCREEN_USB_JASTEC |
554 | default y | 619 | default y |
555 | bool "JASTEC/DigiTech DTR-02U USB touch controller device support" if EMBEDDED | 620 | bool "JASTEC/DigiTech DTR-02U USB touch controller device support" if EXPERT |
556 | depends on TOUCHSCREEN_USB_COMPOSITE | 621 | depends on TOUCHSCREEN_USB_COMPOSITE |
557 | 622 | ||
558 | config TOUCHSCREEN_USB_E2I | 623 | config TOUCHSCREEN_USB_E2I |
@@ -562,17 +627,17 @@ config TOUCHSCREEN_USB_E2I | |||
562 | 627 | ||
563 | config TOUCHSCREEN_USB_ZYTRONIC | 628 | config TOUCHSCREEN_USB_ZYTRONIC |
564 | default y | 629 | default y |
565 | bool "Zytronic controller" if EMBEDDED | 630 | bool "Zytronic controller" if EXPERT |
566 | depends on TOUCHSCREEN_USB_COMPOSITE | 631 | depends on TOUCHSCREEN_USB_COMPOSITE |
567 | 632 | ||
568 | config TOUCHSCREEN_USB_ETT_TC45USB | 633 | config TOUCHSCREEN_USB_ETT_TC45USB |
569 | default y | 634 | default y |
570 | bool "ET&T USB series TC4UM/TC5UH touchscreen controler support" if EMBEDDED | 635 | bool "ET&T USB series TC4UM/TC5UH touchscreen controller support" if EXPERT |
571 | depends on TOUCHSCREEN_USB_COMPOSITE | 636 | depends on TOUCHSCREEN_USB_COMPOSITE |
572 | 637 | ||
573 | config TOUCHSCREEN_USB_NEXIO | 638 | config TOUCHSCREEN_USB_NEXIO |
574 | default y | 639 | default y |
575 | bool "NEXIO/iNexio device support" if EMBEDDED | 640 | bool "NEXIO/iNexio device support" if EXPERT |
576 | depends on TOUCHSCREEN_USB_COMPOSITE | 641 | depends on TOUCHSCREEN_USB_COMPOSITE |
577 | 642 | ||
578 | config TOUCHSCREEN_TOUCHIT213 | 643 | config TOUCHSCREEN_TOUCHIT213 |
@@ -586,6 +651,17 @@ config TOUCHSCREEN_TOUCHIT213 | |||
586 | To compile this driver as a module, choose M here: the | 651 | To compile this driver as a module, choose M here: the |
587 | module will be called touchit213. | 652 | module will be called touchit213. |
588 | 653 | ||
654 | config TOUCHSCREEN_TSC2005 | ||
655 | tristate "TSC2005 based touchscreens" | ||
656 | depends on SPI_MASTER && GENERIC_HARDIRQS | ||
657 | help | ||
658 | Say Y here if you have a TSC2005 based touchscreen. | ||
659 | |||
660 | If unsure, say N. | ||
661 | |||
662 | To compile this driver as a module, choose M here: the | ||
663 | module will be called tsc2005. | ||
664 | |||
589 | config TOUCHSCREEN_TSC2007 | 665 | config TOUCHSCREEN_TSC2007 |
590 | tristate "TSC2007 based touchscreens" | 666 | tristate "TSC2007 based touchscreens" |
591 | depends on I2C | 667 | depends on I2C |
@@ -616,17 +692,17 @@ config TOUCHSCREEN_PCAP | |||
616 | To compile this driver as a module, choose M here: the | 692 | To compile this driver as a module, choose M here: the |
617 | module will be called pcap_ts. | 693 | module will be called pcap_ts. |
618 | 694 | ||
619 | config TOUCHSCREEN_TPS6507X | 695 | config TOUCHSCREEN_ST1232 |
620 | tristate "TPS6507x based touchscreens" | 696 | tristate "Sitronix ST1232 touchscreen controllers" |
621 | depends on I2C | 697 | depends on I2C |
622 | help | 698 | help |
623 | Say Y here if you have a TPS6507x based touchscreen | 699 | Say Y here if you want to support Sitronix ST1232 |
624 | controller. | 700 | touchscreen controller. |
625 | 701 | ||
626 | If unsure, say N. | 702 | If unsure, say N. |
627 | 703 | ||
628 | To compile this driver as a module, choose M here: the | 704 | To compile this driver as a module, choose M here: the |
629 | module will be called tps6507x_ts. | 705 | module will be called st1232_ts. |
630 | 706 | ||
631 | config TOUCHSCREEN_STMPE | 707 | config TOUCHSCREEN_STMPE |
632 | tristate "STMicroelectronics STMPE touchscreens" | 708 | tristate "STMicroelectronics STMPE touchscreens" |
@@ -638,4 +714,16 @@ config TOUCHSCREEN_STMPE | |||
638 | To compile this driver as a module, choose M here: the | 714 | To compile this driver as a module, choose M here: the |
639 | module will be called stmpe-ts. | 715 | module will be called stmpe-ts. |
640 | 716 | ||
717 | config TOUCHSCREEN_TPS6507X | ||
718 | tristate "TPS6507x based touchscreens" | ||
719 | depends on I2C | ||
720 | help | ||
721 | Say Y here if you have a TPS6507x based touchscreen | ||
722 | controller. | ||
723 | |||
724 | If unsure, say N. | ||
725 | |||
726 | To compile this driver as a module, choose M here: the | ||
727 | module will be called tps6507x_ts. | ||
728 | |||
641 | endif | 729 | endif |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 28217e1dcafd..282d6f76ae26 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -12,8 +12,10 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o | |||
12 | obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o | 12 | obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o |
13 | obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o | 13 | obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o |
14 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o | 14 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o |
15 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o | ||
15 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o | 16 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o |
16 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o | 17 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o |
18 | obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o | ||
17 | obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o | 19 | obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o |
18 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o | 20 | obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o |
19 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o | 21 | obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o |
@@ -23,6 +25,9 @@ obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o | |||
23 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 25 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
24 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o | 26 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o |
25 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o | 27 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o |
28 | obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o | ||
29 | obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o | ||
30 | obj-$(CONFIG_TOUCHSCREEN_MAX11801) += max11801_ts.o | ||
26 | obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o | 31 | obj-$(CONFIG_TOUCHSCREEN_MC13783) += mc13783_ts.o |
27 | obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o | 32 | obj-$(CONFIG_TOUCHSCREEN_MCS5000) += mcs5000_ts.o |
28 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o | 33 | obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o |
@@ -34,15 +39,18 @@ obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o | |||
34 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o | 39 | obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o |
35 | obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o | 40 | obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o |
36 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o | 41 | obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o |
37 | obj-$(CONFIG_TOUCHSCREEN_QT602240) += qt602240_ts.o | ||
38 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o | 42 | obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o |
43 | obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o | ||
39 | obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o | 44 | obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o |
45 | obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o | ||
40 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o | 46 | obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o |
41 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o | 47 | obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o |
42 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o | 48 | obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o |
49 | obj-$(CONFIG_TOUCHSCREEN_TSC2005) += tsc2005.o | ||
43 | obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o | 50 | obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o |
44 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o | 51 | obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o |
45 | obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o | 52 | obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o |
53 | obj-$(CONFIG_TOUCHSCREEN_WM831X) += wm831x-ts.o | ||
46 | obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o | 54 | obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o |
47 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o | 55 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o |
48 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o | 56 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o |
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index 5f0221cffef9..714d4e0f9f95 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/input.h> | 42 | #include <linux/input.h> |
43 | #include <linux/interrupt.h> | 43 | #include <linux/interrupt.h> |
44 | #include <linux/pm.h> | ||
44 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
45 | #include <linux/spi/spi.h> | 46 | #include <linux/spi/spi.h> |
46 | #include <linux/spi/ad7877.h> | 47 | #include <linux/spi/ad7877.h> |
@@ -191,13 +192,12 @@ struct ad7877 { | |||
191 | struct spi_message msg; | 192 | struct spi_message msg; |
192 | 193 | ||
193 | struct mutex mutex; | 194 | struct mutex mutex; |
194 | unsigned disabled:1; /* P: mutex */ | 195 | bool disabled; /* P: mutex */ |
195 | unsigned gpio3:1; /* P: mutex */ | 196 | bool gpio3; /* P: mutex */ |
196 | unsigned gpio4:1; /* P: mutex */ | 197 | bool gpio4; /* P: mutex */ |
197 | 198 | ||
198 | spinlock_t lock; | 199 | spinlock_t lock; |
199 | struct timer_list timer; /* P: lock */ | 200 | struct timer_list timer; /* P: lock */ |
200 | unsigned pending:1; /* P: lock */ | ||
201 | 201 | ||
202 | /* | 202 | /* |
203 | * DMA (thus cache coherency maintenance) requires the | 203 | * DMA (thus cache coherency maintenance) requires the |
@@ -206,8 +206,8 @@ struct ad7877 { | |||
206 | u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned; | 206 | u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned; |
207 | }; | 207 | }; |
208 | 208 | ||
209 | static int gpio3; | 209 | static bool gpio3; |
210 | module_param(gpio3, int, 0); | 210 | module_param(gpio3, bool, 0); |
211 | MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3"); | 211 | MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3"); |
212 | 212 | ||
213 | /* | 213 | /* |
@@ -230,6 +230,7 @@ static int ad7877_read(struct spi_device *spi, u16 reg) | |||
230 | AD7877_READADD(reg)); | 230 | AD7877_READADD(reg)); |
231 | req->xfer[0].tx_buf = &req->command; | 231 | req->xfer[0].tx_buf = &req->command; |
232 | req->xfer[0].len = 2; | 232 | req->xfer[0].len = 2; |
233 | req->xfer[0].cs_change = 1; | ||
233 | 234 | ||
234 | req->xfer[1].rx_buf = &req->sample; | 235 | req->xfer[1].rx_buf = &req->sample; |
235 | req->xfer[1].len = 2; | 236 | req->xfer[1].len = 2; |
@@ -295,20 +296,25 @@ static int ad7877_read_adc(struct spi_device *spi, unsigned command) | |||
295 | 296 | ||
296 | req->xfer[0].tx_buf = &req->reset; | 297 | req->xfer[0].tx_buf = &req->reset; |
297 | req->xfer[0].len = 2; | 298 | req->xfer[0].len = 2; |
299 | req->xfer[0].cs_change = 1; | ||
298 | 300 | ||
299 | req->xfer[1].tx_buf = &req->ref_on; | 301 | req->xfer[1].tx_buf = &req->ref_on; |
300 | req->xfer[1].len = 2; | 302 | req->xfer[1].len = 2; |
301 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; | 303 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; |
304 | req->xfer[1].cs_change = 1; | ||
302 | 305 | ||
303 | req->xfer[2].tx_buf = &req->command; | 306 | req->xfer[2].tx_buf = &req->command; |
304 | req->xfer[2].len = 2; | 307 | req->xfer[2].len = 2; |
305 | req->xfer[2].delay_usecs = ts->vref_delay_usecs; | 308 | req->xfer[2].delay_usecs = ts->vref_delay_usecs; |
309 | req->xfer[2].cs_change = 1; | ||
306 | 310 | ||
307 | req->xfer[3].rx_buf = &req->sample; | 311 | req->xfer[3].rx_buf = &req->sample; |
308 | req->xfer[3].len = 2; | 312 | req->xfer[3].len = 2; |
313 | req->xfer[3].cs_change = 1; | ||
309 | 314 | ||
310 | req->xfer[4].tx_buf = &ts->cmd_crtl2; /*REF OFF*/ | 315 | req->xfer[4].tx_buf = &ts->cmd_crtl2; /*REF OFF*/ |
311 | req->xfer[4].len = 2; | 316 | req->xfer[4].len = 2; |
317 | req->xfer[4].cs_change = 1; | ||
312 | 318 | ||
313 | req->xfer[5].tx_buf = &ts->cmd_crtl1; /*DEFAULT*/ | 319 | req->xfer[5].tx_buf = &ts->cmd_crtl1; /*DEFAULT*/ |
314 | req->xfer[5].len = 2; | 320 | req->xfer[5].len = 2; |
@@ -327,7 +333,7 @@ static int ad7877_read_adc(struct spi_device *spi, unsigned command) | |||
327 | return status ? : sample; | 333 | return status ? : sample; |
328 | } | 334 | } |
329 | 335 | ||
330 | static void ad7877_rx(struct ad7877 *ts) | 336 | static int ad7877_process_data(struct ad7877 *ts) |
331 | { | 337 | { |
332 | struct input_dev *input_dev = ts->input; | 338 | struct input_dev *input_dev = ts->input; |
333 | unsigned Rt; | 339 | unsigned Rt; |
@@ -354,11 +360,25 @@ static void ad7877_rx(struct ad7877 *ts) | |||
354 | Rt /= z1; | 360 | Rt /= z1; |
355 | Rt = (Rt + 2047) >> 12; | 361 | Rt = (Rt + 2047) >> 12; |
356 | 362 | ||
363 | /* | ||
364 | * Sample found inconsistent, pressure is beyond | ||
365 | * the maximum. Don't report it to user space. | ||
366 | */ | ||
367 | if (Rt > ts->pressure_max) | ||
368 | return -EINVAL; | ||
369 | |||
370 | if (!timer_pending(&ts->timer)) | ||
371 | input_report_key(input_dev, BTN_TOUCH, 1); | ||
372 | |||
357 | input_report_abs(input_dev, ABS_X, x); | 373 | input_report_abs(input_dev, ABS_X, x); |
358 | input_report_abs(input_dev, ABS_Y, y); | 374 | input_report_abs(input_dev, ABS_Y, y); |
359 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | 375 | input_report_abs(input_dev, ABS_PRESSURE, Rt); |
360 | input_sync(input_dev); | 376 | input_sync(input_dev); |
377 | |||
378 | return 0; | ||
361 | } | 379 | } |
380 | |||
381 | return -EINVAL; | ||
362 | } | 382 | } |
363 | 383 | ||
364 | static inline void ad7877_ts_event_release(struct ad7877 *ts) | 384 | static inline void ad7877_ts_event_release(struct ad7877 *ts) |
@@ -366,72 +386,56 @@ static inline void ad7877_ts_event_release(struct ad7877 *ts) | |||
366 | struct input_dev *input_dev = ts->input; | 386 | struct input_dev *input_dev = ts->input; |
367 | 387 | ||
368 | input_report_abs(input_dev, ABS_PRESSURE, 0); | 388 | input_report_abs(input_dev, ABS_PRESSURE, 0); |
389 | input_report_key(input_dev, BTN_TOUCH, 0); | ||
369 | input_sync(input_dev); | 390 | input_sync(input_dev); |
370 | } | 391 | } |
371 | 392 | ||
372 | static void ad7877_timer(unsigned long handle) | 393 | static void ad7877_timer(unsigned long handle) |
373 | { | 394 | { |
374 | struct ad7877 *ts = (void *)handle; | 395 | struct ad7877 *ts = (void *)handle; |
396 | unsigned long flags; | ||
375 | 397 | ||
398 | spin_lock_irqsave(&ts->lock, flags); | ||
376 | ad7877_ts_event_release(ts); | 399 | ad7877_ts_event_release(ts); |
400 | spin_unlock_irqrestore(&ts->lock, flags); | ||
377 | } | 401 | } |
378 | 402 | ||
379 | static irqreturn_t ad7877_irq(int irq, void *handle) | 403 | static irqreturn_t ad7877_irq(int irq, void *handle) |
380 | { | 404 | { |
381 | struct ad7877 *ts = handle; | 405 | struct ad7877 *ts = handle; |
382 | unsigned long flags; | 406 | unsigned long flags; |
383 | int status; | 407 | int error; |
384 | 408 | ||
385 | /* | 409 | error = spi_sync(ts->spi, &ts->msg); |
386 | * The repeated conversion sequencer controlled by TMR kicked off | 410 | if (error) { |
387 | * too fast. We ignore the last and process the sample sequence | 411 | dev_err(&ts->spi->dev, "spi_sync --> %d\n", error); |
388 | * currently in the queue. It can't be older than 9.4ms, and we | 412 | goto out; |
389 | * need to avoid that ts->msg doesn't get issued twice while in work. | 413 | } |
390 | */ | ||
391 | 414 | ||
392 | spin_lock_irqsave(&ts->lock, flags); | 415 | spin_lock_irqsave(&ts->lock, flags); |
393 | if (!ts->pending) { | 416 | error = ad7877_process_data(ts); |
394 | ts->pending = 1; | 417 | if (!error) |
395 | 418 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | |
396 | status = spi_async(ts->spi, &ts->msg); | ||
397 | if (status) | ||
398 | dev_err(&ts->spi->dev, "spi_sync --> %d\n", status); | ||
399 | } | ||
400 | spin_unlock_irqrestore(&ts->lock, flags); | 419 | spin_unlock_irqrestore(&ts->lock, flags); |
401 | 420 | ||
421 | out: | ||
402 | return IRQ_HANDLED; | 422 | return IRQ_HANDLED; |
403 | } | 423 | } |
404 | 424 | ||
405 | static void ad7877_callback(void *_ts) | ||
406 | { | ||
407 | struct ad7877 *ts = _ts; | ||
408 | |||
409 | spin_lock_irq(&ts->lock); | ||
410 | |||
411 | ad7877_rx(ts); | ||
412 | ts->pending = 0; | ||
413 | mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT); | ||
414 | |||
415 | spin_unlock_irq(&ts->lock); | ||
416 | } | ||
417 | |||
418 | static void ad7877_disable(struct ad7877 *ts) | 425 | static void ad7877_disable(struct ad7877 *ts) |
419 | { | 426 | { |
420 | mutex_lock(&ts->mutex); | 427 | mutex_lock(&ts->mutex); |
421 | 428 | ||
422 | if (!ts->disabled) { | 429 | if (!ts->disabled) { |
423 | ts->disabled = 1; | 430 | ts->disabled = true; |
424 | disable_irq(ts->spi->irq); | 431 | disable_irq(ts->spi->irq); |
425 | 432 | ||
426 | /* Wait for spi_async callback */ | ||
427 | while (ts->pending) | ||
428 | msleep(1); | ||
429 | |||
430 | if (del_timer_sync(&ts->timer)) | 433 | if (del_timer_sync(&ts->timer)) |
431 | ad7877_ts_event_release(ts); | 434 | ad7877_ts_event_release(ts); |
432 | } | 435 | } |
433 | 436 | ||
434 | /* we know the chip's in lowpower mode since we always | 437 | /* |
438 | * We know the chip's in lowpower mode since we always | ||
435 | * leave it that way after every request | 439 | * leave it that way after every request |
436 | */ | 440 | */ |
437 | 441 | ||
@@ -443,7 +447,7 @@ static void ad7877_enable(struct ad7877 *ts) | |||
443 | mutex_lock(&ts->mutex); | 447 | mutex_lock(&ts->mutex); |
444 | 448 | ||
445 | if (ts->disabled) { | 449 | if (ts->disabled) { |
446 | ts->disabled = 0; | 450 | ts->disabled = false; |
447 | enable_irq(ts->spi->irq); | 451 | enable_irq(ts->spi->irq); |
448 | } | 452 | } |
449 | 453 | ||
@@ -453,7 +457,7 @@ static void ad7877_enable(struct ad7877 *ts) | |||
453 | #define SHOW(name) static ssize_t \ | 457 | #define SHOW(name) static ssize_t \ |
454 | name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ | 458 | name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ |
455 | { \ | 459 | { \ |
456 | struct ad7877 *ts = dev_get_drvdata(dev); \ | 460 | struct ad7877 *ts = dev_get_drvdata(dev); \ |
457 | ssize_t v = ad7877_read_adc(ts->spi, \ | 461 | ssize_t v = ad7877_read_adc(ts->spi, \ |
458 | AD7877_READ_CHAN(name)); \ | 462 | AD7877_READ_CHAN(name)); \ |
459 | if (v < 0) \ | 463 | if (v < 0) \ |
@@ -473,7 +477,7 @@ SHOW(temp2) | |||
473 | static ssize_t ad7877_disable_show(struct device *dev, | 477 | static ssize_t ad7877_disable_show(struct device *dev, |
474 | struct device_attribute *attr, char *buf) | 478 | struct device_attribute *attr, char *buf) |
475 | { | 479 | { |
476 | struct ad7877 *ts = dev_get_drvdata(dev); | 480 | struct ad7877 *ts = dev_get_drvdata(dev); |
477 | 481 | ||
478 | return sprintf(buf, "%u\n", ts->disabled); | 482 | return sprintf(buf, "%u\n", ts->disabled); |
479 | } | 483 | } |
@@ -503,7 +507,7 @@ static DEVICE_ATTR(disable, 0664, ad7877_disable_show, ad7877_disable_store); | |||
503 | static ssize_t ad7877_dac_show(struct device *dev, | 507 | static ssize_t ad7877_dac_show(struct device *dev, |
504 | struct device_attribute *attr, char *buf) | 508 | struct device_attribute *attr, char *buf) |
505 | { | 509 | { |
506 | struct ad7877 *ts = dev_get_drvdata(dev); | 510 | struct ad7877 *ts = dev_get_drvdata(dev); |
507 | 511 | ||
508 | return sprintf(buf, "%u\n", ts->dac); | 512 | return sprintf(buf, "%u\n", ts->dac); |
509 | } | 513 | } |
@@ -533,7 +537,7 @@ static DEVICE_ATTR(dac, 0664, ad7877_dac_show, ad7877_dac_store); | |||
533 | static ssize_t ad7877_gpio3_show(struct device *dev, | 537 | static ssize_t ad7877_gpio3_show(struct device *dev, |
534 | struct device_attribute *attr, char *buf) | 538 | struct device_attribute *attr, char *buf) |
535 | { | 539 | { |
536 | struct ad7877 *ts = dev_get_drvdata(dev); | 540 | struct ad7877 *ts = dev_get_drvdata(dev); |
537 | 541 | ||
538 | return sprintf(buf, "%u\n", ts->gpio3); | 542 | return sprintf(buf, "%u\n", ts->gpio3); |
539 | } | 543 | } |
@@ -564,7 +568,7 @@ static DEVICE_ATTR(gpio3, 0664, ad7877_gpio3_show, ad7877_gpio3_store); | |||
564 | static ssize_t ad7877_gpio4_show(struct device *dev, | 568 | static ssize_t ad7877_gpio4_show(struct device *dev, |
565 | struct device_attribute *attr, char *buf) | 569 | struct device_attribute *attr, char *buf) |
566 | { | 570 | { |
567 | struct ad7877 *ts = dev_get_drvdata(dev); | 571 | struct ad7877 *ts = dev_get_drvdata(dev); |
568 | 572 | ||
569 | return sprintf(buf, "%u\n", ts->gpio4); | 573 | return sprintf(buf, "%u\n", ts->gpio4); |
570 | } | 574 | } |
@@ -597,16 +601,35 @@ static struct attribute *ad7877_attributes[] = { | |||
597 | &dev_attr_temp2.attr, | 601 | &dev_attr_temp2.attr, |
598 | &dev_attr_aux1.attr, | 602 | &dev_attr_aux1.attr, |
599 | &dev_attr_aux2.attr, | 603 | &dev_attr_aux2.attr, |
604 | &dev_attr_aux3.attr, | ||
600 | &dev_attr_bat1.attr, | 605 | &dev_attr_bat1.attr, |
601 | &dev_attr_bat2.attr, | 606 | &dev_attr_bat2.attr, |
602 | &dev_attr_disable.attr, | 607 | &dev_attr_disable.attr, |
603 | &dev_attr_dac.attr, | 608 | &dev_attr_dac.attr, |
609 | &dev_attr_gpio3.attr, | ||
604 | &dev_attr_gpio4.attr, | 610 | &dev_attr_gpio4.attr, |
605 | NULL | 611 | NULL |
606 | }; | 612 | }; |
607 | 613 | ||
614 | static mode_t ad7877_attr_is_visible(struct kobject *kobj, | ||
615 | struct attribute *attr, int n) | ||
616 | { | ||
617 | mode_t mode = attr->mode; | ||
618 | |||
619 | if (attr == &dev_attr_aux3.attr) { | ||
620 | if (gpio3) | ||
621 | mode = 0; | ||
622 | } else if (attr == &dev_attr_gpio3.attr) { | ||
623 | if (!gpio3) | ||
624 | mode = 0; | ||
625 | } | ||
626 | |||
627 | return mode; | ||
628 | } | ||
629 | |||
608 | static const struct attribute_group ad7877_attr_group = { | 630 | static const struct attribute_group ad7877_attr_group = { |
609 | .attrs = ad7877_attributes, | 631 | .is_visible = ad7877_attr_is_visible, |
632 | .attrs = ad7877_attributes, | ||
610 | }; | 633 | }; |
611 | 634 | ||
612 | static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) | 635 | static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) |
@@ -635,22 +658,25 @@ static void ad7877_setup_ts_def_msg(struct spi_device *spi, struct ad7877 *ts) | |||
635 | 658 | ||
636 | spi_message_init(m); | 659 | spi_message_init(m); |
637 | 660 | ||
638 | m->complete = ad7877_callback; | ||
639 | m->context = ts; | 661 | m->context = ts; |
640 | 662 | ||
641 | ts->xfer[0].tx_buf = &ts->cmd_crtl1; | 663 | ts->xfer[0].tx_buf = &ts->cmd_crtl1; |
642 | ts->xfer[0].len = 2; | 664 | ts->xfer[0].len = 2; |
665 | ts->xfer[0].cs_change = 1; | ||
643 | 666 | ||
644 | spi_message_add_tail(&ts->xfer[0], m); | 667 | spi_message_add_tail(&ts->xfer[0], m); |
645 | 668 | ||
646 | ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */ | 669 | ts->xfer[1].tx_buf = &ts->cmd_dummy; /* Send ZERO */ |
647 | ts->xfer[1].len = 2; | 670 | ts->xfer[1].len = 2; |
671 | ts->xfer[1].cs_change = 1; | ||
648 | 672 | ||
649 | spi_message_add_tail(&ts->xfer[1], m); | 673 | spi_message_add_tail(&ts->xfer[1], m); |
650 | 674 | ||
651 | for (i = 0; i < 11; i++) { | 675 | for (i = 0; i < AD7877_NR_SENSE; i++) { |
652 | ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i]; | 676 | ts->xfer[i + 2].rx_buf = &ts->conversion_data[AD7877_SEQ_YPOS + i]; |
653 | ts->xfer[i + 2].len = 2; | 677 | ts->xfer[i + 2].len = 2; |
678 | if (i < (AD7877_NR_SENSE - 1)) | ||
679 | ts->xfer[i + 2].cs_change = 1; | ||
654 | spi_message_add_tail(&ts->xfer[i + 2], m); | 680 | spi_message_add_tail(&ts->xfer[i + 2], m); |
655 | } | 681 | } |
656 | } | 682 | } |
@@ -718,6 +744,8 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
718 | input_dev->phys = ts->phys; | 744 | input_dev->phys = ts->phys; |
719 | input_dev->dev.parent = &spi->dev; | 745 | input_dev->dev.parent = &spi->dev; |
720 | 746 | ||
747 | __set_bit(EV_KEY, input_dev->evbit); | ||
748 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
721 | __set_bit(EV_ABS, input_dev->evbit); | 749 | __set_bit(EV_ABS, input_dev->evbit); |
722 | __set_bit(ABS_X, input_dev->absbit); | 750 | __set_bit(ABS_X, input_dev->absbit); |
723 | __set_bit(ABS_Y, input_dev->absbit); | 751 | __set_bit(ABS_Y, input_dev->absbit); |
@@ -752,8 +780,9 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
752 | 780 | ||
753 | /* Request AD7877 /DAV GPIO interrupt */ | 781 | /* Request AD7877 /DAV GPIO interrupt */ |
754 | 782 | ||
755 | err = request_irq(spi->irq, ad7877_irq, IRQF_TRIGGER_FALLING, | 783 | err = request_threaded_irq(spi->irq, NULL, ad7877_irq, |
756 | spi->dev.driver->name, ts); | 784 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
785 | spi->dev.driver->name, ts); | ||
757 | if (err) { | 786 | if (err) { |
758 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 787 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); |
759 | goto err_free_mem; | 788 | goto err_free_mem; |
@@ -763,20 +792,12 @@ static int __devinit ad7877_probe(struct spi_device *spi) | |||
763 | if (err) | 792 | if (err) |
764 | goto err_free_irq; | 793 | goto err_free_irq; |
765 | 794 | ||
766 | err = device_create_file(&spi->dev, | ||
767 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
768 | if (err) | ||
769 | goto err_remove_attr_group; | ||
770 | |||
771 | err = input_register_device(input_dev); | 795 | err = input_register_device(input_dev); |
772 | if (err) | 796 | if (err) |
773 | goto err_remove_attr; | 797 | goto err_remove_attr_group; |
774 | 798 | ||
775 | return 0; | 799 | return 0; |
776 | 800 | ||
777 | err_remove_attr: | ||
778 | device_remove_file(&spi->dev, | ||
779 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
780 | err_remove_attr_group: | 801 | err_remove_attr_group: |
781 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); | 802 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); |
782 | err_free_irq: | 803 | err_free_irq: |
@@ -790,11 +811,9 @@ err_free_mem: | |||
790 | 811 | ||
791 | static int __devexit ad7877_remove(struct spi_device *spi) | 812 | static int __devexit ad7877_remove(struct spi_device *spi) |
792 | { | 813 | { |
793 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | 814 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); |
794 | 815 | ||
795 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); | 816 | sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); |
796 | device_remove_file(&spi->dev, | ||
797 | gpio3 ? &dev_attr_gpio3 : &dev_attr_aux3); | ||
798 | 817 | ||
799 | ad7877_disable(ts); | 818 | ad7877_disable(ts); |
800 | free_irq(ts->spi->irq, ts); | 819 | free_irq(ts->spi->irq, ts); |
@@ -808,39 +827,37 @@ static int __devexit ad7877_remove(struct spi_device *spi) | |||
808 | return 0; | 827 | return 0; |
809 | } | 828 | } |
810 | 829 | ||
811 | #ifdef CONFIG_PM | 830 | #ifdef CONFIG_PM_SLEEP |
812 | static int ad7877_suspend(struct spi_device *spi, pm_message_t message) | 831 | static int ad7877_suspend(struct device *dev) |
813 | { | 832 | { |
814 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | 833 | struct ad7877 *ts = dev_get_drvdata(dev); |
815 | 834 | ||
816 | ad7877_disable(ts); | 835 | ad7877_disable(ts); |
817 | 836 | ||
818 | return 0; | 837 | return 0; |
819 | } | 838 | } |
820 | 839 | ||
821 | static int ad7877_resume(struct spi_device *spi) | 840 | static int ad7877_resume(struct device *dev) |
822 | { | 841 | { |
823 | struct ad7877 *ts = dev_get_drvdata(&spi->dev); | 842 | struct ad7877 *ts = dev_get_drvdata(dev); |
824 | 843 | ||
825 | ad7877_enable(ts); | 844 | ad7877_enable(ts); |
826 | 845 | ||
827 | return 0; | 846 | return 0; |
828 | } | 847 | } |
829 | #else | ||
830 | #define ad7877_suspend NULL | ||
831 | #define ad7877_resume NULL | ||
832 | #endif | 848 | #endif |
833 | 849 | ||
850 | static SIMPLE_DEV_PM_OPS(ad7877_pm, ad7877_suspend, ad7877_resume); | ||
851 | |||
834 | static struct spi_driver ad7877_driver = { | 852 | static struct spi_driver ad7877_driver = { |
835 | .driver = { | 853 | .driver = { |
836 | .name = "ad7877", | 854 | .name = "ad7877", |
837 | .bus = &spi_bus_type, | 855 | .bus = &spi_bus_type, |
838 | .owner = THIS_MODULE, | 856 | .owner = THIS_MODULE, |
857 | .pm = &ad7877_pm, | ||
839 | }, | 858 | }, |
840 | .probe = ad7877_probe, | 859 | .probe = ad7877_probe, |
841 | .remove = __devexit_p(ad7877_remove), | 860 | .remove = __devexit_p(ad7877_remove), |
842 | .suspend = ad7877_suspend, | ||
843 | .resume = ad7877_resume, | ||
844 | }; | 861 | }; |
845 | 862 | ||
846 | static int __init ad7877_init(void) | 863 | static int __init ad7877_init(void) |
diff --git a/drivers/input/touchscreen/ad7879-i2c.c b/drivers/input/touchscreen/ad7879-i2c.c index d82a38ee9a3e..4e4e58cec6c8 100644 --- a/drivers/input/touchscreen/ad7879-i2c.c +++ b/drivers/input/touchscreen/ad7879-i2c.c | |||
@@ -10,14 +10,16 @@ | |||
10 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/pm.h> | ||
13 | 14 | ||
14 | #include "ad7879.h" | 15 | #include "ad7879.h" |
15 | 16 | ||
16 | #define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */ | 17 | #define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */ |
17 | 18 | ||
18 | #ifdef CONFIG_PM | 19 | #ifdef CONFIG_PM |
19 | static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message) | 20 | static int ad7879_i2c_suspend(struct device *dev) |
20 | { | 21 | { |
22 | struct i2c_client *client = to_i2c_client(dev); | ||
21 | struct ad7879 *ts = i2c_get_clientdata(client); | 23 | struct ad7879 *ts = i2c_get_clientdata(client); |
22 | 24 | ||
23 | ad7879_suspend(ts); | 25 | ad7879_suspend(ts); |
@@ -25,17 +27,17 @@ static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message) | |||
25 | return 0; | 27 | return 0; |
26 | } | 28 | } |
27 | 29 | ||
28 | static int ad7879_i2c_resume(struct i2c_client *client) | 30 | static int ad7879_i2c_resume(struct device *dev) |
29 | { | 31 | { |
32 | struct i2c_client *client = to_i2c_client(dev); | ||
30 | struct ad7879 *ts = i2c_get_clientdata(client); | 33 | struct ad7879 *ts = i2c_get_clientdata(client); |
31 | 34 | ||
32 | ad7879_resume(ts); | 35 | ad7879_resume(ts); |
33 | 36 | ||
34 | return 0; | 37 | return 0; |
35 | } | 38 | } |
36 | #else | 39 | |
37 | # define ad7879_i2c_suspend NULL | 40 | static SIMPLE_DEV_PM_OPS(ad7879_i2c_pm, ad7879_i2c_suspend, ad7879_i2c_resume); |
38 | # define ad7879_i2c_resume NULL | ||
39 | #endif | 41 | #endif |
40 | 42 | ||
41 | /* All registers are word-sized. | 43 | /* All registers are word-sized. |
@@ -117,11 +119,12 @@ static struct i2c_driver ad7879_i2c_driver = { | |||
117 | .driver = { | 119 | .driver = { |
118 | .name = "ad7879", | 120 | .name = "ad7879", |
119 | .owner = THIS_MODULE, | 121 | .owner = THIS_MODULE, |
122 | #ifdef CONFIG_PM | ||
123 | .pm = &ad7879_i2c_pm, | ||
124 | #endif | ||
120 | }, | 125 | }, |
121 | .probe = ad7879_i2c_probe, | 126 | .probe = ad7879_i2c_probe, |
122 | .remove = __devexit_p(ad7879_i2c_remove), | 127 | .remove = __devexit_p(ad7879_i2c_remove), |
123 | .suspend = ad7879_i2c_suspend, | ||
124 | .resume = ad7879_i2c_resume, | ||
125 | .id_table = ad7879_id, | 128 | .id_table = ad7879_id, |
126 | }; | 129 | }; |
127 | 130 | ||
diff --git a/drivers/input/touchscreen/ad7879-spi.c b/drivers/input/touchscreen/ad7879-spi.c index 59c6e68c4325..ddf732f3cafc 100644 --- a/drivers/input/touchscreen/ad7879-spi.c +++ b/drivers/input/touchscreen/ad7879-spi.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/input.h> /* BUS_SPI */ | 9 | #include <linux/input.h> /* BUS_SPI */ |
10 | #include <linux/pm.h> | ||
10 | #include <linux/spi/spi.h> | 11 | #include <linux/spi/spi.h> |
11 | 12 | ||
12 | #include "ad7879.h" | 13 | #include "ad7879.h" |
@@ -20,9 +21,10 @@ | |||
20 | #define AD7879_WRITECMD(reg) (AD7879_CMD(reg)) | 21 | #define AD7879_WRITECMD(reg) (AD7879_CMD(reg)) |
21 | #define AD7879_READCMD(reg) (AD7879_CMD(reg) | AD7879_CMD_READ) | 22 | #define AD7879_READCMD(reg) (AD7879_CMD(reg) | AD7879_CMD_READ) |
22 | 23 | ||
23 | #ifdef CONFIG_PM | 24 | #ifdef CONFIG_PM_SLEEP |
24 | static int ad7879_spi_suspend(struct spi_device *spi, pm_message_t message) | 25 | static int ad7879_spi_suspend(struct device *dev) |
25 | { | 26 | { |
27 | struct spi_device *spi = to_spi_device(dev); | ||
26 | struct ad7879 *ts = spi_get_drvdata(spi); | 28 | struct ad7879 *ts = spi_get_drvdata(spi); |
27 | 29 | ||
28 | ad7879_suspend(ts); | 30 | ad7879_suspend(ts); |
@@ -30,19 +32,19 @@ static int ad7879_spi_suspend(struct spi_device *spi, pm_message_t message) | |||
30 | return 0; | 32 | return 0; |
31 | } | 33 | } |
32 | 34 | ||
33 | static int ad7879_spi_resume(struct spi_device *spi) | 35 | static int ad7879_spi_resume(struct device *dev) |
34 | { | 36 | { |
37 | struct spi_device *spi = to_spi_device(dev); | ||
35 | struct ad7879 *ts = spi_get_drvdata(spi); | 38 | struct ad7879 *ts = spi_get_drvdata(spi); |
36 | 39 | ||
37 | ad7879_resume(ts); | 40 | ad7879_resume(ts); |
38 | 41 | ||
39 | return 0; | 42 | return 0; |
40 | } | 43 | } |
41 | #else | ||
42 | # define ad7879_spi_suspend NULL | ||
43 | # define ad7879_spi_resume NULL | ||
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | static SIMPLE_DEV_PM_OPS(ad7879_spi_pm, ad7879_spi_suspend, ad7879_spi_resume); | ||
47 | |||
46 | /* | 48 | /* |
47 | * ad7879_read/write are only used for initial setup and for sysfs controls. | 49 | * ad7879_read/write are only used for initial setup and for sysfs controls. |
48 | * The main traffic is done in ad7879_collect(). | 50 | * The main traffic is done in ad7879_collect(). |
@@ -173,11 +175,10 @@ static struct spi_driver ad7879_spi_driver = { | |||
173 | .name = "ad7879", | 175 | .name = "ad7879", |
174 | .bus = &spi_bus_type, | 176 | .bus = &spi_bus_type, |
175 | .owner = THIS_MODULE, | 177 | .owner = THIS_MODULE, |
178 | .pm = &ad7879_spi_pm, | ||
176 | }, | 179 | }, |
177 | .probe = ad7879_spi_probe, | 180 | .probe = ad7879_spi_probe, |
178 | .remove = __devexit_p(ad7879_spi_remove), | 181 | .remove = __devexit_p(ad7879_spi_remove), |
179 | .suspend = ad7879_spi_suspend, | ||
180 | .resume = ad7879_spi_resume, | ||
181 | }; | 182 | }; |
182 | 183 | ||
183 | static int __init ad7879_spi_init(void) | 184 | static int __init ad7879_spi_init(void) |
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index ba6f0bd1e762..bc3b5187f3a3 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c | |||
@@ -129,6 +129,9 @@ struct ad7879 { | |||
129 | u16 cmd_crtl1; | 129 | u16 cmd_crtl1; |
130 | u16 cmd_crtl2; | 130 | u16 cmd_crtl2; |
131 | u16 cmd_crtl3; | 131 | u16 cmd_crtl3; |
132 | int x; | ||
133 | int y; | ||
134 | int Rt; | ||
132 | }; | 135 | }; |
133 | 136 | ||
134 | static int ad7879_read(struct ad7879 *ts, u8 reg) | 137 | static int ad7879_read(struct ad7879 *ts, u8 reg) |
@@ -175,13 +178,32 @@ static int ad7879_report(struct ad7879 *ts) | |||
175 | Rt /= z1; | 178 | Rt /= z1; |
176 | Rt = (Rt + 2047) >> 12; | 179 | Rt = (Rt + 2047) >> 12; |
177 | 180 | ||
178 | if (!timer_pending(&ts->timer)) | 181 | /* |
182 | * Sample found inconsistent, pressure is beyond | ||
183 | * the maximum. Don't report it to user space. | ||
184 | */ | ||
185 | if (Rt > ts->pressure_max) | ||
186 | return -EINVAL; | ||
187 | |||
188 | /* | ||
189 | * Note that we delay reporting events by one sample. | ||
190 | * This is done to avoid reporting last sample of the | ||
191 | * touch sequence, which may be incomplete if finger | ||
192 | * leaves the surface before last reading is taken. | ||
193 | */ | ||
194 | if (timer_pending(&ts->timer)) { | ||
195 | /* Touch continues */ | ||
179 | input_report_key(input_dev, BTN_TOUCH, 1); | 196 | input_report_key(input_dev, BTN_TOUCH, 1); |
197 | input_report_abs(input_dev, ABS_X, ts->x); | ||
198 | input_report_abs(input_dev, ABS_Y, ts->y); | ||
199 | input_report_abs(input_dev, ABS_PRESSURE, ts->Rt); | ||
200 | input_sync(input_dev); | ||
201 | } | ||
202 | |||
203 | ts->x = x; | ||
204 | ts->y = y; | ||
205 | ts->Rt = Rt; | ||
180 | 206 | ||
181 | input_report_abs(input_dev, ABS_X, x); | ||
182 | input_report_abs(input_dev, ABS_Y, y); | ||
183 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | ||
184 | input_sync(input_dev); | ||
185 | return 0; | 207 | return 0; |
186 | } | 208 | } |
187 | 209 | ||
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 16031933a8f6..5196861b86ef 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -17,13 +17,16 @@ | |||
17 | * it under the terms of the GNU General Public License version 2 as | 17 | * it under the terms of the GNU General Public License version 2 as |
18 | * published by the Free Software Foundation. | 18 | * published by the Free Software Foundation. |
19 | */ | 19 | */ |
20 | #include <linux/types.h> | ||
20 | #include <linux/hwmon.h> | 21 | #include <linux/hwmon.h> |
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
22 | #include <linux/err.h> | 23 | #include <linux/err.h> |
24 | #include <linux/sched.h> | ||
23 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
24 | #include <linux/input.h> | 26 | #include <linux/input.h> |
25 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
26 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/pm.h> | ||
27 | #include <linux/gpio.h> | 30 | #include <linux/gpio.h> |
28 | #include <linux/spi/spi.h> | 31 | #include <linux/spi/spi.h> |
29 | #include <linux/spi/ads7846.h> | 32 | #include <linux/spi/ads7846.h> |
@@ -52,22 +55,23 @@ | |||
52 | * files. | 55 | * files. |
53 | */ | 56 | */ |
54 | 57 | ||
55 | #define TS_POLL_DELAY (1 * 1000000) /* ns delay before the first sample */ | 58 | #define TS_POLL_DELAY 1 /* ms delay before the first sample */ |
56 | #define TS_POLL_PERIOD (5 * 1000000) /* ns delay between samples */ | 59 | #define TS_POLL_PERIOD 5 /* ms delay between samples */ |
57 | 60 | ||
58 | /* this driver doesn't aim at the peak continuous sample rate */ | 61 | /* this driver doesn't aim at the peak continuous sample rate */ |
59 | #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) | 62 | #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) |
60 | 63 | ||
61 | struct ts_event { | 64 | struct ts_event { |
62 | /* For portability, we can't read 12 bit values using SPI (which | 65 | /* |
63 | * would make the controller deliver them as native byteorder u16 | 66 | * For portability, we can't read 12 bit values using SPI (which |
67 | * would make the controller deliver them as native byte order u16 | ||
64 | * with msbs zeroed). Instead, we read them as two 8-bit values, | 68 | * with msbs zeroed). Instead, we read them as two 8-bit values, |
65 | * *** WHICH NEED BYTESWAPPING *** and range adjustment. | 69 | * *** WHICH NEED BYTESWAPPING *** and range adjustment. |
66 | */ | 70 | */ |
67 | u16 x; | 71 | u16 x; |
68 | u16 y; | 72 | u16 y; |
69 | u16 z1, z2; | 73 | u16 z1, z2; |
70 | int ignore; | 74 | bool ignore; |
71 | u8 x_buf[3]; | 75 | u8 x_buf[3]; |
72 | u8 y_buf[3]; | 76 | u8 y_buf[3]; |
73 | }; | 77 | }; |
@@ -105,13 +109,17 @@ struct ads7846 { | |||
105 | u16 pressure_max; | 109 | u16 pressure_max; |
106 | 110 | ||
107 | bool swap_xy; | 111 | bool swap_xy; |
112 | bool use_internal; | ||
108 | 113 | ||
109 | struct ads7846_packet *packet; | 114 | struct ads7846_packet *packet; |
110 | 115 | ||
111 | struct spi_transfer xfer[18]; | 116 | struct spi_transfer xfer[18]; |
112 | struct spi_message msg[5]; | 117 | struct spi_message msg[5]; |
113 | struct spi_message *last_msg; | 118 | int msg_count; |
114 | int msg_idx; | 119 | wait_queue_head_t wait; |
120 | |||
121 | bool pendown; | ||
122 | |||
115 | int read_cnt; | 123 | int read_cnt; |
116 | int read_rep; | 124 | int read_rep; |
117 | int last_read; | 125 | int last_read; |
@@ -122,14 +130,10 @@ struct ads7846 { | |||
122 | 130 | ||
123 | u16 penirq_recheck_delay_usecs; | 131 | u16 penirq_recheck_delay_usecs; |
124 | 132 | ||
125 | spinlock_t lock; | 133 | struct mutex lock; |
126 | struct hrtimer timer; | 134 | bool stopped; /* P: lock */ |
127 | unsigned pendown:1; /* P: lock */ | 135 | bool disabled; /* P: lock */ |
128 | unsigned pending:1; /* P: lock */ | 136 | bool suspended; /* P: lock */ |
129 | // FIXME remove "irq_disabled" | ||
130 | unsigned irq_disabled:1; /* P: lock */ | ||
131 | unsigned disabled:1; | ||
132 | unsigned is_suspended:1; | ||
133 | 137 | ||
134 | int (*filter)(void *data, int data_idx, int *val); | 138 | int (*filter)(void *data, int data_idx, int *val); |
135 | void *filter_data; | 139 | void *filter_data; |
@@ -165,7 +169,7 @@ struct ads7846 { | |||
165 | #define ADS_12_BIT (0 << 3) | 169 | #define ADS_12_BIT (0 << 3) |
166 | #define ADS_SER (1 << 2) /* non-differential */ | 170 | #define ADS_SER (1 << 2) /* non-differential */ |
167 | #define ADS_DFR (0 << 2) /* differential */ | 171 | #define ADS_DFR (0 << 2) /* differential */ |
168 | #define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */ | 172 | #define ADS_PD10_PDOWN (0 << 0) /* low power mode + penirq */ |
169 | #define ADS_PD10_ADC_ON (1 << 0) /* ADC on */ | 173 | #define ADS_PD10_ADC_ON (1 << 0) /* ADC on */ |
170 | #define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */ | 174 | #define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */ |
171 | #define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */ | 175 | #define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */ |
@@ -193,6 +197,78 @@ struct ads7846 { | |||
193 | #define REF_ON (READ_12BIT_DFR(x, 1, 1)) | 197 | #define REF_ON (READ_12BIT_DFR(x, 1, 1)) |
194 | #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) | 198 | #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) |
195 | 199 | ||
200 | /* Must be called with ts->lock held */ | ||
201 | static void ads7846_stop(struct ads7846 *ts) | ||
202 | { | ||
203 | if (!ts->disabled && !ts->suspended) { | ||
204 | /* Signal IRQ thread to stop polling and disable the handler. */ | ||
205 | ts->stopped = true; | ||
206 | mb(); | ||
207 | wake_up(&ts->wait); | ||
208 | disable_irq(ts->spi->irq); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /* Must be called with ts->lock held */ | ||
213 | static void ads7846_restart(struct ads7846 *ts) | ||
214 | { | ||
215 | if (!ts->disabled && !ts->suspended) { | ||
216 | /* Tell IRQ thread that it may poll the device. */ | ||
217 | ts->stopped = false; | ||
218 | mb(); | ||
219 | enable_irq(ts->spi->irq); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /* Must be called with ts->lock held */ | ||
224 | static void __ads7846_disable(struct ads7846 *ts) | ||
225 | { | ||
226 | ads7846_stop(ts); | ||
227 | regulator_disable(ts->reg); | ||
228 | |||
229 | /* | ||
230 | * We know the chip's in low power mode since we always | ||
231 | * leave it that way after every request | ||
232 | */ | ||
233 | } | ||
234 | |||
235 | /* Must be called with ts->lock held */ | ||
236 | static void __ads7846_enable(struct ads7846 *ts) | ||
237 | { | ||
238 | regulator_enable(ts->reg); | ||
239 | ads7846_restart(ts); | ||
240 | } | ||
241 | |||
242 | static void ads7846_disable(struct ads7846 *ts) | ||
243 | { | ||
244 | mutex_lock(&ts->lock); | ||
245 | |||
246 | if (!ts->disabled) { | ||
247 | |||
248 | if (!ts->suspended) | ||
249 | __ads7846_disable(ts); | ||
250 | |||
251 | ts->disabled = true; | ||
252 | } | ||
253 | |||
254 | mutex_unlock(&ts->lock); | ||
255 | } | ||
256 | |||
257 | static void ads7846_enable(struct ads7846 *ts) | ||
258 | { | ||
259 | mutex_lock(&ts->lock); | ||
260 | |||
261 | if (ts->disabled) { | ||
262 | |||
263 | ts->disabled = false; | ||
264 | |||
265 | if (!ts->suspended) | ||
266 | __ads7846_enable(ts); | ||
267 | } | ||
268 | |||
269 | mutex_unlock(&ts->lock); | ||
270 | } | ||
271 | |||
196 | /*--------------------------------------------------------------------------*/ | 272 | /*--------------------------------------------------------------------------*/ |
197 | 273 | ||
198 | /* | 274 | /* |
@@ -206,46 +282,41 @@ struct ser_req { | |||
206 | u8 command; | 282 | u8 command; |
207 | u8 ref_off; | 283 | u8 ref_off; |
208 | u16 scratch; | 284 | u16 scratch; |
209 | __be16 sample; | ||
210 | struct spi_message msg; | 285 | struct spi_message msg; |
211 | struct spi_transfer xfer[6]; | 286 | struct spi_transfer xfer[6]; |
287 | /* | ||
288 | * DMA (thus cache coherency maintenance) requires the | ||
289 | * transfer buffers to live in their own cache lines. | ||
290 | */ | ||
291 | __be16 sample ____cacheline_aligned; | ||
212 | }; | 292 | }; |
213 | 293 | ||
214 | struct ads7845_ser_req { | 294 | struct ads7845_ser_req { |
215 | u8 command[3]; | 295 | u8 command[3]; |
216 | u8 pwrdown[3]; | ||
217 | u8 sample[3]; | ||
218 | struct spi_message msg; | 296 | struct spi_message msg; |
219 | struct spi_transfer xfer[2]; | 297 | struct spi_transfer xfer[2]; |
298 | /* | ||
299 | * DMA (thus cache coherency maintenance) requires the | ||
300 | * transfer buffers to live in their own cache lines. | ||
301 | */ | ||
302 | u8 sample[3] ____cacheline_aligned; | ||
220 | }; | 303 | }; |
221 | 304 | ||
222 | static void ads7846_enable(struct ads7846 *ts); | ||
223 | static void ads7846_disable(struct ads7846 *ts); | ||
224 | |||
225 | static int device_suspended(struct device *dev) | ||
226 | { | ||
227 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
228 | return ts->is_suspended || ts->disabled; | ||
229 | } | ||
230 | |||
231 | static int ads7846_read12_ser(struct device *dev, unsigned command) | 305 | static int ads7846_read12_ser(struct device *dev, unsigned command) |
232 | { | 306 | { |
233 | struct spi_device *spi = to_spi_device(dev); | 307 | struct spi_device *spi = to_spi_device(dev); |
234 | struct ads7846 *ts = dev_get_drvdata(dev); | 308 | struct ads7846 *ts = dev_get_drvdata(dev); |
235 | struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); | 309 | struct ser_req *req; |
236 | int status; | 310 | int status; |
237 | int use_internal; | ||
238 | 311 | ||
312 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
239 | if (!req) | 313 | if (!req) |
240 | return -ENOMEM; | 314 | return -ENOMEM; |
241 | 315 | ||
242 | spi_message_init(&req->msg); | 316 | spi_message_init(&req->msg); |
243 | 317 | ||
244 | /* FIXME boards with ads7846 might use external vref instead ... */ | ||
245 | use_internal = (ts->model == 7846); | ||
246 | |||
247 | /* maybe turn on internal vREF, and let it settle */ | 318 | /* maybe turn on internal vREF, and let it settle */ |
248 | if (use_internal) { | 319 | if (ts->use_internal) { |
249 | req->ref_on = REF_ON; | 320 | req->ref_on = REF_ON; |
250 | req->xfer[0].tx_buf = &req->ref_on; | 321 | req->xfer[0].tx_buf = &req->ref_on; |
251 | req->xfer[0].len = 1; | 322 | req->xfer[0].len = 1; |
@@ -257,8 +328,14 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
257 | /* for 1uF, settle for 800 usec; no cap, 100 usec. */ | 328 | /* for 1uF, settle for 800 usec; no cap, 100 usec. */ |
258 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; | 329 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; |
259 | spi_message_add_tail(&req->xfer[1], &req->msg); | 330 | spi_message_add_tail(&req->xfer[1], &req->msg); |
331 | |||
332 | /* Enable reference voltage */ | ||
333 | command |= ADS_PD10_REF_ON; | ||
260 | } | 334 | } |
261 | 335 | ||
336 | /* Enable ADC in every case */ | ||
337 | command |= ADS_PD10_ADC_ON; | ||
338 | |||
262 | /* take sample */ | 339 | /* take sample */ |
263 | req->command = (u8) command; | 340 | req->command = (u8) command; |
264 | req->xfer[2].tx_buf = &req->command; | 341 | req->xfer[2].tx_buf = &req->command; |
@@ -282,11 +359,11 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
282 | CS_CHANGE(req->xfer[5]); | 359 | CS_CHANGE(req->xfer[5]); |
283 | spi_message_add_tail(&req->xfer[5], &req->msg); | 360 | spi_message_add_tail(&req->xfer[5], &req->msg); |
284 | 361 | ||
285 | ts->irq_disabled = 1; | 362 | mutex_lock(&ts->lock); |
286 | disable_irq(spi->irq); | 363 | ads7846_stop(ts); |
287 | status = spi_sync(spi, &req->msg); | 364 | status = spi_sync(spi, &req->msg); |
288 | ts->irq_disabled = 0; | 365 | ads7846_restart(ts); |
289 | enable_irq(spi->irq); | 366 | mutex_unlock(&ts->lock); |
290 | 367 | ||
291 | if (status == 0) { | 368 | if (status == 0) { |
292 | /* on-wire is a must-ignore bit, a BE12 value, then padding */ | 369 | /* on-wire is a must-ignore bit, a BE12 value, then padding */ |
@@ -301,11 +378,12 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
301 | 378 | ||
302 | static int ads7845_read12_ser(struct device *dev, unsigned command) | 379 | static int ads7845_read12_ser(struct device *dev, unsigned command) |
303 | { | 380 | { |
304 | struct spi_device *spi = to_spi_device(dev); | 381 | struct spi_device *spi = to_spi_device(dev); |
305 | struct ads7846 *ts = dev_get_drvdata(dev); | 382 | struct ads7846 *ts = dev_get_drvdata(dev); |
306 | struct ads7845_ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); | 383 | struct ads7845_ser_req *req; |
307 | int status; | 384 | int status; |
308 | 385 | ||
386 | req = kzalloc(sizeof *req, GFP_KERNEL); | ||
309 | if (!req) | 387 | if (!req) |
310 | return -ENOMEM; | 388 | return -ENOMEM; |
311 | 389 | ||
@@ -317,11 +395,11 @@ static int ads7845_read12_ser(struct device *dev, unsigned command) | |||
317 | req->xfer[0].len = 3; | 395 | req->xfer[0].len = 3; |
318 | spi_message_add_tail(&req->xfer[0], &req->msg); | 396 | spi_message_add_tail(&req->xfer[0], &req->msg); |
319 | 397 | ||
320 | ts->irq_disabled = 1; | 398 | mutex_lock(&ts->lock); |
321 | disable_irq(spi->irq); | 399 | ads7846_stop(ts); |
322 | status = spi_sync(spi, &req->msg); | 400 | status = spi_sync(spi, &req->msg); |
323 | ts->irq_disabled = 0; | 401 | ads7846_restart(ts); |
324 | enable_irq(spi->irq); | 402 | mutex_unlock(&ts->lock); |
325 | 403 | ||
326 | if (status == 0) { | 404 | if (status == 0) { |
327 | /* BE12 value, then padding */ | 405 | /* BE12 value, then padding */ |
@@ -341,7 +419,7 @@ name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ | |||
341 | { \ | 419 | { \ |
342 | struct ads7846 *ts = dev_get_drvdata(dev); \ | 420 | struct ads7846 *ts = dev_get_drvdata(dev); \ |
343 | ssize_t v = ads7846_read12_ser(dev, \ | 421 | ssize_t v = ads7846_read12_ser(dev, \ |
344 | READ_12BIT_SER(var) | ADS_PD10_ALL_ON); \ | 422 | READ_12BIT_SER(var)); \ |
345 | if (v < 0) \ | 423 | if (v < 0) \ |
346 | return v; \ | 424 | return v; \ |
347 | return sprintf(buf, "%u\n", adjust(ts, v)); \ | 425 | return sprintf(buf, "%u\n", adjust(ts, v)); \ |
@@ -374,6 +452,7 @@ static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v) | |||
374 | /* external resistors may scale vAUX into 0..vREF */ | 452 | /* external resistors may scale vAUX into 0..vREF */ |
375 | retval *= ts->vref_mv; | 453 | retval *= ts->vref_mv; |
376 | retval = retval >> 12; | 454 | retval = retval >> 12; |
455 | |||
377 | return retval; | 456 | return retval; |
378 | } | 457 | } |
379 | 458 | ||
@@ -384,13 +463,13 @@ static inline unsigned vbatt_adjust(struct ads7846 *ts, ssize_t v) | |||
384 | /* ads7846 has a resistor ladder to scale this signal down */ | 463 | /* ads7846 has a resistor ladder to scale this signal down */ |
385 | if (ts->model == 7846) | 464 | if (ts->model == 7846) |
386 | retval *= 4; | 465 | retval *= 4; |
466 | |||
387 | return retval; | 467 | return retval; |
388 | } | 468 | } |
389 | 469 | ||
390 | SHOW(in0_input, vaux, vaux_adjust) | 470 | SHOW(in0_input, vaux, vaux_adjust) |
391 | SHOW(in1_input, vbatt, vbatt_adjust) | 471 | SHOW(in1_input, vbatt, vbatt_adjust) |
392 | 472 | ||
393 | |||
394 | static struct attribute *ads7846_attributes[] = { | 473 | static struct attribute *ads7846_attributes[] = { |
395 | &dev_attr_temp0.attr, | 474 | &dev_attr_temp0.attr, |
396 | &dev_attr_temp1.attr, | 475 | &dev_attr_temp1.attr, |
@@ -433,6 +512,7 @@ static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) | |||
433 | if (!ts->vref_mv) { | 512 | if (!ts->vref_mv) { |
434 | dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); | 513 | dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); |
435 | ts->vref_mv = 2500; | 514 | ts->vref_mv = 2500; |
515 | ts->use_internal = true; | ||
436 | } | 516 | } |
437 | break; | 517 | break; |
438 | case 7845: | 518 | case 7845: |
@@ -498,17 +578,12 @@ static inline void ads784x_hwmon_unregister(struct spi_device *spi, | |||
498 | } | 578 | } |
499 | #endif | 579 | #endif |
500 | 580 | ||
501 | static int is_pen_down(struct device *dev) | ||
502 | { | ||
503 | struct ads7846 *ts = dev_get_drvdata(dev); | ||
504 | |||
505 | return ts->pendown; | ||
506 | } | ||
507 | |||
508 | static ssize_t ads7846_pen_down_show(struct device *dev, | 581 | static ssize_t ads7846_pen_down_show(struct device *dev, |
509 | struct device_attribute *attr, char *buf) | 582 | struct device_attribute *attr, char *buf) |
510 | { | 583 | { |
511 | return sprintf(buf, "%u\n", is_pen_down(dev)); | 584 | struct ads7846 *ts = dev_get_drvdata(dev); |
585 | |||
586 | return sprintf(buf, "%u\n", ts->pendown); | ||
512 | } | 587 | } |
513 | 588 | ||
514 | static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); | 589 | static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); |
@@ -516,7 +591,7 @@ static DEVICE_ATTR(pen_down, S_IRUGO, ads7846_pen_down_show, NULL); | |||
516 | static ssize_t ads7846_disable_show(struct device *dev, | 591 | static ssize_t ads7846_disable_show(struct device *dev, |
517 | struct device_attribute *attr, char *buf) | 592 | struct device_attribute *attr, char *buf) |
518 | { | 593 | { |
519 | struct ads7846 *ts = dev_get_drvdata(dev); | 594 | struct ads7846 *ts = dev_get_drvdata(dev); |
520 | 595 | ||
521 | return sprintf(buf, "%u\n", ts->disabled); | 596 | return sprintf(buf, "%u\n", ts->disabled); |
522 | } | 597 | } |
@@ -531,15 +606,11 @@ static ssize_t ads7846_disable_store(struct device *dev, | |||
531 | if (strict_strtoul(buf, 10, &i)) | 606 | if (strict_strtoul(buf, 10, &i)) |
532 | return -EINVAL; | 607 | return -EINVAL; |
533 | 608 | ||
534 | spin_lock_irq(&ts->lock); | ||
535 | |||
536 | if (i) | 609 | if (i) |
537 | ads7846_disable(ts); | 610 | ads7846_disable(ts); |
538 | else | 611 | else |
539 | ads7846_enable(ts); | 612 | ads7846_enable(ts); |
540 | 613 | ||
541 | spin_unlock_irq(&ts->lock); | ||
542 | |||
543 | return count; | 614 | return count; |
544 | } | 615 | } |
545 | 616 | ||
@@ -569,23 +640,141 @@ static void null_wait_for_sync(void) | |||
569 | { | 640 | { |
570 | } | 641 | } |
571 | 642 | ||
572 | /* | 643 | static int ads7846_debounce_filter(void *ads, int data_idx, int *val) |
573 | * PENIRQ only kicks the timer. The timer only reissues the SPI transfer, | 644 | { |
574 | * to retrieve touchscreen status. | 645 | struct ads7846 *ts = ads; |
575 | * | 646 | |
576 | * The SPI transfer completion callback does the real work. It reports | 647 | if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { |
577 | * touchscreen events and reactivates the timer (or IRQ) as appropriate. | 648 | /* Start over collecting consistent readings. */ |
578 | */ | 649 | ts->read_rep = 0; |
650 | /* | ||
651 | * Repeat it, if this was the first read or the read | ||
652 | * wasn't consistent enough. | ||
653 | */ | ||
654 | if (ts->read_cnt < ts->debounce_max) { | ||
655 | ts->last_read = *val; | ||
656 | ts->read_cnt++; | ||
657 | return ADS7846_FILTER_REPEAT; | ||
658 | } else { | ||
659 | /* | ||
660 | * Maximum number of debouncing reached and still | ||
661 | * not enough number of consistent readings. Abort | ||
662 | * the whole sample, repeat it in the next sampling | ||
663 | * period. | ||
664 | */ | ||
665 | ts->read_cnt = 0; | ||
666 | return ADS7846_FILTER_IGNORE; | ||
667 | } | ||
668 | } else { | ||
669 | if (++ts->read_rep > ts->debounce_rep) { | ||
670 | /* | ||
671 | * Got a good reading for this coordinate, | ||
672 | * go for the next one. | ||
673 | */ | ||
674 | ts->read_cnt = 0; | ||
675 | ts->read_rep = 0; | ||
676 | return ADS7846_FILTER_OK; | ||
677 | } else { | ||
678 | /* Read more values that are consistent. */ | ||
679 | ts->read_cnt++; | ||
680 | return ADS7846_FILTER_REPEAT; | ||
681 | } | ||
682 | } | ||
683 | } | ||
684 | |||
685 | static int ads7846_no_filter(void *ads, int data_idx, int *val) | ||
686 | { | ||
687 | return ADS7846_FILTER_OK; | ||
688 | } | ||
689 | |||
690 | static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m) | ||
691 | { | ||
692 | struct spi_transfer *t = | ||
693 | list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
694 | |||
695 | if (ts->model == 7845) { | ||
696 | return be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3; | ||
697 | } else { | ||
698 | /* | ||
699 | * adjust: on-wire is a must-ignore bit, a BE12 value, then | ||
700 | * padding; built from two 8 bit values written msb-first. | ||
701 | */ | ||
702 | return be16_to_cpup((__be16 *)t->rx_buf) >> 3; | ||
703 | } | ||
704 | } | ||
705 | |||
706 | static void ads7846_update_value(struct spi_message *m, int val) | ||
707 | { | ||
708 | struct spi_transfer *t = | ||
709 | list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
579 | 710 | ||
580 | static void ads7846_rx(void *ads) | 711 | *(u16 *)t->rx_buf = val; |
712 | } | ||
713 | |||
714 | static void ads7846_read_state(struct ads7846 *ts) | ||
581 | { | 715 | { |
582 | struct ads7846 *ts = ads; | 716 | struct ads7846_packet *packet = ts->packet; |
583 | struct ads7846_packet *packet = ts->packet; | 717 | struct spi_message *m; |
584 | unsigned Rt; | 718 | int msg_idx = 0; |
585 | u16 x, y, z1, z2; | 719 | int val; |
720 | int action; | ||
721 | int error; | ||
586 | 722 | ||
587 | /* ads7846_rx_val() did in-place conversion (including byteswap) from | 723 | while (msg_idx < ts->msg_count) { |
588 | * on-the-wire format as part of debouncing to get stable readings. | 724 | |
725 | ts->wait_for_sync(); | ||
726 | |||
727 | m = &ts->msg[msg_idx]; | ||
728 | error = spi_sync(ts->spi, m); | ||
729 | if (error) { | ||
730 | dev_err(&ts->spi->dev, "spi_async --> %d\n", error); | ||
731 | packet->tc.ignore = true; | ||
732 | return; | ||
733 | } | ||
734 | |||
735 | /* | ||
736 | * Last message is power down request, no need to convert | ||
737 | * or filter the value. | ||
738 | */ | ||
739 | if (msg_idx < ts->msg_count - 1) { | ||
740 | |||
741 | val = ads7846_get_value(ts, m); | ||
742 | |||
743 | action = ts->filter(ts->filter_data, msg_idx, &val); | ||
744 | switch (action) { | ||
745 | case ADS7846_FILTER_REPEAT: | ||
746 | continue; | ||
747 | |||
748 | case ADS7846_FILTER_IGNORE: | ||
749 | packet->tc.ignore = true; | ||
750 | msg_idx = ts->msg_count - 1; | ||
751 | continue; | ||
752 | |||
753 | case ADS7846_FILTER_OK: | ||
754 | ads7846_update_value(m, val); | ||
755 | packet->tc.ignore = false; | ||
756 | msg_idx++; | ||
757 | break; | ||
758 | |||
759 | default: | ||
760 | BUG(); | ||
761 | } | ||
762 | } else { | ||
763 | msg_idx++; | ||
764 | } | ||
765 | } | ||
766 | } | ||
767 | |||
768 | static void ads7846_report_state(struct ads7846 *ts) | ||
769 | { | ||
770 | struct ads7846_packet *packet = ts->packet; | ||
771 | unsigned int Rt; | ||
772 | u16 x, y, z1, z2; | ||
773 | |||
774 | /* | ||
775 | * ads7846_get_value() does in-place conversion (including byte swap) | ||
776 | * from on-the-wire format as part of debouncing to get stable | ||
777 | * readings. | ||
589 | */ | 778 | */ |
590 | if (ts->model == 7845) { | 779 | if (ts->model == 7845) { |
591 | x = *(u16 *)packet->tc.x_buf; | 780 | x = *(u16 *)packet->tc.x_buf; |
@@ -623,19 +812,19 @@ static void ads7846_rx(void *ads) | |||
623 | Rt = 0; | 812 | Rt = 0; |
624 | } | 813 | } |
625 | 814 | ||
626 | /* Sample found inconsistent by debouncing or pressure is beyond | 815 | /* |
816 | * Sample found inconsistent by debouncing or pressure is beyond | ||
627 | * the maximum. Don't report it to user space, repeat at least | 817 | * the maximum. Don't report it to user space, repeat at least |
628 | * once more the measurement | 818 | * once more the measurement |
629 | */ | 819 | */ |
630 | if (packet->tc.ignore || Rt > ts->pressure_max) { | 820 | if (packet->tc.ignore || Rt > ts->pressure_max) { |
631 | dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", | 821 | dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n", |
632 | packet->tc.ignore, Rt); | 822 | packet->tc.ignore, Rt); |
633 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | ||
634 | HRTIMER_MODE_REL); | ||
635 | return; | 823 | return; |
636 | } | 824 | } |
637 | 825 | ||
638 | /* Maybe check the pendown state before reporting. This discards | 826 | /* |
827 | * Maybe check the pendown state before reporting. This discards | ||
639 | * false readings when the pen is lifted. | 828 | * false readings when the pen is lifted. |
640 | */ | 829 | */ |
641 | if (ts->penirq_recheck_delay_usecs) { | 830 | if (ts->penirq_recheck_delay_usecs) { |
@@ -644,8 +833,9 @@ static void ads7846_rx(void *ads) | |||
644 | Rt = 0; | 833 | Rt = 0; |
645 | } | 834 | } |
646 | 835 | ||
647 | /* NOTE: We can't rely on the pressure to determine the pen down | 836 | /* |
648 | * state, even this controller has a pressure sensor. The pressure | 837 | * NOTE: We can't rely on the pressure to determine the pen down |
838 | * state, even this controller has a pressure sensor. The pressure | ||
649 | * value can fluctuate for quite a while after lifting the pen and | 839 | * value can fluctuate for quite a while after lifting the pen and |
650 | * in some cases may not even settle at the expected value. | 840 | * in some cases may not even settle at the expected value. |
651 | * | 841 | * |
@@ -655,15 +845,15 @@ static void ads7846_rx(void *ads) | |||
655 | if (Rt) { | 845 | if (Rt) { |
656 | struct input_dev *input = ts->input; | 846 | struct input_dev *input = ts->input; |
657 | 847 | ||
848 | if (ts->swap_xy) | ||
849 | swap(x, y); | ||
850 | |||
658 | if (!ts->pendown) { | 851 | if (!ts->pendown) { |
659 | input_report_key(input, BTN_TOUCH, 1); | 852 | input_report_key(input, BTN_TOUCH, 1); |
660 | ts->pendown = 1; | 853 | ts->pendown = true; |
661 | dev_vdbg(&ts->spi->dev, "DOWN\n"); | 854 | dev_vdbg(&ts->spi->dev, "DOWN\n"); |
662 | } | 855 | } |
663 | 856 | ||
664 | if (ts->swap_xy) | ||
665 | swap(x, y); | ||
666 | |||
667 | input_report_abs(input, ABS_X, x); | 857 | input_report_abs(input, ABS_X, x); |
668 | input_report_abs(input, ABS_Y, y); | 858 | input_report_abs(input, ABS_Y, y); |
669 | input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt); | 859 | input_report_abs(input, ABS_PRESSURE, ts->pressure_max - Rt); |
@@ -671,407 +861,161 @@ static void ads7846_rx(void *ads) | |||
671 | input_sync(input); | 861 | input_sync(input); |
672 | dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); | 862 | dev_vdbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); |
673 | } | 863 | } |
674 | |||
675 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | ||
676 | HRTIMER_MODE_REL); | ||
677 | } | 864 | } |
678 | 865 | ||
679 | static int ads7846_debounce(void *ads, int data_idx, int *val) | 866 | static irqreturn_t ads7846_hard_irq(int irq, void *handle) |
680 | { | 867 | { |
681 | struct ads7846 *ts = ads; | 868 | struct ads7846 *ts = handle; |
682 | 869 | ||
683 | if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { | 870 | return get_pendown_state(ts) ? IRQ_WAKE_THREAD : IRQ_HANDLED; |
684 | /* Start over collecting consistent readings. */ | ||
685 | ts->read_rep = 0; | ||
686 | /* Repeat it, if this was the first read or the read | ||
687 | * wasn't consistent enough. */ | ||
688 | if (ts->read_cnt < ts->debounce_max) { | ||
689 | ts->last_read = *val; | ||
690 | ts->read_cnt++; | ||
691 | return ADS7846_FILTER_REPEAT; | ||
692 | } else { | ||
693 | /* Maximum number of debouncing reached and still | ||
694 | * not enough number of consistent readings. Abort | ||
695 | * the whole sample, repeat it in the next sampling | ||
696 | * period. | ||
697 | */ | ||
698 | ts->read_cnt = 0; | ||
699 | return ADS7846_FILTER_IGNORE; | ||
700 | } | ||
701 | } else { | ||
702 | if (++ts->read_rep > ts->debounce_rep) { | ||
703 | /* Got a good reading for this coordinate, | ||
704 | * go for the next one. */ | ||
705 | ts->read_cnt = 0; | ||
706 | ts->read_rep = 0; | ||
707 | return ADS7846_FILTER_OK; | ||
708 | } else { | ||
709 | /* Read more values that are consistent. */ | ||
710 | ts->read_cnt++; | ||
711 | return ADS7846_FILTER_REPEAT; | ||
712 | } | ||
713 | } | ||
714 | } | 871 | } |
715 | 872 | ||
716 | static int ads7846_no_filter(void *ads, int data_idx, int *val) | ||
717 | { | ||
718 | return ADS7846_FILTER_OK; | ||
719 | } | ||
720 | 873 | ||
721 | static void ads7846_rx_val(void *ads) | 874 | static irqreturn_t ads7846_irq(int irq, void *handle) |
722 | { | 875 | { |
723 | struct ads7846 *ts = ads; | 876 | struct ads7846 *ts = handle; |
724 | struct ads7846_packet *packet = ts->packet; | ||
725 | struct spi_message *m; | ||
726 | struct spi_transfer *t; | ||
727 | int val; | ||
728 | int action; | ||
729 | int status; | ||
730 | |||
731 | m = &ts->msg[ts->msg_idx]; | ||
732 | t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
733 | 877 | ||
734 | if (ts->model == 7845) { | 878 | /* Start with a small delay before checking pendown state */ |
735 | val = be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3; | 879 | msleep(TS_POLL_DELAY); |
736 | } else { | ||
737 | /* adjust: on-wire is a must-ignore bit, a BE12 value, then | ||
738 | * padding; built from two 8 bit values written msb-first. | ||
739 | */ | ||
740 | val = be16_to_cpup((__be16 *)t->rx_buf) >> 3; | ||
741 | } | ||
742 | 880 | ||
743 | action = ts->filter(ts->filter_data, ts->msg_idx, &val); | 881 | while (!ts->stopped && get_pendown_state(ts)) { |
744 | switch (action) { | ||
745 | case ADS7846_FILTER_REPEAT: | ||
746 | break; | ||
747 | case ADS7846_FILTER_IGNORE: | ||
748 | packet->tc.ignore = 1; | ||
749 | /* Last message will contain ads7846_rx() as the | ||
750 | * completion function. | ||
751 | */ | ||
752 | m = ts->last_msg; | ||
753 | break; | ||
754 | case ADS7846_FILTER_OK: | ||
755 | *(u16 *)t->rx_buf = val; | ||
756 | packet->tc.ignore = 0; | ||
757 | m = &ts->msg[++ts->msg_idx]; | ||
758 | break; | ||
759 | default: | ||
760 | BUG(); | ||
761 | } | ||
762 | ts->wait_for_sync(); | ||
763 | status = spi_async(ts->spi, m); | ||
764 | if (status) | ||
765 | dev_err(&ts->spi->dev, "spi_async --> %d\n", | ||
766 | status); | ||
767 | } | ||
768 | 882 | ||
769 | static enum hrtimer_restart ads7846_timer(struct hrtimer *handle) | 883 | /* pen is down, continue with the measurement */ |
770 | { | 884 | ads7846_read_state(ts); |
771 | struct ads7846 *ts = container_of(handle, struct ads7846, timer); | ||
772 | int status = 0; | ||
773 | 885 | ||
774 | spin_lock(&ts->lock); | 886 | if (!ts->stopped) |
887 | ads7846_report_state(ts); | ||
775 | 888 | ||
776 | if (unlikely(!get_pendown_state(ts) || | 889 | wait_event_timeout(ts->wait, ts->stopped, |
777 | device_suspended(&ts->spi->dev))) { | 890 | msecs_to_jiffies(TS_POLL_PERIOD)); |
778 | if (ts->pendown) { | 891 | } |
779 | struct input_dev *input = ts->input; | ||
780 | 892 | ||
781 | input_report_key(input, BTN_TOUCH, 0); | 893 | if (ts->pendown) { |
782 | input_report_abs(input, ABS_PRESSURE, 0); | 894 | struct input_dev *input = ts->input; |
783 | input_sync(input); | ||
784 | 895 | ||
785 | ts->pendown = 0; | 896 | input_report_key(input, BTN_TOUCH, 0); |
786 | dev_vdbg(&ts->spi->dev, "UP\n"); | 897 | input_report_abs(input, ABS_PRESSURE, 0); |
787 | } | 898 | input_sync(input); |
788 | 899 | ||
789 | /* measurement cycle ended */ | 900 | ts->pendown = false; |
790 | if (!device_suspended(&ts->spi->dev)) { | 901 | dev_vdbg(&ts->spi->dev, "UP\n"); |
791 | ts->irq_disabled = 0; | ||
792 | enable_irq(ts->spi->irq); | ||
793 | } | ||
794 | ts->pending = 0; | ||
795 | } else { | ||
796 | /* pen is still down, continue with the measurement */ | ||
797 | ts->msg_idx = 0; | ||
798 | ts->wait_for_sync(); | ||
799 | status = spi_async(ts->spi, &ts->msg[0]); | ||
800 | if (status) | ||
801 | dev_err(&ts->spi->dev, "spi_async --> %d\n", status); | ||
802 | } | 902 | } |
803 | 903 | ||
804 | spin_unlock(&ts->lock); | 904 | return IRQ_HANDLED; |
805 | return HRTIMER_NORESTART; | ||
806 | } | 905 | } |
807 | 906 | ||
808 | static irqreturn_t ads7846_irq(int irq, void *handle) | 907 | #ifdef CONFIG_PM_SLEEP |
908 | static int ads7846_suspend(struct device *dev) | ||
809 | { | 909 | { |
810 | struct ads7846 *ts = handle; | 910 | struct ads7846 *ts = dev_get_drvdata(dev); |
811 | unsigned long flags; | ||
812 | |||
813 | spin_lock_irqsave(&ts->lock, flags); | ||
814 | if (likely(get_pendown_state(ts))) { | ||
815 | if (!ts->irq_disabled) { | ||
816 | /* The ARM do_simple_IRQ() dispatcher doesn't act | ||
817 | * like the other dispatchers: it will report IRQs | ||
818 | * even after they've been disabled. We work around | ||
819 | * that here. (The "generic irq" framework may help...) | ||
820 | */ | ||
821 | ts->irq_disabled = 1; | ||
822 | disable_irq_nosync(ts->spi->irq); | ||
823 | ts->pending = 1; | ||
824 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), | ||
825 | HRTIMER_MODE_REL); | ||
826 | } | ||
827 | } | ||
828 | spin_unlock_irqrestore(&ts->lock, flags); | ||
829 | 911 | ||
830 | return IRQ_HANDLED; | 912 | mutex_lock(&ts->lock); |
831 | } | ||
832 | 913 | ||
833 | /*--------------------------------------------------------------------------*/ | 914 | if (!ts->suspended) { |
834 | 915 | ||
835 | /* Must be called with ts->lock held */ | 916 | if (!ts->disabled) |
836 | static void ads7846_disable(struct ads7846 *ts) | 917 | __ads7846_disable(ts); |
837 | { | ||
838 | if (ts->disabled) | ||
839 | return; | ||
840 | 918 | ||
841 | ts->disabled = 1; | 919 | if (device_may_wakeup(&ts->spi->dev)) |
920 | enable_irq_wake(ts->spi->irq); | ||
842 | 921 | ||
843 | /* are we waiting for IRQ, or polling? */ | 922 | ts->suspended = true; |
844 | if (!ts->pending) { | ||
845 | ts->irq_disabled = 1; | ||
846 | disable_irq(ts->spi->irq); | ||
847 | } else { | ||
848 | /* the timer will run at least once more, and | ||
849 | * leave everything in a clean state, IRQ disabled | ||
850 | */ | ||
851 | while (ts->pending) { | ||
852 | spin_unlock_irq(&ts->lock); | ||
853 | msleep(1); | ||
854 | spin_lock_irq(&ts->lock); | ||
855 | } | ||
856 | } | 923 | } |
857 | 924 | ||
858 | regulator_disable(ts->reg); | 925 | mutex_unlock(&ts->lock); |
859 | 926 | ||
860 | /* we know the chip's in lowpower mode since we always | 927 | return 0; |
861 | * leave it that way after every request | ||
862 | */ | ||
863 | } | 928 | } |
864 | 929 | ||
865 | /* Must be called with ts->lock held */ | 930 | static int ads7846_resume(struct device *dev) |
866 | static void ads7846_enable(struct ads7846 *ts) | ||
867 | { | 931 | { |
868 | if (!ts->disabled) | 932 | struct ads7846 *ts = dev_get_drvdata(dev); |
869 | return; | ||
870 | |||
871 | regulator_enable(ts->reg); | ||
872 | 933 | ||
873 | ts->disabled = 0; | 934 | mutex_lock(&ts->lock); |
874 | ts->irq_disabled = 0; | ||
875 | enable_irq(ts->spi->irq); | ||
876 | } | ||
877 | 935 | ||
878 | static int ads7846_suspend(struct spi_device *spi, pm_message_t message) | 936 | if (ts->suspended) { |
879 | { | ||
880 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | ||
881 | 937 | ||
882 | spin_lock_irq(&ts->lock); | 938 | ts->suspended = false; |
883 | 939 | ||
884 | ts->is_suspended = 1; | 940 | if (device_may_wakeup(&ts->spi->dev)) |
885 | ads7846_disable(ts); | 941 | disable_irq_wake(ts->spi->irq); |
886 | 942 | ||
887 | spin_unlock_irq(&ts->lock); | 943 | if (!ts->disabled) |
944 | __ads7846_enable(ts); | ||
945 | } | ||
888 | 946 | ||
889 | if (device_may_wakeup(&ts->spi->dev)) | 947 | mutex_unlock(&ts->lock); |
890 | enable_irq_wake(ts->spi->irq); | ||
891 | 948 | ||
892 | return 0; | 949 | return 0; |
893 | |||
894 | } | 950 | } |
951 | #endif | ||
895 | 952 | ||
896 | static int ads7846_resume(struct spi_device *spi) | 953 | static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); |
897 | { | ||
898 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | ||
899 | |||
900 | if (device_may_wakeup(&ts->spi->dev)) | ||
901 | disable_irq_wake(ts->spi->irq); | ||
902 | |||
903 | spin_lock_irq(&ts->lock); | ||
904 | |||
905 | ts->is_suspended = 0; | ||
906 | ads7846_enable(ts); | ||
907 | |||
908 | spin_unlock_irq(&ts->lock); | ||
909 | |||
910 | return 0; | ||
911 | } | ||
912 | 954 | ||
913 | static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts) | 955 | static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts) |
914 | { | 956 | { |
915 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 957 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
916 | int err; | 958 | int err; |
917 | 959 | ||
918 | /* REVISIT when the irq can be triggered active-low, or if for some | 960 | /* |
961 | * REVISIT when the irq can be triggered active-low, or if for some | ||
919 | * reason the touchscreen isn't hooked up, we don't need to access | 962 | * reason the touchscreen isn't hooked up, we don't need to access |
920 | * the pendown state. | 963 | * the pendown state. |
921 | */ | 964 | */ |
922 | if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) { | ||
923 | dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); | ||
924 | return -EINVAL; | ||
925 | } | ||
926 | 965 | ||
927 | if (pdata->get_pendown_state) { | 966 | if (pdata->get_pendown_state) { |
928 | ts->get_pendown_state = pdata->get_pendown_state; | 967 | ts->get_pendown_state = pdata->get_pendown_state; |
929 | return 0; | 968 | } else if (gpio_is_valid(pdata->gpio_pendown)) { |
930 | } | ||
931 | 969 | ||
932 | err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); | 970 | err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); |
933 | if (err) { | 971 | if (err) { |
934 | dev_err(&spi->dev, "failed to request pendown GPIO%d\n", | 972 | dev_err(&spi->dev, "failed to request pendown GPIO%d\n", |
935 | pdata->gpio_pendown); | 973 | pdata->gpio_pendown); |
936 | return err; | 974 | return err; |
937 | } | 975 | } |
938 | 976 | err = gpio_direction_input(pdata->gpio_pendown); | |
939 | ts->gpio_pendown = pdata->gpio_pendown; | 977 | if (err) { |
940 | return 0; | 978 | dev_err(&spi->dev, "failed to setup pendown GPIO%d\n", |
941 | } | 979 | pdata->gpio_pendown); |
942 | 980 | gpio_free(pdata->gpio_pendown); | |
943 | static int __devinit ads7846_probe(struct spi_device *spi) | 981 | return err; |
944 | { | 982 | } |
945 | struct ads7846 *ts; | ||
946 | struct ads7846_packet *packet; | ||
947 | struct input_dev *input_dev; | ||
948 | const struct ads7846_platform_data *pdata = spi->dev.platform_data; | ||
949 | struct spi_message *m; | ||
950 | struct spi_transfer *x; | ||
951 | unsigned long irq_flags; | ||
952 | int vref; | ||
953 | int err; | ||
954 | |||
955 | if (!spi->irq) { | ||
956 | dev_dbg(&spi->dev, "no IRQ?\n"); | ||
957 | return -ENODEV; | ||
958 | } | ||
959 | 983 | ||
960 | if (!pdata) { | 984 | ts->gpio_pendown = pdata->gpio_pendown; |
961 | dev_dbg(&spi->dev, "no platform data?\n"); | ||
962 | return -ENODEV; | ||
963 | } | ||
964 | 985 | ||
965 | /* don't exceed max specified sample rate */ | 986 | } else { |
966 | if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { | 987 | dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); |
967 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", | ||
968 | (spi->max_speed_hz/SAMPLE_BITS)/1000); | ||
969 | return -EINVAL; | 988 | return -EINVAL; |
970 | } | 989 | } |
971 | 990 | ||
972 | /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except | 991 | return 0; |
973 | * that even if the hardware can do that, the SPI controller driver | 992 | } |
974 | * may not. So we stick to very-portable 8 bit words, both RX and TX. | ||
975 | */ | ||
976 | spi->bits_per_word = 8; | ||
977 | spi->mode = SPI_MODE_0; | ||
978 | err = spi_setup(spi); | ||
979 | if (err < 0) | ||
980 | return err; | ||
981 | |||
982 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); | ||
983 | packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL); | ||
984 | input_dev = input_allocate_device(); | ||
985 | if (!ts || !packet || !input_dev) { | ||
986 | err = -ENOMEM; | ||
987 | goto err_free_mem; | ||
988 | } | ||
989 | |||
990 | dev_set_drvdata(&spi->dev, ts); | ||
991 | |||
992 | ts->packet = packet; | ||
993 | ts->spi = spi; | ||
994 | ts->input = input_dev; | ||
995 | ts->vref_mv = pdata->vref_mv; | ||
996 | ts->swap_xy = pdata->swap_xy; | ||
997 | |||
998 | hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
999 | ts->timer.function = ads7846_timer; | ||
1000 | |||
1001 | spin_lock_init(&ts->lock); | ||
1002 | |||
1003 | ts->model = pdata->model ? : 7846; | ||
1004 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | ||
1005 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | ||
1006 | ts->pressure_max = pdata->pressure_max ? : ~0; | ||
1007 | |||
1008 | if (pdata->filter != NULL) { | ||
1009 | if (pdata->filter_init != NULL) { | ||
1010 | err = pdata->filter_init(pdata, &ts->filter_data); | ||
1011 | if (err < 0) | ||
1012 | goto err_free_mem; | ||
1013 | } | ||
1014 | ts->filter = pdata->filter; | ||
1015 | ts->filter_cleanup = pdata->filter_cleanup; | ||
1016 | } else if (pdata->debounce_max) { | ||
1017 | ts->debounce_max = pdata->debounce_max; | ||
1018 | if (ts->debounce_max < 2) | ||
1019 | ts->debounce_max = 2; | ||
1020 | ts->debounce_tol = pdata->debounce_tol; | ||
1021 | ts->debounce_rep = pdata->debounce_rep; | ||
1022 | ts->filter = ads7846_debounce; | ||
1023 | ts->filter_data = ts; | ||
1024 | } else | ||
1025 | ts->filter = ads7846_no_filter; | ||
1026 | |||
1027 | err = setup_pendown(spi, ts); | ||
1028 | if (err) | ||
1029 | goto err_cleanup_filter; | ||
1030 | |||
1031 | if (pdata->penirq_recheck_delay_usecs) | ||
1032 | ts->penirq_recheck_delay_usecs = | ||
1033 | pdata->penirq_recheck_delay_usecs; | ||
1034 | |||
1035 | ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; | ||
1036 | |||
1037 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); | ||
1038 | snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model); | ||
1039 | |||
1040 | input_dev->name = ts->name; | ||
1041 | input_dev->phys = ts->phys; | ||
1042 | input_dev->dev.parent = &spi->dev; | ||
1043 | |||
1044 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
1045 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
1046 | input_set_abs_params(input_dev, ABS_X, | ||
1047 | pdata->x_min ? : 0, | ||
1048 | pdata->x_max ? : MAX_12BIT, | ||
1049 | 0, 0); | ||
1050 | input_set_abs_params(input_dev, ABS_Y, | ||
1051 | pdata->y_min ? : 0, | ||
1052 | pdata->y_max ? : MAX_12BIT, | ||
1053 | 0, 0); | ||
1054 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
1055 | pdata->pressure_min, pdata->pressure_max, 0, 0); | ||
1056 | 993 | ||
1057 | vref = pdata->keep_vref_on; | 994 | /* |
995 | * Set up the transfers to read touchscreen state; this assumes we | ||
996 | * use formula #2 for pressure, not #3. | ||
997 | */ | ||
998 | static void __devinit ads7846_setup_spi_msg(struct ads7846 *ts, | ||
999 | const struct ads7846_platform_data *pdata) | ||
1000 | { | ||
1001 | struct spi_message *m = &ts->msg[0]; | ||
1002 | struct spi_transfer *x = ts->xfer; | ||
1003 | struct ads7846_packet *packet = ts->packet; | ||
1004 | int vref = pdata->keep_vref_on; | ||
1058 | 1005 | ||
1059 | if (ts->model == 7873) { | 1006 | if (ts->model == 7873) { |
1060 | /* The AD7873 is almost identical to the ADS7846 | 1007 | /* |
1008 | * The AD7873 is almost identical to the ADS7846 | ||
1061 | * keep VREF off during differential/ratiometric | 1009 | * keep VREF off during differential/ratiometric |
1062 | * conversion modes | 1010 | * conversion modes. |
1063 | */ | 1011 | */ |
1064 | ts->model = 7846; | 1012 | ts->model = 7846; |
1065 | vref = 0; | 1013 | vref = 0; |
1066 | } | 1014 | } |
1067 | 1015 | ||
1068 | /* set up the transfers to read touchscreen state; this assumes we | 1016 | ts->msg_count = 1; |
1069 | * use formula #2 for pressure, not #3. | ||
1070 | */ | ||
1071 | m = &ts->msg[0]; | ||
1072 | x = ts->xfer; | ||
1073 | |||
1074 | spi_message_init(m); | 1017 | spi_message_init(m); |
1018 | m->context = ts; | ||
1075 | 1019 | ||
1076 | if (ts->model == 7845) { | 1020 | if (ts->model == 7845) { |
1077 | packet->read_y_cmd[0] = READ_Y(vref); | 1021 | packet->read_y_cmd[0] = READ_Y(vref); |
@@ -1094,7 +1038,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1094 | spi_message_add_tail(x, m); | 1038 | spi_message_add_tail(x, m); |
1095 | } | 1039 | } |
1096 | 1040 | ||
1097 | /* the first sample after switching drivers can be low quality; | 1041 | /* |
1042 | * The first sample after switching drivers can be low quality; | ||
1098 | * optionally discard it, using a second one after the signals | 1043 | * optionally discard it, using a second one after the signals |
1099 | * have had enough time to stabilize. | 1044 | * have had enough time to stabilize. |
1100 | */ | 1045 | */ |
@@ -1112,11 +1057,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1112 | spi_message_add_tail(x, m); | 1057 | spi_message_add_tail(x, m); |
1113 | } | 1058 | } |
1114 | 1059 | ||
1115 | m->complete = ads7846_rx_val; | 1060 | ts->msg_count++; |
1116 | m->context = ts; | ||
1117 | |||
1118 | m++; | 1061 | m++; |
1119 | spi_message_init(m); | 1062 | spi_message_init(m); |
1063 | m->context = ts; | ||
1120 | 1064 | ||
1121 | if (ts->model == 7845) { | 1065 | if (ts->model == 7845) { |
1122 | x++; | 1066 | x++; |
@@ -1156,13 +1100,12 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1156 | spi_message_add_tail(x, m); | 1100 | spi_message_add_tail(x, m); |
1157 | } | 1101 | } |
1158 | 1102 | ||
1159 | m->complete = ads7846_rx_val; | ||
1160 | m->context = ts; | ||
1161 | |||
1162 | /* turn y+ off, x- on; we'll use formula #2 */ | 1103 | /* turn y+ off, x- on; we'll use formula #2 */ |
1163 | if (ts->model == 7846) { | 1104 | if (ts->model == 7846) { |
1105 | ts->msg_count++; | ||
1164 | m++; | 1106 | m++; |
1165 | spi_message_init(m); | 1107 | spi_message_init(m); |
1108 | m->context = ts; | ||
1166 | 1109 | ||
1167 | x++; | 1110 | x++; |
1168 | packet->read_z1 = READ_Z1(vref); | 1111 | packet->read_z1 = READ_Z1(vref); |
@@ -1190,11 +1133,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1190 | spi_message_add_tail(x, m); | 1133 | spi_message_add_tail(x, m); |
1191 | } | 1134 | } |
1192 | 1135 | ||
1193 | m->complete = ads7846_rx_val; | 1136 | ts->msg_count++; |
1194 | m->context = ts; | ||
1195 | |||
1196 | m++; | 1137 | m++; |
1197 | spi_message_init(m); | 1138 | spi_message_init(m); |
1139 | m->context = ts; | ||
1198 | 1140 | ||
1199 | x++; | 1141 | x++; |
1200 | packet->read_z2 = READ_Z2(vref); | 1142 | packet->read_z2 = READ_Z2(vref); |
@@ -1221,14 +1163,13 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1221 | x->len = 2; | 1163 | x->len = 2; |
1222 | spi_message_add_tail(x, m); | 1164 | spi_message_add_tail(x, m); |
1223 | } | 1165 | } |
1224 | |||
1225 | m->complete = ads7846_rx_val; | ||
1226 | m->context = ts; | ||
1227 | } | 1166 | } |
1228 | 1167 | ||
1229 | /* power down */ | 1168 | /* power down */ |
1169 | ts->msg_count++; | ||
1230 | m++; | 1170 | m++; |
1231 | spi_message_init(m); | 1171 | spi_message_init(m); |
1172 | m->context = ts; | ||
1232 | 1173 | ||
1233 | if (ts->model == 7845) { | 1174 | if (ts->model == 7845) { |
1234 | x++; | 1175 | x++; |
@@ -1251,11 +1192,119 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1251 | 1192 | ||
1252 | CS_CHANGE(*x); | 1193 | CS_CHANGE(*x); |
1253 | spi_message_add_tail(x, m); | 1194 | spi_message_add_tail(x, m); |
1195 | } | ||
1254 | 1196 | ||
1255 | m->complete = ads7846_rx; | 1197 | static int __devinit ads7846_probe(struct spi_device *spi) |
1256 | m->context = ts; | 1198 | { |
1199 | struct ads7846 *ts; | ||
1200 | struct ads7846_packet *packet; | ||
1201 | struct input_dev *input_dev; | ||
1202 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | ||
1203 | unsigned long irq_flags; | ||
1204 | int err; | ||
1205 | |||
1206 | if (!spi->irq) { | ||
1207 | dev_dbg(&spi->dev, "no IRQ?\n"); | ||
1208 | return -ENODEV; | ||
1209 | } | ||
1210 | |||
1211 | if (!pdata) { | ||
1212 | dev_dbg(&spi->dev, "no platform data?\n"); | ||
1213 | return -ENODEV; | ||
1214 | } | ||
1215 | |||
1216 | /* don't exceed max specified sample rate */ | ||
1217 | if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { | ||
1218 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", | ||
1219 | (spi->max_speed_hz/SAMPLE_BITS)/1000); | ||
1220 | return -EINVAL; | ||
1221 | } | ||
1222 | |||
1223 | /* We'd set TX word size 8 bits and RX word size to 13 bits ... except | ||
1224 | * that even if the hardware can do that, the SPI controller driver | ||
1225 | * may not. So we stick to very-portable 8 bit words, both RX and TX. | ||
1226 | */ | ||
1227 | spi->bits_per_word = 8; | ||
1228 | spi->mode = SPI_MODE_0; | ||
1229 | err = spi_setup(spi); | ||
1230 | if (err < 0) | ||
1231 | return err; | ||
1232 | |||
1233 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); | ||
1234 | packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL); | ||
1235 | input_dev = input_allocate_device(); | ||
1236 | if (!ts || !packet || !input_dev) { | ||
1237 | err = -ENOMEM; | ||
1238 | goto err_free_mem; | ||
1239 | } | ||
1240 | |||
1241 | dev_set_drvdata(&spi->dev, ts); | ||
1242 | |||
1243 | ts->packet = packet; | ||
1244 | ts->spi = spi; | ||
1245 | ts->input = input_dev; | ||
1246 | ts->vref_mv = pdata->vref_mv; | ||
1247 | ts->swap_xy = pdata->swap_xy; | ||
1248 | |||
1249 | mutex_init(&ts->lock); | ||
1250 | init_waitqueue_head(&ts->wait); | ||
1251 | |||
1252 | ts->model = pdata->model ? : 7846; | ||
1253 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | ||
1254 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | ||
1255 | ts->pressure_max = pdata->pressure_max ? : ~0; | ||
1256 | |||
1257 | if (pdata->filter != NULL) { | ||
1258 | if (pdata->filter_init != NULL) { | ||
1259 | err = pdata->filter_init(pdata, &ts->filter_data); | ||
1260 | if (err < 0) | ||
1261 | goto err_free_mem; | ||
1262 | } | ||
1263 | ts->filter = pdata->filter; | ||
1264 | ts->filter_cleanup = pdata->filter_cleanup; | ||
1265 | } else if (pdata->debounce_max) { | ||
1266 | ts->debounce_max = pdata->debounce_max; | ||
1267 | if (ts->debounce_max < 2) | ||
1268 | ts->debounce_max = 2; | ||
1269 | ts->debounce_tol = pdata->debounce_tol; | ||
1270 | ts->debounce_rep = pdata->debounce_rep; | ||
1271 | ts->filter = ads7846_debounce_filter; | ||
1272 | ts->filter_data = ts; | ||
1273 | } else { | ||
1274 | ts->filter = ads7846_no_filter; | ||
1275 | } | ||
1276 | |||
1277 | err = ads7846_setup_pendown(spi, ts); | ||
1278 | if (err) | ||
1279 | goto err_cleanup_filter; | ||
1280 | |||
1281 | if (pdata->penirq_recheck_delay_usecs) | ||
1282 | ts->penirq_recheck_delay_usecs = | ||
1283 | pdata->penirq_recheck_delay_usecs; | ||
1284 | |||
1285 | ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; | ||
1286 | |||
1287 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); | ||
1288 | snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model); | ||
1289 | |||
1290 | input_dev->name = ts->name; | ||
1291 | input_dev->phys = ts->phys; | ||
1292 | input_dev->dev.parent = &spi->dev; | ||
1293 | |||
1294 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
1295 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
1296 | input_set_abs_params(input_dev, ABS_X, | ||
1297 | pdata->x_min ? : 0, | ||
1298 | pdata->x_max ? : MAX_12BIT, | ||
1299 | 0, 0); | ||
1300 | input_set_abs_params(input_dev, ABS_Y, | ||
1301 | pdata->y_min ? : 0, | ||
1302 | pdata->y_max ? : MAX_12BIT, | ||
1303 | 0, 0); | ||
1304 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
1305 | pdata->pressure_min, pdata->pressure_max, 0, 0); | ||
1257 | 1306 | ||
1258 | ts->last_msg = m; | 1307 | ads7846_setup_spi_msg(ts, pdata); |
1259 | 1308 | ||
1260 | ts->reg = regulator_get(&spi->dev, "vcc"); | 1309 | ts->reg = regulator_get(&spi->dev, "vcc"); |
1261 | if (IS_ERR(ts->reg)) { | 1310 | if (IS_ERR(ts->reg)) { |
@@ -1271,16 +1320,17 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1271 | } | 1320 | } |
1272 | 1321 | ||
1273 | irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING; | 1322 | irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING; |
1323 | irq_flags |= IRQF_ONESHOT; | ||
1274 | 1324 | ||
1275 | err = request_irq(spi->irq, ads7846_irq, irq_flags, | 1325 | err = request_threaded_irq(spi->irq, ads7846_hard_irq, ads7846_irq, |
1276 | spi->dev.driver->name, ts); | 1326 | irq_flags, spi->dev.driver->name, ts); |
1277 | |||
1278 | if (err && !pdata->irq_flags) { | 1327 | if (err && !pdata->irq_flags) { |
1279 | dev_info(&spi->dev, | 1328 | dev_info(&spi->dev, |
1280 | "trying pin change workaround on irq %d\n", spi->irq); | 1329 | "trying pin change workaround on irq %d\n", spi->irq); |
1281 | err = request_irq(spi->irq, ads7846_irq, | 1330 | irq_flags |= IRQF_TRIGGER_RISING; |
1282 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 1331 | err = request_threaded_irq(spi->irq, |
1283 | spi->dev.driver->name, ts); | 1332 | ads7846_hard_irq, ads7846_irq, |
1333 | irq_flags, spi->dev.driver->name, ts); | ||
1284 | } | 1334 | } |
1285 | 1335 | ||
1286 | if (err) { | 1336 | if (err) { |
@@ -1294,14 +1344,14 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1294 | 1344 | ||
1295 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); | 1345 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); |
1296 | 1346 | ||
1297 | /* take a first sample, leaving nPENIRQ active and vREF off; avoid | 1347 | /* |
1348 | * Take a first sample, leaving nPENIRQ active and vREF off; avoid | ||
1298 | * the touchscreen, in case it's not connected. | 1349 | * the touchscreen, in case it's not connected. |
1299 | */ | 1350 | */ |
1300 | if (ts->model == 7845) | 1351 | if (ts->model == 7845) |
1301 | ads7845_read12_ser(&spi->dev, PWRDOWN); | 1352 | ads7845_read12_ser(&spi->dev, PWRDOWN); |
1302 | else | 1353 | else |
1303 | (void) ads7846_read12_ser(&spi->dev, | 1354 | (void) ads7846_read12_ser(&spi->dev, READ_12BIT_SER(vaux)); |
1304 | READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); | ||
1305 | 1355 | ||
1306 | err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); | 1356 | err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); |
1307 | if (err) | 1357 | if (err) |
@@ -1326,7 +1376,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1326 | err_put_regulator: | 1376 | err_put_regulator: |
1327 | regulator_put(ts->reg); | 1377 | regulator_put(ts->reg); |
1328 | err_free_gpio: | 1378 | err_free_gpio: |
1329 | if (ts->gpio_pendown != -1) | 1379 | if (!ts->get_pendown_state) |
1330 | gpio_free(ts->gpio_pendown); | 1380 | gpio_free(ts->gpio_pendown); |
1331 | err_cleanup_filter: | 1381 | err_cleanup_filter: |
1332 | if (ts->filter_cleanup) | 1382 | if (ts->filter_cleanup) |
@@ -1340,26 +1390,29 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
1340 | 1390 | ||
1341 | static int __devexit ads7846_remove(struct spi_device *spi) | 1391 | static int __devexit ads7846_remove(struct spi_device *spi) |
1342 | { | 1392 | { |
1343 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 1393 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
1344 | 1394 | ||
1345 | device_init_wakeup(&spi->dev, false); | 1395 | device_init_wakeup(&spi->dev, false); |
1346 | 1396 | ||
1347 | ads784x_hwmon_unregister(spi, ts); | ||
1348 | input_unregister_device(ts->input); | ||
1349 | |||
1350 | ads7846_suspend(spi, PMSG_SUSPEND); | ||
1351 | |||
1352 | sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); | 1397 | sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); |
1353 | 1398 | ||
1399 | ads7846_disable(ts); | ||
1354 | free_irq(ts->spi->irq, ts); | 1400 | free_irq(ts->spi->irq, ts); |
1355 | /* suspend left the IRQ disabled */ | 1401 | |
1356 | enable_irq(ts->spi->irq); | 1402 | input_unregister_device(ts->input); |
1403 | |||
1404 | ads784x_hwmon_unregister(spi, ts); | ||
1357 | 1405 | ||
1358 | regulator_disable(ts->reg); | 1406 | regulator_disable(ts->reg); |
1359 | regulator_put(ts->reg); | 1407 | regulator_put(ts->reg); |
1360 | 1408 | ||
1361 | if (ts->gpio_pendown != -1) | 1409 | if (!ts->get_pendown_state) { |
1410 | /* | ||
1411 | * If we are not using specialized pendown method we must | ||
1412 | * have been relying on gpio we set up ourselves. | ||
1413 | */ | ||
1362 | gpio_free(ts->gpio_pendown); | 1414 | gpio_free(ts->gpio_pendown); |
1415 | } | ||
1363 | 1416 | ||
1364 | if (ts->filter_cleanup) | 1417 | if (ts->filter_cleanup) |
1365 | ts->filter_cleanup(ts->filter_data); | 1418 | ts->filter_cleanup(ts->filter_data); |
@@ -1368,6 +1421,7 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
1368 | kfree(ts); | 1421 | kfree(ts); |
1369 | 1422 | ||
1370 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); | 1423 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); |
1424 | |||
1371 | return 0; | 1425 | return 0; |
1372 | } | 1426 | } |
1373 | 1427 | ||
@@ -1376,11 +1430,10 @@ static struct spi_driver ads7846_driver = { | |||
1376 | .name = "ads7846", | 1430 | .name = "ads7846", |
1377 | .bus = &spi_bus_type, | 1431 | .bus = &spi_bus_type, |
1378 | .owner = THIS_MODULE, | 1432 | .owner = THIS_MODULE, |
1433 | .pm = &ads7846_pm, | ||
1379 | }, | 1434 | }, |
1380 | .probe = ads7846_probe, | 1435 | .probe = ads7846_probe, |
1381 | .remove = __devexit_p(ads7846_remove), | 1436 | .remove = __devexit_p(ads7846_remove), |
1382 | .suspend = ads7846_suspend, | ||
1383 | .resume = ads7846_resume, | ||
1384 | }; | 1437 | }; |
1385 | 1438 | ||
1386 | static int __init ads7846_init(void) | 1439 | static int __init ads7846_init(void) |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c new file mode 100644 index 000000000000..1e61387c73ca --- /dev/null +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -0,0 +1,1243 @@ | |||
1 | /* | ||
2 | * Atmel maXTouch Touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | ||
5 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/firmware.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/i2c/atmel_mxt_ts.h> | ||
20 | #include <linux/input/mt.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | /* Version */ | ||
25 | #define MXT_VER_20 20 | ||
26 | #define MXT_VER_21 21 | ||
27 | #define MXT_VER_22 22 | ||
28 | |||
29 | /* Slave addresses */ | ||
30 | #define MXT_APP_LOW 0x4a | ||
31 | #define MXT_APP_HIGH 0x4b | ||
32 | #define MXT_BOOT_LOW 0x24 | ||
33 | #define MXT_BOOT_HIGH 0x25 | ||
34 | |||
35 | /* Firmware */ | ||
36 | #define MXT_FW_NAME "maxtouch.fw" | ||
37 | |||
38 | /* Registers */ | ||
39 | #define MXT_FAMILY_ID 0x00 | ||
40 | #define MXT_VARIANT_ID 0x01 | ||
41 | #define MXT_VERSION 0x02 | ||
42 | #define MXT_BUILD 0x03 | ||
43 | #define MXT_MATRIX_X_SIZE 0x04 | ||
44 | #define MXT_MATRIX_Y_SIZE 0x05 | ||
45 | #define MXT_OBJECT_NUM 0x06 | ||
46 | #define MXT_OBJECT_START 0x07 | ||
47 | |||
48 | #define MXT_OBJECT_SIZE 6 | ||
49 | |||
50 | /* Object types */ | ||
51 | #define MXT_DEBUG_DIAGNOSTIC 37 | ||
52 | #define MXT_GEN_MESSAGE 5 | ||
53 | #define MXT_GEN_COMMAND 6 | ||
54 | #define MXT_GEN_POWER 7 | ||
55 | #define MXT_GEN_ACQUIRE 8 | ||
56 | #define MXT_TOUCH_MULTI 9 | ||
57 | #define MXT_TOUCH_KEYARRAY 15 | ||
58 | #define MXT_TOUCH_PROXIMITY 23 | ||
59 | #define MXT_PROCI_GRIPFACE 20 | ||
60 | #define MXT_PROCG_NOISE 22 | ||
61 | #define MXT_PROCI_ONETOUCH 24 | ||
62 | #define MXT_PROCI_TWOTOUCH 27 | ||
63 | #define MXT_PROCI_GRIP 40 | ||
64 | #define MXT_PROCI_PALM 41 | ||
65 | #define MXT_SPT_COMMSCONFIG 18 | ||
66 | #define MXT_SPT_GPIOPWM 19 | ||
67 | #define MXT_SPT_SELFTEST 25 | ||
68 | #define MXT_SPT_CTECONFIG 28 | ||
69 | #define MXT_SPT_USERDATA 38 | ||
70 | #define MXT_SPT_DIGITIZER 43 | ||
71 | #define MXT_SPT_MESSAGECOUNT 44 | ||
72 | |||
73 | /* MXT_GEN_COMMAND field */ | ||
74 | #define MXT_COMMAND_RESET 0 | ||
75 | #define MXT_COMMAND_BACKUPNV 1 | ||
76 | #define MXT_COMMAND_CALIBRATE 2 | ||
77 | #define MXT_COMMAND_REPORTALL 3 | ||
78 | #define MXT_COMMAND_DIAGNOSTIC 5 | ||
79 | |||
80 | /* MXT_GEN_POWER field */ | ||
81 | #define MXT_POWER_IDLEACQINT 0 | ||
82 | #define MXT_POWER_ACTVACQINT 1 | ||
83 | #define MXT_POWER_ACTV2IDLETO 2 | ||
84 | |||
85 | /* MXT_GEN_ACQUIRE field */ | ||
86 | #define MXT_ACQUIRE_CHRGTIME 0 | ||
87 | #define MXT_ACQUIRE_TCHDRIFT 2 | ||
88 | #define MXT_ACQUIRE_DRIFTST 3 | ||
89 | #define MXT_ACQUIRE_TCHAUTOCAL 4 | ||
90 | #define MXT_ACQUIRE_SYNC 5 | ||
91 | #define MXT_ACQUIRE_ATCHCALST 6 | ||
92 | #define MXT_ACQUIRE_ATCHCALSTHR 7 | ||
93 | |||
94 | /* MXT_TOUCH_MULTI field */ | ||
95 | #define MXT_TOUCH_CTRL 0 | ||
96 | #define MXT_TOUCH_XORIGIN 1 | ||
97 | #define MXT_TOUCH_YORIGIN 2 | ||
98 | #define MXT_TOUCH_XSIZE 3 | ||
99 | #define MXT_TOUCH_YSIZE 4 | ||
100 | #define MXT_TOUCH_BLEN 6 | ||
101 | #define MXT_TOUCH_TCHTHR 7 | ||
102 | #define MXT_TOUCH_TCHDI 8 | ||
103 | #define MXT_TOUCH_ORIENT 9 | ||
104 | #define MXT_TOUCH_MOVHYSTI 11 | ||
105 | #define MXT_TOUCH_MOVHYSTN 12 | ||
106 | #define MXT_TOUCH_NUMTOUCH 14 | ||
107 | #define MXT_TOUCH_MRGHYST 15 | ||
108 | #define MXT_TOUCH_MRGTHR 16 | ||
109 | #define MXT_TOUCH_AMPHYST 17 | ||
110 | #define MXT_TOUCH_XRANGE_LSB 18 | ||
111 | #define MXT_TOUCH_XRANGE_MSB 19 | ||
112 | #define MXT_TOUCH_YRANGE_LSB 20 | ||
113 | #define MXT_TOUCH_YRANGE_MSB 21 | ||
114 | #define MXT_TOUCH_XLOCLIP 22 | ||
115 | #define MXT_TOUCH_XHICLIP 23 | ||
116 | #define MXT_TOUCH_YLOCLIP 24 | ||
117 | #define MXT_TOUCH_YHICLIP 25 | ||
118 | #define MXT_TOUCH_XEDGECTRL 26 | ||
119 | #define MXT_TOUCH_XEDGEDIST 27 | ||
120 | #define MXT_TOUCH_YEDGECTRL 28 | ||
121 | #define MXT_TOUCH_YEDGEDIST 29 | ||
122 | #define MXT_TOUCH_JUMPLIMIT 30 | ||
123 | |||
124 | /* MXT_PROCI_GRIPFACE field */ | ||
125 | #define MXT_GRIPFACE_CTRL 0 | ||
126 | #define MXT_GRIPFACE_XLOGRIP 1 | ||
127 | #define MXT_GRIPFACE_XHIGRIP 2 | ||
128 | #define MXT_GRIPFACE_YLOGRIP 3 | ||
129 | #define MXT_GRIPFACE_YHIGRIP 4 | ||
130 | #define MXT_GRIPFACE_MAXTCHS 5 | ||
131 | #define MXT_GRIPFACE_SZTHR1 7 | ||
132 | #define MXT_GRIPFACE_SZTHR2 8 | ||
133 | #define MXT_GRIPFACE_SHPTHR1 9 | ||
134 | #define MXT_GRIPFACE_SHPTHR2 10 | ||
135 | #define MXT_GRIPFACE_SUPEXTTO 11 | ||
136 | |||
137 | /* MXT_PROCI_NOISE field */ | ||
138 | #define MXT_NOISE_CTRL 0 | ||
139 | #define MXT_NOISE_OUTFLEN 1 | ||
140 | #define MXT_NOISE_GCAFUL_LSB 3 | ||
141 | #define MXT_NOISE_GCAFUL_MSB 4 | ||
142 | #define MXT_NOISE_GCAFLL_LSB 5 | ||
143 | #define MXT_NOISE_GCAFLL_MSB 6 | ||
144 | #define MXT_NOISE_ACTVGCAFVALID 7 | ||
145 | #define MXT_NOISE_NOISETHR 8 | ||
146 | #define MXT_NOISE_FREQHOPSCALE 10 | ||
147 | #define MXT_NOISE_FREQ0 11 | ||
148 | #define MXT_NOISE_FREQ1 12 | ||
149 | #define MXT_NOISE_FREQ2 13 | ||
150 | #define MXT_NOISE_FREQ3 14 | ||
151 | #define MXT_NOISE_FREQ4 15 | ||
152 | #define MXT_NOISE_IDLEGCAFVALID 16 | ||
153 | |||
154 | /* MXT_SPT_COMMSCONFIG */ | ||
155 | #define MXT_COMMS_CTRL 0 | ||
156 | #define MXT_COMMS_CMD 1 | ||
157 | |||
158 | /* MXT_SPT_CTECONFIG field */ | ||
159 | #define MXT_CTE_CTRL 0 | ||
160 | #define MXT_CTE_CMD 1 | ||
161 | #define MXT_CTE_MODE 2 | ||
162 | #define MXT_CTE_IDLEGCAFDEPTH 3 | ||
163 | #define MXT_CTE_ACTVGCAFDEPTH 4 | ||
164 | #define MXT_CTE_VOLTAGE 5 | ||
165 | |||
166 | #define MXT_VOLTAGE_DEFAULT 2700000 | ||
167 | #define MXT_VOLTAGE_STEP 10000 | ||
168 | |||
169 | /* Define for MXT_GEN_COMMAND */ | ||
170 | #define MXT_BOOT_VALUE 0xa5 | ||
171 | #define MXT_BACKUP_VALUE 0x55 | ||
172 | #define MXT_BACKUP_TIME 25 /* msec */ | ||
173 | #define MXT_RESET_TIME 65 /* msec */ | ||
174 | |||
175 | #define MXT_FWRESET_TIME 175 /* msec */ | ||
176 | |||
177 | /* Command to unlock bootloader */ | ||
178 | #define MXT_UNLOCK_CMD_MSB 0xaa | ||
179 | #define MXT_UNLOCK_CMD_LSB 0xdc | ||
180 | |||
181 | /* Bootloader mode status */ | ||
182 | #define MXT_WAITING_BOOTLOAD_CMD 0xc0 /* valid 7 6 bit only */ | ||
183 | #define MXT_WAITING_FRAME_DATA 0x80 /* valid 7 6 bit only */ | ||
184 | #define MXT_FRAME_CRC_CHECK 0x02 | ||
185 | #define MXT_FRAME_CRC_FAIL 0x03 | ||
186 | #define MXT_FRAME_CRC_PASS 0x04 | ||
187 | #define MXT_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */ | ||
188 | #define MXT_BOOT_STATUS_MASK 0x3f | ||
189 | |||
190 | /* Touch status */ | ||
191 | #define MXT_SUPPRESS (1 << 1) | ||
192 | #define MXT_AMP (1 << 2) | ||
193 | #define MXT_VECTOR (1 << 3) | ||
194 | #define MXT_MOVE (1 << 4) | ||
195 | #define MXT_RELEASE (1 << 5) | ||
196 | #define MXT_PRESS (1 << 6) | ||
197 | #define MXT_DETECT (1 << 7) | ||
198 | |||
199 | /* Touch orient bits */ | ||
200 | #define MXT_XY_SWITCH (1 << 0) | ||
201 | #define MXT_X_INVERT (1 << 1) | ||
202 | #define MXT_Y_INVERT (1 << 2) | ||
203 | |||
204 | /* Touchscreen absolute values */ | ||
205 | #define MXT_MAX_AREA 0xff | ||
206 | |||
207 | #define MXT_MAX_FINGER 10 | ||
208 | |||
209 | struct mxt_info { | ||
210 | u8 family_id; | ||
211 | u8 variant_id; | ||
212 | u8 version; | ||
213 | u8 build; | ||
214 | u8 matrix_xsize; | ||
215 | u8 matrix_ysize; | ||
216 | u8 object_num; | ||
217 | }; | ||
218 | |||
219 | struct mxt_object { | ||
220 | u8 type; | ||
221 | u16 start_address; | ||
222 | u8 size; | ||
223 | u8 instances; | ||
224 | u8 num_report_ids; | ||
225 | |||
226 | /* to map object and message */ | ||
227 | u8 max_reportid; | ||
228 | }; | ||
229 | |||
230 | struct mxt_message { | ||
231 | u8 reportid; | ||
232 | u8 message[7]; | ||
233 | u8 checksum; | ||
234 | }; | ||
235 | |||
236 | struct mxt_finger { | ||
237 | int status; | ||
238 | int x; | ||
239 | int y; | ||
240 | int area; | ||
241 | }; | ||
242 | |||
243 | /* Each client has this additional data */ | ||
244 | struct mxt_data { | ||
245 | struct i2c_client *client; | ||
246 | struct input_dev *input_dev; | ||
247 | const struct mxt_platform_data *pdata; | ||
248 | struct mxt_object *object_table; | ||
249 | struct mxt_info info; | ||
250 | struct mxt_finger finger[MXT_MAX_FINGER]; | ||
251 | unsigned int irq; | ||
252 | unsigned int max_x; | ||
253 | unsigned int max_y; | ||
254 | }; | ||
255 | |||
256 | static bool mxt_object_readable(unsigned int type) | ||
257 | { | ||
258 | switch (type) { | ||
259 | case MXT_GEN_MESSAGE: | ||
260 | case MXT_GEN_COMMAND: | ||
261 | case MXT_GEN_POWER: | ||
262 | case MXT_GEN_ACQUIRE: | ||
263 | case MXT_TOUCH_MULTI: | ||
264 | case MXT_TOUCH_KEYARRAY: | ||
265 | case MXT_TOUCH_PROXIMITY: | ||
266 | case MXT_PROCI_GRIPFACE: | ||
267 | case MXT_PROCG_NOISE: | ||
268 | case MXT_PROCI_ONETOUCH: | ||
269 | case MXT_PROCI_TWOTOUCH: | ||
270 | case MXT_PROCI_GRIP: | ||
271 | case MXT_PROCI_PALM: | ||
272 | case MXT_SPT_COMMSCONFIG: | ||
273 | case MXT_SPT_GPIOPWM: | ||
274 | case MXT_SPT_SELFTEST: | ||
275 | case MXT_SPT_CTECONFIG: | ||
276 | case MXT_SPT_USERDATA: | ||
277 | return true; | ||
278 | default: | ||
279 | return false; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | static bool mxt_object_writable(unsigned int type) | ||
284 | { | ||
285 | switch (type) { | ||
286 | case MXT_GEN_COMMAND: | ||
287 | case MXT_GEN_POWER: | ||
288 | case MXT_GEN_ACQUIRE: | ||
289 | case MXT_TOUCH_MULTI: | ||
290 | case MXT_TOUCH_KEYARRAY: | ||
291 | case MXT_TOUCH_PROXIMITY: | ||
292 | case MXT_PROCI_GRIPFACE: | ||
293 | case MXT_PROCG_NOISE: | ||
294 | case MXT_PROCI_ONETOUCH: | ||
295 | case MXT_PROCI_TWOTOUCH: | ||
296 | case MXT_PROCI_GRIP: | ||
297 | case MXT_PROCI_PALM: | ||
298 | case MXT_SPT_GPIOPWM: | ||
299 | case MXT_SPT_SELFTEST: | ||
300 | case MXT_SPT_CTECONFIG: | ||
301 | return true; | ||
302 | default: | ||
303 | return false; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | static void mxt_dump_message(struct device *dev, | ||
308 | struct mxt_message *message) | ||
309 | { | ||
310 | dev_dbg(dev, "reportid:\t0x%x\n", message->reportid); | ||
311 | dev_dbg(dev, "message1:\t0x%x\n", message->message[0]); | ||
312 | dev_dbg(dev, "message2:\t0x%x\n", message->message[1]); | ||
313 | dev_dbg(dev, "message3:\t0x%x\n", message->message[2]); | ||
314 | dev_dbg(dev, "message4:\t0x%x\n", message->message[3]); | ||
315 | dev_dbg(dev, "message5:\t0x%x\n", message->message[4]); | ||
316 | dev_dbg(dev, "message6:\t0x%x\n", message->message[5]); | ||
317 | dev_dbg(dev, "message7:\t0x%x\n", message->message[6]); | ||
318 | dev_dbg(dev, "checksum:\t0x%x\n", message->checksum); | ||
319 | } | ||
320 | |||
321 | static int mxt_check_bootloader(struct i2c_client *client, | ||
322 | unsigned int state) | ||
323 | { | ||
324 | u8 val; | ||
325 | |||
326 | recheck: | ||
327 | if (i2c_master_recv(client, &val, 1) != 1) { | ||
328 | dev_err(&client->dev, "%s: i2c recv failed\n", __func__); | ||
329 | return -EIO; | ||
330 | } | ||
331 | |||
332 | switch (state) { | ||
333 | case MXT_WAITING_BOOTLOAD_CMD: | ||
334 | case MXT_WAITING_FRAME_DATA: | ||
335 | val &= ~MXT_BOOT_STATUS_MASK; | ||
336 | break; | ||
337 | case MXT_FRAME_CRC_PASS: | ||
338 | if (val == MXT_FRAME_CRC_CHECK) | ||
339 | goto recheck; | ||
340 | break; | ||
341 | default: | ||
342 | return -EINVAL; | ||
343 | } | ||
344 | |||
345 | if (val != state) { | ||
346 | dev_err(&client->dev, "Unvalid bootloader mode state\n"); | ||
347 | return -EINVAL; | ||
348 | } | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int mxt_unlock_bootloader(struct i2c_client *client) | ||
354 | { | ||
355 | u8 buf[2]; | ||
356 | |||
357 | buf[0] = MXT_UNLOCK_CMD_LSB; | ||
358 | buf[1] = MXT_UNLOCK_CMD_MSB; | ||
359 | |||
360 | if (i2c_master_send(client, buf, 2) != 2) { | ||
361 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
362 | return -EIO; | ||
363 | } | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static int mxt_fw_write(struct i2c_client *client, | ||
369 | const u8 *data, unsigned int frame_size) | ||
370 | { | ||
371 | if (i2c_master_send(client, data, frame_size) != frame_size) { | ||
372 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
373 | return -EIO; | ||
374 | } | ||
375 | |||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static int __mxt_read_reg(struct i2c_client *client, | ||
380 | u16 reg, u16 len, void *val) | ||
381 | { | ||
382 | struct i2c_msg xfer[2]; | ||
383 | u8 buf[2]; | ||
384 | |||
385 | buf[0] = reg & 0xff; | ||
386 | buf[1] = (reg >> 8) & 0xff; | ||
387 | |||
388 | /* Write register */ | ||
389 | xfer[0].addr = client->addr; | ||
390 | xfer[0].flags = 0; | ||
391 | xfer[0].len = 2; | ||
392 | xfer[0].buf = buf; | ||
393 | |||
394 | /* Read data */ | ||
395 | xfer[1].addr = client->addr; | ||
396 | xfer[1].flags = I2C_M_RD; | ||
397 | xfer[1].len = len; | ||
398 | xfer[1].buf = val; | ||
399 | |||
400 | if (i2c_transfer(client->adapter, xfer, 2) != 2) { | ||
401 | dev_err(&client->dev, "%s: i2c transfer failed\n", __func__); | ||
402 | return -EIO; | ||
403 | } | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val) | ||
409 | { | ||
410 | return __mxt_read_reg(client, reg, 1, val); | ||
411 | } | ||
412 | |||
413 | static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val) | ||
414 | { | ||
415 | u8 buf[3]; | ||
416 | |||
417 | buf[0] = reg & 0xff; | ||
418 | buf[1] = (reg >> 8) & 0xff; | ||
419 | buf[2] = val; | ||
420 | |||
421 | if (i2c_master_send(client, buf, 3) != 3) { | ||
422 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
423 | return -EIO; | ||
424 | } | ||
425 | |||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static int mxt_read_object_table(struct i2c_client *client, | ||
430 | u16 reg, u8 *object_buf) | ||
431 | { | ||
432 | return __mxt_read_reg(client, reg, MXT_OBJECT_SIZE, | ||
433 | object_buf); | ||
434 | } | ||
435 | |||
436 | static struct mxt_object * | ||
437 | mxt_get_object(struct mxt_data *data, u8 type) | ||
438 | { | ||
439 | struct mxt_object *object; | ||
440 | int i; | ||
441 | |||
442 | for (i = 0; i < data->info.object_num; i++) { | ||
443 | object = data->object_table + i; | ||
444 | if (object->type == type) | ||
445 | return object; | ||
446 | } | ||
447 | |||
448 | dev_err(&data->client->dev, "Invalid object type\n"); | ||
449 | return NULL; | ||
450 | } | ||
451 | |||
452 | static int mxt_read_message(struct mxt_data *data, | ||
453 | struct mxt_message *message) | ||
454 | { | ||
455 | struct mxt_object *object; | ||
456 | u16 reg; | ||
457 | |||
458 | object = mxt_get_object(data, MXT_GEN_MESSAGE); | ||
459 | if (!object) | ||
460 | return -EINVAL; | ||
461 | |||
462 | reg = object->start_address; | ||
463 | return __mxt_read_reg(data->client, reg, | ||
464 | sizeof(struct mxt_message), message); | ||
465 | } | ||
466 | |||
467 | static int mxt_read_object(struct mxt_data *data, | ||
468 | u8 type, u8 offset, u8 *val) | ||
469 | { | ||
470 | struct mxt_object *object; | ||
471 | u16 reg; | ||
472 | |||
473 | object = mxt_get_object(data, type); | ||
474 | if (!object) | ||
475 | return -EINVAL; | ||
476 | |||
477 | reg = object->start_address; | ||
478 | return __mxt_read_reg(data->client, reg + offset, 1, val); | ||
479 | } | ||
480 | |||
481 | static int mxt_write_object(struct mxt_data *data, | ||
482 | u8 type, u8 offset, u8 val) | ||
483 | { | ||
484 | struct mxt_object *object; | ||
485 | u16 reg; | ||
486 | |||
487 | object = mxt_get_object(data, type); | ||
488 | if (!object) | ||
489 | return -EINVAL; | ||
490 | |||
491 | reg = object->start_address; | ||
492 | return mxt_write_reg(data->client, reg + offset, val); | ||
493 | } | ||
494 | |||
495 | static void mxt_input_report(struct mxt_data *data, int single_id) | ||
496 | { | ||
497 | struct mxt_finger *finger = data->finger; | ||
498 | struct input_dev *input_dev = data->input_dev; | ||
499 | int status = finger[single_id].status; | ||
500 | int finger_num = 0; | ||
501 | int id; | ||
502 | |||
503 | for (id = 0; id < MXT_MAX_FINGER; id++) { | ||
504 | if (!finger[id].status) | ||
505 | continue; | ||
506 | |||
507 | input_mt_slot(input_dev, id); | ||
508 | input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, | ||
509 | finger[id].status != MXT_RELEASE); | ||
510 | |||
511 | if (finger[id].status != MXT_RELEASE) { | ||
512 | finger_num++; | ||
513 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, | ||
514 | finger[id].area); | ||
515 | input_report_abs(input_dev, ABS_MT_POSITION_X, | ||
516 | finger[id].x); | ||
517 | input_report_abs(input_dev, ABS_MT_POSITION_Y, | ||
518 | finger[id].y); | ||
519 | } else { | ||
520 | finger[id].status = 0; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | input_report_key(input_dev, BTN_TOUCH, finger_num > 0); | ||
525 | |||
526 | if (status != MXT_RELEASE) { | ||
527 | input_report_abs(input_dev, ABS_X, finger[single_id].x); | ||
528 | input_report_abs(input_dev, ABS_Y, finger[single_id].y); | ||
529 | } | ||
530 | |||
531 | input_sync(input_dev); | ||
532 | } | ||
533 | |||
534 | static void mxt_input_touchevent(struct mxt_data *data, | ||
535 | struct mxt_message *message, int id) | ||
536 | { | ||
537 | struct mxt_finger *finger = data->finger; | ||
538 | struct device *dev = &data->client->dev; | ||
539 | u8 status = message->message[0]; | ||
540 | int x; | ||
541 | int y; | ||
542 | int area; | ||
543 | |||
544 | /* Check the touch is present on the screen */ | ||
545 | if (!(status & MXT_DETECT)) { | ||
546 | if (status & MXT_RELEASE) { | ||
547 | dev_dbg(dev, "[%d] released\n", id); | ||
548 | |||
549 | finger[id].status = MXT_RELEASE; | ||
550 | mxt_input_report(data, id); | ||
551 | } | ||
552 | return; | ||
553 | } | ||
554 | |||
555 | /* Check only AMP detection */ | ||
556 | if (!(status & (MXT_PRESS | MXT_MOVE))) | ||
557 | return; | ||
558 | |||
559 | x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf); | ||
560 | y = (message->message[2] << 4) | ((message->message[3] & 0xf)); | ||
561 | if (data->max_x < 1024) | ||
562 | x = x >> 2; | ||
563 | if (data->max_y < 1024) | ||
564 | y = y >> 2; | ||
565 | |||
566 | area = message->message[4]; | ||
567 | |||
568 | dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id, | ||
569 | status & MXT_MOVE ? "moved" : "pressed", | ||
570 | x, y, area); | ||
571 | |||
572 | finger[id].status = status & MXT_MOVE ? | ||
573 | MXT_MOVE : MXT_PRESS; | ||
574 | finger[id].x = x; | ||
575 | finger[id].y = y; | ||
576 | finger[id].area = area; | ||
577 | |||
578 | mxt_input_report(data, id); | ||
579 | } | ||
580 | |||
581 | static irqreturn_t mxt_interrupt(int irq, void *dev_id) | ||
582 | { | ||
583 | struct mxt_data *data = dev_id; | ||
584 | struct mxt_message message; | ||
585 | struct mxt_object *object; | ||
586 | struct device *dev = &data->client->dev; | ||
587 | int id; | ||
588 | u8 reportid; | ||
589 | u8 max_reportid; | ||
590 | u8 min_reportid; | ||
591 | |||
592 | do { | ||
593 | if (mxt_read_message(data, &message)) { | ||
594 | dev_err(dev, "Failed to read message\n"); | ||
595 | goto end; | ||
596 | } | ||
597 | |||
598 | reportid = message.reportid; | ||
599 | |||
600 | /* whether reportid is thing of MXT_TOUCH_MULTI */ | ||
601 | object = mxt_get_object(data, MXT_TOUCH_MULTI); | ||
602 | if (!object) | ||
603 | goto end; | ||
604 | |||
605 | max_reportid = object->max_reportid; | ||
606 | min_reportid = max_reportid - object->num_report_ids + 1; | ||
607 | id = reportid - min_reportid; | ||
608 | |||
609 | if (reportid >= min_reportid && reportid <= max_reportid) | ||
610 | mxt_input_touchevent(data, &message, id); | ||
611 | else | ||
612 | mxt_dump_message(dev, &message); | ||
613 | } while (reportid != 0xff); | ||
614 | |||
615 | end: | ||
616 | return IRQ_HANDLED; | ||
617 | } | ||
618 | |||
619 | static int mxt_check_reg_init(struct mxt_data *data) | ||
620 | { | ||
621 | const struct mxt_platform_data *pdata = data->pdata; | ||
622 | struct mxt_object *object; | ||
623 | struct device *dev = &data->client->dev; | ||
624 | int index = 0; | ||
625 | int i, j, config_offset; | ||
626 | |||
627 | if (!pdata->config) { | ||
628 | dev_dbg(dev, "No cfg data defined, skipping reg init\n"); | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | for (i = 0; i < data->info.object_num; i++) { | ||
633 | object = data->object_table + i; | ||
634 | |||
635 | if (!mxt_object_writable(object->type)) | ||
636 | continue; | ||
637 | |||
638 | for (j = 0; j < object->size + 1; j++) { | ||
639 | config_offset = index + j; | ||
640 | if (config_offset > pdata->config_length) { | ||
641 | dev_err(dev, "Not enough config data!\n"); | ||
642 | return -EINVAL; | ||
643 | } | ||
644 | mxt_write_object(data, object->type, j, | ||
645 | pdata->config[config_offset]); | ||
646 | } | ||
647 | index += object->size + 1; | ||
648 | } | ||
649 | |||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | static int mxt_make_highchg(struct mxt_data *data) | ||
654 | { | ||
655 | struct device *dev = &data->client->dev; | ||
656 | struct mxt_message message; | ||
657 | int count = 10; | ||
658 | int error; | ||
659 | |||
660 | /* Read dummy message to make high CHG pin */ | ||
661 | do { | ||
662 | error = mxt_read_message(data, &message); | ||
663 | if (error) | ||
664 | return error; | ||
665 | } while (message.reportid != 0xff && --count); | ||
666 | |||
667 | if (!count) { | ||
668 | dev_err(dev, "CHG pin isn't cleared\n"); | ||
669 | return -EBUSY; | ||
670 | } | ||
671 | |||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | static void mxt_handle_pdata(struct mxt_data *data) | ||
676 | { | ||
677 | const struct mxt_platform_data *pdata = data->pdata; | ||
678 | u8 voltage; | ||
679 | |||
680 | /* Set touchscreen lines */ | ||
681 | mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_XSIZE, | ||
682 | pdata->x_line); | ||
683 | mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_YSIZE, | ||
684 | pdata->y_line); | ||
685 | |||
686 | /* Set touchscreen orient */ | ||
687 | mxt_write_object(data, MXT_TOUCH_MULTI, MXT_TOUCH_ORIENT, | ||
688 | pdata->orient); | ||
689 | |||
690 | /* Set touchscreen burst length */ | ||
691 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
692 | MXT_TOUCH_BLEN, pdata->blen); | ||
693 | |||
694 | /* Set touchscreen threshold */ | ||
695 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
696 | MXT_TOUCH_TCHTHR, pdata->threshold); | ||
697 | |||
698 | /* Set touchscreen resolution */ | ||
699 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
700 | MXT_TOUCH_XRANGE_LSB, (pdata->x_size - 1) & 0xff); | ||
701 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
702 | MXT_TOUCH_XRANGE_MSB, (pdata->x_size - 1) >> 8); | ||
703 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
704 | MXT_TOUCH_YRANGE_LSB, (pdata->y_size - 1) & 0xff); | ||
705 | mxt_write_object(data, MXT_TOUCH_MULTI, | ||
706 | MXT_TOUCH_YRANGE_MSB, (pdata->y_size - 1) >> 8); | ||
707 | |||
708 | /* Set touchscreen voltage */ | ||
709 | if (pdata->voltage) { | ||
710 | if (pdata->voltage < MXT_VOLTAGE_DEFAULT) { | ||
711 | voltage = (MXT_VOLTAGE_DEFAULT - pdata->voltage) / | ||
712 | MXT_VOLTAGE_STEP; | ||
713 | voltage = 0xff - voltage + 1; | ||
714 | } else | ||
715 | voltage = (pdata->voltage - MXT_VOLTAGE_DEFAULT) / | ||
716 | MXT_VOLTAGE_STEP; | ||
717 | |||
718 | mxt_write_object(data, MXT_SPT_CTECONFIG, | ||
719 | MXT_CTE_VOLTAGE, voltage); | ||
720 | } | ||
721 | } | ||
722 | |||
723 | static int mxt_get_info(struct mxt_data *data) | ||
724 | { | ||
725 | struct i2c_client *client = data->client; | ||
726 | struct mxt_info *info = &data->info; | ||
727 | int error; | ||
728 | u8 val; | ||
729 | |||
730 | error = mxt_read_reg(client, MXT_FAMILY_ID, &val); | ||
731 | if (error) | ||
732 | return error; | ||
733 | info->family_id = val; | ||
734 | |||
735 | error = mxt_read_reg(client, MXT_VARIANT_ID, &val); | ||
736 | if (error) | ||
737 | return error; | ||
738 | info->variant_id = val; | ||
739 | |||
740 | error = mxt_read_reg(client, MXT_VERSION, &val); | ||
741 | if (error) | ||
742 | return error; | ||
743 | info->version = val; | ||
744 | |||
745 | error = mxt_read_reg(client, MXT_BUILD, &val); | ||
746 | if (error) | ||
747 | return error; | ||
748 | info->build = val; | ||
749 | |||
750 | error = mxt_read_reg(client, MXT_OBJECT_NUM, &val); | ||
751 | if (error) | ||
752 | return error; | ||
753 | info->object_num = val; | ||
754 | |||
755 | return 0; | ||
756 | } | ||
757 | |||
758 | static int mxt_get_object_table(struct mxt_data *data) | ||
759 | { | ||
760 | int error; | ||
761 | int i; | ||
762 | u16 reg; | ||
763 | u8 reportid = 0; | ||
764 | u8 buf[MXT_OBJECT_SIZE]; | ||
765 | |||
766 | for (i = 0; i < data->info.object_num; i++) { | ||
767 | struct mxt_object *object = data->object_table + i; | ||
768 | |||
769 | reg = MXT_OBJECT_START + MXT_OBJECT_SIZE * i; | ||
770 | error = mxt_read_object_table(data->client, reg, buf); | ||
771 | if (error) | ||
772 | return error; | ||
773 | |||
774 | object->type = buf[0]; | ||
775 | object->start_address = (buf[2] << 8) | buf[1]; | ||
776 | object->size = buf[3]; | ||
777 | object->instances = buf[4]; | ||
778 | object->num_report_ids = buf[5]; | ||
779 | |||
780 | if (object->num_report_ids) { | ||
781 | reportid += object->num_report_ids * | ||
782 | (object->instances + 1); | ||
783 | object->max_reportid = reportid; | ||
784 | } | ||
785 | } | ||
786 | |||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | static int mxt_initialize(struct mxt_data *data) | ||
791 | { | ||
792 | struct i2c_client *client = data->client; | ||
793 | struct mxt_info *info = &data->info; | ||
794 | int error; | ||
795 | u8 val; | ||
796 | |||
797 | error = mxt_get_info(data); | ||
798 | if (error) | ||
799 | return error; | ||
800 | |||
801 | data->object_table = kcalloc(info->object_num, | ||
802 | sizeof(struct mxt_object), | ||
803 | GFP_KERNEL); | ||
804 | if (!data->object_table) { | ||
805 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
806 | return -ENOMEM; | ||
807 | } | ||
808 | |||
809 | /* Get object table information */ | ||
810 | error = mxt_get_object_table(data); | ||
811 | if (error) | ||
812 | return error; | ||
813 | |||
814 | /* Check register init values */ | ||
815 | error = mxt_check_reg_init(data); | ||
816 | if (error) | ||
817 | return error; | ||
818 | |||
819 | mxt_handle_pdata(data); | ||
820 | |||
821 | /* Backup to memory */ | ||
822 | mxt_write_object(data, MXT_GEN_COMMAND, | ||
823 | MXT_COMMAND_BACKUPNV, | ||
824 | MXT_BACKUP_VALUE); | ||
825 | msleep(MXT_BACKUP_TIME); | ||
826 | |||
827 | /* Soft reset */ | ||
828 | mxt_write_object(data, MXT_GEN_COMMAND, | ||
829 | MXT_COMMAND_RESET, 1); | ||
830 | msleep(MXT_RESET_TIME); | ||
831 | |||
832 | /* Update matrix size at info struct */ | ||
833 | error = mxt_read_reg(client, MXT_MATRIX_X_SIZE, &val); | ||
834 | if (error) | ||
835 | return error; | ||
836 | info->matrix_xsize = val; | ||
837 | |||
838 | error = mxt_read_reg(client, MXT_MATRIX_Y_SIZE, &val); | ||
839 | if (error) | ||
840 | return error; | ||
841 | info->matrix_ysize = val; | ||
842 | |||
843 | dev_info(&client->dev, | ||
844 | "Family ID: %d Variant ID: %d Version: %d Build: %d\n", | ||
845 | info->family_id, info->variant_id, info->version, | ||
846 | info->build); | ||
847 | |||
848 | dev_info(&client->dev, | ||
849 | "Matrix X Size: %d Matrix Y Size: %d Object Num: %d\n", | ||
850 | info->matrix_xsize, info->matrix_ysize, | ||
851 | info->object_num); | ||
852 | |||
853 | return 0; | ||
854 | } | ||
855 | |||
856 | static void mxt_calc_resolution(struct mxt_data *data) | ||
857 | { | ||
858 | unsigned int max_x = data->pdata->x_size - 1; | ||
859 | unsigned int max_y = data->pdata->y_size - 1; | ||
860 | |||
861 | if (data->pdata->orient & MXT_XY_SWITCH) { | ||
862 | data->max_x = max_y; | ||
863 | data->max_y = max_x; | ||
864 | } else { | ||
865 | data->max_x = max_x; | ||
866 | data->max_y = max_y; | ||
867 | } | ||
868 | } | ||
869 | |||
870 | static ssize_t mxt_object_show(struct device *dev, | ||
871 | struct device_attribute *attr, char *buf) | ||
872 | { | ||
873 | struct mxt_data *data = dev_get_drvdata(dev); | ||
874 | struct mxt_object *object; | ||
875 | int count = 0; | ||
876 | int i, j; | ||
877 | int error; | ||
878 | u8 val; | ||
879 | |||
880 | for (i = 0; i < data->info.object_num; i++) { | ||
881 | object = data->object_table + i; | ||
882 | |||
883 | count += sprintf(buf + count, | ||
884 | "Object Table Element %d(Type %d)\n", | ||
885 | i + 1, object->type); | ||
886 | |||
887 | if (!mxt_object_readable(object->type)) { | ||
888 | count += sprintf(buf + count, "\n"); | ||
889 | continue; | ||
890 | } | ||
891 | |||
892 | for (j = 0; j < object->size + 1; j++) { | ||
893 | error = mxt_read_object(data, | ||
894 | object->type, j, &val); | ||
895 | if (error) | ||
896 | return error; | ||
897 | |||
898 | count += sprintf(buf + count, | ||
899 | " Byte %d: 0x%x (%d)\n", j, val, val); | ||
900 | } | ||
901 | |||
902 | count += sprintf(buf + count, "\n"); | ||
903 | } | ||
904 | |||
905 | return count; | ||
906 | } | ||
907 | |||
908 | static int mxt_load_fw(struct device *dev, const char *fn) | ||
909 | { | ||
910 | struct mxt_data *data = dev_get_drvdata(dev); | ||
911 | struct i2c_client *client = data->client; | ||
912 | const struct firmware *fw = NULL; | ||
913 | unsigned int frame_size; | ||
914 | unsigned int pos = 0; | ||
915 | int ret; | ||
916 | |||
917 | ret = request_firmware(&fw, fn, dev); | ||
918 | if (ret) { | ||
919 | dev_err(dev, "Unable to open firmware %s\n", fn); | ||
920 | return ret; | ||
921 | } | ||
922 | |||
923 | /* Change to the bootloader mode */ | ||
924 | mxt_write_object(data, MXT_GEN_COMMAND, | ||
925 | MXT_COMMAND_RESET, MXT_BOOT_VALUE); | ||
926 | msleep(MXT_RESET_TIME); | ||
927 | |||
928 | /* Change to slave address of bootloader */ | ||
929 | if (client->addr == MXT_APP_LOW) | ||
930 | client->addr = MXT_BOOT_LOW; | ||
931 | else | ||
932 | client->addr = MXT_BOOT_HIGH; | ||
933 | |||
934 | ret = mxt_check_bootloader(client, MXT_WAITING_BOOTLOAD_CMD); | ||
935 | if (ret) | ||
936 | goto out; | ||
937 | |||
938 | /* Unlock bootloader */ | ||
939 | mxt_unlock_bootloader(client); | ||
940 | |||
941 | while (pos < fw->size) { | ||
942 | ret = mxt_check_bootloader(client, | ||
943 | MXT_WAITING_FRAME_DATA); | ||
944 | if (ret) | ||
945 | goto out; | ||
946 | |||
947 | frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); | ||
948 | |||
949 | /* We should add 2 at frame size as the the firmware data is not | ||
950 | * included the CRC bytes. | ||
951 | */ | ||
952 | frame_size += 2; | ||
953 | |||
954 | /* Write one frame to device */ | ||
955 | mxt_fw_write(client, fw->data + pos, frame_size); | ||
956 | |||
957 | ret = mxt_check_bootloader(client, | ||
958 | MXT_FRAME_CRC_PASS); | ||
959 | if (ret) | ||
960 | goto out; | ||
961 | |||
962 | pos += frame_size; | ||
963 | |||
964 | dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size); | ||
965 | } | ||
966 | |||
967 | out: | ||
968 | release_firmware(fw); | ||
969 | |||
970 | /* Change to slave address of application */ | ||
971 | if (client->addr == MXT_BOOT_LOW) | ||
972 | client->addr = MXT_APP_LOW; | ||
973 | else | ||
974 | client->addr = MXT_APP_HIGH; | ||
975 | |||
976 | return ret; | ||
977 | } | ||
978 | |||
979 | static ssize_t mxt_update_fw_store(struct device *dev, | ||
980 | struct device_attribute *attr, | ||
981 | const char *buf, size_t count) | ||
982 | { | ||
983 | struct mxt_data *data = dev_get_drvdata(dev); | ||
984 | int error; | ||
985 | |||
986 | disable_irq(data->irq); | ||
987 | |||
988 | error = mxt_load_fw(dev, MXT_FW_NAME); | ||
989 | if (error) { | ||
990 | dev_err(dev, "The firmware update failed(%d)\n", error); | ||
991 | count = error; | ||
992 | } else { | ||
993 | dev_dbg(dev, "The firmware update succeeded\n"); | ||
994 | |||
995 | /* Wait for reset */ | ||
996 | msleep(MXT_FWRESET_TIME); | ||
997 | |||
998 | kfree(data->object_table); | ||
999 | data->object_table = NULL; | ||
1000 | |||
1001 | mxt_initialize(data); | ||
1002 | } | ||
1003 | |||
1004 | enable_irq(data->irq); | ||
1005 | |||
1006 | error = mxt_make_highchg(data); | ||
1007 | if (error) | ||
1008 | return error; | ||
1009 | |||
1010 | return count; | ||
1011 | } | ||
1012 | |||
1013 | static DEVICE_ATTR(object, 0444, mxt_object_show, NULL); | ||
1014 | static DEVICE_ATTR(update_fw, 0664, NULL, mxt_update_fw_store); | ||
1015 | |||
1016 | static struct attribute *mxt_attrs[] = { | ||
1017 | &dev_attr_object.attr, | ||
1018 | &dev_attr_update_fw.attr, | ||
1019 | NULL | ||
1020 | }; | ||
1021 | |||
1022 | static const struct attribute_group mxt_attr_group = { | ||
1023 | .attrs = mxt_attrs, | ||
1024 | }; | ||
1025 | |||
1026 | static void mxt_start(struct mxt_data *data) | ||
1027 | { | ||
1028 | /* Touch enable */ | ||
1029 | mxt_write_object(data, | ||
1030 | MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, 0x83); | ||
1031 | } | ||
1032 | |||
1033 | static void mxt_stop(struct mxt_data *data) | ||
1034 | { | ||
1035 | /* Touch disable */ | ||
1036 | mxt_write_object(data, | ||
1037 | MXT_TOUCH_MULTI, MXT_TOUCH_CTRL, 0); | ||
1038 | } | ||
1039 | |||
1040 | static int mxt_input_open(struct input_dev *dev) | ||
1041 | { | ||
1042 | struct mxt_data *data = input_get_drvdata(dev); | ||
1043 | |||
1044 | mxt_start(data); | ||
1045 | |||
1046 | return 0; | ||
1047 | } | ||
1048 | |||
1049 | static void mxt_input_close(struct input_dev *dev) | ||
1050 | { | ||
1051 | struct mxt_data *data = input_get_drvdata(dev); | ||
1052 | |||
1053 | mxt_stop(data); | ||
1054 | } | ||
1055 | |||
1056 | static int __devinit mxt_probe(struct i2c_client *client, | ||
1057 | const struct i2c_device_id *id) | ||
1058 | { | ||
1059 | const struct mxt_platform_data *pdata = client->dev.platform_data; | ||
1060 | struct mxt_data *data; | ||
1061 | struct input_dev *input_dev; | ||
1062 | int error; | ||
1063 | |||
1064 | if (!pdata) | ||
1065 | return -EINVAL; | ||
1066 | |||
1067 | data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL); | ||
1068 | input_dev = input_allocate_device(); | ||
1069 | if (!data || !input_dev) { | ||
1070 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
1071 | error = -ENOMEM; | ||
1072 | goto err_free_mem; | ||
1073 | } | ||
1074 | |||
1075 | input_dev->name = "Atmel maXTouch Touchscreen"; | ||
1076 | input_dev->id.bustype = BUS_I2C; | ||
1077 | input_dev->dev.parent = &client->dev; | ||
1078 | input_dev->open = mxt_input_open; | ||
1079 | input_dev->close = mxt_input_close; | ||
1080 | |||
1081 | data->client = client; | ||
1082 | data->input_dev = input_dev; | ||
1083 | data->pdata = pdata; | ||
1084 | data->irq = client->irq; | ||
1085 | |||
1086 | mxt_calc_resolution(data); | ||
1087 | |||
1088 | __set_bit(EV_ABS, input_dev->evbit); | ||
1089 | __set_bit(EV_KEY, input_dev->evbit); | ||
1090 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
1091 | |||
1092 | /* For single touch */ | ||
1093 | input_set_abs_params(input_dev, ABS_X, | ||
1094 | 0, data->max_x, 0, 0); | ||
1095 | input_set_abs_params(input_dev, ABS_Y, | ||
1096 | 0, data->max_y, 0, 0); | ||
1097 | |||
1098 | /* For multi touch */ | ||
1099 | input_mt_init_slots(input_dev, MXT_MAX_FINGER); | ||
1100 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
1101 | 0, MXT_MAX_AREA, 0, 0); | ||
1102 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1103 | 0, data->max_x, 0, 0); | ||
1104 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1105 | 0, data->max_y, 0, 0); | ||
1106 | |||
1107 | input_set_drvdata(input_dev, data); | ||
1108 | i2c_set_clientdata(client, data); | ||
1109 | |||
1110 | error = mxt_initialize(data); | ||
1111 | if (error) | ||
1112 | goto err_free_object; | ||
1113 | |||
1114 | error = request_threaded_irq(client->irq, NULL, mxt_interrupt, | ||
1115 | pdata->irqflags, client->dev.driver->name, data); | ||
1116 | if (error) { | ||
1117 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
1118 | goto err_free_object; | ||
1119 | } | ||
1120 | |||
1121 | error = mxt_make_highchg(data); | ||
1122 | if (error) | ||
1123 | goto err_free_irq; | ||
1124 | |||
1125 | error = input_register_device(input_dev); | ||
1126 | if (error) | ||
1127 | goto err_free_irq; | ||
1128 | |||
1129 | error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); | ||
1130 | if (error) | ||
1131 | goto err_unregister_device; | ||
1132 | |||
1133 | return 0; | ||
1134 | |||
1135 | err_unregister_device: | ||
1136 | input_unregister_device(input_dev); | ||
1137 | input_dev = NULL; | ||
1138 | err_free_irq: | ||
1139 | free_irq(client->irq, data); | ||
1140 | err_free_object: | ||
1141 | kfree(data->object_table); | ||
1142 | err_free_mem: | ||
1143 | input_free_device(input_dev); | ||
1144 | kfree(data); | ||
1145 | return error; | ||
1146 | } | ||
1147 | |||
1148 | static int __devexit mxt_remove(struct i2c_client *client) | ||
1149 | { | ||
1150 | struct mxt_data *data = i2c_get_clientdata(client); | ||
1151 | |||
1152 | sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); | ||
1153 | free_irq(data->irq, data); | ||
1154 | input_unregister_device(data->input_dev); | ||
1155 | kfree(data->object_table); | ||
1156 | kfree(data); | ||
1157 | |||
1158 | return 0; | ||
1159 | } | ||
1160 | |||
1161 | #ifdef CONFIG_PM | ||
1162 | static int mxt_suspend(struct device *dev) | ||
1163 | { | ||
1164 | struct i2c_client *client = to_i2c_client(dev); | ||
1165 | struct mxt_data *data = i2c_get_clientdata(client); | ||
1166 | struct input_dev *input_dev = data->input_dev; | ||
1167 | |||
1168 | mutex_lock(&input_dev->mutex); | ||
1169 | |||
1170 | if (input_dev->users) | ||
1171 | mxt_stop(data); | ||
1172 | |||
1173 | mutex_unlock(&input_dev->mutex); | ||
1174 | |||
1175 | return 0; | ||
1176 | } | ||
1177 | |||
1178 | static int mxt_resume(struct device *dev) | ||
1179 | { | ||
1180 | struct i2c_client *client = to_i2c_client(dev); | ||
1181 | struct mxt_data *data = i2c_get_clientdata(client); | ||
1182 | struct input_dev *input_dev = data->input_dev; | ||
1183 | |||
1184 | /* Soft reset */ | ||
1185 | mxt_write_object(data, MXT_GEN_COMMAND, | ||
1186 | MXT_COMMAND_RESET, 1); | ||
1187 | |||
1188 | msleep(MXT_RESET_TIME); | ||
1189 | |||
1190 | mutex_lock(&input_dev->mutex); | ||
1191 | |||
1192 | if (input_dev->users) | ||
1193 | mxt_start(data); | ||
1194 | |||
1195 | mutex_unlock(&input_dev->mutex); | ||
1196 | |||
1197 | return 0; | ||
1198 | } | ||
1199 | |||
1200 | static const struct dev_pm_ops mxt_pm_ops = { | ||
1201 | .suspend = mxt_suspend, | ||
1202 | .resume = mxt_resume, | ||
1203 | }; | ||
1204 | #endif | ||
1205 | |||
1206 | static const struct i2c_device_id mxt_id[] = { | ||
1207 | { "qt602240_ts", 0 }, | ||
1208 | { "atmel_mxt_ts", 0 }, | ||
1209 | { "mXT224", 0 }, | ||
1210 | { } | ||
1211 | }; | ||
1212 | MODULE_DEVICE_TABLE(i2c, mxt_id); | ||
1213 | |||
1214 | static struct i2c_driver mxt_driver = { | ||
1215 | .driver = { | ||
1216 | .name = "atmel_mxt_ts", | ||
1217 | .owner = THIS_MODULE, | ||
1218 | #ifdef CONFIG_PM | ||
1219 | .pm = &mxt_pm_ops, | ||
1220 | #endif | ||
1221 | }, | ||
1222 | .probe = mxt_probe, | ||
1223 | .remove = __devexit_p(mxt_remove), | ||
1224 | .id_table = mxt_id, | ||
1225 | }; | ||
1226 | |||
1227 | static int __init mxt_init(void) | ||
1228 | { | ||
1229 | return i2c_add_driver(&mxt_driver); | ||
1230 | } | ||
1231 | |||
1232 | static void __exit mxt_exit(void) | ||
1233 | { | ||
1234 | i2c_del_driver(&mxt_driver); | ||
1235 | } | ||
1236 | |||
1237 | module_init(mxt_init); | ||
1238 | module_exit(mxt_exit); | ||
1239 | |||
1240 | /* Module information */ | ||
1241 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | ||
1242 | MODULE_DESCRIPTION("Atmel maXTouch Touchscreen driver"); | ||
1243 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c index 3d9b5166ebe9..432c69be6ac6 100644 --- a/drivers/input/touchscreen/atmel_tsadcc.c +++ b/drivers/input/touchscreen/atmel_tsadcc.c | |||
@@ -317,7 +317,7 @@ err_unmap_regs: | |||
317 | err_release_mem: | 317 | err_release_mem: |
318 | release_mem_region(res->start, resource_size(res)); | 318 | release_mem_region(res->start, resource_size(res)); |
319 | err_free_dev: | 319 | err_free_dev: |
320 | input_free_device(ts_dev->input); | 320 | input_free_device(input_dev); |
321 | err_free_mem: | 321 | err_free_mem: |
322 | kfree(ts_dev); | 322 | kfree(ts_dev); |
323 | return err; | 323 | return err; |
diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c new file mode 100644 index 000000000000..1507ce108d5b --- /dev/null +++ b/drivers/input/touchscreen/bu21013_ts.c | |||
@@ -0,0 +1,681 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson | ||
4 | * License terms:GNU General Public License (GPL) version 2 | ||
5 | */ | ||
6 | |||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/workqueue.h> | ||
12 | #include <linux/input.h> | ||
13 | #include <linux/input/bu21013.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/regulator/consumer.h> | ||
16 | |||
17 | #define PEN_DOWN_INTR 0 | ||
18 | #define MAX_FINGERS 2 | ||
19 | #define RESET_DELAY 30 | ||
20 | #define PENUP_TIMEOUT (10) | ||
21 | #define DELTA_MIN 16 | ||
22 | #define MASK_BITS 0x03 | ||
23 | #define SHIFT_8 8 | ||
24 | #define SHIFT_2 2 | ||
25 | #define LENGTH_OF_BUFFER 11 | ||
26 | #define I2C_RETRY_COUNT 5 | ||
27 | |||
28 | #define BU21013_SENSORS_BTN_0_7_REG 0x70 | ||
29 | #define BU21013_SENSORS_BTN_8_15_REG 0x71 | ||
30 | #define BU21013_SENSORS_BTN_16_23_REG 0x72 | ||
31 | #define BU21013_X1_POS_MSB_REG 0x73 | ||
32 | #define BU21013_X1_POS_LSB_REG 0x74 | ||
33 | #define BU21013_Y1_POS_MSB_REG 0x75 | ||
34 | #define BU21013_Y1_POS_LSB_REG 0x76 | ||
35 | #define BU21013_X2_POS_MSB_REG 0x77 | ||
36 | #define BU21013_X2_POS_LSB_REG 0x78 | ||
37 | #define BU21013_Y2_POS_MSB_REG 0x79 | ||
38 | #define BU21013_Y2_POS_LSB_REG 0x7A | ||
39 | #define BU21013_INT_CLR_REG 0xE8 | ||
40 | #define BU21013_INT_MODE_REG 0xE9 | ||
41 | #define BU21013_GAIN_REG 0xEA | ||
42 | #define BU21013_OFFSET_MODE_REG 0xEB | ||
43 | #define BU21013_XY_EDGE_REG 0xEC | ||
44 | #define BU21013_RESET_REG 0xED | ||
45 | #define BU21013_CALIB_REG 0xEE | ||
46 | #define BU21013_DONE_REG 0xEF | ||
47 | #define BU21013_SENSOR_0_7_REG 0xF0 | ||
48 | #define BU21013_SENSOR_8_15_REG 0xF1 | ||
49 | #define BU21013_SENSOR_16_23_REG 0xF2 | ||
50 | #define BU21013_POS_MODE1_REG 0xF3 | ||
51 | #define BU21013_POS_MODE2_REG 0xF4 | ||
52 | #define BU21013_CLK_MODE_REG 0xF5 | ||
53 | #define BU21013_IDLE_REG 0xFA | ||
54 | #define BU21013_FILTER_REG 0xFB | ||
55 | #define BU21013_TH_ON_REG 0xFC | ||
56 | #define BU21013_TH_OFF_REG 0xFD | ||
57 | |||
58 | |||
59 | #define BU21013_RESET_ENABLE 0x01 | ||
60 | |||
61 | #define BU21013_SENSORS_EN_0_7 0x3F | ||
62 | #define BU21013_SENSORS_EN_8_15 0xFC | ||
63 | #define BU21013_SENSORS_EN_16_23 0x1F | ||
64 | |||
65 | #define BU21013_POS_MODE1_0 0x02 | ||
66 | #define BU21013_POS_MODE1_1 0x04 | ||
67 | #define BU21013_POS_MODE1_2 0x08 | ||
68 | |||
69 | #define BU21013_POS_MODE2_ZERO 0x01 | ||
70 | #define BU21013_POS_MODE2_AVG1 0x02 | ||
71 | #define BU21013_POS_MODE2_AVG2 0x04 | ||
72 | #define BU21013_POS_MODE2_EN_XY 0x08 | ||
73 | #define BU21013_POS_MODE2_EN_RAW 0x10 | ||
74 | #define BU21013_POS_MODE2_MULTI 0x80 | ||
75 | |||
76 | #define BU21013_CLK_MODE_DIV 0x01 | ||
77 | #define BU21013_CLK_MODE_EXT 0x02 | ||
78 | #define BU21013_CLK_MODE_CALIB 0x80 | ||
79 | |||
80 | #define BU21013_IDLET_0 0x01 | ||
81 | #define BU21013_IDLET_1 0x02 | ||
82 | #define BU21013_IDLET_2 0x04 | ||
83 | #define BU21013_IDLET_3 0x08 | ||
84 | #define BU21013_IDLE_INTERMIT_EN 0x10 | ||
85 | |||
86 | #define BU21013_DELTA_0_6 0x7F | ||
87 | #define BU21013_FILTER_EN 0x80 | ||
88 | |||
89 | #define BU21013_INT_MODE_LEVEL 0x00 | ||
90 | #define BU21013_INT_MODE_EDGE 0x01 | ||
91 | |||
92 | #define BU21013_GAIN_0 0x01 | ||
93 | #define BU21013_GAIN_1 0x02 | ||
94 | #define BU21013_GAIN_2 0x04 | ||
95 | |||
96 | #define BU21013_OFFSET_MODE_DEFAULT 0x00 | ||
97 | #define BU21013_OFFSET_MODE_MOVE 0x01 | ||
98 | #define BU21013_OFFSET_MODE_DISABLE 0x02 | ||
99 | |||
100 | #define BU21013_TH_ON_0 0x01 | ||
101 | #define BU21013_TH_ON_1 0x02 | ||
102 | #define BU21013_TH_ON_2 0x04 | ||
103 | #define BU21013_TH_ON_3 0x08 | ||
104 | #define BU21013_TH_ON_4 0x10 | ||
105 | #define BU21013_TH_ON_5 0x20 | ||
106 | #define BU21013_TH_ON_6 0x40 | ||
107 | #define BU21013_TH_ON_7 0x80 | ||
108 | #define BU21013_TH_ON_MAX 0xFF | ||
109 | |||
110 | #define BU21013_TH_OFF_0 0x01 | ||
111 | #define BU21013_TH_OFF_1 0x02 | ||
112 | #define BU21013_TH_OFF_2 0x04 | ||
113 | #define BU21013_TH_OFF_3 0x08 | ||
114 | #define BU21013_TH_OFF_4 0x10 | ||
115 | #define BU21013_TH_OFF_5 0x20 | ||
116 | #define BU21013_TH_OFF_6 0x40 | ||
117 | #define BU21013_TH_OFF_7 0x80 | ||
118 | #define BU21013_TH_OFF_MAX 0xFF | ||
119 | |||
120 | #define BU21013_X_EDGE_0 0x01 | ||
121 | #define BU21013_X_EDGE_1 0x02 | ||
122 | #define BU21013_X_EDGE_2 0x04 | ||
123 | #define BU21013_X_EDGE_3 0x08 | ||
124 | #define BU21013_Y_EDGE_0 0x10 | ||
125 | #define BU21013_Y_EDGE_1 0x20 | ||
126 | #define BU21013_Y_EDGE_2 0x40 | ||
127 | #define BU21013_Y_EDGE_3 0x80 | ||
128 | |||
129 | #define BU21013_DONE 0x01 | ||
130 | #define BU21013_NUMBER_OF_X_SENSORS (6) | ||
131 | #define BU21013_NUMBER_OF_Y_SENSORS (11) | ||
132 | |||
133 | #define DRIVER_TP "bu21013_tp" | ||
134 | |||
135 | /** | ||
136 | * struct bu21013_ts_data - touch panel data structure | ||
137 | * @client: pointer to the i2c client | ||
138 | * @wait: variable to wait_queue_head_t structure | ||
139 | * @touch_stopped: touch stop flag | ||
140 | * @chip: pointer to the touch panel controller | ||
141 | * @in_dev: pointer to the input device structure | ||
142 | * @intr_pin: interrupt pin value | ||
143 | * @regulator: pointer to the Regulator used for touch screen | ||
144 | * | ||
145 | * Touch panel device data structure | ||
146 | */ | ||
147 | struct bu21013_ts_data { | ||
148 | struct i2c_client *client; | ||
149 | wait_queue_head_t wait; | ||
150 | bool touch_stopped; | ||
151 | const struct bu21013_platform_device *chip; | ||
152 | struct input_dev *in_dev; | ||
153 | unsigned int intr_pin; | ||
154 | struct regulator *regulator; | ||
155 | }; | ||
156 | |||
157 | /** | ||
158 | * bu21013_read_block_data(): read the touch co-ordinates | ||
159 | * @data: bu21013_ts_data structure pointer | ||
160 | * @buf: byte pointer | ||
161 | * | ||
162 | * Read the touch co-ordinates using i2c read block into buffer | ||
163 | * and returns integer. | ||
164 | */ | ||
165 | static int bu21013_read_block_data(struct bu21013_ts_data *data, u8 *buf) | ||
166 | { | ||
167 | int ret, i; | ||
168 | |||
169 | for (i = 0; i < I2C_RETRY_COUNT; i++) { | ||
170 | ret = i2c_smbus_read_i2c_block_data | ||
171 | (data->client, BU21013_SENSORS_BTN_0_7_REG, | ||
172 | LENGTH_OF_BUFFER, buf); | ||
173 | if (ret == LENGTH_OF_BUFFER) | ||
174 | return 0; | ||
175 | } | ||
176 | return -EINVAL; | ||
177 | } | ||
178 | |||
179 | /** | ||
180 | * bu21013_do_touch_report(): Get the touch co-ordinates | ||
181 | * @data: bu21013_ts_data structure pointer | ||
182 | * | ||
183 | * Get the touch co-ordinates from touch sensor registers and writes | ||
184 | * into device structure and returns integer. | ||
185 | */ | ||
186 | static int bu21013_do_touch_report(struct bu21013_ts_data *data) | ||
187 | { | ||
188 | u8 buf[LENGTH_OF_BUFFER]; | ||
189 | unsigned int pos_x[2], pos_y[2]; | ||
190 | bool has_x_sensors, has_y_sensors; | ||
191 | int finger_down_count = 0; | ||
192 | int i; | ||
193 | |||
194 | if (data == NULL) | ||
195 | return -EINVAL; | ||
196 | |||
197 | if (bu21013_read_block_data(data, buf) < 0) | ||
198 | return -EINVAL; | ||
199 | |||
200 | has_x_sensors = hweight32(buf[0] & BU21013_SENSORS_EN_0_7); | ||
201 | has_y_sensors = hweight32(((buf[1] & BU21013_SENSORS_EN_8_15) | | ||
202 | ((buf[2] & BU21013_SENSORS_EN_16_23) << SHIFT_8)) >> SHIFT_2); | ||
203 | if (!has_x_sensors || !has_y_sensors) | ||
204 | return 0; | ||
205 | |||
206 | for (i = 0; i < MAX_FINGERS; i++) { | ||
207 | const u8 *p = &buf[4 * i + 3]; | ||
208 | unsigned int x = p[0] << SHIFT_2 | (p[1] & MASK_BITS); | ||
209 | unsigned int y = p[2] << SHIFT_2 | (p[3] & MASK_BITS); | ||
210 | if (x == 0 || y == 0) | ||
211 | continue; | ||
212 | pos_x[finger_down_count] = x; | ||
213 | pos_y[finger_down_count] = y; | ||
214 | finger_down_count++; | ||
215 | } | ||
216 | |||
217 | if (finger_down_count) { | ||
218 | if (finger_down_count == 2 && | ||
219 | (abs(pos_x[0] - pos_x[1]) < DELTA_MIN || | ||
220 | abs(pos_y[0] - pos_y[1]) < DELTA_MIN)) { | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | for (i = 0; i < finger_down_count; i++) { | ||
225 | if (data->chip->x_flip) | ||
226 | pos_x[i] = data->chip->touch_x_max - pos_x[i]; | ||
227 | if (data->chip->y_flip) | ||
228 | pos_y[i] = data->chip->touch_y_max - pos_y[i]; | ||
229 | |||
230 | input_report_abs(data->in_dev, | ||
231 | ABS_MT_POSITION_X, pos_x[i]); | ||
232 | input_report_abs(data->in_dev, | ||
233 | ABS_MT_POSITION_Y, pos_y[i]); | ||
234 | input_mt_sync(data->in_dev); | ||
235 | } | ||
236 | } else | ||
237 | input_mt_sync(data->in_dev); | ||
238 | |||
239 | input_sync(data->in_dev); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | /** | ||
244 | * bu21013_gpio_irq() - gpio thread function for touch interrupt | ||
245 | * @irq: irq value | ||
246 | * @device_data: void pointer | ||
247 | * | ||
248 | * This gpio thread function for touch interrupt | ||
249 | * and returns irqreturn_t. | ||
250 | */ | ||
251 | static irqreturn_t bu21013_gpio_irq(int irq, void *device_data) | ||
252 | { | ||
253 | struct bu21013_ts_data *data = device_data; | ||
254 | struct i2c_client *i2c = data->client; | ||
255 | int retval; | ||
256 | |||
257 | do { | ||
258 | retval = bu21013_do_touch_report(data); | ||
259 | if (retval < 0) { | ||
260 | dev_err(&i2c->dev, "bu21013_do_touch_report failed\n"); | ||
261 | return IRQ_NONE; | ||
262 | } | ||
263 | |||
264 | data->intr_pin = data->chip->irq_read_val(); | ||
265 | if (data->intr_pin == PEN_DOWN_INTR) | ||
266 | wait_event_timeout(data->wait, data->touch_stopped, | ||
267 | msecs_to_jiffies(2)); | ||
268 | } while (!data->intr_pin && !data->touch_stopped); | ||
269 | |||
270 | return IRQ_HANDLED; | ||
271 | } | ||
272 | |||
273 | /** | ||
274 | * bu21013_init_chip() - power on sequence for the bu21013 controller | ||
275 | * @data: device structure pointer | ||
276 | * | ||
277 | * This function is used to power on | ||
278 | * the bu21013 controller and returns integer. | ||
279 | */ | ||
280 | static int bu21013_init_chip(struct bu21013_ts_data *data) | ||
281 | { | ||
282 | int retval; | ||
283 | struct i2c_client *i2c = data->client; | ||
284 | |||
285 | retval = i2c_smbus_write_byte_data(i2c, BU21013_RESET_REG, | ||
286 | BU21013_RESET_ENABLE); | ||
287 | if (retval < 0) { | ||
288 | dev_err(&i2c->dev, "BU21013_RESET reg write failed\n"); | ||
289 | return retval; | ||
290 | } | ||
291 | msleep(RESET_DELAY); | ||
292 | |||
293 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_0_7_REG, | ||
294 | BU21013_SENSORS_EN_0_7); | ||
295 | if (retval < 0) { | ||
296 | dev_err(&i2c->dev, "BU21013_SENSOR_0_7 reg write failed\n"); | ||
297 | return retval; | ||
298 | } | ||
299 | |||
300 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_8_15_REG, | ||
301 | BU21013_SENSORS_EN_8_15); | ||
302 | if (retval < 0) { | ||
303 | dev_err(&i2c->dev, "BU21013_SENSOR_8_15 reg write failed\n"); | ||
304 | return retval; | ||
305 | } | ||
306 | |||
307 | retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_16_23_REG, | ||
308 | BU21013_SENSORS_EN_16_23); | ||
309 | if (retval < 0) { | ||
310 | dev_err(&i2c->dev, "BU21013_SENSOR_16_23 reg write failed\n"); | ||
311 | return retval; | ||
312 | } | ||
313 | |||
314 | retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE1_REG, | ||
315 | (BU21013_POS_MODE1_0 | BU21013_POS_MODE1_1)); | ||
316 | if (retval < 0) { | ||
317 | dev_err(&i2c->dev, "BU21013_POS_MODE1 reg write failed\n"); | ||
318 | return retval; | ||
319 | } | ||
320 | |||
321 | retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE2_REG, | ||
322 | (BU21013_POS_MODE2_ZERO | BU21013_POS_MODE2_AVG1 | | ||
323 | BU21013_POS_MODE2_AVG2 | BU21013_POS_MODE2_EN_RAW | | ||
324 | BU21013_POS_MODE2_MULTI)); | ||
325 | if (retval < 0) { | ||
326 | dev_err(&i2c->dev, "BU21013_POS_MODE2 reg write failed\n"); | ||
327 | return retval; | ||
328 | } | ||
329 | |||
330 | if (data->chip->ext_clk) | ||
331 | retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG, | ||
332 | (BU21013_CLK_MODE_EXT | BU21013_CLK_MODE_CALIB)); | ||
333 | else | ||
334 | retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG, | ||
335 | (BU21013_CLK_MODE_DIV | BU21013_CLK_MODE_CALIB)); | ||
336 | if (retval < 0) { | ||
337 | dev_err(&i2c->dev, "BU21013_CLK_MODE reg write failed\n"); | ||
338 | return retval; | ||
339 | } | ||
340 | |||
341 | retval = i2c_smbus_write_byte_data(i2c, BU21013_IDLE_REG, | ||
342 | (BU21013_IDLET_0 | BU21013_IDLE_INTERMIT_EN)); | ||
343 | if (retval < 0) { | ||
344 | dev_err(&i2c->dev, "BU21013_IDLE reg write failed\n"); | ||
345 | return retval; | ||
346 | } | ||
347 | |||
348 | retval = i2c_smbus_write_byte_data(i2c, BU21013_INT_MODE_REG, | ||
349 | BU21013_INT_MODE_LEVEL); | ||
350 | if (retval < 0) { | ||
351 | dev_err(&i2c->dev, "BU21013_INT_MODE reg write failed\n"); | ||
352 | return retval; | ||
353 | } | ||
354 | |||
355 | retval = i2c_smbus_write_byte_data(i2c, BU21013_FILTER_REG, | ||
356 | (BU21013_DELTA_0_6 | | ||
357 | BU21013_FILTER_EN)); | ||
358 | if (retval < 0) { | ||
359 | dev_err(&i2c->dev, "BU21013_FILTER reg write failed\n"); | ||
360 | return retval; | ||
361 | } | ||
362 | |||
363 | retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_ON_REG, | ||
364 | BU21013_TH_ON_5); | ||
365 | if (retval < 0) { | ||
366 | dev_err(&i2c->dev, "BU21013_TH_ON reg write failed\n"); | ||
367 | return retval; | ||
368 | } | ||
369 | |||
370 | retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_OFF_REG, | ||
371 | BU21013_TH_OFF_4 | BU21013_TH_OFF_3); | ||
372 | if (retval < 0) { | ||
373 | dev_err(&i2c->dev, "BU21013_TH_OFF reg write failed\n"); | ||
374 | return retval; | ||
375 | } | ||
376 | |||
377 | retval = i2c_smbus_write_byte_data(i2c, BU21013_GAIN_REG, | ||
378 | (BU21013_GAIN_0 | BU21013_GAIN_1)); | ||
379 | if (retval < 0) { | ||
380 | dev_err(&i2c->dev, "BU21013_GAIN reg write failed\n"); | ||
381 | return retval; | ||
382 | } | ||
383 | |||
384 | retval = i2c_smbus_write_byte_data(i2c, BU21013_OFFSET_MODE_REG, | ||
385 | BU21013_OFFSET_MODE_DEFAULT); | ||
386 | if (retval < 0) { | ||
387 | dev_err(&i2c->dev, "BU21013_OFFSET_MODE reg write failed\n"); | ||
388 | return retval; | ||
389 | } | ||
390 | |||
391 | retval = i2c_smbus_write_byte_data(i2c, BU21013_XY_EDGE_REG, | ||
392 | (BU21013_X_EDGE_0 | BU21013_X_EDGE_2 | | ||
393 | BU21013_Y_EDGE_1 | BU21013_Y_EDGE_3)); | ||
394 | if (retval < 0) { | ||
395 | dev_err(&i2c->dev, "BU21013_XY_EDGE reg write failed\n"); | ||
396 | return retval; | ||
397 | } | ||
398 | |||
399 | retval = i2c_smbus_write_byte_data(i2c, BU21013_DONE_REG, | ||
400 | BU21013_DONE); | ||
401 | if (retval < 0) { | ||
402 | dev_err(&i2c->dev, "BU21013_REG_DONE reg write failed\n"); | ||
403 | return retval; | ||
404 | } | ||
405 | |||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | /** | ||
410 | * bu21013_free_irq() - frees IRQ registered for touchscreen | ||
411 | * @bu21013_data: device structure pointer | ||
412 | * | ||
413 | * This function signals interrupt thread to stop processing and | ||
414 | * frees interrupt. | ||
415 | */ | ||
416 | static void bu21013_free_irq(struct bu21013_ts_data *bu21013_data) | ||
417 | { | ||
418 | bu21013_data->touch_stopped = true; | ||
419 | wake_up(&bu21013_data->wait); | ||
420 | free_irq(bu21013_data->chip->irq, bu21013_data); | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * bu21013_probe() - initializes the i2c-client touchscreen driver | ||
425 | * @client: i2c client structure pointer | ||
426 | * @id: i2c device id pointer | ||
427 | * | ||
428 | * This function used to initializes the i2c-client touchscreen | ||
429 | * driver and returns integer. | ||
430 | */ | ||
431 | static int __devinit bu21013_probe(struct i2c_client *client, | ||
432 | const struct i2c_device_id *id) | ||
433 | { | ||
434 | struct bu21013_ts_data *bu21013_data; | ||
435 | struct input_dev *in_dev; | ||
436 | const struct bu21013_platform_device *pdata = | ||
437 | client->dev.platform_data; | ||
438 | int error; | ||
439 | |||
440 | if (!i2c_check_functionality(client->adapter, | ||
441 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
442 | dev_err(&client->dev, "i2c smbus byte data not supported\n"); | ||
443 | return -EIO; | ||
444 | } | ||
445 | |||
446 | if (!pdata) { | ||
447 | dev_err(&client->dev, "platform data not defined\n"); | ||
448 | return -EINVAL; | ||
449 | } | ||
450 | |||
451 | bu21013_data = kzalloc(sizeof(struct bu21013_ts_data), GFP_KERNEL); | ||
452 | in_dev = input_allocate_device(); | ||
453 | if (!bu21013_data || !in_dev) { | ||
454 | dev_err(&client->dev, "device memory alloc failed\n"); | ||
455 | error = -ENOMEM; | ||
456 | goto err_free_mem; | ||
457 | } | ||
458 | |||
459 | bu21013_data->in_dev = in_dev; | ||
460 | bu21013_data->chip = pdata; | ||
461 | bu21013_data->client = client; | ||
462 | |||
463 | bu21013_data->regulator = regulator_get(&client->dev, "V-TOUCH"); | ||
464 | if (IS_ERR(bu21013_data->regulator)) { | ||
465 | dev_err(&client->dev, "regulator_get failed\n"); | ||
466 | error = PTR_ERR(bu21013_data->regulator); | ||
467 | goto err_free_mem; | ||
468 | } | ||
469 | |||
470 | error = regulator_enable(bu21013_data->regulator); | ||
471 | if (error < 0) { | ||
472 | dev_err(&client->dev, "regulator enable failed\n"); | ||
473 | goto err_put_regulator; | ||
474 | } | ||
475 | |||
476 | bu21013_data->touch_stopped = false; | ||
477 | init_waitqueue_head(&bu21013_data->wait); | ||
478 | |||
479 | /* configure the gpio pins */ | ||
480 | if (pdata->cs_en) { | ||
481 | error = pdata->cs_en(pdata->cs_pin); | ||
482 | if (error < 0) { | ||
483 | dev_err(&client->dev, "chip init failed\n"); | ||
484 | goto err_disable_regulator; | ||
485 | } | ||
486 | } | ||
487 | |||
488 | /* configure the touch panel controller */ | ||
489 | error = bu21013_init_chip(bu21013_data); | ||
490 | if (error) { | ||
491 | dev_err(&client->dev, "error in bu21013 config\n"); | ||
492 | goto err_cs_disable; | ||
493 | } | ||
494 | |||
495 | /* register the device to input subsystem */ | ||
496 | in_dev->name = DRIVER_TP; | ||
497 | in_dev->id.bustype = BUS_I2C; | ||
498 | in_dev->dev.parent = &client->dev; | ||
499 | |||
500 | __set_bit(EV_SYN, in_dev->evbit); | ||
501 | __set_bit(EV_KEY, in_dev->evbit); | ||
502 | __set_bit(EV_ABS, in_dev->evbit); | ||
503 | |||
504 | input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0, | ||
505 | pdata->touch_x_max, 0, 0); | ||
506 | input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0, | ||
507 | pdata->touch_y_max, 0, 0); | ||
508 | input_set_drvdata(in_dev, bu21013_data); | ||
509 | |||
510 | error = request_threaded_irq(pdata->irq, NULL, bu21013_gpio_irq, | ||
511 | IRQF_TRIGGER_FALLING | IRQF_SHARED, | ||
512 | DRIVER_TP, bu21013_data); | ||
513 | if (error) { | ||
514 | dev_err(&client->dev, "request irq %d failed\n", pdata->irq); | ||
515 | goto err_cs_disable; | ||
516 | } | ||
517 | |||
518 | error = input_register_device(in_dev); | ||
519 | if (error) { | ||
520 | dev_err(&client->dev, "failed to register input device\n"); | ||
521 | goto err_free_irq; | ||
522 | } | ||
523 | |||
524 | device_init_wakeup(&client->dev, pdata->wakeup); | ||
525 | i2c_set_clientdata(client, bu21013_data); | ||
526 | |||
527 | return 0; | ||
528 | |||
529 | err_free_irq: | ||
530 | bu21013_free_irq(bu21013_data); | ||
531 | err_cs_disable: | ||
532 | pdata->cs_dis(pdata->cs_pin); | ||
533 | err_disable_regulator: | ||
534 | regulator_disable(bu21013_data->regulator); | ||
535 | err_put_regulator: | ||
536 | regulator_put(bu21013_data->regulator); | ||
537 | err_free_mem: | ||
538 | input_free_device(in_dev); | ||
539 | kfree(bu21013_data); | ||
540 | |||
541 | return error; | ||
542 | } | ||
543 | /** | ||
544 | * bu21013_remove() - removes the i2c-client touchscreen driver | ||
545 | * @client: i2c client structure pointer | ||
546 | * | ||
547 | * This function uses to remove the i2c-client | ||
548 | * touchscreen driver and returns integer. | ||
549 | */ | ||
550 | static int __devexit bu21013_remove(struct i2c_client *client) | ||
551 | { | ||
552 | struct bu21013_ts_data *bu21013_data = i2c_get_clientdata(client); | ||
553 | |||
554 | bu21013_free_irq(bu21013_data); | ||
555 | |||
556 | bu21013_data->chip->cs_dis(bu21013_data->chip->cs_pin); | ||
557 | |||
558 | input_unregister_device(bu21013_data->in_dev); | ||
559 | |||
560 | regulator_disable(bu21013_data->regulator); | ||
561 | regulator_put(bu21013_data->regulator); | ||
562 | |||
563 | kfree(bu21013_data); | ||
564 | |||
565 | device_init_wakeup(&client->dev, false); | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | #ifdef CONFIG_PM | ||
571 | /** | ||
572 | * bu21013_suspend() - suspend the touch screen controller | ||
573 | * @dev: pointer to device structure | ||
574 | * | ||
575 | * This function is used to suspend the | ||
576 | * touch panel controller and returns integer | ||
577 | */ | ||
578 | static int bu21013_suspend(struct device *dev) | ||
579 | { | ||
580 | struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev); | ||
581 | struct i2c_client *client = bu21013_data->client; | ||
582 | |||
583 | bu21013_data->touch_stopped = true; | ||
584 | if (device_may_wakeup(&client->dev)) | ||
585 | enable_irq_wake(bu21013_data->chip->irq); | ||
586 | else | ||
587 | disable_irq(bu21013_data->chip->irq); | ||
588 | |||
589 | regulator_disable(bu21013_data->regulator); | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | /** | ||
595 | * bu21013_resume() - resume the touch screen controller | ||
596 | * @dev: pointer to device structure | ||
597 | * | ||
598 | * This function is used to resume the touch panel | ||
599 | * controller and returns integer. | ||
600 | */ | ||
601 | static int bu21013_resume(struct device *dev) | ||
602 | { | ||
603 | struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev); | ||
604 | struct i2c_client *client = bu21013_data->client; | ||
605 | int retval; | ||
606 | |||
607 | retval = regulator_enable(bu21013_data->regulator); | ||
608 | if (retval < 0) { | ||
609 | dev_err(&client->dev, "bu21013 regulator enable failed\n"); | ||
610 | return retval; | ||
611 | } | ||
612 | |||
613 | retval = bu21013_init_chip(bu21013_data); | ||
614 | if (retval < 0) { | ||
615 | dev_err(&client->dev, "bu21013 controller config failed\n"); | ||
616 | return retval; | ||
617 | } | ||
618 | |||
619 | bu21013_data->touch_stopped = false; | ||
620 | |||
621 | if (device_may_wakeup(&client->dev)) | ||
622 | disable_irq_wake(bu21013_data->chip->irq); | ||
623 | else | ||
624 | enable_irq(bu21013_data->chip->irq); | ||
625 | |||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static const struct dev_pm_ops bu21013_dev_pm_ops = { | ||
630 | .suspend = bu21013_suspend, | ||
631 | .resume = bu21013_resume, | ||
632 | }; | ||
633 | #endif | ||
634 | |||
635 | static const struct i2c_device_id bu21013_id[] = { | ||
636 | { DRIVER_TP, 0 }, | ||
637 | { } | ||
638 | }; | ||
639 | MODULE_DEVICE_TABLE(i2c, bu21013_id); | ||
640 | |||
641 | static struct i2c_driver bu21013_driver = { | ||
642 | .driver = { | ||
643 | .name = DRIVER_TP, | ||
644 | .owner = THIS_MODULE, | ||
645 | #ifdef CONFIG_PM | ||
646 | .pm = &bu21013_dev_pm_ops, | ||
647 | #endif | ||
648 | }, | ||
649 | .probe = bu21013_probe, | ||
650 | .remove = __devexit_p(bu21013_remove), | ||
651 | .id_table = bu21013_id, | ||
652 | }; | ||
653 | |||
654 | /** | ||
655 | * bu21013_init() - initializes the bu21013 touchscreen driver | ||
656 | * | ||
657 | * This function used to initializes the bu21013 | ||
658 | * touchscreen driver and returns integer. | ||
659 | */ | ||
660 | static int __init bu21013_init(void) | ||
661 | { | ||
662 | return i2c_add_driver(&bu21013_driver); | ||
663 | } | ||
664 | |||
665 | /** | ||
666 | * bu21013_exit() - de-initializes the bu21013 touchscreen driver | ||
667 | * | ||
668 | * This function uses to de-initializes the bu21013 | ||
669 | * touchscreen driver and returns none. | ||
670 | */ | ||
671 | static void __exit bu21013_exit(void) | ||
672 | { | ||
673 | i2c_del_driver(&bu21013_driver); | ||
674 | } | ||
675 | |||
676 | module_init(bu21013_init); | ||
677 | module_exit(bu21013_exit); | ||
678 | |||
679 | MODULE_LICENSE("GPL v2"); | ||
680 | MODULE_AUTHOR("Naveen Kumar G <naveen.gaddipati@stericsson.com>"); | ||
681 | MODULE_DESCRIPTION("bu21013 touch screen controller driver"); | ||
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index 5ec0946938fe..a93c5c26ab3f 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c | |||
@@ -206,9 +206,9 @@ static int __devinit cy8ctmg110_probe(struct i2c_client *client, | |||
206 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 206 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
207 | 207 | ||
208 | input_set_abs_params(input_dev, ABS_X, | 208 | input_set_abs_params(input_dev, ABS_X, |
209 | CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 0, 0); | 209 | CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 4, 0); |
210 | input_set_abs_params(input_dev, ABS_Y, | 210 | input_set_abs_params(input_dev, ABS_Y, |
211 | CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 0, 0); | 211 | CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 4, 0); |
212 | 212 | ||
213 | if (ts->reset_pin) { | 213 | if (ts->reset_pin) { |
214 | err = gpio_request(ts->reset_pin, NULL); | 214 | err = gpio_request(ts->reset_pin, NULL); |
@@ -280,8 +280,9 @@ err_free_mem: | |||
280 | } | 280 | } |
281 | 281 | ||
282 | #ifdef CONFIG_PM | 282 | #ifdef CONFIG_PM |
283 | static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg) | 283 | static int cy8ctmg110_suspend(struct device *dev) |
284 | { | 284 | { |
285 | struct i2c_client *client = to_i2c_client(dev); | ||
285 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); | 286 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); |
286 | 287 | ||
287 | if (device_may_wakeup(&client->dev)) | 288 | if (device_may_wakeup(&client->dev)) |
@@ -293,8 +294,9 @@ static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg) | |||
293 | return 0; | 294 | return 0; |
294 | } | 295 | } |
295 | 296 | ||
296 | static int cy8ctmg110_resume(struct i2c_client *client) | 297 | static int cy8ctmg110_resume(struct device *dev) |
297 | { | 298 | { |
299 | struct i2c_client *client = to_i2c_client(dev); | ||
298 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); | 300 | struct cy8ctmg110 *ts = i2c_get_clientdata(client); |
299 | 301 | ||
300 | if (device_may_wakeup(&client->dev)) | 302 | if (device_may_wakeup(&client->dev)) |
@@ -305,6 +307,8 @@ static int cy8ctmg110_resume(struct i2c_client *client) | |||
305 | } | 307 | } |
306 | return 0; | 308 | return 0; |
307 | } | 309 | } |
310 | |||
311 | static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume); | ||
308 | #endif | 312 | #endif |
309 | 313 | ||
310 | static int __devexit cy8ctmg110_remove(struct i2c_client *client) | 314 | static int __devexit cy8ctmg110_remove(struct i2c_client *client) |
@@ -335,14 +339,13 @@ static struct i2c_driver cy8ctmg110_driver = { | |||
335 | .driver = { | 339 | .driver = { |
336 | .owner = THIS_MODULE, | 340 | .owner = THIS_MODULE, |
337 | .name = CY8CTMG110_DRIVER_NAME, | 341 | .name = CY8CTMG110_DRIVER_NAME, |
342 | #ifdef CONFIG_PM | ||
343 | .pm = &cy8ctmg110_pm, | ||
344 | #endif | ||
338 | }, | 345 | }, |
339 | .id_table = cy8ctmg110_idtable, | 346 | .id_table = cy8ctmg110_idtable, |
340 | .probe = cy8ctmg110_probe, | 347 | .probe = cy8ctmg110_probe, |
341 | .remove = __devexit_p(cy8ctmg110_remove), | 348 | .remove = __devexit_p(cy8ctmg110_remove), |
342 | #ifdef CONFIG_PM | ||
343 | .suspend = cy8ctmg110_suspend, | ||
344 | .resume = cy8ctmg110_resume, | ||
345 | #endif | ||
346 | }; | 349 | }; |
347 | 350 | ||
348 | static int __init cy8ctmg110_init(void) | 351 | static int __init cy8ctmg110_init(void) |
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 7a3a916f84a8..7f8f538a9806 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c | |||
@@ -261,8 +261,9 @@ static int __devexit eeti_ts_remove(struct i2c_client *client) | |||
261 | } | 261 | } |
262 | 262 | ||
263 | #ifdef CONFIG_PM | 263 | #ifdef CONFIG_PM |
264 | static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 264 | static int eeti_ts_suspend(struct device *dev) |
265 | { | 265 | { |
266 | struct i2c_client *client = to_i2c_client(dev); | ||
266 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 267 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
267 | struct input_dev *input_dev = priv->input; | 268 | struct input_dev *input_dev = priv->input; |
268 | 269 | ||
@@ -279,8 +280,9 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | |||
279 | return 0; | 280 | return 0; |
280 | } | 281 | } |
281 | 282 | ||
282 | static int eeti_ts_resume(struct i2c_client *client) | 283 | static int eeti_ts_resume(struct device *dev) |
283 | { | 284 | { |
285 | struct i2c_client *client = to_i2c_client(dev); | ||
284 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | 286 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); |
285 | struct input_dev *input_dev = priv->input; | 287 | struct input_dev *input_dev = priv->input; |
286 | 288 | ||
@@ -296,9 +298,8 @@ static int eeti_ts_resume(struct i2c_client *client) | |||
296 | 298 | ||
297 | return 0; | 299 | return 0; |
298 | } | 300 | } |
299 | #else | 301 | |
300 | #define eeti_ts_suspend NULL | 302 | static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume); |
301 | #define eeti_ts_resume NULL | ||
302 | #endif | 303 | #endif |
303 | 304 | ||
304 | static const struct i2c_device_id eeti_ts_id[] = { | 305 | static const struct i2c_device_id eeti_ts_id[] = { |
@@ -310,11 +311,12 @@ MODULE_DEVICE_TABLE(i2c, eeti_ts_id); | |||
310 | static struct i2c_driver eeti_ts_driver = { | 311 | static struct i2c_driver eeti_ts_driver = { |
311 | .driver = { | 312 | .driver = { |
312 | .name = "eeti_ts", | 313 | .name = "eeti_ts", |
314 | #ifdef CONFIG_PM | ||
315 | .pm = &eeti_ts_pm, | ||
316 | #endif | ||
313 | }, | 317 | }, |
314 | .probe = eeti_ts_probe, | 318 | .probe = eeti_ts_probe, |
315 | .remove = __devexit_p(eeti_ts_remove), | 319 | .remove = __devexit_p(eeti_ts_remove), |
316 | .suspend = eeti_ts_suspend, | ||
317 | .resume = eeti_ts_resume, | ||
318 | .id_table = eeti_ts_id, | 320 | .id_table = eeti_ts_id, |
319 | }; | 321 | }; |
320 | 322 | ||
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index b4d7f63deff1..211811ae5525 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c | |||
@@ -62,7 +62,7 @@ MODULE_LICENSE("GPL"); | |||
62 | Programmer has no control over these numbers. | 62 | Programmer has no control over these numbers. |
63 | TODO there are holes - specifically 1,7,0x0a | 63 | TODO there are holes - specifically 1,7,0x0a |
64 | */ | 64 | */ |
65 | #define VERSION_ID 0 /* Get Version (request/respose) */ | 65 | #define VERSION_ID 0 /* Get Version (request/response) */ |
66 | #define KEYBD_ID 2 /* Keyboard (event) */ | 66 | #define KEYBD_ID 2 /* Keyboard (event) */ |
67 | #define TOUCHS_ID 3 /* Touch Screen (event)*/ | 67 | #define TOUCHS_ID 3 /* Touch Screen (event)*/ |
68 | #define EEPROM_READ_ID 4 /* (request/response) */ | 68 | #define EEPROM_READ_ID 4 /* (request/response) */ |
@@ -396,34 +396,37 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) | |||
396 | set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE); | 396 | set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE); |
397 | 397 | ||
398 | if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler, | 398 | if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler, |
399 | IRQF_SHARED | IRQF_DISABLED, "h3600_action", &ts->dev)) { | 399 | IRQF_SHARED | IRQF_DISABLED, "h3600_action", ts->dev)) { |
400 | printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); | 400 | printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); |
401 | err = -EBUSY; | 401 | err = -EBUSY; |
402 | goto fail2; | 402 | goto fail1; |
403 | } | 403 | } |
404 | 404 | ||
405 | if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, | 405 | if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, |
406 | IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", &ts->dev)) { | 406 | IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", ts->dev)) { |
407 | printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); | 407 | printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); |
408 | err = -EBUSY; | 408 | err = -EBUSY; |
409 | goto fail3; | 409 | goto fail2; |
410 | } | 410 | } |
411 | 411 | ||
412 | serio_set_drvdata(serio, ts); | 412 | serio_set_drvdata(serio, ts); |
413 | 413 | ||
414 | err = serio_open(serio, drv); | 414 | err = serio_open(serio, drv); |
415 | if (err) | 415 | if (err) |
416 | return err; | 416 | goto fail3; |
417 | 417 | ||
418 | //h3600_flite_control(1, 25); /* default brightness */ | 418 | //h3600_flite_control(1, 25); /* default brightness */ |
419 | input_register_device(ts->dev); | 419 | err = input_register_device(ts->dev); |
420 | if (err) | ||
421 | goto fail4; | ||
420 | 422 | ||
421 | return 0; | 423 | return 0; |
422 | 424 | ||
423 | fail3: free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); | 425 | fail4: serio_close(serio); |
426 | fail3: serio_set_drvdata(serio, NULL); | ||
427 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); | ||
424 | fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); | 428 | fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); |
425 | fail1: serio_set_drvdata(serio, NULL); | 429 | fail1: input_free_device(input_dev); |
426 | input_free_device(input_dev); | ||
427 | kfree(ts); | 430 | kfree(ts); |
428 | return err; | 431 | return err; |
429 | } | 432 | } |
@@ -436,8 +439,8 @@ static void h3600ts_disconnect(struct serio *serio) | |||
436 | { | 439 | { |
437 | struct h3600_dev *ts = serio_get_drvdata(serio); | 440 | struct h3600_dev *ts = serio_get_drvdata(serio); |
438 | 441 | ||
439 | free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); | 442 | free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); |
440 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev); | 443 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); |
441 | input_get_device(ts->dev); | 444 | input_get_device(ts->dev); |
442 | input_unregister_device(ts->dev); | 445 | input_unregister_device(ts->dev); |
443 | serio_close(serio); | 446 | serio_close(serio); |
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index a89700e7ace4..dd4e8f020b99 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c | |||
@@ -28,29 +28,29 @@ static void do_softint(struct work_struct *work) | |||
28 | u8 scpdr; | 28 | u8 scpdr; |
29 | int touched = 0; | 29 | int touched = 0; |
30 | 30 | ||
31 | if (ctrl_inb(PHDR) & PHDR_TS_PEN_DOWN) { | 31 | if (__raw_readb(PHDR) & PHDR_TS_PEN_DOWN) { |
32 | scpdr = ctrl_inb(SCPDR); | 32 | scpdr = __raw_readb(SCPDR); |
33 | scpdr |= SCPDR_TS_SCAN_ENABLE; | 33 | scpdr |= SCPDR_TS_SCAN_ENABLE; |
34 | scpdr &= ~SCPDR_TS_SCAN_Y; | 34 | scpdr &= ~SCPDR_TS_SCAN_Y; |
35 | ctrl_outb(scpdr, SCPDR); | 35 | __raw_writeb(scpdr, SCPDR); |
36 | udelay(30); | 36 | udelay(30); |
37 | 37 | ||
38 | absy = adc_single(ADC_CHANNEL_TS_Y); | 38 | absy = adc_single(ADC_CHANNEL_TS_Y); |
39 | 39 | ||
40 | scpdr = ctrl_inb(SCPDR); | 40 | scpdr = __raw_readb(SCPDR); |
41 | scpdr |= SCPDR_TS_SCAN_Y; | 41 | scpdr |= SCPDR_TS_SCAN_Y; |
42 | scpdr &= ~SCPDR_TS_SCAN_X; | 42 | scpdr &= ~SCPDR_TS_SCAN_X; |
43 | ctrl_outb(scpdr, SCPDR); | 43 | __raw_writeb(scpdr, SCPDR); |
44 | udelay(30); | 44 | udelay(30); |
45 | 45 | ||
46 | absx = adc_single(ADC_CHANNEL_TS_X); | 46 | absx = adc_single(ADC_CHANNEL_TS_X); |
47 | 47 | ||
48 | scpdr = ctrl_inb(SCPDR); | 48 | scpdr = __raw_readb(SCPDR); |
49 | scpdr |= SCPDR_TS_SCAN_X; | 49 | scpdr |= SCPDR_TS_SCAN_X; |
50 | scpdr &= ~SCPDR_TS_SCAN_ENABLE; | 50 | scpdr &= ~SCPDR_TS_SCAN_ENABLE; |
51 | ctrl_outb(scpdr, SCPDR); | 51 | __raw_writeb(scpdr, SCPDR); |
52 | udelay(100); | 52 | udelay(100); |
53 | touched = ctrl_inb(PHDR) & PHDR_TS_PEN_DOWN; | 53 | touched = __raw_readb(PHDR) & PHDR_TS_PEN_DOWN; |
54 | } | 54 | } |
55 | 55 | ||
56 | if (touched) { | 56 | if (touched) { |
@@ -107,8 +107,7 @@ static int __init hp680_ts_init(void) | |||
107 | return 0; | 107 | return 0; |
108 | 108 | ||
109 | fail2: free_irq(HP680_TS_IRQ, NULL); | 109 | fail2: free_irq(HP680_TS_IRQ, NULL); |
110 | cancel_delayed_work(&work); | 110 | cancel_delayed_work_sync(&work); |
111 | flush_scheduled_work(); | ||
112 | fail1: input_free_device(hp680_ts_dev); | 111 | fail1: input_free_device(hp680_ts_dev); |
113 | return err; | 112 | return err; |
114 | } | 113 | } |
@@ -116,8 +115,7 @@ static int __init hp680_ts_init(void) | |||
116 | static void __exit hp680_ts_exit(void) | 115 | static void __exit hp680_ts_exit(void) |
117 | { | 116 | { |
118 | free_irq(HP680_TS_IRQ, NULL); | 117 | free_irq(HP680_TS_IRQ, NULL); |
119 | cancel_delayed_work(&work); | 118 | cancel_delayed_work_sync(&work); |
120 | flush_scheduled_work(); | ||
121 | input_unregister_device(hp680_ts_dev); | 119 | input_unregister_device(hp680_ts_dev); |
122 | } | 120 | } |
123 | 121 | ||
diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c new file mode 100644 index 000000000000..66c96bfc5522 --- /dev/null +++ b/drivers/input/touchscreen/intel-mid-touch.c | |||
@@ -0,0 +1,687 @@ | |||
1 | /* | ||
2 | * Intel MID Resistive Touch Screen Driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Intel Corp | ||
5 | * | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
20 | * | ||
21 | * Questions/Comments/Bug fixes to Sreedhara (sreedhara.ds@intel.com) | ||
22 | * Ramesh Agarwal (ramesh.agarwal@intel.com) | ||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
24 | * | ||
25 | * TODO: | ||
26 | * review conversion of r/m/w sequences | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/input.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/err.h> | ||
34 | #include <linux/param.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/irq.h> | ||
38 | #include <linux/delay.h> | ||
39 | #include <asm/intel_scu_ipc.h> | ||
40 | |||
41 | /* PMIC Interrupt registers */ | ||
42 | #define PMIC_REG_ID1 0x00 /* PMIC ID1 register */ | ||
43 | |||
44 | /* PMIC Interrupt registers */ | ||
45 | #define PMIC_REG_INT 0x04 /* PMIC interrupt register */ | ||
46 | #define PMIC_REG_MINT 0x05 /* PMIC interrupt mask register */ | ||
47 | |||
48 | /* ADC Interrupt registers */ | ||
49 | #define PMIC_REG_ADCINT 0x5F /* ADC interrupt register */ | ||
50 | #define PMIC_REG_MADCINT 0x60 /* ADC interrupt mask register */ | ||
51 | |||
52 | /* ADC Control registers */ | ||
53 | #define PMIC_REG_ADCCNTL1 0x61 /* ADC control register */ | ||
54 | |||
55 | /* ADC Channel Selection registers */ | ||
56 | #define PMICADDR0 0xA4 | ||
57 | #define END_OF_CHANNEL 0x1F | ||
58 | |||
59 | /* ADC Result register */ | ||
60 | #define PMIC_REG_ADCSNS0H 0x64 | ||
61 | |||
62 | /* ADC channels for touch screen */ | ||
63 | #define MRST_TS_CHAN10 0xA /* Touch screen X+ connection */ | ||
64 | #define MRST_TS_CHAN11 0xB /* Touch screen X- connection */ | ||
65 | #define MRST_TS_CHAN12 0xC /* Touch screen Y+ connection */ | ||
66 | #define MRST_TS_CHAN13 0xD /* Touch screen Y- connection */ | ||
67 | |||
68 | /* Touch screen channel BIAS constants */ | ||
69 | #define MRST_XBIAS 0x20 | ||
70 | #define MRST_YBIAS 0x40 | ||
71 | #define MRST_ZBIAS 0x80 | ||
72 | |||
73 | /* Touch screen coordinates */ | ||
74 | #define MRST_X_MIN 10 | ||
75 | #define MRST_X_MAX 1024 | ||
76 | #define MRST_X_FUZZ 5 | ||
77 | #define MRST_Y_MIN 10 | ||
78 | #define MRST_Y_MAX 1024 | ||
79 | #define MRST_Y_FUZZ 5 | ||
80 | #define MRST_PRESSURE_MIN 0 | ||
81 | #define MRST_PRESSURE_NOMINAL 50 | ||
82 | #define MRST_PRESSURE_MAX 100 | ||
83 | |||
84 | #define WAIT_ADC_COMPLETION 10 /* msec */ | ||
85 | |||
86 | /* PMIC ADC round robin delays */ | ||
87 | #define ADC_LOOP_DELAY0 0x0 /* Continuous loop */ | ||
88 | #define ADC_LOOP_DELAY1 0x1 /* 4.5 ms approximate */ | ||
89 | |||
90 | /* PMIC Vendor Identifiers */ | ||
91 | #define PMIC_VENDOR_FS 0 /* PMIC vendor FreeScale */ | ||
92 | #define PMIC_VENDOR_MAXIM 1 /* PMIC vendor MAXIM */ | ||
93 | #define PMIC_VENDOR_NEC 2 /* PMIC vendor NEC */ | ||
94 | #define MRSTOUCH_MAX_CHANNELS 32 /* Maximum ADC channels */ | ||
95 | |||
96 | /* Touch screen device structure */ | ||
97 | struct mrstouch_dev { | ||
98 | struct device *dev; /* device associated with touch screen */ | ||
99 | struct input_dev *input; | ||
100 | char phys[32]; | ||
101 | u16 asr; /* Address selection register */ | ||
102 | int irq; | ||
103 | unsigned int vendor; /* PMIC vendor */ | ||
104 | unsigned int rev; /* PMIC revision */ | ||
105 | |||
106 | int (*read_prepare)(struct mrstouch_dev *tsdev); | ||
107 | int (*read)(struct mrstouch_dev *tsdev, u16 *x, u16 *y, u16 *z); | ||
108 | int (*read_finish)(struct mrstouch_dev *tsdev); | ||
109 | }; | ||
110 | |||
111 | |||
112 | /*************************** NEC and Maxim Interface ************************/ | ||
113 | |||
114 | static int mrstouch_nec_adc_read_prepare(struct mrstouch_dev *tsdev) | ||
115 | { | ||
116 | return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0, 0x20); | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Enables PENDET interrupt. | ||
121 | */ | ||
122 | static int mrstouch_nec_adc_read_finish(struct mrstouch_dev *tsdev) | ||
123 | { | ||
124 | int err; | ||
125 | |||
126 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x20, 0x20); | ||
127 | if (!err) | ||
128 | err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, 0, 0x05); | ||
129 | |||
130 | return err; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * Reads PMIC ADC touch screen result | ||
135 | * Reads ADC storage registers for higher 7 and lower 3 bits and | ||
136 | * converts the two readings into a single value and turns off gain bit | ||
137 | */ | ||
138 | static int mrstouch_ts_chan_read(u16 offset, u16 chan, u16 *vp, u16 *vm) | ||
139 | { | ||
140 | int err; | ||
141 | u16 result; | ||
142 | u32 res; | ||
143 | |||
144 | result = PMIC_REG_ADCSNS0H + offset; | ||
145 | |||
146 | if (chan == MRST_TS_CHAN12) | ||
147 | result += 4; | ||
148 | |||
149 | err = intel_scu_ipc_ioread32(result, &res); | ||
150 | if (err) | ||
151 | return err; | ||
152 | |||
153 | /* Mash the bits up */ | ||
154 | |||
155 | *vp = (res & 0xFF) << 3; /* Highest 7 bits */ | ||
156 | *vp |= (res >> 8) & 0x07; /* Lower 3 bits */ | ||
157 | *vp &= 0x3FF; | ||
158 | |||
159 | res >>= 16; | ||
160 | |||
161 | *vm = (res & 0xFF) << 3; /* Highest 7 bits */ | ||
162 | *vm |= (res >> 8) & 0x07; /* Lower 3 bits */ | ||
163 | *vm &= 0x3FF; | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Enables X, Y and Z bias values | ||
170 | * Enables YPYM for X channels and XPXM for Y channels | ||
171 | */ | ||
172 | static int mrstouch_ts_bias_set(uint offset, uint bias) | ||
173 | { | ||
174 | int count; | ||
175 | u16 chan, start; | ||
176 | u16 reg[4]; | ||
177 | u8 data[4]; | ||
178 | |||
179 | chan = PMICADDR0 + offset; | ||
180 | start = MRST_TS_CHAN10; | ||
181 | |||
182 | for (count = 0; count <= 3; count++) { | ||
183 | reg[count] = chan++; | ||
184 | data[count] = bias | (start + count); | ||
185 | } | ||
186 | |||
187 | return intel_scu_ipc_writev(reg, data, 4); | ||
188 | } | ||
189 | |||
190 | /* To read touch screen channel values */ | ||
191 | static int mrstouch_nec_adc_read(struct mrstouch_dev *tsdev, | ||
192 | u16 *x, u16 *y, u16 *z) | ||
193 | { | ||
194 | int err; | ||
195 | u16 xm, ym, zm; | ||
196 | |||
197 | /* configure Y bias for X channels */ | ||
198 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_YBIAS); | ||
199 | if (err) | ||
200 | goto ipc_error; | ||
201 | |||
202 | msleep(WAIT_ADC_COMPLETION); | ||
203 | |||
204 | /* read x+ and x- channels */ | ||
205 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, x, &xm); | ||
206 | if (err) | ||
207 | goto ipc_error; | ||
208 | |||
209 | /* configure x bias for y channels */ | ||
210 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_XBIAS); | ||
211 | if (err) | ||
212 | goto ipc_error; | ||
213 | |||
214 | msleep(WAIT_ADC_COMPLETION); | ||
215 | |||
216 | /* read y+ and y- channels */ | ||
217 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN12, y, &ym); | ||
218 | if (err) | ||
219 | goto ipc_error; | ||
220 | |||
221 | /* configure z bias for x and y channels */ | ||
222 | err = mrstouch_ts_bias_set(tsdev->asr, MRST_ZBIAS); | ||
223 | if (err) | ||
224 | goto ipc_error; | ||
225 | |||
226 | msleep(WAIT_ADC_COMPLETION); | ||
227 | |||
228 | /* read z+ and z- channels */ | ||
229 | err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, z, &zm); | ||
230 | if (err) | ||
231 | goto ipc_error; | ||
232 | |||
233 | return 0; | ||
234 | |||
235 | ipc_error: | ||
236 | dev_err(tsdev->dev, "ipc error during adc read\n"); | ||
237 | return err; | ||
238 | } | ||
239 | |||
240 | |||
241 | /*************************** Freescale Interface ************************/ | ||
242 | |||
243 | static int mrstouch_fs_adc_read_prepare(struct mrstouch_dev *tsdev) | ||
244 | { | ||
245 | int err, count; | ||
246 | u16 chan; | ||
247 | u16 reg[5]; | ||
248 | u8 data[5]; | ||
249 | |||
250 | /* Stop the ADC */ | ||
251 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x00, 0x02); | ||
252 | if (err) | ||
253 | goto ipc_error; | ||
254 | |||
255 | chan = PMICADDR0 + tsdev->asr; | ||
256 | |||
257 | /* Set X BIAS */ | ||
258 | for (count = 0; count <= 3; count++) { | ||
259 | reg[count] = chan++; | ||
260 | data[count] = 0x2A; | ||
261 | } | ||
262 | reg[count] = chan++; /* Dummy */ | ||
263 | data[count] = 0; | ||
264 | |||
265 | err = intel_scu_ipc_writev(reg, data, 5); | ||
266 | if (err) | ||
267 | goto ipc_error; | ||
268 | |||
269 | msleep(WAIT_ADC_COMPLETION); | ||
270 | |||
271 | /* Set Y BIAS */ | ||
272 | for (count = 0; count <= 3; count++) { | ||
273 | reg[count] = chan++; | ||
274 | data[count] = 0x4A; | ||
275 | } | ||
276 | reg[count] = chan++; /* Dummy */ | ||
277 | data[count] = 0; | ||
278 | |||
279 | err = intel_scu_ipc_writev(reg, data, 5); | ||
280 | if (err) | ||
281 | goto ipc_error; | ||
282 | |||
283 | msleep(WAIT_ADC_COMPLETION); | ||
284 | |||
285 | /* Set Z BIAS */ | ||
286 | err = intel_scu_ipc_iowrite32(chan + 2, 0x8A8A8A8A); | ||
287 | if (err) | ||
288 | goto ipc_error; | ||
289 | |||
290 | msleep(WAIT_ADC_COMPLETION); | ||
291 | |||
292 | return 0; | ||
293 | |||
294 | ipc_error: | ||
295 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
296 | return err; | ||
297 | } | ||
298 | |||
299 | static int mrstouch_fs_adc_read(struct mrstouch_dev *tsdev, | ||
300 | u16 *x, u16 *y, u16 *z) | ||
301 | { | ||
302 | int err; | ||
303 | u16 result; | ||
304 | u16 reg[4]; | ||
305 | u8 data[4]; | ||
306 | |||
307 | result = PMIC_REG_ADCSNS0H + tsdev->asr; | ||
308 | |||
309 | reg[0] = result + 4; | ||
310 | reg[1] = result + 5; | ||
311 | reg[2] = result + 16; | ||
312 | reg[3] = result + 17; | ||
313 | |||
314 | err = intel_scu_ipc_readv(reg, data, 4); | ||
315 | if (err) | ||
316 | goto ipc_error; | ||
317 | |||
318 | *x = data[0] << 3; /* Higher 7 bits */ | ||
319 | *x |= data[1] & 0x7; /* Lower 3 bits */ | ||
320 | *x &= 0x3FF; | ||
321 | |||
322 | *y = data[2] << 3; /* Higher 7 bits */ | ||
323 | *y |= data[3] & 0x7; /* Lower 3 bits */ | ||
324 | *y &= 0x3FF; | ||
325 | |||
326 | /* Read Z value */ | ||
327 | reg[0] = result + 28; | ||
328 | reg[1] = result + 29; | ||
329 | |||
330 | err = intel_scu_ipc_readv(reg, data, 4); | ||
331 | if (err) | ||
332 | goto ipc_error; | ||
333 | |||
334 | *z = data[0] << 3; /* Higher 7 bits */ | ||
335 | *z |= data[1] & 0x7; /* Lower 3 bits */ | ||
336 | *z &= 0x3FF; | ||
337 | |||
338 | return 0; | ||
339 | |||
340 | ipc_error: | ||
341 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
342 | return err; | ||
343 | } | ||
344 | |||
345 | static int mrstouch_fs_adc_read_finish(struct mrstouch_dev *tsdev) | ||
346 | { | ||
347 | int err, count; | ||
348 | u16 chan; | ||
349 | u16 reg[5]; | ||
350 | u8 data[5]; | ||
351 | |||
352 | /* Clear all TS channels */ | ||
353 | chan = PMICADDR0 + tsdev->asr; | ||
354 | for (count = 0; count <= 4; count++) { | ||
355 | reg[count] = chan++; | ||
356 | data[count] = 0; | ||
357 | } | ||
358 | err = intel_scu_ipc_writev(reg, data, 5); | ||
359 | if (err) | ||
360 | goto ipc_error; | ||
361 | |||
362 | for (count = 0; count <= 4; count++) { | ||
363 | reg[count] = chan++; | ||
364 | data[count] = 0; | ||
365 | } | ||
366 | err = intel_scu_ipc_writev(reg, data, 5); | ||
367 | if (err) | ||
368 | goto ipc_error; | ||
369 | |||
370 | err = intel_scu_ipc_iowrite32(chan + 2, 0x00000000); | ||
371 | if (err) | ||
372 | goto ipc_error; | ||
373 | |||
374 | /* Start ADC */ | ||
375 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x02, 0x02); | ||
376 | if (err) | ||
377 | goto ipc_error; | ||
378 | |||
379 | return 0; | ||
380 | |||
381 | ipc_error: | ||
382 | dev_err(tsdev->dev, "ipc error during %s\n", __func__); | ||
383 | return err; | ||
384 | } | ||
385 | |||
386 | static void mrstouch_report_event(struct input_dev *input, | ||
387 | unsigned int x, unsigned int y, unsigned int z) | ||
388 | { | ||
389 | if (z > MRST_PRESSURE_NOMINAL) { | ||
390 | /* Pen touched, report button touch and coordinates */ | ||
391 | input_report_key(input, BTN_TOUCH, 1); | ||
392 | input_report_abs(input, ABS_X, x); | ||
393 | input_report_abs(input, ABS_Y, y); | ||
394 | } else { | ||
395 | input_report_key(input, BTN_TOUCH, 0); | ||
396 | } | ||
397 | |||
398 | input_report_abs(input, ABS_PRESSURE, z); | ||
399 | input_sync(input); | ||
400 | } | ||
401 | |||
402 | /* PENDET interrupt handler */ | ||
403 | static irqreturn_t mrstouch_pendet_irq(int irq, void *dev_id) | ||
404 | { | ||
405 | struct mrstouch_dev *tsdev = dev_id; | ||
406 | u16 x, y, z; | ||
407 | |||
408 | /* | ||
409 | * Should we lower thread priority? Probably not, since we are | ||
410 | * not spinning but sleeping... | ||
411 | */ | ||
412 | |||
413 | if (tsdev->read_prepare(tsdev)) | ||
414 | goto out; | ||
415 | |||
416 | do { | ||
417 | if (tsdev->read(tsdev, &x, &y, &z)) | ||
418 | break; | ||
419 | |||
420 | mrstouch_report_event(tsdev->input, x, y, z); | ||
421 | } while (z > MRST_PRESSURE_NOMINAL); | ||
422 | |||
423 | tsdev->read_finish(tsdev); | ||
424 | |||
425 | out: | ||
426 | return IRQ_HANDLED; | ||
427 | } | ||
428 | |||
429 | /* Utility to read PMIC ID */ | ||
430 | static int __devinit mrstouch_read_pmic_id(uint *vendor, uint *rev) | ||
431 | { | ||
432 | int err; | ||
433 | u8 r; | ||
434 | |||
435 | err = intel_scu_ipc_ioread8(PMIC_REG_ID1, &r); | ||
436 | if (err) | ||
437 | return err; | ||
438 | |||
439 | *vendor = r & 0x7; | ||
440 | *rev = (r >> 3) & 0x7; | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * Parse ADC channels to find end of the channel configured by other ADC user | ||
447 | * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels | ||
448 | */ | ||
449 | static int __devinit mrstouch_chan_parse(struct mrstouch_dev *tsdev) | ||
450 | { | ||
451 | int err, i, found; | ||
452 | u8 r8; | ||
453 | |||
454 | found = -1; | ||
455 | |||
456 | for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) { | ||
457 | if (found >= 0) | ||
458 | break; | ||
459 | |||
460 | err = intel_scu_ipc_ioread8(PMICADDR0 + i, &r8); | ||
461 | if (err) | ||
462 | return err; | ||
463 | |||
464 | if (r8 == END_OF_CHANNEL) { | ||
465 | found = i; | ||
466 | break; | ||
467 | } | ||
468 | } | ||
469 | if (found < 0) | ||
470 | return 0; | ||
471 | |||
472 | if (tsdev->vendor == PMIC_VENDOR_FS) { | ||
473 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 18)) | ||
474 | return -ENOSPC; | ||
475 | } else { | ||
476 | if (found && found > (MRSTOUCH_MAX_CHANNELS - 4)) | ||
477 | return -ENOSPC; | ||
478 | } | ||
479 | return found; | ||
480 | } | ||
481 | |||
482 | |||
483 | /* | ||
484 | * Writes touch screen channels to ADC address selection registers | ||
485 | */ | ||
486 | static int __devinit mrstouch_ts_chan_set(uint offset) | ||
487 | { | ||
488 | u16 chan; | ||
489 | |||
490 | int ret, count; | ||
491 | |||
492 | chan = PMICADDR0 + offset; | ||
493 | for (count = 0; count <= 3; count++) { | ||
494 | ret = intel_scu_ipc_iowrite8(chan++, MRST_TS_CHAN10 + count); | ||
495 | if (ret) | ||
496 | return ret; | ||
497 | } | ||
498 | return intel_scu_ipc_iowrite8(chan++, END_OF_CHANNEL); | ||
499 | } | ||
500 | |||
501 | /* Initialize ADC */ | ||
502 | static int __devinit mrstouch_adc_init(struct mrstouch_dev *tsdev) | ||
503 | { | ||
504 | int err, start; | ||
505 | u8 ra, rm; | ||
506 | |||
507 | err = mrstouch_read_pmic_id(&tsdev->vendor, &tsdev->rev); | ||
508 | if (err) { | ||
509 | dev_err(tsdev->dev, "Unable to read PMIC id\n"); | ||
510 | return err; | ||
511 | } | ||
512 | |||
513 | switch (tsdev->vendor) { | ||
514 | case PMIC_VENDOR_NEC: | ||
515 | case PMIC_VENDOR_MAXIM: | ||
516 | tsdev->read_prepare = mrstouch_nec_adc_read_prepare; | ||
517 | tsdev->read = mrstouch_nec_adc_read; | ||
518 | tsdev->read_finish = mrstouch_nec_adc_read_finish; | ||
519 | break; | ||
520 | |||
521 | case PMIC_VENDOR_FS: | ||
522 | tsdev->read_prepare = mrstouch_fs_adc_read_prepare; | ||
523 | tsdev->read = mrstouch_fs_adc_read; | ||
524 | tsdev->read_finish = mrstouch_fs_adc_read_finish; | ||
525 | break; | ||
526 | |||
527 | default: | ||
528 | dev_err(tsdev->dev, | ||
529 | "Unsupported touchscreen: %d\n", tsdev->vendor); | ||
530 | return -ENXIO; | ||
531 | } | ||
532 | |||
533 | start = mrstouch_chan_parse(tsdev); | ||
534 | if (start < 0) { | ||
535 | dev_err(tsdev->dev, "Unable to parse channels\n"); | ||
536 | return start; | ||
537 | } | ||
538 | |||
539 | tsdev->asr = start; | ||
540 | |||
541 | /* | ||
542 | * ADC power on, start, enable PENDET and set loop delay | ||
543 | * ADC loop delay is set to 4.5 ms approximately | ||
544 | * Loop delay more than this results in jitter in adc readings | ||
545 | * Setting loop delay to 0 (continuous loop) in MAXIM stops PENDET | ||
546 | * interrupt generation sometimes. | ||
547 | */ | ||
548 | |||
549 | if (tsdev->vendor == PMIC_VENDOR_FS) { | ||
550 | ra = 0xE0 | ADC_LOOP_DELAY0; | ||
551 | rm = 0x5; | ||
552 | } else { | ||
553 | /* NEC and MAXIm not consistent with loop delay 0 */ | ||
554 | ra = 0xE0 | ADC_LOOP_DELAY1; | ||
555 | rm = 0x0; | ||
556 | |||
557 | /* configure touch screen channels */ | ||
558 | err = mrstouch_ts_chan_set(tsdev->asr); | ||
559 | if (err) | ||
560 | return err; | ||
561 | } | ||
562 | |||
563 | err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, ra, 0xE7); | ||
564 | if (err) | ||
565 | return err; | ||
566 | |||
567 | err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, rm, 0x03); | ||
568 | if (err) | ||
569 | return err; | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | |||
575 | /* Probe function for touch screen driver */ | ||
576 | static int __devinit mrstouch_probe(struct platform_device *pdev) | ||
577 | { | ||
578 | struct mrstouch_dev *tsdev; | ||
579 | struct input_dev *input; | ||
580 | int err; | ||
581 | int irq; | ||
582 | |||
583 | irq = platform_get_irq(pdev, 0); | ||
584 | if (irq < 0) { | ||
585 | dev_err(&pdev->dev, "no interrupt assigned\n"); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | |||
589 | tsdev = kzalloc(sizeof(struct mrstouch_dev), GFP_KERNEL); | ||
590 | input = input_allocate_device(); | ||
591 | if (!tsdev || !input) { | ||
592 | dev_err(&pdev->dev, "unable to allocate memory\n"); | ||
593 | err = -ENOMEM; | ||
594 | goto err_free_mem; | ||
595 | } | ||
596 | |||
597 | tsdev->dev = &pdev->dev; | ||
598 | tsdev->input = input; | ||
599 | tsdev->irq = irq; | ||
600 | |||
601 | snprintf(tsdev->phys, sizeof(tsdev->phys), | ||
602 | "%s/input0", dev_name(tsdev->dev)); | ||
603 | |||
604 | err = mrstouch_adc_init(tsdev); | ||
605 | if (err) { | ||
606 | dev_err(&pdev->dev, "ADC initialization failed\n"); | ||
607 | goto err_free_mem; | ||
608 | } | ||
609 | |||
610 | input->name = "mrst_touchscreen"; | ||
611 | input->phys = tsdev->phys; | ||
612 | input->dev.parent = tsdev->dev; | ||
613 | |||
614 | input->id.vendor = tsdev->vendor; | ||
615 | input->id.version = tsdev->rev; | ||
616 | |||
617 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
618 | input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
619 | |||
620 | input_set_abs_params(tsdev->input, ABS_X, | ||
621 | MRST_X_MIN, MRST_X_MAX, MRST_X_FUZZ, 0); | ||
622 | input_set_abs_params(tsdev->input, ABS_Y, | ||
623 | MRST_Y_MIN, MRST_Y_MAX, MRST_Y_FUZZ, 0); | ||
624 | input_set_abs_params(tsdev->input, ABS_PRESSURE, | ||
625 | MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0); | ||
626 | |||
627 | err = request_threaded_irq(tsdev->irq, NULL, mrstouch_pendet_irq, | ||
628 | 0, "mrstouch", tsdev); | ||
629 | if (err) { | ||
630 | dev_err(tsdev->dev, "unable to allocate irq\n"); | ||
631 | goto err_free_mem; | ||
632 | } | ||
633 | |||
634 | err = input_register_device(tsdev->input); | ||
635 | if (err) { | ||
636 | dev_err(tsdev->dev, "unable to register input device\n"); | ||
637 | goto err_free_irq; | ||
638 | } | ||
639 | |||
640 | platform_set_drvdata(pdev, tsdev); | ||
641 | return 0; | ||
642 | |||
643 | err_free_irq: | ||
644 | free_irq(tsdev->irq, tsdev); | ||
645 | err_free_mem: | ||
646 | input_free_device(input); | ||
647 | kfree(tsdev); | ||
648 | return err; | ||
649 | } | ||
650 | |||
651 | static int __devexit mrstouch_remove(struct platform_device *pdev) | ||
652 | { | ||
653 | struct mrstouch_dev *tsdev = platform_get_drvdata(pdev); | ||
654 | |||
655 | free_irq(tsdev->irq, tsdev); | ||
656 | input_unregister_device(tsdev->input); | ||
657 | kfree(tsdev); | ||
658 | |||
659 | platform_set_drvdata(pdev, NULL); | ||
660 | |||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | static struct platform_driver mrstouch_driver = { | ||
665 | .driver = { | ||
666 | .name = "pmic_touch", | ||
667 | .owner = THIS_MODULE, | ||
668 | }, | ||
669 | .probe = mrstouch_probe, | ||
670 | .remove = __devexit_p(mrstouch_remove), | ||
671 | }; | ||
672 | |||
673 | static int __init mrstouch_init(void) | ||
674 | { | ||
675 | return platform_driver_register(&mrstouch_driver); | ||
676 | } | ||
677 | module_init(mrstouch_init); | ||
678 | |||
679 | static void __exit mrstouch_exit(void) | ||
680 | { | ||
681 | platform_driver_unregister(&mrstouch_driver); | ||
682 | } | ||
683 | module_exit(mrstouch_exit); | ||
684 | |||
685 | MODULE_AUTHOR("Sreedhara Murthy. D.S, sreedhara.ds@intel.com"); | ||
686 | MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver"); | ||
687 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c new file mode 100644 index 000000000000..dcf803f5a1f7 --- /dev/null +++ b/drivers/input/touchscreen/lpc32xx_ts.c | |||
@@ -0,0 +1,411 @@ | |||
1 | /* | ||
2 | * LPC32xx built-in touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2010 NXP Semiconductors | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/slab.h> | ||
25 | |||
26 | /* | ||
27 | * Touchscreen controller register offsets | ||
28 | */ | ||
29 | #define LPC32XX_TSC_STAT 0x00 | ||
30 | #define LPC32XX_TSC_SEL 0x04 | ||
31 | #define LPC32XX_TSC_CON 0x08 | ||
32 | #define LPC32XX_TSC_FIFO 0x0C | ||
33 | #define LPC32XX_TSC_DTR 0x10 | ||
34 | #define LPC32XX_TSC_RTR 0x14 | ||
35 | #define LPC32XX_TSC_UTR 0x18 | ||
36 | #define LPC32XX_TSC_TTR 0x1C | ||
37 | #define LPC32XX_TSC_DXP 0x20 | ||
38 | #define LPC32XX_TSC_MIN_X 0x24 | ||
39 | #define LPC32XX_TSC_MAX_X 0x28 | ||
40 | #define LPC32XX_TSC_MIN_Y 0x2C | ||
41 | #define LPC32XX_TSC_MAX_Y 0x30 | ||
42 | #define LPC32XX_TSC_AUX_UTR 0x34 | ||
43 | #define LPC32XX_TSC_AUX_MIN 0x38 | ||
44 | #define LPC32XX_TSC_AUX_MAX 0x3C | ||
45 | |||
46 | #define LPC32XX_TSC_STAT_FIFO_OVRRN (1 << 8) | ||
47 | #define LPC32XX_TSC_STAT_FIFO_EMPTY (1 << 7) | ||
48 | |||
49 | #define LPC32XX_TSC_SEL_DEFVAL 0x0284 | ||
50 | |||
51 | #define LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 (0x1 << 11) | ||
52 | #define LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(s) ((10 - (s)) << 7) | ||
53 | #define LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(s) ((10 - (s)) << 4) | ||
54 | #define LPC32XX_TSC_ADCCON_POWER_UP (1 << 2) | ||
55 | #define LPC32XX_TSC_ADCCON_AUTO_EN (1 << 0) | ||
56 | |||
57 | #define LPC32XX_TSC_FIFO_TS_P_LEVEL (1 << 31) | ||
58 | #define LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(x) (((x) & 0x03FF0000) >> 16) | ||
59 | #define LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(y) ((y) & 0x000003FF) | ||
60 | |||
61 | #define LPC32XX_TSC_ADCDAT_VALUE_MASK 0x000003FF | ||
62 | |||
63 | #define LPC32XX_TSC_MIN_XY_VAL 0x0 | ||
64 | #define LPC32XX_TSC_MAX_XY_VAL 0x3FF | ||
65 | |||
66 | #define MOD_NAME "ts-lpc32xx" | ||
67 | |||
68 | #define tsc_readl(dev, reg) \ | ||
69 | __raw_readl((dev)->tsc_base + (reg)) | ||
70 | #define tsc_writel(dev, reg, val) \ | ||
71 | __raw_writel((val), (dev)->tsc_base + (reg)) | ||
72 | |||
73 | struct lpc32xx_tsc { | ||
74 | struct input_dev *dev; | ||
75 | void __iomem *tsc_base; | ||
76 | int irq; | ||
77 | struct clk *clk; | ||
78 | }; | ||
79 | |||
80 | static void lpc32xx_fifo_clear(struct lpc32xx_tsc *tsc) | ||
81 | { | ||
82 | while (!(tsc_readl(tsc, LPC32XX_TSC_STAT) & | ||
83 | LPC32XX_TSC_STAT_FIFO_EMPTY)) | ||
84 | tsc_readl(tsc, LPC32XX_TSC_FIFO); | ||
85 | } | ||
86 | |||
87 | static irqreturn_t lpc32xx_ts_interrupt(int irq, void *dev_id) | ||
88 | { | ||
89 | u32 tmp, rv[4], xs[4], ys[4]; | ||
90 | int idx; | ||
91 | struct lpc32xx_tsc *tsc = dev_id; | ||
92 | struct input_dev *input = tsc->dev; | ||
93 | |||
94 | tmp = tsc_readl(tsc, LPC32XX_TSC_STAT); | ||
95 | |||
96 | if (tmp & LPC32XX_TSC_STAT_FIFO_OVRRN) { | ||
97 | /* FIFO overflow - throw away samples */ | ||
98 | lpc32xx_fifo_clear(tsc); | ||
99 | return IRQ_HANDLED; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * Gather and normalize 4 samples. Pen-up events may have less | ||
104 | * than 4 samples, but its ok to pop 4 and let the last sample | ||
105 | * pen status check drop the samples. | ||
106 | */ | ||
107 | idx = 0; | ||
108 | while (idx < 4 && | ||
109 | !(tsc_readl(tsc, LPC32XX_TSC_STAT) & | ||
110 | LPC32XX_TSC_STAT_FIFO_EMPTY)) { | ||
111 | tmp = tsc_readl(tsc, LPC32XX_TSC_FIFO); | ||
112 | xs[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - | ||
113 | LPC32XX_TSC_FIFO_NORMALIZE_X_VAL(tmp); | ||
114 | ys[idx] = LPC32XX_TSC_ADCDAT_VALUE_MASK - | ||
115 | LPC32XX_TSC_FIFO_NORMALIZE_Y_VAL(tmp); | ||
116 | rv[idx] = tmp; | ||
117 | idx++; | ||
118 | } | ||
119 | |||
120 | /* Data is only valid if pen is still down in last sample */ | ||
121 | if (!(rv[3] & LPC32XX_TSC_FIFO_TS_P_LEVEL) && idx == 4) { | ||
122 | /* Use average of 2nd and 3rd sample for position */ | ||
123 | input_report_abs(input, ABS_X, (xs[1] + xs[2]) / 2); | ||
124 | input_report_abs(input, ABS_Y, (ys[1] + ys[2]) / 2); | ||
125 | input_report_key(input, BTN_TOUCH, 1); | ||
126 | } else { | ||
127 | input_report_key(input, BTN_TOUCH, 0); | ||
128 | } | ||
129 | |||
130 | input_sync(input); | ||
131 | |||
132 | return IRQ_HANDLED; | ||
133 | } | ||
134 | |||
135 | static void lpc32xx_stop_tsc(struct lpc32xx_tsc *tsc) | ||
136 | { | ||
137 | /* Disable auto mode */ | ||
138 | tsc_writel(tsc, LPC32XX_TSC_CON, | ||
139 | tsc_readl(tsc, LPC32XX_TSC_CON) & | ||
140 | ~LPC32XX_TSC_ADCCON_AUTO_EN); | ||
141 | |||
142 | clk_disable(tsc->clk); | ||
143 | } | ||
144 | |||
145 | static void lpc32xx_setup_tsc(struct lpc32xx_tsc *tsc) | ||
146 | { | ||
147 | u32 tmp; | ||
148 | |||
149 | clk_enable(tsc->clk); | ||
150 | |||
151 | tmp = tsc_readl(tsc, LPC32XX_TSC_CON) & ~LPC32XX_TSC_ADCCON_POWER_UP; | ||
152 | |||
153 | /* Set the TSC FIFO depth to 4 samples @ 10-bits per sample (max) */ | ||
154 | tmp = LPC32XX_TSC_ADCCON_IRQ_TO_FIFO_4 | | ||
155 | LPC32XX_TSC_ADCCON_X_SAMPLE_SIZE(10) | | ||
156 | LPC32XX_TSC_ADCCON_Y_SAMPLE_SIZE(10); | ||
157 | tsc_writel(tsc, LPC32XX_TSC_CON, tmp); | ||
158 | |||
159 | /* These values are all preset */ | ||
160 | tsc_writel(tsc, LPC32XX_TSC_SEL, LPC32XX_TSC_SEL_DEFVAL); | ||
161 | tsc_writel(tsc, LPC32XX_TSC_MIN_X, LPC32XX_TSC_MIN_XY_VAL); | ||
162 | tsc_writel(tsc, LPC32XX_TSC_MAX_X, LPC32XX_TSC_MAX_XY_VAL); | ||
163 | tsc_writel(tsc, LPC32XX_TSC_MIN_Y, LPC32XX_TSC_MIN_XY_VAL); | ||
164 | tsc_writel(tsc, LPC32XX_TSC_MAX_Y, LPC32XX_TSC_MAX_XY_VAL); | ||
165 | |||
166 | /* Aux support is not used */ | ||
167 | tsc_writel(tsc, LPC32XX_TSC_AUX_UTR, 0); | ||
168 | tsc_writel(tsc, LPC32XX_TSC_AUX_MIN, 0); | ||
169 | tsc_writel(tsc, LPC32XX_TSC_AUX_MAX, 0); | ||
170 | |||
171 | /* | ||
172 | * Set sample rate to about 240Hz per X/Y pair. A single measurement | ||
173 | * consists of 4 pairs which gives about a 60Hz sample rate based on | ||
174 | * a stable 32768Hz clock source. Values are in clocks. | ||
175 | * Rate is (32768 / (RTR + XCONV + RTR + YCONV + DXP + TTR + UTR) / 4 | ||
176 | */ | ||
177 | tsc_writel(tsc, LPC32XX_TSC_RTR, 0x2); | ||
178 | tsc_writel(tsc, LPC32XX_TSC_DTR, 0x2); | ||
179 | tsc_writel(tsc, LPC32XX_TSC_TTR, 0x10); | ||
180 | tsc_writel(tsc, LPC32XX_TSC_DXP, 0x4); | ||
181 | tsc_writel(tsc, LPC32XX_TSC_UTR, 88); | ||
182 | |||
183 | lpc32xx_fifo_clear(tsc); | ||
184 | |||
185 | /* Enable automatic ts event capture */ | ||
186 | tsc_writel(tsc, LPC32XX_TSC_CON, tmp | LPC32XX_TSC_ADCCON_AUTO_EN); | ||
187 | } | ||
188 | |||
189 | static int lpc32xx_ts_open(struct input_dev *dev) | ||
190 | { | ||
191 | struct lpc32xx_tsc *tsc = input_get_drvdata(dev); | ||
192 | |||
193 | lpc32xx_setup_tsc(tsc); | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static void lpc32xx_ts_close(struct input_dev *dev) | ||
199 | { | ||
200 | struct lpc32xx_tsc *tsc = input_get_drvdata(dev); | ||
201 | |||
202 | lpc32xx_stop_tsc(tsc); | ||
203 | } | ||
204 | |||
205 | static int __devinit lpc32xx_ts_probe(struct platform_device *pdev) | ||
206 | { | ||
207 | struct lpc32xx_tsc *tsc; | ||
208 | struct input_dev *input; | ||
209 | struct resource *res; | ||
210 | resource_size_t size; | ||
211 | int irq; | ||
212 | int error; | ||
213 | |||
214 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
215 | if (!res) { | ||
216 | dev_err(&pdev->dev, "Can't get memory resource\n"); | ||
217 | return -ENOENT; | ||
218 | } | ||
219 | |||
220 | irq = platform_get_irq(pdev, 0); | ||
221 | if (irq < 0) { | ||
222 | dev_err(&pdev->dev, "Can't get interrupt resource\n"); | ||
223 | return irq; | ||
224 | } | ||
225 | |||
226 | tsc = kzalloc(sizeof(*tsc), GFP_KERNEL); | ||
227 | input = input_allocate_device(); | ||
228 | if (!tsc || !input) { | ||
229 | dev_err(&pdev->dev, "failed allocating memory\n"); | ||
230 | error = -ENOMEM; | ||
231 | goto err_free_mem; | ||
232 | } | ||
233 | |||
234 | tsc->dev = input; | ||
235 | tsc->irq = irq; | ||
236 | |||
237 | size = resource_size(res); | ||
238 | |||
239 | if (!request_mem_region(res->start, size, pdev->name)) { | ||
240 | dev_err(&pdev->dev, "TSC registers are not free\n"); | ||
241 | error = -EBUSY; | ||
242 | goto err_free_mem; | ||
243 | } | ||
244 | |||
245 | tsc->tsc_base = ioremap(res->start, size); | ||
246 | if (!tsc->tsc_base) { | ||
247 | dev_err(&pdev->dev, "Can't map memory\n"); | ||
248 | error = -ENOMEM; | ||
249 | goto err_release_mem; | ||
250 | } | ||
251 | |||
252 | tsc->clk = clk_get(&pdev->dev, NULL); | ||
253 | if (IS_ERR(tsc->clk)) { | ||
254 | dev_err(&pdev->dev, "failed getting clock\n"); | ||
255 | error = PTR_ERR(tsc->clk); | ||
256 | goto err_unmap; | ||
257 | } | ||
258 | |||
259 | input->name = MOD_NAME; | ||
260 | input->phys = "lpc32xx/input0"; | ||
261 | input->id.bustype = BUS_HOST; | ||
262 | input->id.vendor = 0x0001; | ||
263 | input->id.product = 0x0002; | ||
264 | input->id.version = 0x0100; | ||
265 | input->dev.parent = &pdev->dev; | ||
266 | input->open = lpc32xx_ts_open; | ||
267 | input->close = lpc32xx_ts_close; | ||
268 | |||
269 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
270 | input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
271 | input_set_abs_params(input, ABS_X, LPC32XX_TSC_MIN_XY_VAL, | ||
272 | LPC32XX_TSC_MAX_XY_VAL, 0, 0); | ||
273 | input_set_abs_params(input, ABS_Y, LPC32XX_TSC_MIN_XY_VAL, | ||
274 | LPC32XX_TSC_MAX_XY_VAL, 0, 0); | ||
275 | |||
276 | input_set_drvdata(input, tsc); | ||
277 | |||
278 | error = request_irq(tsc->irq, lpc32xx_ts_interrupt, | ||
279 | IRQF_DISABLED, pdev->name, tsc); | ||
280 | if (error) { | ||
281 | dev_err(&pdev->dev, "failed requesting interrupt\n"); | ||
282 | goto err_put_clock; | ||
283 | } | ||
284 | |||
285 | error = input_register_device(input); | ||
286 | if (error) { | ||
287 | dev_err(&pdev->dev, "failed registering input device\n"); | ||
288 | goto err_free_irq; | ||
289 | } | ||
290 | |||
291 | platform_set_drvdata(pdev, tsc); | ||
292 | device_init_wakeup(&pdev->dev, 1); | ||
293 | |||
294 | return 0; | ||
295 | |||
296 | err_free_irq: | ||
297 | free_irq(tsc->irq, tsc); | ||
298 | err_put_clock: | ||
299 | clk_put(tsc->clk); | ||
300 | err_unmap: | ||
301 | iounmap(tsc->tsc_base); | ||
302 | err_release_mem: | ||
303 | release_mem_region(res->start, size); | ||
304 | err_free_mem: | ||
305 | input_free_device(input); | ||
306 | kfree(tsc); | ||
307 | |||
308 | return error; | ||
309 | } | ||
310 | |||
311 | static int __devexit lpc32xx_ts_remove(struct platform_device *pdev) | ||
312 | { | ||
313 | struct lpc32xx_tsc *tsc = platform_get_drvdata(pdev); | ||
314 | struct resource *res; | ||
315 | |||
316 | device_init_wakeup(&pdev->dev, 0); | ||
317 | free_irq(tsc->irq, tsc); | ||
318 | |||
319 | input_unregister_device(tsc->dev); | ||
320 | |||
321 | clk_put(tsc->clk); | ||
322 | |||
323 | iounmap(tsc->tsc_base); | ||
324 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
325 | release_mem_region(res->start, resource_size(res)); | ||
326 | |||
327 | kfree(tsc); | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | #ifdef CONFIG_PM | ||
333 | static int lpc32xx_ts_suspend(struct device *dev) | ||
334 | { | ||
335 | struct lpc32xx_tsc *tsc = dev_get_drvdata(dev); | ||
336 | struct input_dev *input = tsc->dev; | ||
337 | |||
338 | /* | ||
339 | * Suspend and resume can be called when the device hasn't been | ||
340 | * enabled. If there are no users that have the device open, then | ||
341 | * avoid calling the TSC stop and start functions as the TSC | ||
342 | * isn't yet clocked. | ||
343 | */ | ||
344 | mutex_lock(&input->mutex); | ||
345 | |||
346 | if (input->users) { | ||
347 | if (device_may_wakeup(dev)) | ||
348 | enable_irq_wake(tsc->irq); | ||
349 | else | ||
350 | lpc32xx_stop_tsc(tsc); | ||
351 | } | ||
352 | |||
353 | mutex_unlock(&input->mutex); | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int lpc32xx_ts_resume(struct device *dev) | ||
359 | { | ||
360 | struct lpc32xx_tsc *tsc = dev_get_drvdata(dev); | ||
361 | struct input_dev *input = tsc->dev; | ||
362 | |||
363 | mutex_lock(&input->mutex); | ||
364 | |||
365 | if (input->users) { | ||
366 | if (device_may_wakeup(dev)) | ||
367 | disable_irq_wake(tsc->irq); | ||
368 | else | ||
369 | lpc32xx_setup_tsc(tsc); | ||
370 | } | ||
371 | |||
372 | mutex_unlock(&input->mutex); | ||
373 | |||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | static const struct dev_pm_ops lpc32xx_ts_pm_ops = { | ||
378 | .suspend = lpc32xx_ts_suspend, | ||
379 | .resume = lpc32xx_ts_resume, | ||
380 | }; | ||
381 | #define LPC32XX_TS_PM_OPS (&lpc32xx_ts_pm_ops) | ||
382 | #else | ||
383 | #define LPC32XX_TS_PM_OPS NULL | ||
384 | #endif | ||
385 | |||
386 | static struct platform_driver lpc32xx_ts_driver = { | ||
387 | .probe = lpc32xx_ts_probe, | ||
388 | .remove = __devexit_p(lpc32xx_ts_remove), | ||
389 | .driver = { | ||
390 | .name = MOD_NAME, | ||
391 | .owner = THIS_MODULE, | ||
392 | .pm = LPC32XX_TS_PM_OPS, | ||
393 | }, | ||
394 | }; | ||
395 | |||
396 | static int __init lpc32xx_ts_init(void) | ||
397 | { | ||
398 | return platform_driver_register(&lpc32xx_ts_driver); | ||
399 | } | ||
400 | module_init(lpc32xx_ts_init); | ||
401 | |||
402 | static void __exit lpc32xx_ts_exit(void) | ||
403 | { | ||
404 | platform_driver_unregister(&lpc32xx_ts_driver); | ||
405 | } | ||
406 | module_exit(lpc32xx_ts_exit); | ||
407 | |||
408 | MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com"); | ||
409 | MODULE_DESCRIPTION("LPC32XX TSC Driver"); | ||
410 | MODULE_LICENSE("GPL"); | ||
411 | MODULE_ALIAS("platform:lpc32xx_ts"); | ||
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index b6b8b1c7ecea..3242e7076258 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c | |||
@@ -219,7 +219,7 @@ static int wm97xx_acc_startup(struct wm97xx *wm) | |||
219 | } | 219 | } |
220 | 220 | ||
221 | wm->pen_irq = gpio_to_irq(irq); | 221 | wm->pen_irq = gpio_to_irq(irq); |
222 | set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH); | 222 | irq_set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH); |
223 | } else /* pen irq not supported */ | 223 | } else /* pen irq not supported */ |
224 | pen_int = 0; | 224 | pen_int = 0; |
225 | 225 | ||
diff --git a/drivers/input/touchscreen/max11801_ts.c b/drivers/input/touchscreen/max11801_ts.c new file mode 100644 index 000000000000..4f2713d92791 --- /dev/null +++ b/drivers/input/touchscreen/max11801_ts.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* | ||
2 | * Driver for MAXI MAX11801 - A Resistive touch screen controller with | ||
3 | * i2c interface | ||
4 | * | ||
5 | * Copyright (C) 2011 Freescale Semiconductor, Inc. | ||
6 | * Author: Zhang Jiejing <jiejing.zhang@freescale.com> | ||
7 | * | ||
8 | * Based on mcs5000_ts.c | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License. | ||
13 | */ | ||
14 | |||
15 | /* | ||
16 | * This driver aims to support the series of MAXI touch chips max11801 | ||
17 | * through max11803. The main difference between these 4 chips can be | ||
18 | * found in the table below: | ||
19 | * ----------------------------------------------------- | ||
20 | * | CHIP | AUTO MODE SUPPORT(FIFO) | INTERFACE | | ||
21 | * |----------------------------------------------------| | ||
22 | * | max11800 | YES | SPI | | ||
23 | * | max11801 | YES | I2C | | ||
24 | * | max11802 | NO | SPI | | ||
25 | * | max11803 | NO | I2C | | ||
26 | * ------------------------------------------------------ | ||
27 | * | ||
28 | * Currently, this driver only supports max11801. | ||
29 | * | ||
30 | * Data Sheet: | ||
31 | * http://www.maxim-ic.com/datasheet/index.mvp/id/5943 | ||
32 | */ | ||
33 | |||
34 | #include <linux/module.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/i2c.h> | ||
37 | #include <linux/interrupt.h> | ||
38 | #include <linux/input.h> | ||
39 | #include <linux/slab.h> | ||
40 | #include <linux/bitops.h> | ||
41 | |||
42 | /* Register Address define */ | ||
43 | #define GENERNAL_STATUS_REG 0x00 | ||
44 | #define GENERNAL_CONF_REG 0x01 | ||
45 | #define MESURE_RES_CONF_REG 0x02 | ||
46 | #define MESURE_AVER_CONF_REG 0x03 | ||
47 | #define ADC_SAMPLE_TIME_CONF_REG 0x04 | ||
48 | #define PANEL_SETUPTIME_CONF_REG 0x05 | ||
49 | #define DELAY_CONVERSION_CONF_REG 0x06 | ||
50 | #define TOUCH_DETECT_PULLUP_CONF_REG 0x07 | ||
51 | #define AUTO_MODE_TIME_CONF_REG 0x08 /* only for max11800/max11801 */ | ||
52 | #define APERTURE_CONF_REG 0x09 /* only for max11800/max11801 */ | ||
53 | #define AUX_MESURE_CONF_REG 0x0a | ||
54 | #define OP_MODE_CONF_REG 0x0b | ||
55 | |||
56 | /* FIFO is found only in max11800 and max11801 */ | ||
57 | #define FIFO_RD_CMD (0x50 << 1) | ||
58 | #define MAX11801_FIFO_INT (1 << 2) | ||
59 | #define MAX11801_FIFO_OVERFLOW (1 << 3) | ||
60 | |||
61 | #define XY_BUFSIZE 4 | ||
62 | #define XY_BUF_OFFSET 4 | ||
63 | |||
64 | #define MAX11801_MAX_X 0xfff | ||
65 | #define MAX11801_MAX_Y 0xfff | ||
66 | |||
67 | #define MEASURE_TAG_OFFSET 2 | ||
68 | #define MEASURE_TAG_MASK (3 << MEASURE_TAG_OFFSET) | ||
69 | #define EVENT_TAG_OFFSET 0 | ||
70 | #define EVENT_TAG_MASK (3 << EVENT_TAG_OFFSET) | ||
71 | #define MEASURE_X_TAG (0 << MEASURE_TAG_OFFSET) | ||
72 | #define MEASURE_Y_TAG (1 << MEASURE_TAG_OFFSET) | ||
73 | |||
74 | /* These are the state of touch event state machine */ | ||
75 | enum { | ||
76 | EVENT_INIT, | ||
77 | EVENT_MIDDLE, | ||
78 | EVENT_RELEASE, | ||
79 | EVENT_FIFO_END | ||
80 | }; | ||
81 | |||
82 | struct max11801_data { | ||
83 | struct i2c_client *client; | ||
84 | struct input_dev *input_dev; | ||
85 | }; | ||
86 | |||
87 | static u8 read_register(struct i2c_client *client, int addr) | ||
88 | { | ||
89 | /* XXX: The chip ignores LSB of register address */ | ||
90 | return i2c_smbus_read_byte_data(client, addr << 1); | ||
91 | } | ||
92 | |||
93 | static int max11801_write_reg(struct i2c_client *client, int addr, int data) | ||
94 | { | ||
95 | /* XXX: The chip ignores LSB of register address */ | ||
96 | return i2c_smbus_write_byte_data(client, addr << 1, data); | ||
97 | } | ||
98 | |||
99 | static irqreturn_t max11801_ts_interrupt(int irq, void *dev_id) | ||
100 | { | ||
101 | struct max11801_data *data = dev_id; | ||
102 | struct i2c_client *client = data->client; | ||
103 | int status, i, ret; | ||
104 | u8 buf[XY_BUFSIZE]; | ||
105 | int x = -1; | ||
106 | int y = -1; | ||
107 | |||
108 | status = read_register(data->client, GENERNAL_STATUS_REG); | ||
109 | |||
110 | if (status & (MAX11801_FIFO_INT | MAX11801_FIFO_OVERFLOW)) { | ||
111 | status = read_register(data->client, GENERNAL_STATUS_REG); | ||
112 | |||
113 | ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_CMD, | ||
114 | XY_BUFSIZE, buf); | ||
115 | |||
116 | /* | ||
117 | * We should get 4 bytes buffer that contains X,Y | ||
118 | * and event tag | ||
119 | */ | ||
120 | if (ret < XY_BUFSIZE) | ||
121 | goto out; | ||
122 | |||
123 | for (i = 0; i < XY_BUFSIZE; i += XY_BUFSIZE / 2) { | ||
124 | if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_X_TAG) | ||
125 | x = (buf[i] << XY_BUF_OFFSET) + | ||
126 | (buf[i + 1] >> XY_BUF_OFFSET); | ||
127 | else if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_Y_TAG) | ||
128 | y = (buf[i] << XY_BUF_OFFSET) + | ||
129 | (buf[i + 1] >> XY_BUF_OFFSET); | ||
130 | } | ||
131 | |||
132 | if ((buf[1] & EVENT_TAG_MASK) != (buf[3] & EVENT_TAG_MASK)) | ||
133 | goto out; | ||
134 | |||
135 | switch (buf[1] & EVENT_TAG_MASK) { | ||
136 | case EVENT_INIT: | ||
137 | /* fall through */ | ||
138 | case EVENT_MIDDLE: | ||
139 | input_report_abs(data->input_dev, ABS_X, x); | ||
140 | input_report_abs(data->input_dev, ABS_Y, y); | ||
141 | input_event(data->input_dev, EV_KEY, BTN_TOUCH, 1); | ||
142 | input_sync(data->input_dev); | ||
143 | break; | ||
144 | |||
145 | case EVENT_RELEASE: | ||
146 | input_event(data->input_dev, EV_KEY, BTN_TOUCH, 0); | ||
147 | input_sync(data->input_dev); | ||
148 | break; | ||
149 | |||
150 | case EVENT_FIFO_END: | ||
151 | break; | ||
152 | } | ||
153 | } | ||
154 | out: | ||
155 | return IRQ_HANDLED; | ||
156 | } | ||
157 | |||
158 | static void __devinit max11801_ts_phy_init(struct max11801_data *data) | ||
159 | { | ||
160 | struct i2c_client *client = data->client; | ||
161 | |||
162 | /* Average X,Y, take 16 samples, average eight media sample */ | ||
163 | max11801_write_reg(client, MESURE_AVER_CONF_REG, 0xff); | ||
164 | /* X,Y panel setup time set to 20us */ | ||
165 | max11801_write_reg(client, PANEL_SETUPTIME_CONF_REG, 0x11); | ||
166 | /* Rough pullup time (2uS), Fine pullup time (10us) */ | ||
167 | max11801_write_reg(client, TOUCH_DETECT_PULLUP_CONF_REG, 0x10); | ||
168 | /* Auto mode init period = 5ms , scan period = 5ms*/ | ||
169 | max11801_write_reg(client, AUTO_MODE_TIME_CONF_REG, 0xaa); | ||
170 | /* Aperture X,Y set to +- 4LSB */ | ||
171 | max11801_write_reg(client, APERTURE_CONF_REG, 0x33); | ||
172 | /* Enable Power, enable Automode, enable Aperture, enable Average X,Y */ | ||
173 | max11801_write_reg(client, OP_MODE_CONF_REG, 0x36); | ||
174 | } | ||
175 | |||
176 | static int __devinit max11801_ts_probe(struct i2c_client *client, | ||
177 | const struct i2c_device_id *id) | ||
178 | { | ||
179 | struct max11801_data *data; | ||
180 | struct input_dev *input_dev; | ||
181 | int error; | ||
182 | |||
183 | data = kzalloc(sizeof(struct max11801_data), GFP_KERNEL); | ||
184 | input_dev = input_allocate_device(); | ||
185 | if (!data || !input_dev) { | ||
186 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
187 | error = -ENOMEM; | ||
188 | goto err_free_mem; | ||
189 | } | ||
190 | |||
191 | data->client = client; | ||
192 | data->input_dev = input_dev; | ||
193 | |||
194 | input_dev->name = "max11801_ts"; | ||
195 | input_dev->id.bustype = BUS_I2C; | ||
196 | input_dev->dev.parent = &client->dev; | ||
197 | |||
198 | __set_bit(EV_ABS, input_dev->evbit); | ||
199 | __set_bit(EV_KEY, input_dev->evbit); | ||
200 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
201 | input_set_abs_params(input_dev, ABS_X, 0, MAX11801_MAX_X, 0, 0); | ||
202 | input_set_abs_params(input_dev, ABS_Y, 0, MAX11801_MAX_Y, 0, 0); | ||
203 | input_set_drvdata(input_dev, data); | ||
204 | |||
205 | max11801_ts_phy_init(data); | ||
206 | |||
207 | error = request_threaded_irq(client->irq, NULL, max11801_ts_interrupt, | ||
208 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
209 | "max11801_ts", data); | ||
210 | if (error) { | ||
211 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
212 | goto err_free_mem; | ||
213 | } | ||
214 | |||
215 | error = input_register_device(data->input_dev); | ||
216 | if (error) | ||
217 | goto err_free_irq; | ||
218 | |||
219 | i2c_set_clientdata(client, data); | ||
220 | return 0; | ||
221 | |||
222 | err_free_irq: | ||
223 | free_irq(client->irq, data); | ||
224 | err_free_mem: | ||
225 | input_free_device(input_dev); | ||
226 | kfree(data); | ||
227 | return error; | ||
228 | } | ||
229 | |||
230 | static __devexit int max11801_ts_remove(struct i2c_client *client) | ||
231 | { | ||
232 | struct max11801_data *data = i2c_get_clientdata(client); | ||
233 | |||
234 | free_irq(client->irq, data); | ||
235 | input_unregister_device(data->input_dev); | ||
236 | kfree(data); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static const struct i2c_device_id max11801_ts_id[] = { | ||
242 | {"max11801", 0}, | ||
243 | { } | ||
244 | }; | ||
245 | MODULE_DEVICE_TABLE(i2c, max11801_ts_id); | ||
246 | |||
247 | static struct i2c_driver max11801_ts_driver = { | ||
248 | .driver = { | ||
249 | .name = "max11801_ts", | ||
250 | .owner = THIS_MODULE, | ||
251 | }, | ||
252 | .id_table = max11801_ts_id, | ||
253 | .probe = max11801_ts_probe, | ||
254 | .remove = __devexit_p(max11801_ts_remove), | ||
255 | }; | ||
256 | |||
257 | static int __init max11801_ts_init(void) | ||
258 | { | ||
259 | return i2c_add_driver(&max11801_ts_driver); | ||
260 | } | ||
261 | |||
262 | static void __exit max11801_ts_exit(void) | ||
263 | { | ||
264 | i2c_del_driver(&max11801_ts_driver); | ||
265 | } | ||
266 | |||
267 | module_init(max11801_ts_init); | ||
268 | module_exit(max11801_ts_exit); | ||
269 | |||
270 | MODULE_AUTHOR("Zhang Jiejing <jiejing.zhang@freescale.com>"); | ||
271 | MODULE_DESCRIPTION("Touchscreen driver for MAXI MAX11801 controller"); | ||
272 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index 6ee9940aaf5b..2d84c80ceb66 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c | |||
@@ -261,25 +261,27 @@ static int __devexit mcs5000_ts_remove(struct i2c_client *client) | |||
261 | } | 261 | } |
262 | 262 | ||
263 | #ifdef CONFIG_PM | 263 | #ifdef CONFIG_PM |
264 | static int mcs5000_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 264 | static int mcs5000_ts_suspend(struct device *dev) |
265 | { | 265 | { |
266 | struct i2c_client *client = to_i2c_client(dev); | ||
267 | |||
266 | /* Touch sleep mode */ | 268 | /* Touch sleep mode */ |
267 | i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP); | 269 | i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP); |
268 | 270 | ||
269 | return 0; | 271 | return 0; |
270 | } | 272 | } |
271 | 273 | ||
272 | static int mcs5000_ts_resume(struct i2c_client *client) | 274 | static int mcs5000_ts_resume(struct device *dev) |
273 | { | 275 | { |
276 | struct i2c_client *client = to_i2c_client(dev); | ||
274 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); | 277 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); |
275 | 278 | ||
276 | mcs5000_ts_phys_init(data); | 279 | mcs5000_ts_phys_init(data); |
277 | 280 | ||
278 | return 0; | 281 | return 0; |
279 | } | 282 | } |
280 | #else | 283 | |
281 | #define mcs5000_ts_suspend NULL | 284 | static SIMPLE_DEV_PM_OPS(mcs5000_ts_pm, mcs5000_ts_suspend, mcs5000_ts_resume); |
282 | #define mcs5000_ts_resume NULL | ||
283 | #endif | 285 | #endif |
284 | 286 | ||
285 | static const struct i2c_device_id mcs5000_ts_id[] = { | 287 | static const struct i2c_device_id mcs5000_ts_id[] = { |
@@ -291,10 +293,11 @@ MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id); | |||
291 | static struct i2c_driver mcs5000_ts_driver = { | 293 | static struct i2c_driver mcs5000_ts_driver = { |
292 | .probe = mcs5000_ts_probe, | 294 | .probe = mcs5000_ts_probe, |
293 | .remove = __devexit_p(mcs5000_ts_remove), | 295 | .remove = __devexit_p(mcs5000_ts_remove), |
294 | .suspend = mcs5000_ts_suspend, | ||
295 | .resume = mcs5000_ts_resume, | ||
296 | .driver = { | 296 | .driver = { |
297 | .name = "mcs5000_ts", | 297 | .name = "mcs5000_ts", |
298 | #ifdef CONFIG_PM | ||
299 | .pm = &mcs5000_ts_pm, | ||
300 | #endif | ||
298 | }, | 301 | }, |
299 | .id_table = mcs5000_ts_id, | 302 | .id_table = mcs5000_ts_id, |
300 | }; | 303 | }; |
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c index defe5dd3627c..5803bd0c1cca 100644 --- a/drivers/input/touchscreen/migor_ts.c +++ b/drivers/input/touchscreen/migor_ts.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/input.h> | 24 | #include <linux/input.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/pm.h> | ||
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
28 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
@@ -226,8 +227,9 @@ static int migor_ts_remove(struct i2c_client *client) | |||
226 | return 0; | 227 | return 0; |
227 | } | 228 | } |
228 | 229 | ||
229 | static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg) | 230 | static int migor_ts_suspend(struct device *dev) |
230 | { | 231 | { |
232 | struct i2c_client *client = to_i2c_client(dev); | ||
231 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); | 233 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); |
232 | 234 | ||
233 | if (device_may_wakeup(&client->dev)) | 235 | if (device_may_wakeup(&client->dev)) |
@@ -236,8 +238,9 @@ static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg) | |||
236 | return 0; | 238 | return 0; |
237 | } | 239 | } |
238 | 240 | ||
239 | static int migor_ts_resume(struct i2c_client *client) | 241 | static int migor_ts_resume(struct device *dev) |
240 | { | 242 | { |
243 | struct i2c_client *client = to_i2c_client(dev); | ||
241 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); | 244 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); |
242 | 245 | ||
243 | if (device_may_wakeup(&client->dev)) | 246 | if (device_may_wakeup(&client->dev)) |
@@ -246,6 +249,8 @@ static int migor_ts_resume(struct i2c_client *client) | |||
246 | return 0; | 249 | return 0; |
247 | } | 250 | } |
248 | 251 | ||
252 | static SIMPLE_DEV_PM_OPS(migor_ts_pm, migor_ts_suspend, migor_ts_resume); | ||
253 | |||
249 | static const struct i2c_device_id migor_ts_id[] = { | 254 | static const struct i2c_device_id migor_ts_id[] = { |
250 | { "migor_ts", 0 }, | 255 | { "migor_ts", 0 }, |
251 | { } | 256 | { } |
@@ -255,11 +260,10 @@ MODULE_DEVICE_TABLE(i2c, migor_ts); | |||
255 | static struct i2c_driver migor_ts_driver = { | 260 | static struct i2c_driver migor_ts_driver = { |
256 | .driver = { | 261 | .driver = { |
257 | .name = "migor_ts", | 262 | .name = "migor_ts", |
263 | .pm = &migor_ts_pm, | ||
258 | }, | 264 | }, |
259 | .probe = migor_ts_probe, | 265 | .probe = migor_ts_probe, |
260 | .remove = migor_ts_remove, | 266 | .remove = migor_ts_remove, |
261 | .suspend = migor_ts_suspend, | ||
262 | .resume = migor_ts_resume, | ||
263 | .id_table = migor_ts_id, | 267 | .id_table = migor_ts_id, |
264 | }; | 268 | }; |
265 | 269 | ||
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c index efd3aebaba5f..36e57deacd03 100644 --- a/drivers/input/touchscreen/mk712.c +++ b/drivers/input/touchscreen/mk712.c | |||
@@ -17,7 +17,7 @@ | |||
17 | * found in Gateway AOL Connected Touchpad computers. | 17 | * found in Gateway AOL Connected Touchpad computers. |
18 | * | 18 | * |
19 | * Documentation for ICS MK712 can be found at: | 19 | * Documentation for ICS MK712 can be found at: |
20 | * http://www.icst.com/pdf/mk712.pdf | 20 | * http://www.idt.com/products/getDoc.cfm?docID=18713923 |
21 | */ | 21 | */ |
22 | 22 | ||
23 | /* | 23 | /* |
diff --git a/drivers/input/touchscreen/qt602240_ts.c b/drivers/input/touchscreen/qt602240_ts.c deleted file mode 100644 index 66b26ad3032a..000000000000 --- a/drivers/input/touchscreen/qt602240_ts.c +++ /dev/null | |||
@@ -1,1401 +0,0 @@ | |||
1 | /* | ||
2 | * AT42QT602240/ATMXT224 Touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | ||
5 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/firmware.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/i2c/qt602240_ts.h> | ||
20 | #include <linux/input.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | /* Version */ | ||
25 | #define QT602240_VER_20 20 | ||
26 | #define QT602240_VER_21 21 | ||
27 | #define QT602240_VER_22 22 | ||
28 | |||
29 | /* Slave addresses */ | ||
30 | #define QT602240_APP_LOW 0x4a | ||
31 | #define QT602240_APP_HIGH 0x4b | ||
32 | #define QT602240_BOOT_LOW 0x24 | ||
33 | #define QT602240_BOOT_HIGH 0x25 | ||
34 | |||
35 | /* Firmware */ | ||
36 | #define QT602240_FW_NAME "qt602240.fw" | ||
37 | |||
38 | /* Registers */ | ||
39 | #define QT602240_FAMILY_ID 0x00 | ||
40 | #define QT602240_VARIANT_ID 0x01 | ||
41 | #define QT602240_VERSION 0x02 | ||
42 | #define QT602240_BUILD 0x03 | ||
43 | #define QT602240_MATRIX_X_SIZE 0x04 | ||
44 | #define QT602240_MATRIX_Y_SIZE 0x05 | ||
45 | #define QT602240_OBJECT_NUM 0x06 | ||
46 | #define QT602240_OBJECT_START 0x07 | ||
47 | |||
48 | #define QT602240_OBJECT_SIZE 6 | ||
49 | |||
50 | /* Object types */ | ||
51 | #define QT602240_DEBUG_DIAGNOSTIC 37 | ||
52 | #define QT602240_GEN_MESSAGE 5 | ||
53 | #define QT602240_GEN_COMMAND 6 | ||
54 | #define QT602240_GEN_POWER 7 | ||
55 | #define QT602240_GEN_ACQUIRE 8 | ||
56 | #define QT602240_TOUCH_MULTI 9 | ||
57 | #define QT602240_TOUCH_KEYARRAY 15 | ||
58 | #define QT602240_TOUCH_PROXIMITY 23 | ||
59 | #define QT602240_PROCI_GRIPFACE 20 | ||
60 | #define QT602240_PROCG_NOISE 22 | ||
61 | #define QT602240_PROCI_ONETOUCH 24 | ||
62 | #define QT602240_PROCI_TWOTOUCH 27 | ||
63 | #define QT602240_SPT_COMMSCONFIG 18 /* firmware ver 21 over */ | ||
64 | #define QT602240_SPT_GPIOPWM 19 | ||
65 | #define QT602240_SPT_SELFTEST 25 | ||
66 | #define QT602240_SPT_CTECONFIG 28 | ||
67 | #define QT602240_SPT_USERDATA 38 /* firmware ver 21 over */ | ||
68 | |||
69 | /* QT602240_GEN_COMMAND field */ | ||
70 | #define QT602240_COMMAND_RESET 0 | ||
71 | #define QT602240_COMMAND_BACKUPNV 1 | ||
72 | #define QT602240_COMMAND_CALIBRATE 2 | ||
73 | #define QT602240_COMMAND_REPORTALL 3 | ||
74 | #define QT602240_COMMAND_DIAGNOSTIC 5 | ||
75 | |||
76 | /* QT602240_GEN_POWER field */ | ||
77 | #define QT602240_POWER_IDLEACQINT 0 | ||
78 | #define QT602240_POWER_ACTVACQINT 1 | ||
79 | #define QT602240_POWER_ACTV2IDLETO 2 | ||
80 | |||
81 | /* QT602240_GEN_ACQUIRE field */ | ||
82 | #define QT602240_ACQUIRE_CHRGTIME 0 | ||
83 | #define QT602240_ACQUIRE_TCHDRIFT 2 | ||
84 | #define QT602240_ACQUIRE_DRIFTST 3 | ||
85 | #define QT602240_ACQUIRE_TCHAUTOCAL 4 | ||
86 | #define QT602240_ACQUIRE_SYNC 5 | ||
87 | #define QT602240_ACQUIRE_ATCHCALST 6 | ||
88 | #define QT602240_ACQUIRE_ATCHCALSTHR 7 | ||
89 | |||
90 | /* QT602240_TOUCH_MULTI field */ | ||
91 | #define QT602240_TOUCH_CTRL 0 | ||
92 | #define QT602240_TOUCH_XORIGIN 1 | ||
93 | #define QT602240_TOUCH_YORIGIN 2 | ||
94 | #define QT602240_TOUCH_XSIZE 3 | ||
95 | #define QT602240_TOUCH_YSIZE 4 | ||
96 | #define QT602240_TOUCH_BLEN 6 | ||
97 | #define QT602240_TOUCH_TCHTHR 7 | ||
98 | #define QT602240_TOUCH_TCHDI 8 | ||
99 | #define QT602240_TOUCH_ORIENT 9 | ||
100 | #define QT602240_TOUCH_MOVHYSTI 11 | ||
101 | #define QT602240_TOUCH_MOVHYSTN 12 | ||
102 | #define QT602240_TOUCH_NUMTOUCH 14 | ||
103 | #define QT602240_TOUCH_MRGHYST 15 | ||
104 | #define QT602240_TOUCH_MRGTHR 16 | ||
105 | #define QT602240_TOUCH_AMPHYST 17 | ||
106 | #define QT602240_TOUCH_XRANGE_LSB 18 | ||
107 | #define QT602240_TOUCH_XRANGE_MSB 19 | ||
108 | #define QT602240_TOUCH_YRANGE_LSB 20 | ||
109 | #define QT602240_TOUCH_YRANGE_MSB 21 | ||
110 | #define QT602240_TOUCH_XLOCLIP 22 | ||
111 | #define QT602240_TOUCH_XHICLIP 23 | ||
112 | #define QT602240_TOUCH_YLOCLIP 24 | ||
113 | #define QT602240_TOUCH_YHICLIP 25 | ||
114 | #define QT602240_TOUCH_XEDGECTRL 26 | ||
115 | #define QT602240_TOUCH_XEDGEDIST 27 | ||
116 | #define QT602240_TOUCH_YEDGECTRL 28 | ||
117 | #define QT602240_TOUCH_YEDGEDIST 29 | ||
118 | #define QT602240_TOUCH_JUMPLIMIT 30 /* firmware ver 22 over */ | ||
119 | |||
120 | /* QT602240_PROCI_GRIPFACE field */ | ||
121 | #define QT602240_GRIPFACE_CTRL 0 | ||
122 | #define QT602240_GRIPFACE_XLOGRIP 1 | ||
123 | #define QT602240_GRIPFACE_XHIGRIP 2 | ||
124 | #define QT602240_GRIPFACE_YLOGRIP 3 | ||
125 | #define QT602240_GRIPFACE_YHIGRIP 4 | ||
126 | #define QT602240_GRIPFACE_MAXTCHS 5 | ||
127 | #define QT602240_GRIPFACE_SZTHR1 7 | ||
128 | #define QT602240_GRIPFACE_SZTHR2 8 | ||
129 | #define QT602240_GRIPFACE_SHPTHR1 9 | ||
130 | #define QT602240_GRIPFACE_SHPTHR2 10 | ||
131 | #define QT602240_GRIPFACE_SUPEXTTO 11 | ||
132 | |||
133 | /* QT602240_PROCI_NOISE field */ | ||
134 | #define QT602240_NOISE_CTRL 0 | ||
135 | #define QT602240_NOISE_OUTFLEN 1 | ||
136 | #define QT602240_NOISE_GCAFUL_LSB 3 | ||
137 | #define QT602240_NOISE_GCAFUL_MSB 4 | ||
138 | #define QT602240_NOISE_GCAFLL_LSB 5 | ||
139 | #define QT602240_NOISE_GCAFLL_MSB 6 | ||
140 | #define QT602240_NOISE_ACTVGCAFVALID 7 | ||
141 | #define QT602240_NOISE_NOISETHR 8 | ||
142 | #define QT602240_NOISE_FREQHOPSCALE 10 | ||
143 | #define QT602240_NOISE_FREQ0 11 | ||
144 | #define QT602240_NOISE_FREQ1 12 | ||
145 | #define QT602240_NOISE_FREQ2 13 | ||
146 | #define QT602240_NOISE_FREQ3 14 | ||
147 | #define QT602240_NOISE_FREQ4 15 | ||
148 | #define QT602240_NOISE_IDLEGCAFVALID 16 | ||
149 | |||
150 | /* QT602240_SPT_COMMSCONFIG */ | ||
151 | #define QT602240_COMMS_CTRL 0 | ||
152 | #define QT602240_COMMS_CMD 1 | ||
153 | |||
154 | /* QT602240_SPT_CTECONFIG field */ | ||
155 | #define QT602240_CTE_CTRL 0 | ||
156 | #define QT602240_CTE_CMD 1 | ||
157 | #define QT602240_CTE_MODE 2 | ||
158 | #define QT602240_CTE_IDLEGCAFDEPTH 3 | ||
159 | #define QT602240_CTE_ACTVGCAFDEPTH 4 | ||
160 | #define QT602240_CTE_VOLTAGE 5 /* firmware ver 21 over */ | ||
161 | |||
162 | #define QT602240_VOLTAGE_DEFAULT 2700000 | ||
163 | #define QT602240_VOLTAGE_STEP 10000 | ||
164 | |||
165 | /* Define for QT602240_GEN_COMMAND */ | ||
166 | #define QT602240_BOOT_VALUE 0xa5 | ||
167 | #define QT602240_BACKUP_VALUE 0x55 | ||
168 | #define QT602240_BACKUP_TIME 25 /* msec */ | ||
169 | #define QT602240_RESET_TIME 65 /* msec */ | ||
170 | |||
171 | #define QT602240_FWRESET_TIME 175 /* msec */ | ||
172 | |||
173 | /* Command to unlock bootloader */ | ||
174 | #define QT602240_UNLOCK_CMD_MSB 0xaa | ||
175 | #define QT602240_UNLOCK_CMD_LSB 0xdc | ||
176 | |||
177 | /* Bootloader mode status */ | ||
178 | #define QT602240_WAITING_BOOTLOAD_CMD 0xc0 /* valid 7 6 bit only */ | ||
179 | #define QT602240_WAITING_FRAME_DATA 0x80 /* valid 7 6 bit only */ | ||
180 | #define QT602240_FRAME_CRC_CHECK 0x02 | ||
181 | #define QT602240_FRAME_CRC_FAIL 0x03 | ||
182 | #define QT602240_FRAME_CRC_PASS 0x04 | ||
183 | #define QT602240_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */ | ||
184 | #define QT602240_BOOT_STATUS_MASK 0x3f | ||
185 | |||
186 | /* Touch status */ | ||
187 | #define QT602240_SUPPRESS (1 << 1) | ||
188 | #define QT602240_AMP (1 << 2) | ||
189 | #define QT602240_VECTOR (1 << 3) | ||
190 | #define QT602240_MOVE (1 << 4) | ||
191 | #define QT602240_RELEASE (1 << 5) | ||
192 | #define QT602240_PRESS (1 << 6) | ||
193 | #define QT602240_DETECT (1 << 7) | ||
194 | |||
195 | /* Touchscreen absolute values */ | ||
196 | #define QT602240_MAX_XC 0x3ff | ||
197 | #define QT602240_MAX_YC 0x3ff | ||
198 | #define QT602240_MAX_AREA 0xff | ||
199 | |||
200 | #define QT602240_MAX_FINGER 10 | ||
201 | |||
202 | /* Initial register values recommended from chip vendor */ | ||
203 | static const u8 init_vals_ver_20[] = { | ||
204 | /* QT602240_GEN_COMMAND(6) */ | ||
205 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
206 | /* QT602240_GEN_POWER(7) */ | ||
207 | 0x20, 0xff, 0x32, | ||
208 | /* QT602240_GEN_ACQUIRE(8) */ | ||
209 | 0x08, 0x05, 0x05, 0x00, 0x00, 0x00, 0x05, 0x14, | ||
210 | /* QT602240_TOUCH_MULTI(9) */ | ||
211 | 0x00, 0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
212 | 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, | ||
213 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x64, | ||
214 | /* QT602240_TOUCH_KEYARRAY(15) */ | ||
215 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
216 | 0x00, | ||
217 | /* QT602240_SPT_GPIOPWM(19) */ | ||
218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
219 | 0x00, 0x00, | ||
220 | /* QT602240_PROCI_GRIPFACE(20) */ | ||
221 | 0x00, 0x64, 0x64, 0x64, 0x64, 0x00, 0x00, 0x1e, 0x14, 0x04, | ||
222 | 0x1e, 0x00, | ||
223 | /* QT602240_PROCG_NOISE(22) */ | ||
224 | 0x05, 0x00, 0x00, 0x19, 0x00, 0xe7, 0xff, 0x04, 0x32, 0x00, | ||
225 | 0x01, 0x0a, 0x0f, 0x14, 0x00, 0x00, 0xe8, | ||
226 | /* QT602240_TOUCH_PROXIMITY(23) */ | ||
227 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
228 | 0x00, 0x00, 0x00, | ||
229 | /* QT602240_PROCI_ONETOUCH(24) */ | ||
230 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
231 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
232 | /* QT602240_SPT_SELFTEST(25) */ | ||
233 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
234 | 0x00, 0x00, 0x00, 0x00, | ||
235 | /* QT602240_PROCI_TWOTOUCH(27) */ | ||
236 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
237 | /* QT602240_SPT_CTECONFIG(28) */ | ||
238 | 0x00, 0x00, 0x00, 0x04, 0x08, | ||
239 | }; | ||
240 | |||
241 | static const u8 init_vals_ver_21[] = { | ||
242 | /* QT602240_GEN_COMMAND(6) */ | ||
243 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
244 | /* QT602240_GEN_POWER(7) */ | ||
245 | 0x20, 0xff, 0x32, | ||
246 | /* QT602240_GEN_ACQUIRE(8) */ | ||
247 | 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23, | ||
248 | /* QT602240_TOUCH_MULTI(9) */ | ||
249 | 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
250 | 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, | ||
251 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
252 | /* QT602240_TOUCH_KEYARRAY(15) */ | ||
253 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
254 | 0x00, | ||
255 | /* QT602240_SPT_GPIOPWM(19) */ | ||
256 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
257 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
258 | /* QT602240_PROCI_GRIPFACE(20) */ | ||
259 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04, | ||
260 | 0x0f, 0x0a, | ||
261 | /* QT602240_PROCG_NOISE(22) */ | ||
262 | 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, | ||
263 | 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03, | ||
264 | /* QT602240_TOUCH_PROXIMITY(23) */ | ||
265 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
266 | 0x00, 0x00, 0x00, | ||
267 | /* QT602240_PROCI_ONETOUCH(24) */ | ||
268 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
269 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
270 | /* QT602240_SPT_SELFTEST(25) */ | ||
271 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
272 | 0x00, 0x00, 0x00, 0x00, | ||
273 | /* QT602240_PROCI_TWOTOUCH(27) */ | ||
274 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
275 | /* QT602240_SPT_CTECONFIG(28) */ | ||
276 | 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, | ||
277 | }; | ||
278 | |||
279 | static const u8 init_vals_ver_22[] = { | ||
280 | /* QT602240_GEN_COMMAND(6) */ | ||
281 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
282 | /* QT602240_GEN_POWER(7) */ | ||
283 | 0x20, 0xff, 0x32, | ||
284 | /* QT602240_GEN_ACQUIRE(8) */ | ||
285 | 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23, | ||
286 | /* QT602240_TOUCH_MULTI(9) */ | ||
287 | 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
288 | 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, | ||
289 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
290 | 0x00, | ||
291 | /* QT602240_TOUCH_KEYARRAY(15) */ | ||
292 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
293 | 0x00, | ||
294 | /* QT602240_SPT_GPIOPWM(19) */ | ||
295 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
296 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
297 | /* QT602240_PROCI_GRIPFACE(20) */ | ||
298 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04, | ||
299 | 0x0f, 0x0a, | ||
300 | /* QT602240_PROCG_NOISE(22) */ | ||
301 | 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, | ||
302 | 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03, | ||
303 | /* QT602240_TOUCH_PROXIMITY(23) */ | ||
304 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
305 | 0x00, 0x00, 0x00, 0x00, 0x00, | ||
306 | /* QT602240_PROCI_ONETOUCH(24) */ | ||
307 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
308 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
309 | /* QT602240_SPT_SELFTEST(25) */ | ||
310 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
311 | 0x00, 0x00, 0x00, 0x00, | ||
312 | /* QT602240_PROCI_TWOTOUCH(27) */ | ||
313 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
314 | /* QT602240_SPT_CTECONFIG(28) */ | ||
315 | 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, | ||
316 | }; | ||
317 | |||
318 | struct qt602240_info { | ||
319 | u8 family_id; | ||
320 | u8 variant_id; | ||
321 | u8 version; | ||
322 | u8 build; | ||
323 | u8 matrix_xsize; | ||
324 | u8 matrix_ysize; | ||
325 | u8 object_num; | ||
326 | }; | ||
327 | |||
328 | struct qt602240_object { | ||
329 | u8 type; | ||
330 | u16 start_address; | ||
331 | u8 size; | ||
332 | u8 instances; | ||
333 | u8 num_report_ids; | ||
334 | |||
335 | /* to map object and message */ | ||
336 | u8 max_reportid; | ||
337 | }; | ||
338 | |||
339 | struct qt602240_message { | ||
340 | u8 reportid; | ||
341 | u8 message[7]; | ||
342 | u8 checksum; | ||
343 | }; | ||
344 | |||
345 | struct qt602240_finger { | ||
346 | int status; | ||
347 | int x; | ||
348 | int y; | ||
349 | int area; | ||
350 | }; | ||
351 | |||
352 | /* Each client has this additional data */ | ||
353 | struct qt602240_data { | ||
354 | struct i2c_client *client; | ||
355 | struct input_dev *input_dev; | ||
356 | const struct qt602240_platform_data *pdata; | ||
357 | struct qt602240_object *object_table; | ||
358 | struct qt602240_info info; | ||
359 | struct qt602240_finger finger[QT602240_MAX_FINGER]; | ||
360 | unsigned int irq; | ||
361 | }; | ||
362 | |||
363 | static bool qt602240_object_readable(unsigned int type) | ||
364 | { | ||
365 | switch (type) { | ||
366 | case QT602240_GEN_MESSAGE: | ||
367 | case QT602240_GEN_COMMAND: | ||
368 | case QT602240_GEN_POWER: | ||
369 | case QT602240_GEN_ACQUIRE: | ||
370 | case QT602240_TOUCH_MULTI: | ||
371 | case QT602240_TOUCH_KEYARRAY: | ||
372 | case QT602240_TOUCH_PROXIMITY: | ||
373 | case QT602240_PROCI_GRIPFACE: | ||
374 | case QT602240_PROCG_NOISE: | ||
375 | case QT602240_PROCI_ONETOUCH: | ||
376 | case QT602240_PROCI_TWOTOUCH: | ||
377 | case QT602240_SPT_COMMSCONFIG: | ||
378 | case QT602240_SPT_GPIOPWM: | ||
379 | case QT602240_SPT_SELFTEST: | ||
380 | case QT602240_SPT_CTECONFIG: | ||
381 | case QT602240_SPT_USERDATA: | ||
382 | return true; | ||
383 | default: | ||
384 | return false; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | static bool qt602240_object_writable(unsigned int type) | ||
389 | { | ||
390 | switch (type) { | ||
391 | case QT602240_GEN_COMMAND: | ||
392 | case QT602240_GEN_POWER: | ||
393 | case QT602240_GEN_ACQUIRE: | ||
394 | case QT602240_TOUCH_MULTI: | ||
395 | case QT602240_TOUCH_KEYARRAY: | ||
396 | case QT602240_TOUCH_PROXIMITY: | ||
397 | case QT602240_PROCI_GRIPFACE: | ||
398 | case QT602240_PROCG_NOISE: | ||
399 | case QT602240_PROCI_ONETOUCH: | ||
400 | case QT602240_PROCI_TWOTOUCH: | ||
401 | case QT602240_SPT_GPIOPWM: | ||
402 | case QT602240_SPT_SELFTEST: | ||
403 | case QT602240_SPT_CTECONFIG: | ||
404 | return true; | ||
405 | default: | ||
406 | return false; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | static void qt602240_dump_message(struct device *dev, | ||
411 | struct qt602240_message *message) | ||
412 | { | ||
413 | dev_dbg(dev, "reportid:\t0x%x\n", message->reportid); | ||
414 | dev_dbg(dev, "message1:\t0x%x\n", message->message[0]); | ||
415 | dev_dbg(dev, "message2:\t0x%x\n", message->message[1]); | ||
416 | dev_dbg(dev, "message3:\t0x%x\n", message->message[2]); | ||
417 | dev_dbg(dev, "message4:\t0x%x\n", message->message[3]); | ||
418 | dev_dbg(dev, "message5:\t0x%x\n", message->message[4]); | ||
419 | dev_dbg(dev, "message6:\t0x%x\n", message->message[5]); | ||
420 | dev_dbg(dev, "message7:\t0x%x\n", message->message[6]); | ||
421 | dev_dbg(dev, "checksum:\t0x%x\n", message->checksum); | ||
422 | } | ||
423 | |||
424 | static int qt602240_check_bootloader(struct i2c_client *client, | ||
425 | unsigned int state) | ||
426 | { | ||
427 | u8 val; | ||
428 | |||
429 | recheck: | ||
430 | if (i2c_master_recv(client, &val, 1) != 1) { | ||
431 | dev_err(&client->dev, "%s: i2c recv failed\n", __func__); | ||
432 | return -EIO; | ||
433 | } | ||
434 | |||
435 | switch (state) { | ||
436 | case QT602240_WAITING_BOOTLOAD_CMD: | ||
437 | case QT602240_WAITING_FRAME_DATA: | ||
438 | val &= ~QT602240_BOOT_STATUS_MASK; | ||
439 | break; | ||
440 | case QT602240_FRAME_CRC_PASS: | ||
441 | if (val == QT602240_FRAME_CRC_CHECK) | ||
442 | goto recheck; | ||
443 | break; | ||
444 | default: | ||
445 | return -EINVAL; | ||
446 | } | ||
447 | |||
448 | if (val != state) { | ||
449 | dev_err(&client->dev, "Unvalid bootloader mode state\n"); | ||
450 | return -EINVAL; | ||
451 | } | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static int qt602240_unlock_bootloader(struct i2c_client *client) | ||
457 | { | ||
458 | u8 buf[2]; | ||
459 | |||
460 | buf[0] = QT602240_UNLOCK_CMD_LSB; | ||
461 | buf[1] = QT602240_UNLOCK_CMD_MSB; | ||
462 | |||
463 | if (i2c_master_send(client, buf, 2) != 2) { | ||
464 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
465 | return -EIO; | ||
466 | } | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static int qt602240_fw_write(struct i2c_client *client, | ||
472 | const u8 *data, unsigned int frame_size) | ||
473 | { | ||
474 | if (i2c_master_send(client, data, frame_size) != frame_size) { | ||
475 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
476 | return -EIO; | ||
477 | } | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static int __qt602240_read_reg(struct i2c_client *client, | ||
483 | u16 reg, u16 len, void *val) | ||
484 | { | ||
485 | struct i2c_msg xfer[2]; | ||
486 | u8 buf[2]; | ||
487 | |||
488 | buf[0] = reg & 0xff; | ||
489 | buf[1] = (reg >> 8) & 0xff; | ||
490 | |||
491 | /* Write register */ | ||
492 | xfer[0].addr = client->addr; | ||
493 | xfer[0].flags = 0; | ||
494 | xfer[0].len = 2; | ||
495 | xfer[0].buf = buf; | ||
496 | |||
497 | /* Read data */ | ||
498 | xfer[1].addr = client->addr; | ||
499 | xfer[1].flags = I2C_M_RD; | ||
500 | xfer[1].len = len; | ||
501 | xfer[1].buf = val; | ||
502 | |||
503 | if (i2c_transfer(client->adapter, xfer, 2) != 2) { | ||
504 | dev_err(&client->dev, "%s: i2c transfer failed\n", __func__); | ||
505 | return -EIO; | ||
506 | } | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static int qt602240_read_reg(struct i2c_client *client, u16 reg, u8 *val) | ||
512 | { | ||
513 | return __qt602240_read_reg(client, reg, 1, val); | ||
514 | } | ||
515 | |||
516 | static int qt602240_write_reg(struct i2c_client *client, u16 reg, u8 val) | ||
517 | { | ||
518 | u8 buf[3]; | ||
519 | |||
520 | buf[0] = reg & 0xff; | ||
521 | buf[1] = (reg >> 8) & 0xff; | ||
522 | buf[2] = val; | ||
523 | |||
524 | if (i2c_master_send(client, buf, 3) != 3) { | ||
525 | dev_err(&client->dev, "%s: i2c send failed\n", __func__); | ||
526 | return -EIO; | ||
527 | } | ||
528 | |||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | static int qt602240_read_object_table(struct i2c_client *client, | ||
533 | u16 reg, u8 *object_buf) | ||
534 | { | ||
535 | return __qt602240_read_reg(client, reg, QT602240_OBJECT_SIZE, | ||
536 | object_buf); | ||
537 | } | ||
538 | |||
539 | static struct qt602240_object * | ||
540 | qt602240_get_object(struct qt602240_data *data, u8 type) | ||
541 | { | ||
542 | struct qt602240_object *object; | ||
543 | int i; | ||
544 | |||
545 | for (i = 0; i < data->info.object_num; i++) { | ||
546 | object = data->object_table + i; | ||
547 | if (object->type == type) | ||
548 | return object; | ||
549 | } | ||
550 | |||
551 | dev_err(&data->client->dev, "Invalid object type\n"); | ||
552 | return NULL; | ||
553 | } | ||
554 | |||
555 | static int qt602240_read_message(struct qt602240_data *data, | ||
556 | struct qt602240_message *message) | ||
557 | { | ||
558 | struct qt602240_object *object; | ||
559 | u16 reg; | ||
560 | |||
561 | object = qt602240_get_object(data, QT602240_GEN_MESSAGE); | ||
562 | if (!object) | ||
563 | return -EINVAL; | ||
564 | |||
565 | reg = object->start_address; | ||
566 | return __qt602240_read_reg(data->client, reg, | ||
567 | sizeof(struct qt602240_message), message); | ||
568 | } | ||
569 | |||
570 | static int qt602240_read_object(struct qt602240_data *data, | ||
571 | u8 type, u8 offset, u8 *val) | ||
572 | { | ||
573 | struct qt602240_object *object; | ||
574 | u16 reg; | ||
575 | |||
576 | object = qt602240_get_object(data, type); | ||
577 | if (!object) | ||
578 | return -EINVAL; | ||
579 | |||
580 | reg = object->start_address; | ||
581 | return __qt602240_read_reg(data->client, reg + offset, 1, val); | ||
582 | } | ||
583 | |||
584 | static int qt602240_write_object(struct qt602240_data *data, | ||
585 | u8 type, u8 offset, u8 val) | ||
586 | { | ||
587 | struct qt602240_object *object; | ||
588 | u16 reg; | ||
589 | |||
590 | object = qt602240_get_object(data, type); | ||
591 | if (!object) | ||
592 | return -EINVAL; | ||
593 | |||
594 | reg = object->start_address; | ||
595 | return qt602240_write_reg(data->client, reg + offset, val); | ||
596 | } | ||
597 | |||
598 | static void qt602240_input_report(struct qt602240_data *data, int single_id) | ||
599 | { | ||
600 | struct qt602240_finger *finger = data->finger; | ||
601 | struct input_dev *input_dev = data->input_dev; | ||
602 | int status = finger[single_id].status; | ||
603 | int finger_num = 0; | ||
604 | int id; | ||
605 | |||
606 | for (id = 0; id < QT602240_MAX_FINGER; id++) { | ||
607 | if (!finger[id].status) | ||
608 | continue; | ||
609 | |||
610 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, | ||
611 | finger[id].status != QT602240_RELEASE ? | ||
612 | finger[id].area : 0); | ||
613 | input_report_abs(input_dev, ABS_MT_POSITION_X, | ||
614 | finger[id].x); | ||
615 | input_report_abs(input_dev, ABS_MT_POSITION_Y, | ||
616 | finger[id].y); | ||
617 | input_mt_sync(input_dev); | ||
618 | |||
619 | if (finger[id].status == QT602240_RELEASE) | ||
620 | finger[id].status = 0; | ||
621 | else | ||
622 | finger_num++; | ||
623 | } | ||
624 | |||
625 | input_report_key(input_dev, BTN_TOUCH, finger_num > 0); | ||
626 | |||
627 | if (status != QT602240_RELEASE) { | ||
628 | input_report_abs(input_dev, ABS_X, finger[single_id].x); | ||
629 | input_report_abs(input_dev, ABS_Y, finger[single_id].y); | ||
630 | } | ||
631 | |||
632 | input_sync(input_dev); | ||
633 | } | ||
634 | |||
635 | static void qt602240_input_touchevent(struct qt602240_data *data, | ||
636 | struct qt602240_message *message, int id) | ||
637 | { | ||
638 | struct qt602240_finger *finger = data->finger; | ||
639 | struct device *dev = &data->client->dev; | ||
640 | u8 status = message->message[0]; | ||
641 | int x; | ||
642 | int y; | ||
643 | int area; | ||
644 | |||
645 | /* Check the touch is present on the screen */ | ||
646 | if (!(status & QT602240_DETECT)) { | ||
647 | if (status & QT602240_RELEASE) { | ||
648 | dev_dbg(dev, "[%d] released\n", id); | ||
649 | |||
650 | finger[id].status = QT602240_RELEASE; | ||
651 | qt602240_input_report(data, id); | ||
652 | } | ||
653 | return; | ||
654 | } | ||
655 | |||
656 | /* Check only AMP detection */ | ||
657 | if (!(status & (QT602240_PRESS | QT602240_MOVE))) | ||
658 | return; | ||
659 | |||
660 | x = (message->message[1] << 2) | ((message->message[3] & ~0x3f) >> 6); | ||
661 | y = (message->message[2] << 2) | ((message->message[3] & ~0xf3) >> 2); | ||
662 | area = message->message[4]; | ||
663 | |||
664 | dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id, | ||
665 | status & QT602240_MOVE ? "moved" : "pressed", | ||
666 | x, y, area); | ||
667 | |||
668 | finger[id].status = status & QT602240_MOVE ? | ||
669 | QT602240_MOVE : QT602240_PRESS; | ||
670 | finger[id].x = x; | ||
671 | finger[id].y = y; | ||
672 | finger[id].area = area; | ||
673 | |||
674 | qt602240_input_report(data, id); | ||
675 | } | ||
676 | |||
677 | static irqreturn_t qt602240_interrupt(int irq, void *dev_id) | ||
678 | { | ||
679 | struct qt602240_data *data = dev_id; | ||
680 | struct qt602240_message message; | ||
681 | struct qt602240_object *object; | ||
682 | struct device *dev = &data->client->dev; | ||
683 | int id; | ||
684 | u8 reportid; | ||
685 | u8 max_reportid; | ||
686 | u8 min_reportid; | ||
687 | |||
688 | do { | ||
689 | if (qt602240_read_message(data, &message)) { | ||
690 | dev_err(dev, "Failed to read message\n"); | ||
691 | goto end; | ||
692 | } | ||
693 | |||
694 | reportid = message.reportid; | ||
695 | |||
696 | /* whether reportid is thing of QT602240_TOUCH_MULTI */ | ||
697 | object = qt602240_get_object(data, QT602240_TOUCH_MULTI); | ||
698 | if (!object) | ||
699 | goto end; | ||
700 | |||
701 | max_reportid = object->max_reportid; | ||
702 | min_reportid = max_reportid - object->num_report_ids + 1; | ||
703 | id = reportid - min_reportid; | ||
704 | |||
705 | if (reportid >= min_reportid && reportid <= max_reportid) | ||
706 | qt602240_input_touchevent(data, &message, id); | ||
707 | else | ||
708 | qt602240_dump_message(dev, &message); | ||
709 | } while (reportid != 0xff); | ||
710 | |||
711 | end: | ||
712 | return IRQ_HANDLED; | ||
713 | } | ||
714 | |||
715 | static int qt602240_check_reg_init(struct qt602240_data *data) | ||
716 | { | ||
717 | struct qt602240_object *object; | ||
718 | struct device *dev = &data->client->dev; | ||
719 | int index = 0; | ||
720 | int i, j; | ||
721 | u8 version = data->info.version; | ||
722 | u8 *init_vals; | ||
723 | |||
724 | switch (version) { | ||
725 | case QT602240_VER_20: | ||
726 | init_vals = (u8 *)init_vals_ver_20; | ||
727 | break; | ||
728 | case QT602240_VER_21: | ||
729 | init_vals = (u8 *)init_vals_ver_21; | ||
730 | break; | ||
731 | case QT602240_VER_22: | ||
732 | init_vals = (u8 *)init_vals_ver_22; | ||
733 | break; | ||
734 | default: | ||
735 | dev_err(dev, "Firmware version %d doesn't support\n", version); | ||
736 | return -EINVAL; | ||
737 | } | ||
738 | |||
739 | for (i = 0; i < data->info.object_num; i++) { | ||
740 | object = data->object_table + i; | ||
741 | |||
742 | if (!qt602240_object_writable(object->type)) | ||
743 | continue; | ||
744 | |||
745 | for (j = 0; j < object->size + 1; j++) | ||
746 | qt602240_write_object(data, object->type, j, | ||
747 | init_vals[index + j]); | ||
748 | |||
749 | index += object->size + 1; | ||
750 | } | ||
751 | |||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | static int qt602240_check_matrix_size(struct qt602240_data *data) | ||
756 | { | ||
757 | const struct qt602240_platform_data *pdata = data->pdata; | ||
758 | struct device *dev = &data->client->dev; | ||
759 | int mode = -1; | ||
760 | int error; | ||
761 | u8 val; | ||
762 | |||
763 | dev_dbg(dev, "Number of X lines: %d\n", pdata->x_line); | ||
764 | dev_dbg(dev, "Number of Y lines: %d\n", pdata->y_line); | ||
765 | |||
766 | switch (pdata->x_line) { | ||
767 | case 0 ... 15: | ||
768 | if (pdata->y_line <= 14) | ||
769 | mode = 0; | ||
770 | break; | ||
771 | case 16: | ||
772 | if (pdata->y_line <= 12) | ||
773 | mode = 1; | ||
774 | if (pdata->y_line == 13 || pdata->y_line == 14) | ||
775 | mode = 0; | ||
776 | break; | ||
777 | case 17: | ||
778 | if (pdata->y_line <= 11) | ||
779 | mode = 2; | ||
780 | if (pdata->y_line == 12 || pdata->y_line == 13) | ||
781 | mode = 1; | ||
782 | break; | ||
783 | case 18: | ||
784 | if (pdata->y_line <= 10) | ||
785 | mode = 3; | ||
786 | if (pdata->y_line == 11 || pdata->y_line == 12) | ||
787 | mode = 2; | ||
788 | break; | ||
789 | case 19: | ||
790 | if (pdata->y_line <= 9) | ||
791 | mode = 4; | ||
792 | if (pdata->y_line == 10 || pdata->y_line == 11) | ||
793 | mode = 3; | ||
794 | break; | ||
795 | case 20: | ||
796 | mode = 4; | ||
797 | } | ||
798 | |||
799 | if (mode < 0) { | ||
800 | dev_err(dev, "Invalid X/Y lines\n"); | ||
801 | return -EINVAL; | ||
802 | } | ||
803 | |||
804 | error = qt602240_read_object(data, QT602240_SPT_CTECONFIG, | ||
805 | QT602240_CTE_MODE, &val); | ||
806 | if (error) | ||
807 | return error; | ||
808 | |||
809 | if (mode == val) | ||
810 | return 0; | ||
811 | |||
812 | /* Change the CTE configuration */ | ||
813 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
814 | QT602240_CTE_CTRL, 1); | ||
815 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
816 | QT602240_CTE_MODE, mode); | ||
817 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
818 | QT602240_CTE_CTRL, 0); | ||
819 | |||
820 | return 0; | ||
821 | } | ||
822 | |||
823 | static int qt602240_make_highchg(struct qt602240_data *data) | ||
824 | { | ||
825 | struct device *dev = &data->client->dev; | ||
826 | int count = 10; | ||
827 | int error; | ||
828 | u8 val; | ||
829 | |||
830 | /* Read dummy message to make high CHG pin */ | ||
831 | do { | ||
832 | error = qt602240_read_object(data, QT602240_GEN_MESSAGE, 0, &val); | ||
833 | if (error) | ||
834 | return error; | ||
835 | } while ((val != 0xff) && --count); | ||
836 | |||
837 | if (!count) { | ||
838 | dev_err(dev, "CHG pin isn't cleared\n"); | ||
839 | return -EBUSY; | ||
840 | } | ||
841 | |||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | static void qt602240_handle_pdata(struct qt602240_data *data) | ||
846 | { | ||
847 | const struct qt602240_platform_data *pdata = data->pdata; | ||
848 | u8 voltage; | ||
849 | |||
850 | /* Set touchscreen lines */ | ||
851 | qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_XSIZE, | ||
852 | pdata->x_line); | ||
853 | qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_YSIZE, | ||
854 | pdata->y_line); | ||
855 | |||
856 | /* Set touchscreen orient */ | ||
857 | qt602240_write_object(data, QT602240_TOUCH_MULTI, QT602240_TOUCH_ORIENT, | ||
858 | pdata->orient); | ||
859 | |||
860 | /* Set touchscreen burst length */ | ||
861 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
862 | QT602240_TOUCH_BLEN, pdata->blen); | ||
863 | |||
864 | /* Set touchscreen threshold */ | ||
865 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
866 | QT602240_TOUCH_TCHTHR, pdata->threshold); | ||
867 | |||
868 | /* Set touchscreen resolution */ | ||
869 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
870 | QT602240_TOUCH_XRANGE_LSB, (pdata->x_size - 1) & 0xff); | ||
871 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
872 | QT602240_TOUCH_XRANGE_MSB, (pdata->x_size - 1) >> 8); | ||
873 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
874 | QT602240_TOUCH_YRANGE_LSB, (pdata->y_size - 1) & 0xff); | ||
875 | qt602240_write_object(data, QT602240_TOUCH_MULTI, | ||
876 | QT602240_TOUCH_YRANGE_MSB, (pdata->y_size - 1) >> 8); | ||
877 | |||
878 | /* Set touchscreen voltage */ | ||
879 | if (data->info.version >= QT602240_VER_21 && pdata->voltage) { | ||
880 | if (pdata->voltage < QT602240_VOLTAGE_DEFAULT) { | ||
881 | voltage = (QT602240_VOLTAGE_DEFAULT - pdata->voltage) / | ||
882 | QT602240_VOLTAGE_STEP; | ||
883 | voltage = 0xff - voltage + 1; | ||
884 | } else | ||
885 | voltage = (pdata->voltage - QT602240_VOLTAGE_DEFAULT) / | ||
886 | QT602240_VOLTAGE_STEP; | ||
887 | |||
888 | qt602240_write_object(data, QT602240_SPT_CTECONFIG, | ||
889 | QT602240_CTE_VOLTAGE, voltage); | ||
890 | } | ||
891 | } | ||
892 | |||
893 | static int qt602240_get_info(struct qt602240_data *data) | ||
894 | { | ||
895 | struct i2c_client *client = data->client; | ||
896 | struct qt602240_info *info = &data->info; | ||
897 | int error; | ||
898 | u8 val; | ||
899 | |||
900 | error = qt602240_read_reg(client, QT602240_FAMILY_ID, &val); | ||
901 | if (error) | ||
902 | return error; | ||
903 | info->family_id = val; | ||
904 | |||
905 | error = qt602240_read_reg(client, QT602240_VARIANT_ID, &val); | ||
906 | if (error) | ||
907 | return error; | ||
908 | info->variant_id = val; | ||
909 | |||
910 | error = qt602240_read_reg(client, QT602240_VERSION, &val); | ||
911 | if (error) | ||
912 | return error; | ||
913 | info->version = val; | ||
914 | |||
915 | error = qt602240_read_reg(client, QT602240_BUILD, &val); | ||
916 | if (error) | ||
917 | return error; | ||
918 | info->build = val; | ||
919 | |||
920 | error = qt602240_read_reg(client, QT602240_OBJECT_NUM, &val); | ||
921 | if (error) | ||
922 | return error; | ||
923 | info->object_num = val; | ||
924 | |||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | static int qt602240_get_object_table(struct qt602240_data *data) | ||
929 | { | ||
930 | int error; | ||
931 | int i; | ||
932 | u16 reg; | ||
933 | u8 reportid = 0; | ||
934 | u8 buf[QT602240_OBJECT_SIZE]; | ||
935 | |||
936 | for (i = 0; i < data->info.object_num; i++) { | ||
937 | struct qt602240_object *object = data->object_table + i; | ||
938 | |||
939 | reg = QT602240_OBJECT_START + QT602240_OBJECT_SIZE * i; | ||
940 | error = qt602240_read_object_table(data->client, reg, buf); | ||
941 | if (error) | ||
942 | return error; | ||
943 | |||
944 | object->type = buf[0]; | ||
945 | object->start_address = (buf[2] << 8) | buf[1]; | ||
946 | object->size = buf[3]; | ||
947 | object->instances = buf[4]; | ||
948 | object->num_report_ids = buf[5]; | ||
949 | |||
950 | if (object->num_report_ids) { | ||
951 | reportid += object->num_report_ids * | ||
952 | (object->instances + 1); | ||
953 | object->max_reportid = reportid; | ||
954 | } | ||
955 | } | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | static int qt602240_initialize(struct qt602240_data *data) | ||
961 | { | ||
962 | struct i2c_client *client = data->client; | ||
963 | struct qt602240_info *info = &data->info; | ||
964 | int error; | ||
965 | u8 val; | ||
966 | |||
967 | error = qt602240_get_info(data); | ||
968 | if (error) | ||
969 | return error; | ||
970 | |||
971 | data->object_table = kcalloc(info->object_num, | ||
972 | sizeof(struct qt602240_data), | ||
973 | GFP_KERNEL); | ||
974 | if (!data->object_table) { | ||
975 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
976 | return -ENOMEM; | ||
977 | } | ||
978 | |||
979 | /* Get object table information */ | ||
980 | error = qt602240_get_object_table(data); | ||
981 | if (error) | ||
982 | return error; | ||
983 | |||
984 | /* Check register init values */ | ||
985 | error = qt602240_check_reg_init(data); | ||
986 | if (error) | ||
987 | return error; | ||
988 | |||
989 | /* Check X/Y matrix size */ | ||
990 | error = qt602240_check_matrix_size(data); | ||
991 | if (error) | ||
992 | return error; | ||
993 | |||
994 | error = qt602240_make_highchg(data); | ||
995 | if (error) | ||
996 | return error; | ||
997 | |||
998 | qt602240_handle_pdata(data); | ||
999 | |||
1000 | /* Backup to memory */ | ||
1001 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1002 | QT602240_COMMAND_BACKUPNV, | ||
1003 | QT602240_BACKUP_VALUE); | ||
1004 | msleep(QT602240_BACKUP_TIME); | ||
1005 | |||
1006 | /* Soft reset */ | ||
1007 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1008 | QT602240_COMMAND_RESET, 1); | ||
1009 | msleep(QT602240_RESET_TIME); | ||
1010 | |||
1011 | /* Update matrix size at info struct */ | ||
1012 | error = qt602240_read_reg(client, QT602240_MATRIX_X_SIZE, &val); | ||
1013 | if (error) | ||
1014 | return error; | ||
1015 | info->matrix_xsize = val; | ||
1016 | |||
1017 | error = qt602240_read_reg(client, QT602240_MATRIX_Y_SIZE, &val); | ||
1018 | if (error) | ||
1019 | return error; | ||
1020 | info->matrix_ysize = val; | ||
1021 | |||
1022 | dev_info(&client->dev, | ||
1023 | "Family ID: %d Variant ID: %d Version: %d Build: %d\n", | ||
1024 | info->family_id, info->variant_id, info->version, | ||
1025 | info->build); | ||
1026 | |||
1027 | dev_info(&client->dev, | ||
1028 | "Matrix X Size: %d Matrix Y Size: %d Object Num: %d\n", | ||
1029 | info->matrix_xsize, info->matrix_ysize, | ||
1030 | info->object_num); | ||
1031 | |||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | static ssize_t qt602240_object_show(struct device *dev, | ||
1036 | struct device_attribute *attr, char *buf) | ||
1037 | { | ||
1038 | struct qt602240_data *data = dev_get_drvdata(dev); | ||
1039 | struct qt602240_object *object; | ||
1040 | int count = 0; | ||
1041 | int i, j; | ||
1042 | int error; | ||
1043 | u8 val; | ||
1044 | |||
1045 | for (i = 0; i < data->info.object_num; i++) { | ||
1046 | object = data->object_table + i; | ||
1047 | |||
1048 | count += sprintf(buf + count, | ||
1049 | "Object Table Element %d(Type %d)\n", | ||
1050 | i + 1, object->type); | ||
1051 | |||
1052 | if (!qt602240_object_readable(object->type)) { | ||
1053 | count += sprintf(buf + count, "\n"); | ||
1054 | continue; | ||
1055 | } | ||
1056 | |||
1057 | for (j = 0; j < object->size + 1; j++) { | ||
1058 | error = qt602240_read_object(data, | ||
1059 | object->type, j, &val); | ||
1060 | if (error) | ||
1061 | return error; | ||
1062 | |||
1063 | count += sprintf(buf + count, | ||
1064 | " Byte %d: 0x%x (%d)\n", j, val, val); | ||
1065 | } | ||
1066 | |||
1067 | count += sprintf(buf + count, "\n"); | ||
1068 | } | ||
1069 | |||
1070 | return count; | ||
1071 | } | ||
1072 | |||
1073 | static int qt602240_load_fw(struct device *dev, const char *fn) | ||
1074 | { | ||
1075 | struct qt602240_data *data = dev_get_drvdata(dev); | ||
1076 | struct i2c_client *client = data->client; | ||
1077 | const struct firmware *fw = NULL; | ||
1078 | unsigned int frame_size; | ||
1079 | unsigned int pos = 0; | ||
1080 | int ret; | ||
1081 | |||
1082 | ret = request_firmware(&fw, fn, dev); | ||
1083 | if (ret) { | ||
1084 | dev_err(dev, "Unable to open firmware %s\n", fn); | ||
1085 | return ret; | ||
1086 | } | ||
1087 | |||
1088 | /* Change to the bootloader mode */ | ||
1089 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1090 | QT602240_COMMAND_RESET, QT602240_BOOT_VALUE); | ||
1091 | msleep(QT602240_RESET_TIME); | ||
1092 | |||
1093 | /* Change to slave address of bootloader */ | ||
1094 | if (client->addr == QT602240_APP_LOW) | ||
1095 | client->addr = QT602240_BOOT_LOW; | ||
1096 | else | ||
1097 | client->addr = QT602240_BOOT_HIGH; | ||
1098 | |||
1099 | ret = qt602240_check_bootloader(client, QT602240_WAITING_BOOTLOAD_CMD); | ||
1100 | if (ret) | ||
1101 | goto out; | ||
1102 | |||
1103 | /* Unlock bootloader */ | ||
1104 | qt602240_unlock_bootloader(client); | ||
1105 | |||
1106 | while (pos < fw->size) { | ||
1107 | ret = qt602240_check_bootloader(client, | ||
1108 | QT602240_WAITING_FRAME_DATA); | ||
1109 | if (ret) | ||
1110 | goto out; | ||
1111 | |||
1112 | frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); | ||
1113 | |||
1114 | /* We should add 2 at frame size as the the firmware data is not | ||
1115 | * included the CRC bytes. | ||
1116 | */ | ||
1117 | frame_size += 2; | ||
1118 | |||
1119 | /* Write one frame to device */ | ||
1120 | qt602240_fw_write(client, fw->data + pos, frame_size); | ||
1121 | |||
1122 | ret = qt602240_check_bootloader(client, | ||
1123 | QT602240_FRAME_CRC_PASS); | ||
1124 | if (ret) | ||
1125 | goto out; | ||
1126 | |||
1127 | pos += frame_size; | ||
1128 | |||
1129 | dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size); | ||
1130 | } | ||
1131 | |||
1132 | out: | ||
1133 | release_firmware(fw); | ||
1134 | |||
1135 | /* Change to slave address of application */ | ||
1136 | if (client->addr == QT602240_BOOT_LOW) | ||
1137 | client->addr = QT602240_APP_LOW; | ||
1138 | else | ||
1139 | client->addr = QT602240_APP_HIGH; | ||
1140 | |||
1141 | return ret; | ||
1142 | } | ||
1143 | |||
1144 | static ssize_t qt602240_update_fw_store(struct device *dev, | ||
1145 | struct device_attribute *attr, | ||
1146 | const char *buf, size_t count) | ||
1147 | { | ||
1148 | struct qt602240_data *data = dev_get_drvdata(dev); | ||
1149 | unsigned int version; | ||
1150 | int error; | ||
1151 | |||
1152 | if (sscanf(buf, "%u", &version) != 1) { | ||
1153 | dev_err(dev, "Invalid values\n"); | ||
1154 | return -EINVAL; | ||
1155 | } | ||
1156 | |||
1157 | if (data->info.version < QT602240_VER_21 || version < QT602240_VER_21) { | ||
1158 | dev_err(dev, "FW update supported starting with version 21\n"); | ||
1159 | return -EINVAL; | ||
1160 | } | ||
1161 | |||
1162 | disable_irq(data->irq); | ||
1163 | |||
1164 | error = qt602240_load_fw(dev, QT602240_FW_NAME); | ||
1165 | if (error) { | ||
1166 | dev_err(dev, "The firmware update failed(%d)\n", error); | ||
1167 | count = error; | ||
1168 | } else { | ||
1169 | dev_dbg(dev, "The firmware update succeeded\n"); | ||
1170 | |||
1171 | /* Wait for reset */ | ||
1172 | msleep(QT602240_FWRESET_TIME); | ||
1173 | |||
1174 | kfree(data->object_table); | ||
1175 | data->object_table = NULL; | ||
1176 | |||
1177 | qt602240_initialize(data); | ||
1178 | } | ||
1179 | |||
1180 | enable_irq(data->irq); | ||
1181 | |||
1182 | return count; | ||
1183 | } | ||
1184 | |||
1185 | static DEVICE_ATTR(object, 0444, qt602240_object_show, NULL); | ||
1186 | static DEVICE_ATTR(update_fw, 0664, NULL, qt602240_update_fw_store); | ||
1187 | |||
1188 | static struct attribute *qt602240_attrs[] = { | ||
1189 | &dev_attr_object.attr, | ||
1190 | &dev_attr_update_fw.attr, | ||
1191 | NULL | ||
1192 | }; | ||
1193 | |||
1194 | static const struct attribute_group qt602240_attr_group = { | ||
1195 | .attrs = qt602240_attrs, | ||
1196 | }; | ||
1197 | |||
1198 | static void qt602240_start(struct qt602240_data *data) | ||
1199 | { | ||
1200 | /* Touch enable */ | ||
1201 | qt602240_write_object(data, | ||
1202 | QT602240_TOUCH_MULTI, QT602240_TOUCH_CTRL, 0x83); | ||
1203 | } | ||
1204 | |||
1205 | static void qt602240_stop(struct qt602240_data *data) | ||
1206 | { | ||
1207 | /* Touch disable */ | ||
1208 | qt602240_write_object(data, | ||
1209 | QT602240_TOUCH_MULTI, QT602240_TOUCH_CTRL, 0); | ||
1210 | } | ||
1211 | |||
1212 | static int qt602240_input_open(struct input_dev *dev) | ||
1213 | { | ||
1214 | struct qt602240_data *data = input_get_drvdata(dev); | ||
1215 | |||
1216 | qt602240_start(data); | ||
1217 | |||
1218 | return 0; | ||
1219 | } | ||
1220 | |||
1221 | static void qt602240_input_close(struct input_dev *dev) | ||
1222 | { | ||
1223 | struct qt602240_data *data = input_get_drvdata(dev); | ||
1224 | |||
1225 | qt602240_stop(data); | ||
1226 | } | ||
1227 | |||
1228 | static int __devinit qt602240_probe(struct i2c_client *client, | ||
1229 | const struct i2c_device_id *id) | ||
1230 | { | ||
1231 | struct qt602240_data *data; | ||
1232 | struct input_dev *input_dev; | ||
1233 | int error; | ||
1234 | |||
1235 | if (!client->dev.platform_data) | ||
1236 | return -EINVAL; | ||
1237 | |||
1238 | data = kzalloc(sizeof(struct qt602240_data), GFP_KERNEL); | ||
1239 | input_dev = input_allocate_device(); | ||
1240 | if (!data || !input_dev) { | ||
1241 | dev_err(&client->dev, "Failed to allocate memory\n"); | ||
1242 | error = -ENOMEM; | ||
1243 | goto err_free_mem; | ||
1244 | } | ||
1245 | |||
1246 | input_dev->name = "AT42QT602240/ATMXT224 Touchscreen"; | ||
1247 | input_dev->id.bustype = BUS_I2C; | ||
1248 | input_dev->dev.parent = &client->dev; | ||
1249 | input_dev->open = qt602240_input_open; | ||
1250 | input_dev->close = qt602240_input_close; | ||
1251 | |||
1252 | __set_bit(EV_ABS, input_dev->evbit); | ||
1253 | __set_bit(EV_KEY, input_dev->evbit); | ||
1254 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
1255 | |||
1256 | /* For single touch */ | ||
1257 | input_set_abs_params(input_dev, ABS_X, | ||
1258 | 0, QT602240_MAX_XC, 0, 0); | ||
1259 | input_set_abs_params(input_dev, ABS_Y, | ||
1260 | 0, QT602240_MAX_YC, 0, 0); | ||
1261 | |||
1262 | /* For multi touch */ | ||
1263 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
1264 | 0, QT602240_MAX_AREA, 0, 0); | ||
1265 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1266 | 0, QT602240_MAX_XC, 0, 0); | ||
1267 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1268 | 0, QT602240_MAX_YC, 0, 0); | ||
1269 | |||
1270 | input_set_drvdata(input_dev, data); | ||
1271 | |||
1272 | data->client = client; | ||
1273 | data->input_dev = input_dev; | ||
1274 | data->pdata = client->dev.platform_data; | ||
1275 | data->irq = client->irq; | ||
1276 | |||
1277 | i2c_set_clientdata(client, data); | ||
1278 | |||
1279 | error = qt602240_initialize(data); | ||
1280 | if (error) | ||
1281 | goto err_free_object; | ||
1282 | |||
1283 | error = request_threaded_irq(client->irq, NULL, qt602240_interrupt, | ||
1284 | IRQF_TRIGGER_FALLING, client->dev.driver->name, data); | ||
1285 | if (error) { | ||
1286 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
1287 | goto err_free_object; | ||
1288 | } | ||
1289 | |||
1290 | error = input_register_device(input_dev); | ||
1291 | if (error) | ||
1292 | goto err_free_irq; | ||
1293 | |||
1294 | error = sysfs_create_group(&client->dev.kobj, &qt602240_attr_group); | ||
1295 | if (error) | ||
1296 | goto err_unregister_device; | ||
1297 | |||
1298 | return 0; | ||
1299 | |||
1300 | err_unregister_device: | ||
1301 | input_unregister_device(input_dev); | ||
1302 | input_dev = NULL; | ||
1303 | err_free_irq: | ||
1304 | free_irq(client->irq, data); | ||
1305 | err_free_object: | ||
1306 | kfree(data->object_table); | ||
1307 | err_free_mem: | ||
1308 | input_free_device(input_dev); | ||
1309 | kfree(data); | ||
1310 | return error; | ||
1311 | } | ||
1312 | |||
1313 | static int __devexit qt602240_remove(struct i2c_client *client) | ||
1314 | { | ||
1315 | struct qt602240_data *data = i2c_get_clientdata(client); | ||
1316 | |||
1317 | sysfs_remove_group(&client->dev.kobj, &qt602240_attr_group); | ||
1318 | free_irq(data->irq, data); | ||
1319 | input_unregister_device(data->input_dev); | ||
1320 | kfree(data->object_table); | ||
1321 | kfree(data); | ||
1322 | |||
1323 | return 0; | ||
1324 | } | ||
1325 | |||
1326 | #ifdef CONFIG_PM | ||
1327 | static int qt602240_suspend(struct i2c_client *client, pm_message_t mesg) | ||
1328 | { | ||
1329 | struct qt602240_data *data = i2c_get_clientdata(client); | ||
1330 | struct input_dev *input_dev = data->input_dev; | ||
1331 | |||
1332 | mutex_lock(&input_dev->mutex); | ||
1333 | |||
1334 | if (input_dev->users) | ||
1335 | qt602240_stop(data); | ||
1336 | |||
1337 | mutex_unlock(&input_dev->mutex); | ||
1338 | |||
1339 | return 0; | ||
1340 | } | ||
1341 | |||
1342 | static int qt602240_resume(struct i2c_client *client) | ||
1343 | { | ||
1344 | struct qt602240_data *data = i2c_get_clientdata(client); | ||
1345 | struct input_dev *input_dev = data->input_dev; | ||
1346 | |||
1347 | /* Soft reset */ | ||
1348 | qt602240_write_object(data, QT602240_GEN_COMMAND, | ||
1349 | QT602240_COMMAND_RESET, 1); | ||
1350 | |||
1351 | msleep(QT602240_RESET_TIME); | ||
1352 | |||
1353 | mutex_lock(&input_dev->mutex); | ||
1354 | |||
1355 | if (input_dev->users) | ||
1356 | qt602240_start(data); | ||
1357 | |||
1358 | mutex_unlock(&input_dev->mutex); | ||
1359 | |||
1360 | return 0; | ||
1361 | } | ||
1362 | #else | ||
1363 | #define qt602240_suspend NULL | ||
1364 | #define qt602240_resume NULL | ||
1365 | #endif | ||
1366 | |||
1367 | static const struct i2c_device_id qt602240_id[] = { | ||
1368 | { "qt602240_ts", 0 }, | ||
1369 | { } | ||
1370 | }; | ||
1371 | MODULE_DEVICE_TABLE(i2c, qt602240_id); | ||
1372 | |||
1373 | static struct i2c_driver qt602240_driver = { | ||
1374 | .driver = { | ||
1375 | .name = "qt602240_ts", | ||
1376 | .owner = THIS_MODULE, | ||
1377 | }, | ||
1378 | .probe = qt602240_probe, | ||
1379 | .remove = __devexit_p(qt602240_remove), | ||
1380 | .suspend = qt602240_suspend, | ||
1381 | .resume = qt602240_resume, | ||
1382 | .id_table = qt602240_id, | ||
1383 | }; | ||
1384 | |||
1385 | static int __init qt602240_init(void) | ||
1386 | { | ||
1387 | return i2c_add_driver(&qt602240_driver); | ||
1388 | } | ||
1389 | |||
1390 | static void __exit qt602240_exit(void) | ||
1391 | { | ||
1392 | i2c_del_driver(&qt602240_driver); | ||
1393 | } | ||
1394 | |||
1395 | module_init(qt602240_init); | ||
1396 | module_exit(qt602240_exit); | ||
1397 | |||
1398 | /* Module information */ | ||
1399 | MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); | ||
1400 | MODULE_DESCRIPTION("AT42QT602240/ATMXT224 Touchscreen driver"); | ||
1401 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index 6085d12fd561..8feb7f3c8be1 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c | |||
@@ -350,7 +350,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev) | |||
350 | err_tcirq: | 350 | err_tcirq: |
351 | free_irq(ts.irq_tc, ts.input); | 351 | free_irq(ts.irq_tc, ts.input); |
352 | err_inputdev: | 352 | err_inputdev: |
353 | input_unregister_device(ts.input); | 353 | input_free_device(ts.input); |
354 | err_iomap: | 354 | err_iomap: |
355 | iounmap(ts.io); | 355 | iounmap(ts.io); |
356 | err_clk: | 356 | err_clk: |
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c new file mode 100644 index 000000000000..4ab371358b33 --- /dev/null +++ b/drivers/input/touchscreen/st1232.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | * ST1232 Touchscreen Controller Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Renesas Solutions Corp. | ||
5 | * Tony SIM <chinyeow.sim.xt@renesas.com> | ||
6 | * | ||
7 | * Using code from: | ||
8 | * - android.git.kernel.org: projects/kernel/common.git: synaptics_i2c_rmi.c | ||
9 | * Copyright (C) 2007 Google, Inc. | ||
10 | * | ||
11 | * This software is licensed under the terms of the GNU General Public | ||
12 | * License version 2, as published by the Free Software Foundation, and | ||
13 | * may be copied, distributed, and modified under those terms. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | */ | ||
20 | |||
21 | #include <linux/delay.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/types.h> | ||
28 | |||
29 | #define ST1232_TS_NAME "st1232-ts" | ||
30 | |||
31 | #define MIN_X 0x00 | ||
32 | #define MIN_Y 0x00 | ||
33 | #define MAX_X 0x31f /* (800 - 1) */ | ||
34 | #define MAX_Y 0x1df /* (480 - 1) */ | ||
35 | #define MAX_AREA 0xff | ||
36 | #define MAX_FINGERS 2 | ||
37 | |||
38 | struct st1232_ts_finger { | ||
39 | u16 x; | ||
40 | u16 y; | ||
41 | u8 t; | ||
42 | bool is_valid; | ||
43 | }; | ||
44 | |||
45 | struct st1232_ts_data { | ||
46 | struct i2c_client *client; | ||
47 | struct input_dev *input_dev; | ||
48 | struct st1232_ts_finger finger[MAX_FINGERS]; | ||
49 | }; | ||
50 | |||
51 | static int st1232_ts_read_data(struct st1232_ts_data *ts) | ||
52 | { | ||
53 | struct st1232_ts_finger *finger = ts->finger; | ||
54 | struct i2c_client *client = ts->client; | ||
55 | struct i2c_msg msg[2]; | ||
56 | int error; | ||
57 | u8 start_reg; | ||
58 | u8 buf[10]; | ||
59 | |||
60 | /* read touchscreen data from ST1232 */ | ||
61 | msg[0].addr = client->addr; | ||
62 | msg[0].flags = 0; | ||
63 | msg[0].len = 1; | ||
64 | msg[0].buf = &start_reg; | ||
65 | start_reg = 0x10; | ||
66 | |||
67 | msg[1].addr = ts->client->addr; | ||
68 | msg[1].flags = I2C_M_RD; | ||
69 | msg[1].len = sizeof(buf); | ||
70 | msg[1].buf = buf; | ||
71 | |||
72 | error = i2c_transfer(client->adapter, msg, 2); | ||
73 | if (error < 0) | ||
74 | return error; | ||
75 | |||
76 | /* get "valid" bits */ | ||
77 | finger[0].is_valid = buf[2] >> 7; | ||
78 | finger[1].is_valid = buf[5] >> 7; | ||
79 | |||
80 | /* get xy coordinate */ | ||
81 | if (finger[0].is_valid) { | ||
82 | finger[0].x = ((buf[2] & 0x0070) << 4) | buf[3]; | ||
83 | finger[0].y = ((buf[2] & 0x0007) << 8) | buf[4]; | ||
84 | finger[0].t = buf[8]; | ||
85 | } | ||
86 | |||
87 | if (finger[1].is_valid) { | ||
88 | finger[1].x = ((buf[5] & 0x0070) << 4) | buf[6]; | ||
89 | finger[1].y = ((buf[5] & 0x0007) << 8) | buf[7]; | ||
90 | finger[1].t = buf[9]; | ||
91 | } | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id) | ||
97 | { | ||
98 | struct st1232_ts_data *ts = dev_id; | ||
99 | struct st1232_ts_finger *finger = ts->finger; | ||
100 | struct input_dev *input_dev = ts->input_dev; | ||
101 | int count = 0; | ||
102 | int i, ret; | ||
103 | |||
104 | ret = st1232_ts_read_data(ts); | ||
105 | if (ret < 0) | ||
106 | goto end; | ||
107 | |||
108 | /* multi touch protocol */ | ||
109 | for (i = 0; i < MAX_FINGERS; i++) { | ||
110 | if (!finger[i].is_valid) | ||
111 | continue; | ||
112 | |||
113 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, finger[i].t); | ||
114 | input_report_abs(input_dev, ABS_MT_POSITION_X, finger[i].x); | ||
115 | input_report_abs(input_dev, ABS_MT_POSITION_Y, finger[i].y); | ||
116 | input_mt_sync(input_dev); | ||
117 | count++; | ||
118 | } | ||
119 | |||
120 | /* SYN_MT_REPORT only if no contact */ | ||
121 | if (!count) | ||
122 | input_mt_sync(input_dev); | ||
123 | |||
124 | /* SYN_REPORT */ | ||
125 | input_sync(input_dev); | ||
126 | |||
127 | end: | ||
128 | return IRQ_HANDLED; | ||
129 | } | ||
130 | |||
131 | static int __devinit st1232_ts_probe(struct i2c_client *client, | ||
132 | const struct i2c_device_id *id) | ||
133 | { | ||
134 | struct st1232_ts_data *ts; | ||
135 | struct input_dev *input_dev; | ||
136 | int error; | ||
137 | |||
138 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
139 | dev_err(&client->dev, "need I2C_FUNC_I2C\n"); | ||
140 | return -EIO; | ||
141 | } | ||
142 | |||
143 | if (!client->irq) { | ||
144 | dev_err(&client->dev, "no IRQ?\n"); | ||
145 | return -EINVAL; | ||
146 | } | ||
147 | |||
148 | |||
149 | ts = kzalloc(sizeof(struct st1232_ts_data), GFP_KERNEL); | ||
150 | input_dev = input_allocate_device(); | ||
151 | if (!ts || !input_dev) { | ||
152 | error = -ENOMEM; | ||
153 | goto err_free_mem; | ||
154 | } | ||
155 | |||
156 | ts->client = client; | ||
157 | ts->input_dev = input_dev; | ||
158 | |||
159 | input_dev->name = "st1232-touchscreen"; | ||
160 | input_dev->id.bustype = BUS_I2C; | ||
161 | input_dev->dev.parent = &client->dev; | ||
162 | |||
163 | __set_bit(EV_SYN, input_dev->evbit); | ||
164 | __set_bit(EV_KEY, input_dev->evbit); | ||
165 | __set_bit(EV_ABS, input_dev->evbit); | ||
166 | |||
167 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MAX_AREA, 0, 0); | ||
168 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, MIN_X, MAX_X, 0, 0); | ||
169 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, MIN_Y, MAX_Y, 0, 0); | ||
170 | |||
171 | error = request_threaded_irq(client->irq, NULL, st1232_ts_irq_handler, | ||
172 | IRQF_ONESHOT, client->name, ts); | ||
173 | if (error) { | ||
174 | dev_err(&client->dev, "Failed to register interrupt\n"); | ||
175 | goto err_free_mem; | ||
176 | } | ||
177 | |||
178 | error = input_register_device(ts->input_dev); | ||
179 | if (error) { | ||
180 | dev_err(&client->dev, "Unable to register %s input device\n", | ||
181 | input_dev->name); | ||
182 | goto err_free_irq; | ||
183 | } | ||
184 | |||
185 | i2c_set_clientdata(client, ts); | ||
186 | device_init_wakeup(&client->dev, 1); | ||
187 | |||
188 | return 0; | ||
189 | |||
190 | err_free_irq: | ||
191 | free_irq(client->irq, ts); | ||
192 | err_free_mem: | ||
193 | input_free_device(input_dev); | ||
194 | kfree(ts); | ||
195 | return error; | ||
196 | } | ||
197 | |||
198 | static int __devexit st1232_ts_remove(struct i2c_client *client) | ||
199 | { | ||
200 | struct st1232_ts_data *ts = i2c_get_clientdata(client); | ||
201 | |||
202 | device_init_wakeup(&client->dev, 0); | ||
203 | free_irq(client->irq, ts); | ||
204 | input_unregister_device(ts->input_dev); | ||
205 | kfree(ts); | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | #ifdef CONFIG_PM | ||
211 | static int st1232_ts_suspend(struct device *dev) | ||
212 | { | ||
213 | struct i2c_client *client = to_i2c_client(dev); | ||
214 | |||
215 | if (device_may_wakeup(&client->dev)) | ||
216 | enable_irq_wake(client->irq); | ||
217 | else | ||
218 | disable_irq(client->irq); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static int st1232_ts_resume(struct device *dev) | ||
224 | { | ||
225 | struct i2c_client *client = to_i2c_client(dev); | ||
226 | |||
227 | if (device_may_wakeup(&client->dev)) | ||
228 | disable_irq_wake(client->irq); | ||
229 | else | ||
230 | enable_irq(client->irq); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static const struct dev_pm_ops st1232_ts_pm_ops = { | ||
236 | .suspend = st1232_ts_suspend, | ||
237 | .resume = st1232_ts_resume, | ||
238 | }; | ||
239 | #endif | ||
240 | |||
241 | static const struct i2c_device_id st1232_ts_id[] = { | ||
242 | { ST1232_TS_NAME, 0 }, | ||
243 | { } | ||
244 | }; | ||
245 | MODULE_DEVICE_TABLE(i2c, st1232_ts_id); | ||
246 | |||
247 | static struct i2c_driver st1232_ts_driver = { | ||
248 | .probe = st1232_ts_probe, | ||
249 | .remove = __devexit_p(st1232_ts_remove), | ||
250 | .id_table = st1232_ts_id, | ||
251 | .driver = { | ||
252 | .name = ST1232_TS_NAME, | ||
253 | .owner = THIS_MODULE, | ||
254 | #ifdef CONFIG_PM | ||
255 | .pm = &st1232_ts_pm_ops, | ||
256 | #endif | ||
257 | }, | ||
258 | }; | ||
259 | |||
260 | static int __init st1232_ts_init(void) | ||
261 | { | ||
262 | return i2c_add_driver(&st1232_ts_driver); | ||
263 | } | ||
264 | module_init(st1232_ts_init); | ||
265 | |||
266 | static void __exit st1232_ts_exit(void) | ||
267 | { | ||
268 | i2c_del_driver(&st1232_ts_driver); | ||
269 | } | ||
270 | module_exit(st1232_ts_exit); | ||
271 | |||
272 | MODULE_AUTHOR("Tony SIM <chinyeow.sim.xt@renesas.com>"); | ||
273 | MODULE_DESCRIPTION("SITRONIX ST1232 Touchscreen Controller Driver"); | ||
274 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c index 656148ec0027..ae88e13c99ff 100644 --- a/drivers/input/touchscreen/stmpe-ts.c +++ b/drivers/input/touchscreen/stmpe-ts.c | |||
@@ -268,7 +268,7 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev) | |||
268 | struct stmpe_touch *ts; | 268 | struct stmpe_touch *ts; |
269 | struct input_dev *idev; | 269 | struct input_dev *idev; |
270 | struct stmpe_ts_platform_data *ts_pdata = NULL; | 270 | struct stmpe_ts_platform_data *ts_pdata = NULL; |
271 | int ret = 0; | 271 | int ret; |
272 | int ts_irq; | 272 | int ts_irq; |
273 | 273 | ||
274 | ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); | 274 | ts_irq = platform_get_irq_byname(pdev, "FIFO_TH"); |
@@ -276,12 +276,16 @@ static int __devinit stmpe_input_probe(struct platform_device *pdev) | |||
276 | return ts_irq; | 276 | return ts_irq; |
277 | 277 | ||
278 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); | 278 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); |
279 | if (!ts) | 279 | if (!ts) { |
280 | ret = -ENOMEM; | ||
280 | goto err_out; | 281 | goto err_out; |
282 | } | ||
281 | 283 | ||
282 | idev = input_allocate_device(); | 284 | idev = input_allocate_device(); |
283 | if (!idev) | 285 | if (!idev) { |
286 | ret = -ENOMEM; | ||
284 | goto err_free_ts; | 287 | goto err_free_ts; |
288 | } | ||
285 | 289 | ||
286 | platform_set_drvdata(pdev, ts); | 290 | platform_set_drvdata(pdev, ts); |
287 | ts->stmpe = stmpe; | 291 | ts->stmpe = stmpe; |
@@ -361,7 +365,6 @@ static int __devexit stmpe_ts_remove(struct platform_device *pdev) | |||
361 | platform_set_drvdata(pdev, NULL); | 365 | platform_set_drvdata(pdev, NULL); |
362 | 366 | ||
363 | input_unregister_device(ts->idev); | 367 | input_unregister_device(ts->idev); |
364 | input_free_device(ts->idev); | ||
365 | 368 | ||
366 | kfree(ts); | 369 | kfree(ts); |
367 | 370 | ||
diff --git a/drivers/input/touchscreen/tnetv107x-ts.c b/drivers/input/touchscreen/tnetv107x-ts.c new file mode 100644 index 000000000000..22a3411e93c5 --- /dev/null +++ b/drivers/input/touchscreen/tnetv107x-ts.c | |||
@@ -0,0 +1,397 @@ | |||
1 | /* | ||
2 | * Texas Instruments TNETV107X Touchscreen Driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/ctype.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/clk.h> | ||
27 | |||
28 | #include <mach/tnetv107x.h> | ||
29 | |||
30 | #define TSC_PENUP_POLL (HZ / 5) | ||
31 | #define IDLE_TIMEOUT 100 /* msec */ | ||
32 | |||
33 | /* | ||
34 | * The first and last samples of a touch interval are usually garbage and need | ||
35 | * to be filtered out with these devices. The following definitions control | ||
36 | * the number of samples skipped. | ||
37 | */ | ||
38 | #define TSC_HEAD_SKIP 1 | ||
39 | #define TSC_TAIL_SKIP 1 | ||
40 | #define TSC_SKIP (TSC_HEAD_SKIP + TSC_TAIL_SKIP + 1) | ||
41 | #define TSC_SAMPLES (TSC_SKIP + 1) | ||
42 | |||
43 | /* Register Offsets */ | ||
44 | struct tsc_regs { | ||
45 | u32 rev; | ||
46 | u32 tscm; | ||
47 | u32 bwcm; | ||
48 | u32 swc; | ||
49 | u32 adcchnl; | ||
50 | u32 adcdata; | ||
51 | u32 chval[4]; | ||
52 | }; | ||
53 | |||
54 | /* TSC Mode Configuration Register (tscm) bits */ | ||
55 | #define WMODE BIT(0) | ||
56 | #define TSKIND BIT(1) | ||
57 | #define ZMEASURE_EN BIT(2) | ||
58 | #define IDLE BIT(3) | ||
59 | #define TSC_EN BIT(4) | ||
60 | #define STOP BIT(5) | ||
61 | #define ONE_SHOT BIT(6) | ||
62 | #define SINGLE BIT(7) | ||
63 | #define AVG BIT(8) | ||
64 | #define AVGNUM(x) (((x) & 0x03) << 9) | ||
65 | #define PVSTC(x) (((x) & 0x07) << 11) | ||
66 | #define PON BIT(14) | ||
67 | #define PONBG BIT(15) | ||
68 | #define AFERST BIT(16) | ||
69 | |||
70 | /* ADC DATA Capture Register bits */ | ||
71 | #define DATA_VALID BIT(16) | ||
72 | |||
73 | /* Register Access Macros */ | ||
74 | #define tsc_read(ts, reg) __raw_readl(&(ts)->regs->reg) | ||
75 | #define tsc_write(ts, reg, val) __raw_writel(val, &(ts)->regs->reg); | ||
76 | #define tsc_set_bits(ts, reg, val) \ | ||
77 | tsc_write(ts, reg, tsc_read(ts, reg) | (val)) | ||
78 | #define tsc_clr_bits(ts, reg, val) \ | ||
79 | tsc_write(ts, reg, tsc_read(ts, reg) & ~(val)) | ||
80 | |||
81 | struct sample { | ||
82 | int x, y, p; | ||
83 | }; | ||
84 | |||
85 | struct tsc_data { | ||
86 | struct input_dev *input_dev; | ||
87 | struct resource *res; | ||
88 | struct tsc_regs __iomem *regs; | ||
89 | struct timer_list timer; | ||
90 | spinlock_t lock; | ||
91 | struct clk *clk; | ||
92 | struct device *dev; | ||
93 | int sample_count; | ||
94 | struct sample samples[TSC_SAMPLES]; | ||
95 | int tsc_irq; | ||
96 | }; | ||
97 | |||
98 | static int tsc_read_sample(struct tsc_data *ts, struct sample* sample) | ||
99 | { | ||
100 | int x, y, z1, z2, t, p = 0; | ||
101 | u32 val; | ||
102 | |||
103 | val = tsc_read(ts, chval[0]); | ||
104 | if (val & DATA_VALID) | ||
105 | x = val & 0xffff; | ||
106 | else | ||
107 | return -EINVAL; | ||
108 | |||
109 | y = tsc_read(ts, chval[1]) & 0xffff; | ||
110 | z1 = tsc_read(ts, chval[2]) & 0xffff; | ||
111 | z2 = tsc_read(ts, chval[3]) & 0xffff; | ||
112 | |||
113 | if (z1) { | ||
114 | t = ((600 * x) * (z2 - z1)); | ||
115 | p = t / (u32) (z1 << 12); | ||
116 | if (p < 0) | ||
117 | p = 0; | ||
118 | } | ||
119 | |||
120 | sample->x = x; | ||
121 | sample->y = y; | ||
122 | sample->p = p; | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static void tsc_poll(unsigned long data) | ||
128 | { | ||
129 | struct tsc_data *ts = (struct tsc_data *)data; | ||
130 | unsigned long flags; | ||
131 | int i, val, x, y, p; | ||
132 | |||
133 | spin_lock_irqsave(&ts->lock, flags); | ||
134 | |||
135 | if (ts->sample_count >= TSC_SKIP) { | ||
136 | input_report_abs(ts->input_dev, ABS_PRESSURE, 0); | ||
137 | input_report_key(ts->input_dev, BTN_TOUCH, 0); | ||
138 | input_sync(ts->input_dev); | ||
139 | } else if (ts->sample_count > 0) { | ||
140 | /* | ||
141 | * A touch event lasted less than our skip count. Salvage and | ||
142 | * report anyway. | ||
143 | */ | ||
144 | for (i = 0, val = 0; i < ts->sample_count; i++) | ||
145 | val += ts->samples[i].x; | ||
146 | x = val / ts->sample_count; | ||
147 | |||
148 | for (i = 0, val = 0; i < ts->sample_count; i++) | ||
149 | val += ts->samples[i].y; | ||
150 | y = val / ts->sample_count; | ||
151 | |||
152 | for (i = 0, val = 0; i < ts->sample_count; i++) | ||
153 | val += ts->samples[i].p; | ||
154 | p = val / ts->sample_count; | ||
155 | |||
156 | input_report_abs(ts->input_dev, ABS_X, x); | ||
157 | input_report_abs(ts->input_dev, ABS_Y, y); | ||
158 | input_report_abs(ts->input_dev, ABS_PRESSURE, p); | ||
159 | input_report_key(ts->input_dev, BTN_TOUCH, 1); | ||
160 | input_sync(ts->input_dev); | ||
161 | } | ||
162 | |||
163 | ts->sample_count = 0; | ||
164 | |||
165 | spin_unlock_irqrestore(&ts->lock, flags); | ||
166 | } | ||
167 | |||
168 | static irqreturn_t tsc_irq(int irq, void *dev_id) | ||
169 | { | ||
170 | struct tsc_data *ts = (struct tsc_data *)dev_id; | ||
171 | struct sample *sample; | ||
172 | int index; | ||
173 | |||
174 | spin_lock(&ts->lock); | ||
175 | |||
176 | index = ts->sample_count % TSC_SAMPLES; | ||
177 | sample = &ts->samples[index]; | ||
178 | if (tsc_read_sample(ts, sample) < 0) | ||
179 | goto out; | ||
180 | |||
181 | if (++ts->sample_count >= TSC_SKIP) { | ||
182 | index = (ts->sample_count - TSC_TAIL_SKIP - 1) % TSC_SAMPLES; | ||
183 | sample = &ts->samples[index]; | ||
184 | |||
185 | input_report_abs(ts->input_dev, ABS_X, sample->x); | ||
186 | input_report_abs(ts->input_dev, ABS_Y, sample->y); | ||
187 | input_report_abs(ts->input_dev, ABS_PRESSURE, sample->p); | ||
188 | if (ts->sample_count == TSC_SKIP) | ||
189 | input_report_key(ts->input_dev, BTN_TOUCH, 1); | ||
190 | input_sync(ts->input_dev); | ||
191 | } | ||
192 | mod_timer(&ts->timer, jiffies + TSC_PENUP_POLL); | ||
193 | out: | ||
194 | spin_unlock(&ts->lock); | ||
195 | return IRQ_HANDLED; | ||
196 | } | ||
197 | |||
198 | static int tsc_start(struct input_dev *dev) | ||
199 | { | ||
200 | struct tsc_data *ts = input_get_drvdata(dev); | ||
201 | unsigned long timeout = jiffies + msecs_to_jiffies(IDLE_TIMEOUT); | ||
202 | u32 val; | ||
203 | |||
204 | clk_enable(ts->clk); | ||
205 | |||
206 | /* Go to idle mode, before any initialization */ | ||
207 | while (time_after(timeout, jiffies)) { | ||
208 | if (tsc_read(ts, tscm) & IDLE) | ||
209 | break; | ||
210 | } | ||
211 | |||
212 | if (time_before(timeout, jiffies)) { | ||
213 | dev_warn(ts->dev, "timeout waiting for idle\n"); | ||
214 | clk_disable(ts->clk); | ||
215 | return -EIO; | ||
216 | } | ||
217 | |||
218 | /* Configure TSC Control register*/ | ||
219 | val = (PONBG | PON | PVSTC(4) | ONE_SHOT | ZMEASURE_EN); | ||
220 | tsc_write(ts, tscm, val); | ||
221 | |||
222 | /* Bring TSC out of reset: Clear AFE reset bit */ | ||
223 | val &= ~(AFERST); | ||
224 | tsc_write(ts, tscm, val); | ||
225 | |||
226 | /* Configure all pins for hardware control*/ | ||
227 | tsc_write(ts, bwcm, 0); | ||
228 | |||
229 | /* Finally enable the TSC */ | ||
230 | tsc_set_bits(ts, tscm, TSC_EN); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static void tsc_stop(struct input_dev *dev) | ||
236 | { | ||
237 | struct tsc_data *ts = input_get_drvdata(dev); | ||
238 | |||
239 | tsc_clr_bits(ts, tscm, TSC_EN); | ||
240 | synchronize_irq(ts->tsc_irq); | ||
241 | del_timer_sync(&ts->timer); | ||
242 | clk_disable(ts->clk); | ||
243 | } | ||
244 | |||
245 | static int __devinit tsc_probe(struct platform_device *pdev) | ||
246 | { | ||
247 | struct device *dev = &pdev->dev; | ||
248 | struct tsc_data *ts; | ||
249 | int error = 0; | ||
250 | u32 rev = 0; | ||
251 | |||
252 | ts = kzalloc(sizeof(struct tsc_data), GFP_KERNEL); | ||
253 | if (!ts) { | ||
254 | dev_err(dev, "cannot allocate device info\n"); | ||
255 | return -ENOMEM; | ||
256 | } | ||
257 | |||
258 | ts->dev = dev; | ||
259 | spin_lock_init(&ts->lock); | ||
260 | setup_timer(&ts->timer, tsc_poll, (unsigned long)ts); | ||
261 | platform_set_drvdata(pdev, ts); | ||
262 | |||
263 | ts->tsc_irq = platform_get_irq(pdev, 0); | ||
264 | if (ts->tsc_irq < 0) { | ||
265 | dev_err(dev, "cannot determine device interrupt\n"); | ||
266 | error = -ENODEV; | ||
267 | goto error_res; | ||
268 | } | ||
269 | |||
270 | ts->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
271 | if (!ts->res) { | ||
272 | dev_err(dev, "cannot determine register area\n"); | ||
273 | error = -ENODEV; | ||
274 | goto error_res; | ||
275 | } | ||
276 | |||
277 | if (!request_mem_region(ts->res->start, resource_size(ts->res), | ||
278 | pdev->name)) { | ||
279 | dev_err(dev, "cannot claim register memory\n"); | ||
280 | ts->res = NULL; | ||
281 | error = -EINVAL; | ||
282 | goto error_res; | ||
283 | } | ||
284 | |||
285 | ts->regs = ioremap(ts->res->start, resource_size(ts->res)); | ||
286 | if (!ts->regs) { | ||
287 | dev_err(dev, "cannot map register memory\n"); | ||
288 | error = -ENOMEM; | ||
289 | goto error_map; | ||
290 | } | ||
291 | |||
292 | ts->clk = clk_get(dev, NULL); | ||
293 | if (IS_ERR(ts->clk)) { | ||
294 | dev_err(dev, "cannot claim device clock\n"); | ||
295 | error = PTR_ERR(ts->clk); | ||
296 | goto error_clk; | ||
297 | } | ||
298 | |||
299 | error = request_threaded_irq(ts->tsc_irq, NULL, tsc_irq, 0, | ||
300 | dev_name(dev), ts); | ||
301 | if (error < 0) { | ||
302 | dev_err(ts->dev, "Could not allocate ts irq\n"); | ||
303 | goto error_irq; | ||
304 | } | ||
305 | |||
306 | ts->input_dev = input_allocate_device(); | ||
307 | if (!ts->input_dev) { | ||
308 | dev_err(dev, "cannot allocate input device\n"); | ||
309 | error = -ENOMEM; | ||
310 | goto error_input; | ||
311 | } | ||
312 | input_set_drvdata(ts->input_dev, ts); | ||
313 | |||
314 | ts->input_dev->name = pdev->name; | ||
315 | ts->input_dev->id.bustype = BUS_HOST; | ||
316 | ts->input_dev->dev.parent = &pdev->dev; | ||
317 | ts->input_dev->open = tsc_start; | ||
318 | ts->input_dev->close = tsc_stop; | ||
319 | |||
320 | clk_enable(ts->clk); | ||
321 | rev = tsc_read(ts, rev); | ||
322 | ts->input_dev->id.product = ((rev >> 8) & 0x07); | ||
323 | ts->input_dev->id.version = ((rev >> 16) & 0xfff); | ||
324 | clk_disable(ts->clk); | ||
325 | |||
326 | __set_bit(EV_KEY, ts->input_dev->evbit); | ||
327 | __set_bit(EV_ABS, ts->input_dev->evbit); | ||
328 | __set_bit(BTN_TOUCH, ts->input_dev->keybit); | ||
329 | |||
330 | input_set_abs_params(ts->input_dev, ABS_X, 0, 0xffff, 5, 0); | ||
331 | input_set_abs_params(ts->input_dev, ABS_Y, 0, 0xffff, 5, 0); | ||
332 | input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 4095, 128, 0); | ||
333 | |||
334 | error = input_register_device(ts->input_dev); | ||
335 | if (error < 0) { | ||
336 | dev_err(dev, "failed input device registration\n"); | ||
337 | goto error_reg; | ||
338 | } | ||
339 | |||
340 | return 0; | ||
341 | |||
342 | error_reg: | ||
343 | input_free_device(ts->input_dev); | ||
344 | error_input: | ||
345 | free_irq(ts->tsc_irq, ts); | ||
346 | error_irq: | ||
347 | clk_put(ts->clk); | ||
348 | error_clk: | ||
349 | iounmap(ts->regs); | ||
350 | error_map: | ||
351 | release_mem_region(ts->res->start, resource_size(ts->res)); | ||
352 | error_res: | ||
353 | platform_set_drvdata(pdev, NULL); | ||
354 | kfree(ts); | ||
355 | |||
356 | return error; | ||
357 | } | ||
358 | |||
359 | static int __devexit tsc_remove(struct platform_device *pdev) | ||
360 | { | ||
361 | struct tsc_data *ts = platform_get_drvdata(pdev); | ||
362 | |||
363 | input_unregister_device(ts->input_dev); | ||
364 | free_irq(ts->tsc_irq, ts); | ||
365 | clk_put(ts->clk); | ||
366 | iounmap(ts->regs); | ||
367 | release_mem_region(ts->res->start, resource_size(ts->res)); | ||
368 | platform_set_drvdata(pdev, NULL); | ||
369 | kfree(ts); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static struct platform_driver tsc_driver = { | ||
375 | .probe = tsc_probe, | ||
376 | .remove = __devexit_p(tsc_remove), | ||
377 | .driver.name = "tnetv107x-ts", | ||
378 | .driver.owner = THIS_MODULE, | ||
379 | }; | ||
380 | |||
381 | static int __init tsc_init(void) | ||
382 | { | ||
383 | return platform_driver_register(&tsc_driver); | ||
384 | } | ||
385 | |||
386 | static void __exit tsc_exit(void) | ||
387 | { | ||
388 | platform_driver_unregister(&tsc_driver); | ||
389 | } | ||
390 | |||
391 | module_init(tsc_init); | ||
392 | module_exit(tsc_exit); | ||
393 | |||
394 | MODULE_AUTHOR("Cyril Chemparathy"); | ||
395 | MODULE_DESCRIPTION("TNETV107X Touchscreen Driver"); | ||
396 | MODULE_ALIAS("platform: tnetv107x-ts"); | ||
397 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c index a644d18c04dc..43031492d733 100644 --- a/drivers/input/touchscreen/tps6507x-ts.c +++ b/drivers/input/touchscreen/tps6507x-ts.c | |||
@@ -43,7 +43,6 @@ struct tps6507x_ts { | |||
43 | struct input_dev *input_dev; | 43 | struct input_dev *input_dev; |
44 | struct device *dev; | 44 | struct device *dev; |
45 | char phys[32]; | 45 | char phys[32]; |
46 | struct workqueue_struct *wq; | ||
47 | struct delayed_work work; | 46 | struct delayed_work work; |
48 | unsigned polling; /* polling is active */ | 47 | unsigned polling; /* polling is active */ |
49 | struct ts_event tc; | 48 | struct ts_event tc; |
@@ -220,8 +219,8 @@ done: | |||
220 | poll = 1; | 219 | poll = 1; |
221 | 220 | ||
222 | if (poll) { | 221 | if (poll) { |
223 | schd = queue_delayed_work(tsc->wq, &tsc->work, | 222 | schd = schedule_delayed_work(&tsc->work, |
224 | msecs_to_jiffies(tsc->poll_period)); | 223 | msecs_to_jiffies(tsc->poll_period)); |
225 | if (schd) | 224 | if (schd) |
226 | tsc->polling = 1; | 225 | tsc->polling = 1; |
227 | else { | 226 | else { |
@@ -303,7 +302,6 @@ static int tps6507x_ts_probe(struct platform_device *pdev) | |||
303 | tsc->input_dev = input_dev; | 302 | tsc->input_dev = input_dev; |
304 | 303 | ||
305 | INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); | 304 | INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); |
306 | tsc->wq = create_workqueue("TPS6507x Touchscreen"); | ||
307 | 305 | ||
308 | if (init_data) { | 306 | if (init_data) { |
309 | tsc->poll_period = init_data->poll_period; | 307 | tsc->poll_period = init_data->poll_period; |
@@ -325,8 +323,8 @@ static int tps6507x_ts_probe(struct platform_device *pdev) | |||
325 | if (error) | 323 | if (error) |
326 | goto err2; | 324 | goto err2; |
327 | 325 | ||
328 | schd = queue_delayed_work(tsc->wq, &tsc->work, | 326 | schd = schedule_delayed_work(&tsc->work, |
329 | msecs_to_jiffies(tsc->poll_period)); | 327 | msecs_to_jiffies(tsc->poll_period)); |
330 | 328 | ||
331 | if (schd) | 329 | if (schd) |
332 | tsc->polling = 1; | 330 | tsc->polling = 1; |
@@ -335,12 +333,12 @@ static int tps6507x_ts_probe(struct platform_device *pdev) | |||
335 | dev_err(tsc->dev, "schedule failed"); | 333 | dev_err(tsc->dev, "schedule failed"); |
336 | goto err2; | 334 | goto err2; |
337 | } | 335 | } |
336 | platform_set_drvdata(pdev, tps6507x_dev); | ||
338 | 337 | ||
339 | return 0; | 338 | return 0; |
340 | 339 | ||
341 | err2: | 340 | err2: |
342 | cancel_delayed_work_sync(&tsc->work); | 341 | cancel_delayed_work_sync(&tsc->work); |
343 | destroy_workqueue(tsc->wq); | ||
344 | input_free_device(input_dev); | 342 | input_free_device(input_dev); |
345 | err1: | 343 | err1: |
346 | kfree(tsc); | 344 | kfree(tsc); |
@@ -356,9 +354,8 @@ static int __devexit tps6507x_ts_remove(struct platform_device *pdev) | |||
356 | struct input_dev *input_dev = tsc->input_dev; | 354 | struct input_dev *input_dev = tsc->input_dev; |
357 | 355 | ||
358 | cancel_delayed_work_sync(&tsc->work); | 356 | cancel_delayed_work_sync(&tsc->work); |
359 | destroy_workqueue(tsc->wq); | ||
360 | 357 | ||
361 | input_free_device(input_dev); | 358 | input_unregister_device(input_dev); |
362 | 359 | ||
363 | tps6507x_dev->ts = NULL; | 360 | tps6507x_dev->ts = NULL; |
364 | kfree(tsc); | 361 | kfree(tsc); |
diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c new file mode 100644 index 000000000000..cbf0ff322676 --- /dev/null +++ b/drivers/input/touchscreen/tsc2005.c | |||
@@ -0,0 +1,764 @@ | |||
1 | /* | ||
2 | * TSC2005 touchscreen driver | ||
3 | * | ||
4 | * Copyright (C) 2006-2010 Nokia Corporation | ||
5 | * | ||
6 | * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com> | ||
7 | * based on TSC2301 driver by Klaus K. Pedersen <klaus.k.pedersen@nokia.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/input.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/pm.h> | ||
31 | #include <linux/spi/spi.h> | ||
32 | #include <linux/spi/tsc2005.h> | ||
33 | |||
34 | /* | ||
35 | * The touchscreen interface operates as follows: | ||
36 | * | ||
37 | * 1) Pen is pressed against the touchscreen. | ||
38 | * 2) TSC2005 performs AD conversion. | ||
39 | * 3) After the conversion is done TSC2005 drives DAV line down. | ||
40 | * 4) GPIO IRQ is received and tsc2005_irq_thread() is scheduled. | ||
41 | * 5) tsc2005_irq_thread() queues up an spi transfer to fetch the x, y, z1, z2 | ||
42 | * values. | ||
43 | * 6) tsc2005_irq_thread() reports coordinates to input layer and sets up | ||
44 | * tsc2005_penup_timer() to be called after TSC2005_PENUP_TIME_MS (40ms). | ||
45 | * 7) When the penup timer expires, there have not been touch or DAV interrupts | ||
46 | * during the last 40ms which means the pen has been lifted. | ||
47 | * | ||
48 | * ESD recovery via a hardware reset is done if the TSC2005 doesn't respond | ||
49 | * after a configurable period (in ms) of activity. If esd_timeout is 0, the | ||
50 | * watchdog is disabled. | ||
51 | */ | ||
52 | |||
53 | /* control byte 1 */ | ||
54 | #define TSC2005_CMD 0x80 | ||
55 | #define TSC2005_CMD_NORMAL 0x00 | ||
56 | #define TSC2005_CMD_STOP 0x01 | ||
57 | #define TSC2005_CMD_12BIT 0x04 | ||
58 | |||
59 | /* control byte 0 */ | ||
60 | #define TSC2005_REG_READ 0x0001 | ||
61 | #define TSC2005_REG_PND0 0x0002 | ||
62 | #define TSC2005_REG_X 0x0000 | ||
63 | #define TSC2005_REG_Y 0x0008 | ||
64 | #define TSC2005_REG_Z1 0x0010 | ||
65 | #define TSC2005_REG_Z2 0x0018 | ||
66 | #define TSC2005_REG_TEMP_HIGH 0x0050 | ||
67 | #define TSC2005_REG_CFR0 0x0060 | ||
68 | #define TSC2005_REG_CFR1 0x0068 | ||
69 | #define TSC2005_REG_CFR2 0x0070 | ||
70 | |||
71 | /* configuration register 0 */ | ||
72 | #define TSC2005_CFR0_PRECHARGE_276US 0x0040 | ||
73 | #define TSC2005_CFR0_STABTIME_1MS 0x0300 | ||
74 | #define TSC2005_CFR0_CLOCK_1MHZ 0x1000 | ||
75 | #define TSC2005_CFR0_RESOLUTION12 0x2000 | ||
76 | #define TSC2005_CFR0_PENMODE 0x8000 | ||
77 | #define TSC2005_CFR0_INITVALUE (TSC2005_CFR0_STABTIME_1MS | \ | ||
78 | TSC2005_CFR0_CLOCK_1MHZ | \ | ||
79 | TSC2005_CFR0_RESOLUTION12 | \ | ||
80 | TSC2005_CFR0_PRECHARGE_276US | \ | ||
81 | TSC2005_CFR0_PENMODE) | ||
82 | |||
83 | /* bits common to both read and write of configuration register 0 */ | ||
84 | #define TSC2005_CFR0_RW_MASK 0x3fff | ||
85 | |||
86 | /* configuration register 1 */ | ||
87 | #define TSC2005_CFR1_BATCHDELAY_4MS 0x0003 | ||
88 | #define TSC2005_CFR1_INITVALUE TSC2005_CFR1_BATCHDELAY_4MS | ||
89 | |||
90 | /* configuration register 2 */ | ||
91 | #define TSC2005_CFR2_MAVE_Z 0x0004 | ||
92 | #define TSC2005_CFR2_MAVE_Y 0x0008 | ||
93 | #define TSC2005_CFR2_MAVE_X 0x0010 | ||
94 | #define TSC2005_CFR2_AVG_7 0x0800 | ||
95 | #define TSC2005_CFR2_MEDIUM_15 0x3000 | ||
96 | #define TSC2005_CFR2_INITVALUE (TSC2005_CFR2_MAVE_X | \ | ||
97 | TSC2005_CFR2_MAVE_Y | \ | ||
98 | TSC2005_CFR2_MAVE_Z | \ | ||
99 | TSC2005_CFR2_MEDIUM_15 | \ | ||
100 | TSC2005_CFR2_AVG_7) | ||
101 | |||
102 | #define MAX_12BIT 0xfff | ||
103 | #define TSC2005_SPI_MAX_SPEED_HZ 10000000 | ||
104 | #define TSC2005_PENUP_TIME_MS 40 | ||
105 | |||
106 | struct tsc2005_spi_rd { | ||
107 | struct spi_transfer spi_xfer; | ||
108 | u32 spi_tx; | ||
109 | u32 spi_rx; | ||
110 | }; | ||
111 | |||
112 | struct tsc2005 { | ||
113 | struct spi_device *spi; | ||
114 | |||
115 | struct spi_message spi_read_msg; | ||
116 | struct tsc2005_spi_rd spi_x; | ||
117 | struct tsc2005_spi_rd spi_y; | ||
118 | struct tsc2005_spi_rd spi_z1; | ||
119 | struct tsc2005_spi_rd spi_z2; | ||
120 | |||
121 | struct input_dev *idev; | ||
122 | char phys[32]; | ||
123 | |||
124 | struct mutex mutex; | ||
125 | |||
126 | /* raw copy of previous x,y,z */ | ||
127 | int in_x; | ||
128 | int in_y; | ||
129 | int in_z1; | ||
130 | int in_z2; | ||
131 | |||
132 | spinlock_t lock; | ||
133 | struct timer_list penup_timer; | ||
134 | |||
135 | unsigned int esd_timeout; | ||
136 | struct delayed_work esd_work; | ||
137 | unsigned long last_valid_interrupt; | ||
138 | |||
139 | unsigned int x_plate_ohm; | ||
140 | |||
141 | bool opened; | ||
142 | bool suspended; | ||
143 | |||
144 | bool pen_down; | ||
145 | |||
146 | void (*set_reset)(bool enable); | ||
147 | }; | ||
148 | |||
149 | static int tsc2005_cmd(struct tsc2005 *ts, u8 cmd) | ||
150 | { | ||
151 | u8 tx = TSC2005_CMD | TSC2005_CMD_12BIT | cmd; | ||
152 | struct spi_transfer xfer = { | ||
153 | .tx_buf = &tx, | ||
154 | .len = 1, | ||
155 | .bits_per_word = 8, | ||
156 | }; | ||
157 | struct spi_message msg; | ||
158 | int error; | ||
159 | |||
160 | spi_message_init(&msg); | ||
161 | spi_message_add_tail(&xfer, &msg); | ||
162 | |||
163 | error = spi_sync(ts->spi, &msg); | ||
164 | if (error) { | ||
165 | dev_err(&ts->spi->dev, "%s: failed, command: %x, error: %d\n", | ||
166 | __func__, cmd, error); | ||
167 | return error; | ||
168 | } | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value) | ||
174 | { | ||
175 | u32 tx = ((reg | TSC2005_REG_PND0) << 16) | value; | ||
176 | struct spi_transfer xfer = { | ||
177 | .tx_buf = &tx, | ||
178 | .len = 4, | ||
179 | .bits_per_word = 24, | ||
180 | }; | ||
181 | struct spi_message msg; | ||
182 | int error; | ||
183 | |||
184 | spi_message_init(&msg); | ||
185 | spi_message_add_tail(&xfer, &msg); | ||
186 | |||
187 | error = spi_sync(ts->spi, &msg); | ||
188 | if (error) { | ||
189 | dev_err(&ts->spi->dev, | ||
190 | "%s: failed, register: %x, value: %x, error: %d\n", | ||
191 | __func__, reg, value, error); | ||
192 | return error; | ||
193 | } | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static void tsc2005_setup_read(struct tsc2005_spi_rd *rd, u8 reg, bool last) | ||
199 | { | ||
200 | memset(rd, 0, sizeof(*rd)); | ||
201 | |||
202 | rd->spi_tx = (reg | TSC2005_REG_READ) << 16; | ||
203 | rd->spi_xfer.tx_buf = &rd->spi_tx; | ||
204 | rd->spi_xfer.rx_buf = &rd->spi_rx; | ||
205 | rd->spi_xfer.len = 4; | ||
206 | rd->spi_xfer.bits_per_word = 24; | ||
207 | rd->spi_xfer.cs_change = !last; | ||
208 | } | ||
209 | |||
210 | static int tsc2005_read(struct tsc2005 *ts, u8 reg, u16 *value) | ||
211 | { | ||
212 | struct tsc2005_spi_rd spi_rd; | ||
213 | struct spi_message msg; | ||
214 | int error; | ||
215 | |||
216 | tsc2005_setup_read(&spi_rd, reg, true); | ||
217 | |||
218 | spi_message_init(&msg); | ||
219 | spi_message_add_tail(&spi_rd.spi_xfer, &msg); | ||
220 | |||
221 | error = spi_sync(ts->spi, &msg); | ||
222 | if (error) | ||
223 | return error; | ||
224 | |||
225 | *value = spi_rd.spi_rx; | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static void tsc2005_update_pen_state(struct tsc2005 *ts, | ||
230 | int x, int y, int pressure) | ||
231 | { | ||
232 | if (pressure) { | ||
233 | input_report_abs(ts->idev, ABS_X, x); | ||
234 | input_report_abs(ts->idev, ABS_Y, y); | ||
235 | input_report_abs(ts->idev, ABS_PRESSURE, pressure); | ||
236 | if (!ts->pen_down) { | ||
237 | input_report_key(ts->idev, BTN_TOUCH, !!pressure); | ||
238 | ts->pen_down = true; | ||
239 | } | ||
240 | } else { | ||
241 | input_report_abs(ts->idev, ABS_PRESSURE, 0); | ||
242 | if (ts->pen_down) { | ||
243 | input_report_key(ts->idev, BTN_TOUCH, 0); | ||
244 | ts->pen_down = false; | ||
245 | } | ||
246 | } | ||
247 | input_sync(ts->idev); | ||
248 | dev_dbg(&ts->spi->dev, "point(%4d,%4d), pressure (%4d)\n", x, y, | ||
249 | pressure); | ||
250 | } | ||
251 | |||
252 | static irqreturn_t tsc2005_irq_thread(int irq, void *_ts) | ||
253 | { | ||
254 | struct tsc2005 *ts = _ts; | ||
255 | unsigned long flags; | ||
256 | unsigned int pressure; | ||
257 | u32 x, y; | ||
258 | u32 z1, z2; | ||
259 | int error; | ||
260 | |||
261 | /* read the coordinates */ | ||
262 | error = spi_sync(ts->spi, &ts->spi_read_msg); | ||
263 | if (unlikely(error)) | ||
264 | goto out; | ||
265 | |||
266 | x = ts->spi_x.spi_rx; | ||
267 | y = ts->spi_y.spi_rx; | ||
268 | z1 = ts->spi_z1.spi_rx; | ||
269 | z2 = ts->spi_z2.spi_rx; | ||
270 | |||
271 | /* validate position */ | ||
272 | if (unlikely(x > MAX_12BIT || y > MAX_12BIT)) | ||
273 | goto out; | ||
274 | |||
275 | /* Skip reading if the pressure components are out of range */ | ||
276 | if (unlikely(z1 == 0 || z2 > MAX_12BIT || z1 >= z2)) | ||
277 | goto out; | ||
278 | |||
279 | /* | ||
280 | * Skip point if this is a pen down with the exact same values as | ||
281 | * the value before pen-up - that implies SPI fed us stale data | ||
282 | */ | ||
283 | if (!ts->pen_down && | ||
284 | ts->in_x == x && ts->in_y == y && | ||
285 | ts->in_z1 == z1 && ts->in_z2 == z2) { | ||
286 | goto out; | ||
287 | } | ||
288 | |||
289 | /* | ||
290 | * At this point we are happy we have a valid and useful reading. | ||
291 | * Remember it for later comparisons. We may now begin downsampling. | ||
292 | */ | ||
293 | ts->in_x = x; | ||
294 | ts->in_y = y; | ||
295 | ts->in_z1 = z1; | ||
296 | ts->in_z2 = z2; | ||
297 | |||
298 | /* Compute touch pressure resistance using equation #1 */ | ||
299 | pressure = x * (z2 - z1) / z1; | ||
300 | pressure = pressure * ts->x_plate_ohm / 4096; | ||
301 | if (unlikely(pressure > MAX_12BIT)) | ||
302 | goto out; | ||
303 | |||
304 | spin_lock_irqsave(&ts->lock, flags); | ||
305 | |||
306 | tsc2005_update_pen_state(ts, x, y, pressure); | ||
307 | mod_timer(&ts->penup_timer, | ||
308 | jiffies + msecs_to_jiffies(TSC2005_PENUP_TIME_MS)); | ||
309 | |||
310 | spin_unlock_irqrestore(&ts->lock, flags); | ||
311 | |||
312 | ts->last_valid_interrupt = jiffies; | ||
313 | out: | ||
314 | return IRQ_HANDLED; | ||
315 | } | ||
316 | |||
317 | static void tsc2005_penup_timer(unsigned long data) | ||
318 | { | ||
319 | struct tsc2005 *ts = (struct tsc2005 *)data; | ||
320 | unsigned long flags; | ||
321 | |||
322 | spin_lock_irqsave(&ts->lock, flags); | ||
323 | tsc2005_update_pen_state(ts, 0, 0, 0); | ||
324 | spin_unlock_irqrestore(&ts->lock, flags); | ||
325 | } | ||
326 | |||
327 | static void tsc2005_start_scan(struct tsc2005 *ts) | ||
328 | { | ||
329 | tsc2005_write(ts, TSC2005_REG_CFR0, TSC2005_CFR0_INITVALUE); | ||
330 | tsc2005_write(ts, TSC2005_REG_CFR1, TSC2005_CFR1_INITVALUE); | ||
331 | tsc2005_write(ts, TSC2005_REG_CFR2, TSC2005_CFR2_INITVALUE); | ||
332 | tsc2005_cmd(ts, TSC2005_CMD_NORMAL); | ||
333 | } | ||
334 | |||
335 | static void tsc2005_stop_scan(struct tsc2005 *ts) | ||
336 | { | ||
337 | tsc2005_cmd(ts, TSC2005_CMD_STOP); | ||
338 | } | ||
339 | |||
340 | /* must be called with ts->mutex held */ | ||
341 | static void __tsc2005_disable(struct tsc2005 *ts) | ||
342 | { | ||
343 | tsc2005_stop_scan(ts); | ||
344 | |||
345 | disable_irq(ts->spi->irq); | ||
346 | del_timer_sync(&ts->penup_timer); | ||
347 | |||
348 | cancel_delayed_work_sync(&ts->esd_work); | ||
349 | |||
350 | enable_irq(ts->spi->irq); | ||
351 | } | ||
352 | |||
353 | /* must be called with ts->mutex held */ | ||
354 | static void __tsc2005_enable(struct tsc2005 *ts) | ||
355 | { | ||
356 | tsc2005_start_scan(ts); | ||
357 | |||
358 | if (ts->esd_timeout && ts->set_reset) { | ||
359 | ts->last_valid_interrupt = jiffies; | ||
360 | schedule_delayed_work(&ts->esd_work, | ||
361 | round_jiffies_relative( | ||
362 | msecs_to_jiffies(ts->esd_timeout))); | ||
363 | } | ||
364 | |||
365 | } | ||
366 | |||
367 | static ssize_t tsc2005_selftest_show(struct device *dev, | ||
368 | struct device_attribute *attr, | ||
369 | char *buf) | ||
370 | { | ||
371 | struct spi_device *spi = to_spi_device(dev); | ||
372 | struct tsc2005 *ts = spi_get_drvdata(spi); | ||
373 | u16 temp_high; | ||
374 | u16 temp_high_orig; | ||
375 | u16 temp_high_test; | ||
376 | bool success = true; | ||
377 | int error; | ||
378 | |||
379 | mutex_lock(&ts->mutex); | ||
380 | |||
381 | /* | ||
382 | * Test TSC2005 communications via temp high register. | ||
383 | */ | ||
384 | __tsc2005_disable(ts); | ||
385 | |||
386 | error = tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high_orig); | ||
387 | if (error) { | ||
388 | dev_warn(dev, "selftest failed: read error %d\n", error); | ||
389 | success = false; | ||
390 | goto out; | ||
391 | } | ||
392 | |||
393 | temp_high_test = (temp_high_orig - 1) & MAX_12BIT; | ||
394 | |||
395 | error = tsc2005_write(ts, TSC2005_REG_TEMP_HIGH, temp_high_test); | ||
396 | if (error) { | ||
397 | dev_warn(dev, "selftest failed: write error %d\n", error); | ||
398 | success = false; | ||
399 | goto out; | ||
400 | } | ||
401 | |||
402 | error = tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high); | ||
403 | if (error) { | ||
404 | dev_warn(dev, "selftest failed: read error %d after write\n", | ||
405 | error); | ||
406 | success = false; | ||
407 | goto out; | ||
408 | } | ||
409 | |||
410 | if (temp_high != temp_high_test) { | ||
411 | dev_warn(dev, "selftest failed: %d != %d\n", | ||
412 | temp_high, temp_high_test); | ||
413 | success = false; | ||
414 | } | ||
415 | |||
416 | /* hardware reset */ | ||
417 | ts->set_reset(false); | ||
418 | usleep_range(100, 500); /* only 10us required */ | ||
419 | ts->set_reset(true); | ||
420 | |||
421 | if (!success) | ||
422 | goto out; | ||
423 | |||
424 | /* test that the reset really happened */ | ||
425 | error = tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high); | ||
426 | if (error) { | ||
427 | dev_warn(dev, "selftest failed: read error %d after reset\n", | ||
428 | error); | ||
429 | success = false; | ||
430 | goto out; | ||
431 | } | ||
432 | |||
433 | if (temp_high != temp_high_orig) { | ||
434 | dev_warn(dev, "selftest failed after reset: %d != %d\n", | ||
435 | temp_high, temp_high_orig); | ||
436 | success = false; | ||
437 | } | ||
438 | |||
439 | out: | ||
440 | __tsc2005_enable(ts); | ||
441 | mutex_unlock(&ts->mutex); | ||
442 | |||
443 | return sprintf(buf, "%d\n", success); | ||
444 | } | ||
445 | |||
446 | static DEVICE_ATTR(selftest, S_IRUGO, tsc2005_selftest_show, NULL); | ||
447 | |||
448 | static struct attribute *tsc2005_attrs[] = { | ||
449 | &dev_attr_selftest.attr, | ||
450 | NULL | ||
451 | }; | ||
452 | |||
453 | static mode_t tsc2005_attr_is_visible(struct kobject *kobj, | ||
454 | struct attribute *attr, int n) | ||
455 | { | ||
456 | struct device *dev = container_of(kobj, struct device, kobj); | ||
457 | struct spi_device *spi = to_spi_device(dev); | ||
458 | struct tsc2005 *ts = spi_get_drvdata(spi); | ||
459 | mode_t mode = attr->mode; | ||
460 | |||
461 | if (attr == &dev_attr_selftest.attr) { | ||
462 | if (!ts->set_reset) | ||
463 | mode = 0; | ||
464 | } | ||
465 | |||
466 | return mode; | ||
467 | } | ||
468 | |||
469 | static const struct attribute_group tsc2005_attr_group = { | ||
470 | .is_visible = tsc2005_attr_is_visible, | ||
471 | .attrs = tsc2005_attrs, | ||
472 | }; | ||
473 | |||
474 | static void tsc2005_esd_work(struct work_struct *work) | ||
475 | { | ||
476 | struct tsc2005 *ts = container_of(work, struct tsc2005, esd_work.work); | ||
477 | int error; | ||
478 | u16 r; | ||
479 | |||
480 | if (!mutex_trylock(&ts->mutex)) { | ||
481 | /* | ||
482 | * If the mutex is taken, it means that disable or enable is in | ||
483 | * progress. In that case just reschedule the work. If the work | ||
484 | * is not needed, it will be canceled by disable. | ||
485 | */ | ||
486 | goto reschedule; | ||
487 | } | ||
488 | |||
489 | if (time_is_after_jiffies(ts->last_valid_interrupt + | ||
490 | msecs_to_jiffies(ts->esd_timeout))) | ||
491 | goto out; | ||
492 | |||
493 | /* We should be able to read register without disabling interrupts. */ | ||
494 | error = tsc2005_read(ts, TSC2005_REG_CFR0, &r); | ||
495 | if (!error && | ||
496 | !((r ^ TSC2005_CFR0_INITVALUE) & TSC2005_CFR0_RW_MASK)) { | ||
497 | goto out; | ||
498 | } | ||
499 | |||
500 | /* | ||
501 | * If we could not read our known value from configuration register 0 | ||
502 | * then we should reset the controller as if from power-up and start | ||
503 | * scanning again. | ||
504 | */ | ||
505 | dev_info(&ts->spi->dev, "TSC2005 not responding - resetting\n"); | ||
506 | |||
507 | disable_irq(ts->spi->irq); | ||
508 | del_timer_sync(&ts->penup_timer); | ||
509 | |||
510 | tsc2005_update_pen_state(ts, 0, 0, 0); | ||
511 | |||
512 | ts->set_reset(false); | ||
513 | usleep_range(100, 500); /* only 10us required */ | ||
514 | ts->set_reset(true); | ||
515 | |||
516 | enable_irq(ts->spi->irq); | ||
517 | tsc2005_start_scan(ts); | ||
518 | |||
519 | out: | ||
520 | mutex_unlock(&ts->mutex); | ||
521 | reschedule: | ||
522 | /* re-arm the watchdog */ | ||
523 | schedule_delayed_work(&ts->esd_work, | ||
524 | round_jiffies_relative( | ||
525 | msecs_to_jiffies(ts->esd_timeout))); | ||
526 | } | ||
527 | |||
528 | static int tsc2005_open(struct input_dev *input) | ||
529 | { | ||
530 | struct tsc2005 *ts = input_get_drvdata(input); | ||
531 | |||
532 | mutex_lock(&ts->mutex); | ||
533 | |||
534 | if (!ts->suspended) | ||
535 | __tsc2005_enable(ts); | ||
536 | |||
537 | ts->opened = true; | ||
538 | |||
539 | mutex_unlock(&ts->mutex); | ||
540 | |||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | static void tsc2005_close(struct input_dev *input) | ||
545 | { | ||
546 | struct tsc2005 *ts = input_get_drvdata(input); | ||
547 | |||
548 | mutex_lock(&ts->mutex); | ||
549 | |||
550 | if (!ts->suspended) | ||
551 | __tsc2005_disable(ts); | ||
552 | |||
553 | ts->opened = false; | ||
554 | |||
555 | mutex_unlock(&ts->mutex); | ||
556 | } | ||
557 | |||
558 | static void __devinit tsc2005_setup_spi_xfer(struct tsc2005 *ts) | ||
559 | { | ||
560 | tsc2005_setup_read(&ts->spi_x, TSC2005_REG_X, false); | ||
561 | tsc2005_setup_read(&ts->spi_y, TSC2005_REG_Y, false); | ||
562 | tsc2005_setup_read(&ts->spi_z1, TSC2005_REG_Z1, false); | ||
563 | tsc2005_setup_read(&ts->spi_z2, TSC2005_REG_Z2, true); | ||
564 | |||
565 | spi_message_init(&ts->spi_read_msg); | ||
566 | spi_message_add_tail(&ts->spi_x.spi_xfer, &ts->spi_read_msg); | ||
567 | spi_message_add_tail(&ts->spi_y.spi_xfer, &ts->spi_read_msg); | ||
568 | spi_message_add_tail(&ts->spi_z1.spi_xfer, &ts->spi_read_msg); | ||
569 | spi_message_add_tail(&ts->spi_z2.spi_xfer, &ts->spi_read_msg); | ||
570 | } | ||
571 | |||
572 | static int __devinit tsc2005_probe(struct spi_device *spi) | ||
573 | { | ||
574 | const struct tsc2005_platform_data *pdata = spi->dev.platform_data; | ||
575 | struct tsc2005 *ts; | ||
576 | struct input_dev *input_dev; | ||
577 | unsigned int max_x, max_y, max_p; | ||
578 | unsigned int fudge_x, fudge_y, fudge_p; | ||
579 | int error; | ||
580 | |||
581 | if (!pdata) { | ||
582 | dev_dbg(&spi->dev, "no platform data\n"); | ||
583 | return -ENODEV; | ||
584 | } | ||
585 | |||
586 | fudge_x = pdata->ts_x_fudge ? : 4; | ||
587 | fudge_y = pdata->ts_y_fudge ? : 8; | ||
588 | fudge_p = pdata->ts_pressure_fudge ? : 2; | ||
589 | max_x = pdata->ts_x_max ? : MAX_12BIT; | ||
590 | max_y = pdata->ts_y_max ? : MAX_12BIT; | ||
591 | max_p = pdata->ts_pressure_max ? : MAX_12BIT; | ||
592 | |||
593 | if (spi->irq <= 0) { | ||
594 | dev_dbg(&spi->dev, "no irq\n"); | ||
595 | return -ENODEV; | ||
596 | } | ||
597 | |||
598 | spi->mode = SPI_MODE_0; | ||
599 | spi->bits_per_word = 8; | ||
600 | if (!spi->max_speed_hz) | ||
601 | spi->max_speed_hz = TSC2005_SPI_MAX_SPEED_HZ; | ||
602 | |||
603 | error = spi_setup(spi); | ||
604 | if (error) | ||
605 | return error; | ||
606 | |||
607 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); | ||
608 | input_dev = input_allocate_device(); | ||
609 | if (!ts || !input_dev) { | ||
610 | error = -ENOMEM; | ||
611 | goto err_free_mem; | ||
612 | } | ||
613 | |||
614 | ts->spi = spi; | ||
615 | ts->idev = input_dev; | ||
616 | |||
617 | ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280; | ||
618 | ts->esd_timeout = pdata->esd_timeout_ms; | ||
619 | ts->set_reset = pdata->set_reset; | ||
620 | |||
621 | mutex_init(&ts->mutex); | ||
622 | |||
623 | spin_lock_init(&ts->lock); | ||
624 | setup_timer(&ts->penup_timer, tsc2005_penup_timer, (unsigned long)ts); | ||
625 | |||
626 | INIT_DELAYED_WORK(&ts->esd_work, tsc2005_esd_work); | ||
627 | |||
628 | tsc2005_setup_spi_xfer(ts); | ||
629 | |||
630 | snprintf(ts->phys, sizeof(ts->phys), | ||
631 | "%s/input-ts", dev_name(&spi->dev)); | ||
632 | |||
633 | input_dev->name = "TSC2005 touchscreen"; | ||
634 | input_dev->phys = ts->phys; | ||
635 | input_dev->id.bustype = BUS_SPI; | ||
636 | input_dev->dev.parent = &spi->dev; | ||
637 | input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); | ||
638 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
639 | |||
640 | input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0); | ||
641 | input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0); | ||
642 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0); | ||
643 | |||
644 | input_dev->open = tsc2005_open; | ||
645 | input_dev->close = tsc2005_close; | ||
646 | |||
647 | input_set_drvdata(input_dev, ts); | ||
648 | |||
649 | /* Ensure the touchscreen is off */ | ||
650 | tsc2005_stop_scan(ts); | ||
651 | |||
652 | error = request_threaded_irq(spi->irq, NULL, tsc2005_irq_thread, | ||
653 | IRQF_TRIGGER_RISING, "tsc2005", ts); | ||
654 | if (error) { | ||
655 | dev_err(&spi->dev, "Failed to request irq, err: %d\n", error); | ||
656 | goto err_free_mem; | ||
657 | } | ||
658 | |||
659 | spi_set_drvdata(spi, ts); | ||
660 | error = sysfs_create_group(&spi->dev.kobj, &tsc2005_attr_group); | ||
661 | if (error) { | ||
662 | dev_err(&spi->dev, | ||
663 | "Failed to create sysfs attributes, err: %d\n", error); | ||
664 | goto err_clear_drvdata; | ||
665 | } | ||
666 | |||
667 | error = input_register_device(ts->idev); | ||
668 | if (error) { | ||
669 | dev_err(&spi->dev, | ||
670 | "Failed to register input device, err: %d\n", error); | ||
671 | goto err_remove_sysfs; | ||
672 | } | ||
673 | |||
674 | irq_set_irq_wake(spi->irq, 1); | ||
675 | return 0; | ||
676 | |||
677 | err_remove_sysfs: | ||
678 | sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group); | ||
679 | err_clear_drvdata: | ||
680 | spi_set_drvdata(spi, NULL); | ||
681 | free_irq(spi->irq, ts); | ||
682 | err_free_mem: | ||
683 | input_free_device(input_dev); | ||
684 | kfree(ts); | ||
685 | return error; | ||
686 | } | ||
687 | |||
688 | static int __devexit tsc2005_remove(struct spi_device *spi) | ||
689 | { | ||
690 | struct tsc2005 *ts = spi_get_drvdata(spi); | ||
691 | |||
692 | sysfs_remove_group(&ts->spi->dev.kobj, &tsc2005_attr_group); | ||
693 | |||
694 | free_irq(ts->spi->irq, ts); | ||
695 | input_unregister_device(ts->idev); | ||
696 | kfree(ts); | ||
697 | |||
698 | spi_set_drvdata(spi, NULL); | ||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | #ifdef CONFIG_PM_SLEEP | ||
703 | static int tsc2005_suspend(struct device *dev) | ||
704 | { | ||
705 | struct spi_device *spi = to_spi_device(dev); | ||
706 | struct tsc2005 *ts = spi_get_drvdata(spi); | ||
707 | |||
708 | mutex_lock(&ts->mutex); | ||
709 | |||
710 | if (!ts->suspended && ts->opened) | ||
711 | __tsc2005_disable(ts); | ||
712 | |||
713 | ts->suspended = true; | ||
714 | |||
715 | mutex_unlock(&ts->mutex); | ||
716 | |||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | static int tsc2005_resume(struct device *dev) | ||
721 | { | ||
722 | struct spi_device *spi = to_spi_device(dev); | ||
723 | struct tsc2005 *ts = spi_get_drvdata(spi); | ||
724 | |||
725 | mutex_lock(&ts->mutex); | ||
726 | |||
727 | if (ts->suspended && ts->opened) | ||
728 | __tsc2005_enable(ts); | ||
729 | |||
730 | ts->suspended = false; | ||
731 | |||
732 | mutex_unlock(&ts->mutex); | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | #endif | ||
737 | |||
738 | static SIMPLE_DEV_PM_OPS(tsc2005_pm_ops, tsc2005_suspend, tsc2005_resume); | ||
739 | |||
740 | static struct spi_driver tsc2005_driver = { | ||
741 | .driver = { | ||
742 | .name = "tsc2005", | ||
743 | .owner = THIS_MODULE, | ||
744 | .pm = &tsc2005_pm_ops, | ||
745 | }, | ||
746 | .probe = tsc2005_probe, | ||
747 | .remove = __devexit_p(tsc2005_remove), | ||
748 | }; | ||
749 | |||
750 | static int __init tsc2005_init(void) | ||
751 | { | ||
752 | return spi_register_driver(&tsc2005_driver); | ||
753 | } | ||
754 | module_init(tsc2005_init); | ||
755 | |||
756 | static void __exit tsc2005_exit(void) | ||
757 | { | ||
758 | spi_unregister_driver(&tsc2005_driver); | ||
759 | } | ||
760 | module_exit(tsc2005_exit); | ||
761 | |||
762 | MODULE_AUTHOR("Lauri Leukkunen <lauri.leukkunen@nokia.com>"); | ||
763 | MODULE_DESCRIPTION("TSC2005 Touchscreen Driver"); | ||
764 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index be23780e8a3e..fadc11545b1e 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c | |||
@@ -27,9 +27,6 @@ | |||
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/i2c/tsc2007.h> | 28 | #include <linux/i2c/tsc2007.h> |
29 | 29 | ||
30 | #define TS_POLL_DELAY 1 /* ms delay between samples */ | ||
31 | #define TS_POLL_PERIOD 1 /* ms delay between samples */ | ||
32 | |||
33 | #define TSC2007_MEASURE_TEMP0 (0x0 << 4) | 30 | #define TSC2007_MEASURE_TEMP0 (0x0 << 4) |
34 | #define TSC2007_MEASURE_AUX (0x2 << 4) | 31 | #define TSC2007_MEASURE_AUX (0x2 << 4) |
35 | #define TSC2007_MEASURE_TEMP1 (0x4 << 4) | 32 | #define TSC2007_MEASURE_TEMP1 (0x4 << 4) |
@@ -75,6 +72,9 @@ struct tsc2007 { | |||
75 | 72 | ||
76 | u16 model; | 73 | u16 model; |
77 | u16 x_plate_ohms; | 74 | u16 x_plate_ohms; |
75 | u16 max_rt; | ||
76 | unsigned long poll_delay; | ||
77 | unsigned long poll_period; | ||
78 | 78 | ||
79 | bool pendown; | 79 | bool pendown; |
80 | int irq; | 80 | int irq; |
@@ -156,6 +156,7 @@ static void tsc2007_work(struct work_struct *work) | |||
156 | { | 156 | { |
157 | struct tsc2007 *ts = | 157 | struct tsc2007 *ts = |
158 | container_of(to_delayed_work(work), struct tsc2007, work); | 158 | container_of(to_delayed_work(work), struct tsc2007, work); |
159 | bool debounced = false; | ||
159 | struct ts_event tc; | 160 | struct ts_event tc; |
160 | u32 rt; | 161 | u32 rt; |
161 | 162 | ||
@@ -184,13 +185,14 @@ static void tsc2007_work(struct work_struct *work) | |||
184 | tsc2007_read_values(ts, &tc); | 185 | tsc2007_read_values(ts, &tc); |
185 | 186 | ||
186 | rt = tsc2007_calculate_pressure(ts, &tc); | 187 | rt = tsc2007_calculate_pressure(ts, &tc); |
187 | if (rt > MAX_12BIT) { | 188 | if (rt > ts->max_rt) { |
188 | /* | 189 | /* |
189 | * Sample found inconsistent by debouncing or pressure is | 190 | * Sample found inconsistent by debouncing or pressure is |
190 | * beyond the maximum. Don't report it to user space, | 191 | * beyond the maximum. Don't report it to user space, |
191 | * repeat at least once more the measurement. | 192 | * repeat at least once more the measurement. |
192 | */ | 193 | */ |
193 | dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt); | 194 | dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt); |
195 | debounced = true; | ||
194 | goto out; | 196 | goto out; |
195 | 197 | ||
196 | } | 198 | } |
@@ -225,9 +227,9 @@ static void tsc2007_work(struct work_struct *work) | |||
225 | } | 227 | } |
226 | 228 | ||
227 | out: | 229 | out: |
228 | if (ts->pendown) | 230 | if (ts->pendown || debounced) |
229 | schedule_delayed_work(&ts->work, | 231 | schedule_delayed_work(&ts->work, |
230 | msecs_to_jiffies(TS_POLL_PERIOD)); | 232 | msecs_to_jiffies(ts->poll_period)); |
231 | else | 233 | else |
232 | enable_irq(ts->irq); | 234 | enable_irq(ts->irq); |
233 | } | 235 | } |
@@ -239,7 +241,7 @@ static irqreturn_t tsc2007_irq(int irq, void *handle) | |||
239 | if (!ts->get_pendown_state || likely(ts->get_pendown_state())) { | 241 | if (!ts->get_pendown_state || likely(ts->get_pendown_state())) { |
240 | disable_irq_nosync(ts->irq); | 242 | disable_irq_nosync(ts->irq); |
241 | schedule_delayed_work(&ts->work, | 243 | schedule_delayed_work(&ts->work, |
242 | msecs_to_jiffies(TS_POLL_DELAY)); | 244 | msecs_to_jiffies(ts->poll_delay)); |
243 | } | 245 | } |
244 | 246 | ||
245 | if (ts->clear_penirq) | 247 | if (ts->clear_penirq) |
@@ -265,7 +267,7 @@ static int __devinit tsc2007_probe(struct i2c_client *client, | |||
265 | const struct i2c_device_id *id) | 267 | const struct i2c_device_id *id) |
266 | { | 268 | { |
267 | struct tsc2007 *ts; | 269 | struct tsc2007 *ts; |
268 | struct tsc2007_platform_data *pdata = pdata = client->dev.platform_data; | 270 | struct tsc2007_platform_data *pdata = client->dev.platform_data; |
269 | struct input_dev *input_dev; | 271 | struct input_dev *input_dev; |
270 | int err; | 272 | int err; |
271 | 273 | ||
@@ -292,6 +294,9 @@ static int __devinit tsc2007_probe(struct i2c_client *client, | |||
292 | 294 | ||
293 | ts->model = pdata->model; | 295 | ts->model = pdata->model; |
294 | ts->x_plate_ohms = pdata->x_plate_ohms; | 296 | ts->x_plate_ohms = pdata->x_plate_ohms; |
297 | ts->max_rt = pdata->max_rt ? : MAX_12BIT; | ||
298 | ts->poll_delay = pdata->poll_delay ? : 1; | ||
299 | ts->poll_period = pdata->poll_period ? : 1; | ||
295 | ts->get_pendown_state = pdata->get_pendown_state; | 300 | ts->get_pendown_state = pdata->get_pendown_state; |
296 | ts->clear_penirq = pdata->clear_penirq; | 301 | ts->clear_penirq = pdata->clear_penirq; |
297 | 302 | ||
@@ -305,9 +310,10 @@ static int __devinit tsc2007_probe(struct i2c_client *client, | |||
305 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 310 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
306 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 311 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
307 | 312 | ||
308 | input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); | 313 | input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0); |
309 | input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); | 314 | input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0); |
310 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0); | 315 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, |
316 | pdata->fuzzz, 0); | ||
311 | 317 | ||
312 | if (pdata->init_platform_hw) | 318 | if (pdata->init_platform_hw) |
313 | pdata->init_platform_hw(); | 319 | pdata->init_platform_hw(); |
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 028a5363eea1..3b5b5df04dd6 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Copyright: MontaVista Software, Inc. | 6 | * Copyright: MontaVista Software, Inc. |
7 | * | 7 | * |
8 | * Spliting done by: Marek Vasut <marek.vasut@gmail.com> | 8 | * Spliting done by: Marek Vasut <marek.vasut@gmail.com> |
9 | * If something doesnt work and it worked before spliting, e-mail me, | 9 | * If something doesn't work and it worked before spliting, e-mail me, |
10 | * dont bother Nicolas please ;-) | 10 | * dont bother Nicolas please ;-) |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index f45f80f6d336..73fd6642b681 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -178,6 +178,7 @@ static const struct usb_device_id usbtouch_devices[] = { | |||
178 | 178 | ||
179 | #ifdef CONFIG_TOUCHSCREEN_USB_ITM | 179 | #ifdef CONFIG_TOUCHSCREEN_USB_ITM |
180 | {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, | 180 | {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, |
181 | {USB_DEVICE(0x16e3, 0xf9e9), .driver_info = DEVTYPE_ITM}, | ||
181 | #endif | 182 | #endif |
182 | 183 | ||
183 | #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO | 184 | #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO |
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 56dc35c94bb1..c14412ef4648 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * Wacom W8001 penabled serial touchscreen driver | 2 | * Wacom W8001 penabled serial touchscreen driver |
3 | * | 3 | * |
4 | * Copyright (c) 2008 Jaya Kumar | 4 | * Copyright (c) 2008 Jaya Kumar |
5 | * Copyright (c) 2010 Red Hat, Inc. | ||
6 | * Copyright (c) 2010 - 2011 Ping Cheng, Wacom. <pingc@wacom.com> | ||
5 | * | 7 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public | 8 | * This file is subject to the terms and conditions of the GNU General Public |
7 | * License. See the file COPYING in the main directory of this archive for | 9 | * License. See the file COPYING in the main directory of this archive for |
@@ -14,10 +16,11 @@ | |||
14 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
16 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
17 | #include <linux/input.h> | 19 | #include <linux/input/mt.h> |
18 | #include <linux/serio.h> | 20 | #include <linux/serio.h> |
19 | #include <linux/init.h> | 21 | #include <linux/init.h> |
20 | #include <linux/ctype.h> | 22 | #include <linux/ctype.h> |
23 | #include <linux/delay.h> | ||
21 | 24 | ||
22 | #define DRIVER_DESC "Wacom W8001 serial touchscreen driver" | 25 | #define DRIVER_DESC "Wacom W8001 serial touchscreen driver" |
23 | 26 | ||
@@ -30,11 +33,27 @@ MODULE_LICENSE("GPL"); | |||
30 | #define W8001_LEAD_BYTE 0x80 | 33 | #define W8001_LEAD_BYTE 0x80 |
31 | #define W8001_TAB_MASK 0x40 | 34 | #define W8001_TAB_MASK 0x40 |
32 | #define W8001_TAB_BYTE 0x40 | 35 | #define W8001_TAB_BYTE 0x40 |
36 | /* set in first byte of touch data packets */ | ||
37 | #define W8001_TOUCH_MASK (0x10 | W8001_LEAD_MASK) | ||
38 | #define W8001_TOUCH_BYTE (0x10 | W8001_LEAD_BYTE) | ||
33 | 39 | ||
34 | #define W8001_QUERY_PACKET 0x20 | 40 | #define W8001_QUERY_PACKET 0x20 |
35 | 41 | ||
42 | #define W8001_CMD_STOP '0' | ||
36 | #define W8001_CMD_START '1' | 43 | #define W8001_CMD_START '1' |
37 | #define W8001_CMD_QUERY '*' | 44 | #define W8001_CMD_QUERY '*' |
45 | #define W8001_CMD_TOUCHQUERY '%' | ||
46 | |||
47 | /* length of data packets in bytes, depends on device. */ | ||
48 | #define W8001_PKTLEN_TOUCH93 5 | ||
49 | #define W8001_PKTLEN_TOUCH9A 7 | ||
50 | #define W8001_PKTLEN_TPCPEN 9 | ||
51 | #define W8001_PKTLEN_TPCCTL 11 /* control packet */ | ||
52 | #define W8001_PKTLEN_TOUCH2FG 13 | ||
53 | |||
54 | /* resolution in points/mm */ | ||
55 | #define W8001_PEN_RESOLUTION 100 | ||
56 | #define W8001_TOUCH_RESOLUTION 10 | ||
38 | 57 | ||
39 | struct w8001_coord { | 58 | struct w8001_coord { |
40 | u8 rdy; | 59 | u8 rdy; |
@@ -48,6 +67,15 @@ struct w8001_coord { | |||
48 | u8 tilt_y; | 67 | u8 tilt_y; |
49 | }; | 68 | }; |
50 | 69 | ||
70 | /* touch query reply packet */ | ||
71 | struct w8001_touch_query { | ||
72 | u16 x; | ||
73 | u16 y; | ||
74 | u8 panel_res; | ||
75 | u8 capacity_res; | ||
76 | u8 sensor_id; | ||
77 | }; | ||
78 | |||
51 | /* | 79 | /* |
52 | * Per-touchscreen data. | 80 | * Per-touchscreen data. |
53 | */ | 81 | */ |
@@ -62,9 +90,16 @@ struct w8001 { | |||
62 | unsigned char response[W8001_MAX_LENGTH]; | 90 | unsigned char response[W8001_MAX_LENGTH]; |
63 | unsigned char data[W8001_MAX_LENGTH]; | 91 | unsigned char data[W8001_MAX_LENGTH]; |
64 | char phys[32]; | 92 | char phys[32]; |
93 | int type; | ||
94 | unsigned int pktlen; | ||
95 | u16 max_touch_x; | ||
96 | u16 max_touch_y; | ||
97 | u16 max_pen_x; | ||
98 | u16 max_pen_y; | ||
99 | char name[64]; | ||
65 | }; | 100 | }; |
66 | 101 | ||
67 | static void parse_data(u8 *data, struct w8001_coord *coord) | 102 | static void parse_pen_data(u8 *data, struct w8001_coord *coord) |
68 | { | 103 | { |
69 | memset(coord, 0, sizeof(*coord)); | 104 | memset(coord, 0, sizeof(*coord)); |
70 | 105 | ||
@@ -88,11 +123,166 @@ static void parse_data(u8 *data, struct w8001_coord *coord) | |||
88 | coord->tilt_y = data[8] & 0x7F; | 123 | coord->tilt_y = data[8] & 0x7F; |
89 | } | 124 | } |
90 | 125 | ||
126 | static void parse_single_touch(u8 *data, struct w8001_coord *coord) | ||
127 | { | ||
128 | coord->x = (data[1] << 7) | data[2]; | ||
129 | coord->y = (data[3] << 7) | data[4]; | ||
130 | coord->tsw = data[0] & 0x01; | ||
131 | } | ||
132 | |||
133 | static void scale_touch_coordinates(struct w8001 *w8001, | ||
134 | unsigned int *x, unsigned int *y) | ||
135 | { | ||
136 | if (w8001->max_pen_x && w8001->max_touch_x) | ||
137 | *x = *x * w8001->max_pen_x / w8001->max_touch_x; | ||
138 | |||
139 | if (w8001->max_pen_y && w8001->max_touch_y) | ||
140 | *y = *y * w8001->max_pen_y / w8001->max_touch_y; | ||
141 | } | ||
142 | |||
143 | static void parse_multi_touch(struct w8001 *w8001) | ||
144 | { | ||
145 | struct input_dev *dev = w8001->dev; | ||
146 | unsigned char *data = w8001->data; | ||
147 | unsigned int x, y; | ||
148 | int i; | ||
149 | int count = 0; | ||
150 | |||
151 | for (i = 0; i < 2; i++) { | ||
152 | bool touch = data[0] & (1 << i); | ||
153 | |||
154 | input_mt_slot(dev, i); | ||
155 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch); | ||
156 | if (touch) { | ||
157 | x = (data[6 * i + 1] << 7) | data[6 * i + 2]; | ||
158 | y = (data[6 * i + 3] << 7) | data[6 * i + 4]; | ||
159 | /* data[5,6] and [11,12] is finger capacity */ | ||
160 | |||
161 | /* scale to pen maximum */ | ||
162 | scale_touch_coordinates(w8001, &x, &y); | ||
163 | |||
164 | input_report_abs(dev, ABS_MT_POSITION_X, x); | ||
165 | input_report_abs(dev, ABS_MT_POSITION_Y, y); | ||
166 | count++; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | /* emulate single touch events when stylus is out of proximity. | ||
171 | * This is to make single touch backward support consistent | ||
172 | * across all Wacom single touch devices. | ||
173 | */ | ||
174 | if (w8001->type != BTN_TOOL_PEN && | ||
175 | w8001->type != BTN_TOOL_RUBBER) { | ||
176 | w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED; | ||
177 | input_mt_report_pointer_emulation(dev, true); | ||
178 | } | ||
179 | |||
180 | input_sync(dev); | ||
181 | } | ||
182 | |||
183 | static void parse_touchquery(u8 *data, struct w8001_touch_query *query) | ||
184 | { | ||
185 | memset(query, 0, sizeof(*query)); | ||
186 | |||
187 | query->panel_res = data[1]; | ||
188 | query->sensor_id = data[2] & 0x7; | ||
189 | query->capacity_res = data[7]; | ||
190 | |||
191 | query->x = data[3] << 9; | ||
192 | query->x |= data[4] << 2; | ||
193 | query->x |= (data[2] >> 5) & 0x3; | ||
194 | |||
195 | query->y = data[5] << 9; | ||
196 | query->y |= data[6] << 2; | ||
197 | query->y |= (data[2] >> 3) & 0x3; | ||
198 | |||
199 | /* Early days' single-finger touch models need the following defaults */ | ||
200 | if (!query->x && !query->y) { | ||
201 | query->x = 1024; | ||
202 | query->y = 1024; | ||
203 | if (query->panel_res) | ||
204 | query->x = query->y = (1 << query->panel_res); | ||
205 | query->panel_res = W8001_TOUCH_RESOLUTION; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) | ||
210 | { | ||
211 | struct input_dev *dev = w8001->dev; | ||
212 | |||
213 | /* | ||
214 | * We have 1 bit for proximity (rdy) and 3 bits for tip, side, | ||
215 | * side2/eraser. If rdy && f2 are set, this can be either pen + side2, | ||
216 | * or eraser. Assume: | ||
217 | * - if dev is already in proximity and f2 is toggled → pen + side2 | ||
218 | * - if dev comes into proximity with f2 set → eraser | ||
219 | * If f2 disappears after assuming eraser, fake proximity out for | ||
220 | * eraser and in for pen. | ||
221 | */ | ||
222 | |||
223 | switch (w8001->type) { | ||
224 | case BTN_TOOL_RUBBER: | ||
225 | if (!coord->f2) { | ||
226 | input_report_abs(dev, ABS_PRESSURE, 0); | ||
227 | input_report_key(dev, BTN_TOUCH, 0); | ||
228 | input_report_key(dev, BTN_STYLUS, 0); | ||
229 | input_report_key(dev, BTN_STYLUS2, 0); | ||
230 | input_report_key(dev, BTN_TOOL_RUBBER, 0); | ||
231 | input_sync(dev); | ||
232 | w8001->type = BTN_TOOL_PEN; | ||
233 | } | ||
234 | break; | ||
235 | |||
236 | case BTN_TOOL_FINGER: | ||
237 | input_report_key(dev, BTN_TOUCH, 0); | ||
238 | input_report_key(dev, BTN_TOOL_FINGER, 0); | ||
239 | input_sync(dev); | ||
240 | /* fall through */ | ||
241 | |||
242 | case KEY_RESERVED: | ||
243 | w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | ||
244 | break; | ||
245 | |||
246 | default: | ||
247 | input_report_key(dev, BTN_STYLUS2, coord->f2); | ||
248 | break; | ||
249 | } | ||
250 | |||
251 | input_report_abs(dev, ABS_X, coord->x); | ||
252 | input_report_abs(dev, ABS_Y, coord->y); | ||
253 | input_report_abs(dev, ABS_PRESSURE, coord->pen_pressure); | ||
254 | input_report_key(dev, BTN_TOUCH, coord->tsw); | ||
255 | input_report_key(dev, BTN_STYLUS, coord->f1); | ||
256 | input_report_key(dev, w8001->type, coord->rdy); | ||
257 | input_sync(dev); | ||
258 | |||
259 | if (!coord->rdy) | ||
260 | w8001->type = KEY_RESERVED; | ||
261 | } | ||
262 | |||
263 | static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord) | ||
264 | { | ||
265 | struct input_dev *dev = w8001->dev; | ||
266 | unsigned int x = coord->x; | ||
267 | unsigned int y = coord->y; | ||
268 | |||
269 | /* scale to pen maximum */ | ||
270 | scale_touch_coordinates(w8001, &x, &y); | ||
271 | |||
272 | input_report_abs(dev, ABS_X, x); | ||
273 | input_report_abs(dev, ABS_Y, y); | ||
274 | input_report_key(dev, BTN_TOUCH, coord->tsw); | ||
275 | input_report_key(dev, BTN_TOOL_FINGER, coord->tsw); | ||
276 | |||
277 | input_sync(dev); | ||
278 | |||
279 | w8001->type = coord->tsw ? BTN_TOOL_FINGER : KEY_RESERVED; | ||
280 | } | ||
281 | |||
91 | static irqreturn_t w8001_interrupt(struct serio *serio, | 282 | static irqreturn_t w8001_interrupt(struct serio *serio, |
92 | unsigned char data, unsigned int flags) | 283 | unsigned char data, unsigned int flags) |
93 | { | 284 | { |
94 | struct w8001 *w8001 = serio_get_drvdata(serio); | 285 | struct w8001 *w8001 = serio_get_drvdata(serio); |
95 | struct input_dev *dev = w8001->dev; | ||
96 | struct w8001_coord coord; | 286 | struct w8001_coord coord; |
97 | unsigned char tmp; | 287 | unsigned char tmp; |
98 | 288 | ||
@@ -105,26 +295,54 @@ static irqreturn_t w8001_interrupt(struct serio *serio, | |||
105 | } | 295 | } |
106 | break; | 296 | break; |
107 | 297 | ||
108 | case 8: | 298 | case W8001_PKTLEN_TOUCH93 - 1: |
299 | case W8001_PKTLEN_TOUCH9A - 1: | ||
300 | tmp = w8001->data[0] & W8001_TOUCH_BYTE; | ||
301 | if (tmp != W8001_TOUCH_BYTE) | ||
302 | break; | ||
303 | |||
304 | if (w8001->pktlen == w8001->idx) { | ||
305 | w8001->idx = 0; | ||
306 | if (w8001->type != BTN_TOOL_PEN && | ||
307 | w8001->type != BTN_TOOL_RUBBER) { | ||
308 | parse_single_touch(w8001->data, &coord); | ||
309 | report_single_touch(w8001, &coord); | ||
310 | } | ||
311 | } | ||
312 | break; | ||
313 | |||
314 | /* Pen coordinates packet */ | ||
315 | case W8001_PKTLEN_TPCPEN - 1: | ||
109 | tmp = w8001->data[0] & W8001_TAB_MASK; | 316 | tmp = w8001->data[0] & W8001_TAB_MASK; |
110 | if (unlikely(tmp == W8001_TAB_BYTE)) | 317 | if (unlikely(tmp == W8001_TAB_BYTE)) |
111 | break; | 318 | break; |
112 | 319 | ||
320 | tmp = w8001->data[0] & W8001_TOUCH_BYTE; | ||
321 | if (tmp == W8001_TOUCH_BYTE) | ||
322 | break; | ||
323 | |||
113 | w8001->idx = 0; | 324 | w8001->idx = 0; |
114 | parse_data(w8001->data, &coord); | 325 | parse_pen_data(w8001->data, &coord); |
115 | input_report_abs(dev, ABS_X, coord.x); | 326 | report_pen_events(w8001, &coord); |
116 | input_report_abs(dev, ABS_Y, coord.y); | ||
117 | input_report_abs(dev, ABS_PRESSURE, coord.pen_pressure); | ||
118 | input_report_key(dev, BTN_TOUCH, coord.tsw); | ||
119 | input_sync(dev); | ||
120 | break; | 327 | break; |
121 | 328 | ||
122 | case 10: | 329 | /* control packet */ |
330 | case W8001_PKTLEN_TPCCTL - 1: | ||
331 | tmp = w8001->data[0] & W8001_TOUCH_MASK; | ||
332 | if (tmp == W8001_TOUCH_BYTE) | ||
333 | break; | ||
334 | |||
123 | w8001->idx = 0; | 335 | w8001->idx = 0; |
124 | memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH); | 336 | memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH); |
125 | w8001->response_type = W8001_QUERY_PACKET; | 337 | w8001->response_type = W8001_QUERY_PACKET; |
126 | complete(&w8001->cmd_done); | 338 | complete(&w8001->cmd_done); |
127 | break; | 339 | break; |
340 | |||
341 | /* 2 finger touch packet */ | ||
342 | case W8001_PKTLEN_TOUCH2FG - 1: | ||
343 | w8001->idx = 0; | ||
344 | parse_multi_touch(w8001); | ||
345 | break; | ||
128 | } | 346 | } |
129 | 347 | ||
130 | return IRQ_HANDLED; | 348 | return IRQ_HANDLED; |
@@ -153,19 +371,108 @@ static int w8001_setup(struct w8001 *w8001) | |||
153 | { | 371 | { |
154 | struct input_dev *dev = w8001->dev; | 372 | struct input_dev *dev = w8001->dev; |
155 | struct w8001_coord coord; | 373 | struct w8001_coord coord; |
374 | struct w8001_touch_query touch; | ||
156 | int error; | 375 | int error; |
157 | 376 | ||
158 | error = w8001_command(w8001, W8001_CMD_QUERY, true); | 377 | error = w8001_command(w8001, W8001_CMD_STOP, false); |
159 | if (error) | 378 | if (error) |
160 | return error; | 379 | return error; |
161 | 380 | ||
162 | parse_data(w8001->response, &coord); | 381 | msleep(250); /* wait 250ms before querying the device */ |
382 | |||
383 | dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
384 | strlcat(w8001->name, "Wacom Serial", sizeof(w8001->name)); | ||
163 | 385 | ||
164 | input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); | 386 | /* penabled? */ |
165 | input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); | 387 | error = w8001_command(w8001, W8001_CMD_QUERY, true); |
166 | input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); | 388 | if (!error) { |
167 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); | 389 | __set_bit(BTN_TOUCH, dev->keybit); |
168 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); | 390 | __set_bit(BTN_TOOL_PEN, dev->keybit); |
391 | __set_bit(BTN_TOOL_RUBBER, dev->keybit); | ||
392 | __set_bit(BTN_STYLUS, dev->keybit); | ||
393 | __set_bit(BTN_STYLUS2, dev->keybit); | ||
394 | |||
395 | parse_pen_data(w8001->response, &coord); | ||
396 | w8001->max_pen_x = coord.x; | ||
397 | w8001->max_pen_y = coord.y; | ||
398 | |||
399 | input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); | ||
400 | input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); | ||
401 | input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION); | ||
402 | input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION); | ||
403 | input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); | ||
404 | if (coord.tilt_x && coord.tilt_y) { | ||
405 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); | ||
406 | input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); | ||
407 | } | ||
408 | w8001->id = 0x90; | ||
409 | strlcat(w8001->name, " Penabled", sizeof(w8001->name)); | ||
410 | } | ||
411 | |||
412 | /* Touch enabled? */ | ||
413 | error = w8001_command(w8001, W8001_CMD_TOUCHQUERY, true); | ||
414 | |||
415 | /* | ||
416 | * Some non-touch devices may reply to the touch query. But their | ||
417 | * second byte is empty, which indicates touch is not supported. | ||
418 | */ | ||
419 | if (!error && w8001->response[1]) { | ||
420 | __set_bit(BTN_TOUCH, dev->keybit); | ||
421 | __set_bit(BTN_TOOL_FINGER, dev->keybit); | ||
422 | |||
423 | parse_touchquery(w8001->response, &touch); | ||
424 | w8001->max_touch_x = touch.x; | ||
425 | w8001->max_touch_y = touch.y; | ||
426 | |||
427 | if (w8001->max_pen_x && w8001->max_pen_y) { | ||
428 | /* if pen is supported scale to pen maximum */ | ||
429 | touch.x = w8001->max_pen_x; | ||
430 | touch.y = w8001->max_pen_y; | ||
431 | touch.panel_res = W8001_PEN_RESOLUTION; | ||
432 | } | ||
433 | |||
434 | input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); | ||
435 | input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); | ||
436 | input_abs_set_res(dev, ABS_X, touch.panel_res); | ||
437 | input_abs_set_res(dev, ABS_Y, touch.panel_res); | ||
438 | |||
439 | switch (touch.sensor_id) { | ||
440 | case 0: | ||
441 | case 2: | ||
442 | w8001->pktlen = W8001_PKTLEN_TOUCH93; | ||
443 | w8001->id = 0x93; | ||
444 | strlcat(w8001->name, " 1FG", sizeof(w8001->name)); | ||
445 | break; | ||
446 | |||
447 | case 1: | ||
448 | case 3: | ||
449 | case 4: | ||
450 | w8001->pktlen = W8001_PKTLEN_TOUCH9A; | ||
451 | strlcat(w8001->name, " 1FG", sizeof(w8001->name)); | ||
452 | w8001->id = 0x9a; | ||
453 | break; | ||
454 | |||
455 | case 5: | ||
456 | w8001->pktlen = W8001_PKTLEN_TOUCH2FG; | ||
457 | |||
458 | input_mt_init_slots(dev, 2); | ||
459 | input_set_abs_params(dev, ABS_MT_POSITION_X, | ||
460 | 0, touch.x, 0, 0); | ||
461 | input_set_abs_params(dev, ABS_MT_POSITION_Y, | ||
462 | 0, touch.y, 0, 0); | ||
463 | input_set_abs_params(dev, ABS_MT_TOOL_TYPE, | ||
464 | 0, MT_TOOL_MAX, 0, 0); | ||
465 | |||
466 | strlcat(w8001->name, " 2FG", sizeof(w8001->name)); | ||
467 | if (w8001->max_pen_x && w8001->max_pen_y) | ||
468 | w8001->id = 0xE3; | ||
469 | else | ||
470 | w8001->id = 0xE2; | ||
471 | break; | ||
472 | } | ||
473 | } | ||
474 | |||
475 | strlcat(w8001->name, " Touchscreen", sizeof(w8001->name)); | ||
169 | 476 | ||
170 | return w8001_command(w8001, W8001_CMD_START, false); | 477 | return w8001_command(w8001, W8001_CMD_START, false); |
171 | } | 478 | } |
@@ -206,22 +513,10 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
206 | } | 513 | } |
207 | 514 | ||
208 | w8001->serio = serio; | 515 | w8001->serio = serio; |
209 | w8001->id = serio->id.id; | ||
210 | w8001->dev = input_dev; | 516 | w8001->dev = input_dev; |
211 | init_completion(&w8001->cmd_done); | 517 | init_completion(&w8001->cmd_done); |
212 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); | 518 | snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); |
213 | 519 | ||
214 | input_dev->name = "Wacom W8001 Penabled Serial TouchScreen"; | ||
215 | input_dev->phys = w8001->phys; | ||
216 | input_dev->id.bustype = BUS_RS232; | ||
217 | input_dev->id.vendor = SERIO_W8001; | ||
218 | input_dev->id.product = w8001->id; | ||
219 | input_dev->id.version = 0x0100; | ||
220 | input_dev->dev.parent = &serio->dev; | ||
221 | |||
222 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
223 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
224 | |||
225 | serio_set_drvdata(serio, w8001); | 520 | serio_set_drvdata(serio, w8001); |
226 | err = serio_open(serio, drv); | 521 | err = serio_open(serio, drv); |
227 | if (err) | 522 | if (err) |
@@ -231,6 +526,14 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) | |||
231 | if (err) | 526 | if (err) |
232 | goto fail3; | 527 | goto fail3; |
233 | 528 | ||
529 | input_dev->name = w8001->name; | ||
530 | input_dev->phys = w8001->phys; | ||
531 | input_dev->id.product = w8001->id; | ||
532 | input_dev->id.bustype = BUS_RS232; | ||
533 | input_dev->id.vendor = 0x056a; | ||
534 | input_dev->id.version = 0x0100; | ||
535 | input_dev->dev.parent = &serio->dev; | ||
536 | |||
234 | err = input_register_device(w8001->dev); | 537 | err = input_register_device(w8001->dev); |
235 | if (err) | 538 | if (err) |
236 | goto fail3; | 539 | goto fail3; |
diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c new file mode 100644 index 000000000000..9175d49d2546 --- /dev/null +++ b/drivers/input/touchscreen/wm831x-ts.c | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * Touchscreen driver for WM831x PMICs | ||
3 | * | ||
4 | * Copyright 2011 Wolfson Microelectronics plc. | ||
5 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/moduleparam.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/pm.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/mfd/wm831x/core.h> | ||
23 | #include <linux/mfd/wm831x/irq.h> | ||
24 | #include <linux/mfd/wm831x/pdata.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/types.h> | ||
28 | |||
29 | /* | ||
30 | * R16424 (0x4028) - Touch Control 1 | ||
31 | */ | ||
32 | #define WM831X_TCH_ENA 0x8000 /* TCH_ENA */ | ||
33 | #define WM831X_TCH_CVT_ENA 0x4000 /* TCH_CVT_ENA */ | ||
34 | #define WM831X_TCH_SLPENA 0x1000 /* TCH_SLPENA */ | ||
35 | #define WM831X_TCH_Z_ENA 0x0400 /* TCH_Z_ENA */ | ||
36 | #define WM831X_TCH_Y_ENA 0x0200 /* TCH_Y_ENA */ | ||
37 | #define WM831X_TCH_X_ENA 0x0100 /* TCH_X_ENA */ | ||
38 | #define WM831X_TCH_DELAY_MASK 0x00E0 /* TCH_DELAY - [7:5] */ | ||
39 | #define WM831X_TCH_DELAY_SHIFT 5 /* TCH_DELAY - [7:5] */ | ||
40 | #define WM831X_TCH_DELAY_WIDTH 3 /* TCH_DELAY - [7:5] */ | ||
41 | #define WM831X_TCH_RATE_MASK 0x001F /* TCH_RATE - [4:0] */ | ||
42 | #define WM831X_TCH_RATE_SHIFT 0 /* TCH_RATE - [4:0] */ | ||
43 | #define WM831X_TCH_RATE_WIDTH 5 /* TCH_RATE - [4:0] */ | ||
44 | |||
45 | /* | ||
46 | * R16425 (0x4029) - Touch Control 2 | ||
47 | */ | ||
48 | #define WM831X_TCH_PD_WK 0x2000 /* TCH_PD_WK */ | ||
49 | #define WM831X_TCH_5WIRE 0x1000 /* TCH_5WIRE */ | ||
50 | #define WM831X_TCH_PDONLY 0x0800 /* TCH_PDONLY */ | ||
51 | #define WM831X_TCH_ISEL 0x0100 /* TCH_ISEL */ | ||
52 | #define WM831X_TCH_RPU_MASK 0x000F /* TCH_RPU - [3:0] */ | ||
53 | #define WM831X_TCH_RPU_SHIFT 0 /* TCH_RPU - [3:0] */ | ||
54 | #define WM831X_TCH_RPU_WIDTH 4 /* TCH_RPU - [3:0] */ | ||
55 | |||
56 | /* | ||
57 | * R16426-8 (0x402A-C) - Touch Data X/Y/X | ||
58 | */ | ||
59 | #define WM831X_TCH_PD 0x8000 /* TCH_PD1 */ | ||
60 | #define WM831X_TCH_DATA_MASK 0x0FFF /* TCH_DATA - [11:0] */ | ||
61 | #define WM831X_TCH_DATA_SHIFT 0 /* TCH_DATA - [11:0] */ | ||
62 | #define WM831X_TCH_DATA_WIDTH 12 /* TCH_DATA - [11:0] */ | ||
63 | |||
64 | struct wm831x_ts { | ||
65 | struct input_dev *input_dev; | ||
66 | struct wm831x *wm831x; | ||
67 | unsigned int data_irq; | ||
68 | unsigned int pd_irq; | ||
69 | bool pressure; | ||
70 | bool pen_down; | ||
71 | struct work_struct pd_data_work; | ||
72 | }; | ||
73 | |||
74 | static void wm831x_pd_data_work(struct work_struct *work) | ||
75 | { | ||
76 | struct wm831x_ts *wm831x_ts = | ||
77 | container_of(work, struct wm831x_ts, pd_data_work); | ||
78 | |||
79 | if (wm831x_ts->pen_down) { | ||
80 | enable_irq(wm831x_ts->data_irq); | ||
81 | dev_dbg(wm831x_ts->wm831x->dev, "IRQ PD->DATA done\n"); | ||
82 | } else { | ||
83 | enable_irq(wm831x_ts->pd_irq); | ||
84 | dev_dbg(wm831x_ts->wm831x->dev, "IRQ DATA->PD done\n"); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) | ||
89 | { | ||
90 | struct wm831x_ts *wm831x_ts = irq_data; | ||
91 | struct wm831x *wm831x = wm831x_ts->wm831x; | ||
92 | static int data_types[] = { ABS_X, ABS_Y, ABS_PRESSURE }; | ||
93 | u16 data[3]; | ||
94 | int count; | ||
95 | int i, ret; | ||
96 | |||
97 | if (wm831x_ts->pressure) | ||
98 | count = 3; | ||
99 | else | ||
100 | count = 2; | ||
101 | |||
102 | wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1, | ||
103 | WM831X_TCHDATA_EINT, WM831X_TCHDATA_EINT); | ||
104 | |||
105 | ret = wm831x_bulk_read(wm831x, WM831X_TOUCH_DATA_X, count, | ||
106 | data); | ||
107 | if (ret != 0) { | ||
108 | dev_err(wm831x->dev, "Failed to read touch data: %d\n", | ||
109 | ret); | ||
110 | return IRQ_NONE; | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * We get a pen down reading on every reading, report pen up if any | ||
115 | * individual reading does so. | ||
116 | */ | ||
117 | wm831x_ts->pen_down = true; | ||
118 | for (i = 0; i < count; i++) { | ||
119 | if (!(data[i] & WM831X_TCH_PD)) { | ||
120 | wm831x_ts->pen_down = false; | ||
121 | continue; | ||
122 | } | ||
123 | input_report_abs(wm831x_ts->input_dev, data_types[i], | ||
124 | data[i] & WM831X_TCH_DATA_MASK); | ||
125 | } | ||
126 | |||
127 | if (!wm831x_ts->pen_down) { | ||
128 | /* Switch from data to pen down */ | ||
129 | dev_dbg(wm831x->dev, "IRQ DATA->PD\n"); | ||
130 | |||
131 | disable_irq_nosync(wm831x_ts->data_irq); | ||
132 | |||
133 | /* Don't need data any more */ | ||
134 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
135 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | | ||
136 | WM831X_TCH_Z_ENA, 0); | ||
137 | |||
138 | /* Flush any final samples that arrived while reading */ | ||
139 | wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1, | ||
140 | WM831X_TCHDATA_EINT, WM831X_TCHDATA_EINT); | ||
141 | |||
142 | wm831x_bulk_read(wm831x, WM831X_TOUCH_DATA_X, count, data); | ||
143 | |||
144 | if (wm831x_ts->pressure) | ||
145 | input_report_abs(wm831x_ts->input_dev, | ||
146 | ABS_PRESSURE, 0); | ||
147 | |||
148 | input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 0); | ||
149 | |||
150 | schedule_work(&wm831x_ts->pd_data_work); | ||
151 | } else { | ||
152 | input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1); | ||
153 | } | ||
154 | |||
155 | input_sync(wm831x_ts->input_dev); | ||
156 | |||
157 | return IRQ_HANDLED; | ||
158 | } | ||
159 | |||
160 | static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data) | ||
161 | { | ||
162 | struct wm831x_ts *wm831x_ts = irq_data; | ||
163 | struct wm831x *wm831x = wm831x_ts->wm831x; | ||
164 | int ena = 0; | ||
165 | |||
166 | if (wm831x_ts->pen_down) | ||
167 | return IRQ_HANDLED; | ||
168 | |||
169 | disable_irq_nosync(wm831x_ts->pd_irq); | ||
170 | |||
171 | /* Start collecting data */ | ||
172 | if (wm831x_ts->pressure) | ||
173 | ena |= WM831X_TCH_Z_ENA; | ||
174 | |||
175 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
176 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, | ||
177 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | ena); | ||
178 | |||
179 | wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1, | ||
180 | WM831X_TCHPD_EINT, WM831X_TCHPD_EINT); | ||
181 | |||
182 | wm831x_ts->pen_down = true; | ||
183 | |||
184 | /* Switch from pen down to data */ | ||
185 | dev_dbg(wm831x->dev, "IRQ PD->DATA\n"); | ||
186 | schedule_work(&wm831x_ts->pd_data_work); | ||
187 | |||
188 | return IRQ_HANDLED; | ||
189 | } | ||
190 | |||
191 | static int wm831x_ts_input_open(struct input_dev *idev) | ||
192 | { | ||
193 | struct wm831x_ts *wm831x_ts = input_get_drvdata(idev); | ||
194 | struct wm831x *wm831x = wm831x_ts->wm831x; | ||
195 | |||
196 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
197 | WM831X_TCH_ENA | WM831X_TCH_CVT_ENA | | ||
198 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | | ||
199 | WM831X_TCH_Z_ENA, WM831X_TCH_ENA); | ||
200 | |||
201 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
202 | WM831X_TCH_CVT_ENA, WM831X_TCH_CVT_ENA); | ||
203 | |||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static void wm831x_ts_input_close(struct input_dev *idev) | ||
208 | { | ||
209 | struct wm831x_ts *wm831x_ts = input_get_drvdata(idev); | ||
210 | struct wm831x *wm831x = wm831x_ts->wm831x; | ||
211 | |||
212 | /* Shut the controller down, disabling all other functionality too */ | ||
213 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
214 | WM831X_TCH_ENA | WM831X_TCH_X_ENA | | ||
215 | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, 0); | ||
216 | |||
217 | /* Make sure any pending IRQs are done, the above will prevent | ||
218 | * new ones firing. | ||
219 | */ | ||
220 | synchronize_irq(wm831x_ts->data_irq); | ||
221 | synchronize_irq(wm831x_ts->pd_irq); | ||
222 | |||
223 | /* Make sure the IRQ completion work is quiesced */ | ||
224 | flush_work_sync(&wm831x_ts->pd_data_work); | ||
225 | |||
226 | /* If we ended up with the pen down then make sure we revert back | ||
227 | * to pen detection state for the next time we start up. | ||
228 | */ | ||
229 | if (wm831x_ts->pen_down) { | ||
230 | disable_irq(wm831x_ts->data_irq); | ||
231 | enable_irq(wm831x_ts->pd_irq); | ||
232 | wm831x_ts->pen_down = false; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | static __devinit int wm831x_ts_probe(struct platform_device *pdev) | ||
237 | { | ||
238 | struct wm831x_ts *wm831x_ts; | ||
239 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | ||
240 | struct wm831x_pdata *core_pdata = dev_get_platdata(pdev->dev.parent); | ||
241 | struct wm831x_touch_pdata *pdata = NULL; | ||
242 | struct input_dev *input_dev; | ||
243 | int error, irqf; | ||
244 | |||
245 | if (core_pdata) | ||
246 | pdata = core_pdata->touch; | ||
247 | |||
248 | wm831x_ts = kzalloc(sizeof(struct wm831x_ts), GFP_KERNEL); | ||
249 | input_dev = input_allocate_device(); | ||
250 | if (!wm831x_ts || !input_dev) { | ||
251 | error = -ENOMEM; | ||
252 | goto err_alloc; | ||
253 | } | ||
254 | |||
255 | wm831x_ts->wm831x = wm831x; | ||
256 | wm831x_ts->input_dev = input_dev; | ||
257 | INIT_WORK(&wm831x_ts->pd_data_work, wm831x_pd_data_work); | ||
258 | |||
259 | /* | ||
260 | * If we have a direct IRQ use it, otherwise use the interrupt | ||
261 | * from the WM831x IRQ controller. | ||
262 | */ | ||
263 | if (pdata && pdata->data_irq) | ||
264 | wm831x_ts->data_irq = pdata->data_irq; | ||
265 | else | ||
266 | wm831x_ts->data_irq = platform_get_irq_byname(pdev, "TCHDATA"); | ||
267 | |||
268 | if (pdata && pdata->pd_irq) | ||
269 | wm831x_ts->pd_irq = pdata->pd_irq; | ||
270 | else | ||
271 | wm831x_ts->pd_irq = platform_get_irq_byname(pdev, "TCHPD"); | ||
272 | |||
273 | if (pdata) | ||
274 | wm831x_ts->pressure = pdata->pressure; | ||
275 | else | ||
276 | wm831x_ts->pressure = true; | ||
277 | |||
278 | /* Five wire touchscreens can't report pressure */ | ||
279 | if (pdata && pdata->fivewire) { | ||
280 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2, | ||
281 | WM831X_TCH_5WIRE, WM831X_TCH_5WIRE); | ||
282 | |||
283 | /* Pressure measurements are not possible for five wire mode */ | ||
284 | WARN_ON(pdata->pressure && pdata->fivewire); | ||
285 | wm831x_ts->pressure = false; | ||
286 | } else { | ||
287 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2, | ||
288 | WM831X_TCH_5WIRE, 0); | ||
289 | } | ||
290 | |||
291 | if (pdata) { | ||
292 | switch (pdata->isel) { | ||
293 | default: | ||
294 | dev_err(&pdev->dev, "Unsupported ISEL setting: %d\n", | ||
295 | pdata->isel); | ||
296 | /* Fall through */ | ||
297 | case 200: | ||
298 | case 0: | ||
299 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2, | ||
300 | WM831X_TCH_ISEL, 0); | ||
301 | break; | ||
302 | case 400: | ||
303 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2, | ||
304 | WM831X_TCH_ISEL, WM831X_TCH_ISEL); | ||
305 | break; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_2, | ||
310 | WM831X_TCH_PDONLY, 0); | ||
311 | |||
312 | /* Default to 96 samples/sec */ | ||
313 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | ||
314 | WM831X_TCH_RATE_MASK, 6); | ||
315 | |||
316 | if (pdata && pdata->data_irqf) | ||
317 | irqf = pdata->data_irqf; | ||
318 | else | ||
319 | irqf = IRQF_TRIGGER_HIGH; | ||
320 | |||
321 | error = request_threaded_irq(wm831x_ts->data_irq, | ||
322 | NULL, wm831x_ts_data_irq, | ||
323 | irqf | IRQF_ONESHOT, | ||
324 | "Touchscreen data", wm831x_ts); | ||
325 | if (error) { | ||
326 | dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n", | ||
327 | wm831x_ts->data_irq, error); | ||
328 | goto err_alloc; | ||
329 | } | ||
330 | disable_irq(wm831x_ts->data_irq); | ||
331 | |||
332 | if (pdata && pdata->pd_irqf) | ||
333 | irqf = pdata->pd_irqf; | ||
334 | else | ||
335 | irqf = IRQF_TRIGGER_HIGH; | ||
336 | |||
337 | error = request_threaded_irq(wm831x_ts->pd_irq, | ||
338 | NULL, wm831x_ts_pen_down_irq, | ||
339 | irqf | IRQF_ONESHOT, | ||
340 | "Touchscreen pen down", wm831x_ts); | ||
341 | if (error) { | ||
342 | dev_err(&pdev->dev, "Failed to request pen down IRQ %d: %d\n", | ||
343 | wm831x_ts->pd_irq, error); | ||
344 | goto err_data_irq; | ||
345 | } | ||
346 | |||
347 | /* set up touch configuration */ | ||
348 | input_dev->name = "WM831x touchscreen"; | ||
349 | input_dev->phys = "wm831x"; | ||
350 | input_dev->open = wm831x_ts_input_open; | ||
351 | input_dev->close = wm831x_ts_input_close; | ||
352 | |||
353 | __set_bit(EV_ABS, input_dev->evbit); | ||
354 | __set_bit(EV_KEY, input_dev->evbit); | ||
355 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
356 | |||
357 | input_set_abs_params(input_dev, ABS_X, 0, 4095, 5, 0); | ||
358 | input_set_abs_params(input_dev, ABS_Y, 0, 4095, 5, 0); | ||
359 | if (wm831x_ts->pressure) | ||
360 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 4095, 5, 0); | ||
361 | |||
362 | input_set_drvdata(input_dev, wm831x_ts); | ||
363 | input_dev->dev.parent = &pdev->dev; | ||
364 | |||
365 | error = input_register_device(input_dev); | ||
366 | if (error) | ||
367 | goto err_pd_irq; | ||
368 | |||
369 | platform_set_drvdata(pdev, wm831x_ts); | ||
370 | return 0; | ||
371 | |||
372 | err_pd_irq: | ||
373 | free_irq(wm831x_ts->pd_irq, wm831x_ts); | ||
374 | err_data_irq: | ||
375 | free_irq(wm831x_ts->data_irq, wm831x_ts); | ||
376 | err_alloc: | ||
377 | input_free_device(input_dev); | ||
378 | kfree(wm831x_ts); | ||
379 | |||
380 | return error; | ||
381 | } | ||
382 | |||
383 | static __devexit int wm831x_ts_remove(struct platform_device *pdev) | ||
384 | { | ||
385 | struct wm831x_ts *wm831x_ts = platform_get_drvdata(pdev); | ||
386 | |||
387 | free_irq(wm831x_ts->pd_irq, wm831x_ts); | ||
388 | free_irq(wm831x_ts->data_irq, wm831x_ts); | ||
389 | input_unregister_device(wm831x_ts->input_dev); | ||
390 | kfree(wm831x_ts); | ||
391 | |||
392 | platform_set_drvdata(pdev, NULL); | ||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | static struct platform_driver wm831x_ts_driver = { | ||
397 | .driver = { | ||
398 | .name = "wm831x-touch", | ||
399 | .owner = THIS_MODULE, | ||
400 | }, | ||
401 | .probe = wm831x_ts_probe, | ||
402 | .remove = __devexit_p(wm831x_ts_remove), | ||
403 | }; | ||
404 | |||
405 | static int __init wm831x_ts_init(void) | ||
406 | { | ||
407 | return platform_driver_register(&wm831x_ts_driver); | ||
408 | } | ||
409 | module_init(wm831x_ts_init); | ||
410 | |||
411 | static void __exit wm831x_ts_exit(void) | ||
412 | { | ||
413 | platform_driver_unregister(&wm831x_ts_driver); | ||
414 | } | ||
415 | module_exit(wm831x_ts_exit); | ||
416 | |||
417 | /* Module information */ | ||
418 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
419 | MODULE_DESCRIPTION("WM831x PMIC touchscreen driver"); | ||
420 | MODULE_LICENSE("GPL"); | ||
421 | MODULE_ALIAS("platform:wm831x-touch"); | ||
diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c index 6b5be742c27d..98e61175d3f5 100644 --- a/drivers/input/touchscreen/wm9705.c +++ b/drivers/input/touchscreen/wm9705.c | |||
@@ -306,7 +306,7 @@ static int wm9705_acc_enable(struct wm97xx *wm, int enable) | |||
306 | dig2 = wm->dig[2]; | 306 | dig2 = wm->dig[2]; |
307 | 307 | ||
308 | if (enable) { | 308 | if (enable) { |
309 | /* continous mode */ | 309 | /* continuous mode */ |
310 | if (wm->mach_ops->acc_startup && | 310 | if (wm->mach_ops->acc_startup && |
311 | (ret = wm->mach_ops->acc_startup(wm)) < 0) | 311 | (ret = wm->mach_ops->acc_startup(wm)) < 0) |
312 | return ret; | 312 | return ret; |
diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c index 7490b05c3566..2bc2fb801009 100644 --- a/drivers/input/touchscreen/wm9712.c +++ b/drivers/input/touchscreen/wm9712.c | |||
@@ -419,7 +419,7 @@ static int wm9712_acc_enable(struct wm97xx *wm, int enable) | |||
419 | dig2 = wm->dig[2]; | 419 | dig2 = wm->dig[2]; |
420 | 420 | ||
421 | if (enable) { | 421 | if (enable) { |
422 | /* continous mode */ | 422 | /* continuous mode */ |
423 | if (wm->mach_ops->acc_startup) { | 423 | if (wm->mach_ops->acc_startup) { |
424 | ret = wm->mach_ops->acc_startup(wm); | 424 | ret = wm->mach_ops->acc_startup(wm); |
425 | if (ret < 0) | 425 | if (ret < 0) |
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c index 238b5132712e..73ec99568f12 100644 --- a/drivers/input/touchscreen/wm9713.c +++ b/drivers/input/touchscreen/wm9713.c | |||
@@ -431,7 +431,7 @@ static int wm9713_acc_enable(struct wm97xx *wm, int enable) | |||
431 | dig3 = wm->dig[2]; | 431 | dig3 = wm->dig[2]; |
432 | 432 | ||
433 | if (enable) { | 433 | if (enable) { |
434 | /* continous mode */ | 434 | /* continuous mode */ |
435 | if (wm->mach_ops->acc_startup && | 435 | if (wm->mach_ops->acc_startup && |
436 | (ret = wm->mach_ops->acc_startup(wm)) < 0) | 436 | (ret = wm->mach_ops->acc_startup(wm)) < 0) |
437 | return ret; | 437 | return ret; |
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index cbfef1ea7e30..5dbe73af2f8f 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c | |||
@@ -125,6 +125,8 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
125 | { | 125 | { |
126 | int power_adc = 0, auxval; | 126 | int power_adc = 0, auxval; |
127 | u16 power = 0; | 127 | u16 power = 0; |
128 | int rc = 0; | ||
129 | int timeout = 0; | ||
128 | 130 | ||
129 | /* get codec */ | 131 | /* get codec */ |
130 | mutex_lock(&wm->codec_mutex); | 132 | mutex_lock(&wm->codec_mutex); |
@@ -143,7 +145,9 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
143 | 145 | ||
144 | /* Turn polling mode on to read AUX ADC */ | 146 | /* Turn polling mode on to read AUX ADC */ |
145 | wm->pen_probably_down = 1; | 147 | wm->pen_probably_down = 1; |
146 | wm->codec->poll_sample(wm, adcsel, &auxval); | 148 | |
149 | while (rc != RC_VALID && timeout++ < 5) | ||
150 | rc = wm->codec->poll_sample(wm, adcsel, &auxval); | ||
147 | 151 | ||
148 | if (power_adc) | 152 | if (power_adc) |
149 | wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); | 153 | wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000); |
@@ -152,8 +156,15 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel) | |||
152 | 156 | ||
153 | wm->pen_probably_down = 0; | 157 | wm->pen_probably_down = 0; |
154 | 158 | ||
159 | if (timeout >= 5) { | ||
160 | dev_err(wm->dev, | ||
161 | "timeout reading auxadc %d, disabling digitiser\n", | ||
162 | adcsel); | ||
163 | wm->codec->dig_enable(wm, false); | ||
164 | } | ||
165 | |||
155 | mutex_unlock(&wm->codec_mutex); | 166 | mutex_unlock(&wm->codec_mutex); |
156 | return auxval & 0xfff; | 167 | return (rc == RC_VALID ? auxval & 0xfff : -EBUSY); |
157 | } | 168 | } |
158 | EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); | 169 | EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc); |
159 | 170 | ||
@@ -324,7 +335,7 @@ static void wm97xx_pen_irq_worker(struct work_struct *work) | |||
324 | */ | 335 | */ |
325 | if (!wm->mach_ops->acc_enabled || wm->mach_ops->acc_pen_down) { | 336 | if (!wm->mach_ops->acc_enabled || wm->mach_ops->acc_pen_down) { |
326 | if (wm->pen_is_down && !pen_was_down) { | 337 | if (wm->pen_is_down && !pen_was_down) { |
327 | /* Data is not availiable immediately on pen down */ | 338 | /* Data is not available immediately on pen down */ |
328 | queue_delayed_work(wm->ts_workq, &wm->ts_reader, 1); | 339 | queue_delayed_work(wm->ts_workq, &wm->ts_reader, 1); |
329 | } | 340 | } |
330 | 341 | ||
@@ -343,7 +354,7 @@ static void wm97xx_pen_irq_worker(struct work_struct *work) | |||
343 | * Codec PENDOWN irq handler | 354 | * Codec PENDOWN irq handler |
344 | * | 355 | * |
345 | * We have to disable the codec interrupt in the handler because it | 356 | * We have to disable the codec interrupt in the handler because it |
346 | * can take upto 1ms to clear the interrupt source. We schedule a task | 357 | * can take up to 1ms to clear the interrupt source. We schedule a task |
347 | * in a work queue to do the actual interaction with the chip. The | 358 | * in a work queue to do the actual interaction with the chip. The |
348 | * interrupt is then enabled again in the slow handler when the source | 359 | * interrupt is then enabled again in the slow handler when the source |
349 | * has been cleared. | 360 | * has been cleared. |
@@ -684,8 +695,7 @@ static int wm97xx_probe(struct device *dev) | |||
684 | touch_reg_err: | 695 | touch_reg_err: |
685 | platform_device_put(wm->touch_dev); | 696 | platform_device_put(wm->touch_dev); |
686 | touch_err: | 697 | touch_err: |
687 | platform_device_unregister(wm->battery_dev); | 698 | platform_device_del(wm->battery_dev); |
688 | wm->battery_dev = NULL; | ||
689 | batt_reg_err: | 699 | batt_reg_err: |
690 | platform_device_put(wm->battery_dev); | 700 | platform_device_put(wm->battery_dev); |
691 | batt_err: | 701 | batt_err: |
diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c index 048849867643..5b0f15ec874a 100644 --- a/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/drivers/input/touchscreen/zylonite-wm97xx.c | |||
@@ -193,7 +193,7 @@ static int zylonite_wm97xx_probe(struct platform_device *pdev) | |||
193 | gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26); | 193 | gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26); |
194 | 194 | ||
195 | wm->pen_irq = IRQ_GPIO(gpio_touch_irq); | 195 | wm->pen_irq = IRQ_GPIO(gpio_touch_irq); |
196 | set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH); | 196 | irq_set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH); |
197 | 197 | ||
198 | wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, | 198 | wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, |
199 | WM97XX_GPIO_POL_HIGH, | 199 | WM97XX_GPIO_POL_HIGH, |