aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/input/multi-touch-protocol.txt218
-rw-r--r--arch/arm/Kconfig13
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig15
-rw-r--r--arch/arm/mach-s3c64xx/Makefile2
-rw-r--r--arch/arm/mach-s3c64xx/clock.c24
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c2
-rw-r--r--arch/arm/mach-s3c64xx/dev-spi.c2
-rw-r--r--arch/arm/mach-s3c64xx/gpiolib.c2
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/map.h6
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-clock.h5
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c33
-rw-r--r--arch/arm/mach-s3c64xx/s3c6410.c6
-rw-r--r--arch/arm/mach-s3c64xx/setup-fb-24bpp.c2
-rw-r--r--arch/arm/mach-s3c64xx/setup-i2c0.c2
-rw-r--r--arch/arm/mach-s3c64xx/setup-i2c1.c2
-rw-r--r--arch/arm/mach-s3c64xx/setup-ide.c46
-rw-r--r--arch/arm/mach-s3c64xx/setup-keypad.c34
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci-gpio.c17
-rw-r--r--arch/arm/mach-s5p6440/Kconfig8
-rw-r--r--arch/arm/mach-s5p6440/cpu.c3
-rw-r--r--arch/arm/mach-s5p6440/dev-audio.c2
-rw-r--r--arch/arm/mach-s5p6440/dev-spi.c2
-rw-r--r--arch/arm/mach-s5p6440/gpio.c4
-rw-r--r--arch/arm/mach-s5p6442/Kconfig1
-rw-r--r--arch/arm/mach-s5p6442/dev-audio.c2
-rw-r--r--arch/arm/mach-s5p6442/dev-spi.c2
-rw-r--r--arch/arm/mach-s5pc100/Kconfig12
-rw-r--r--arch/arm/mach-s5pc100/dev-audio.c2
-rw-r--r--arch/arm/mach-s5pc100/dev-spi.c2
-rw-r--r--arch/arm/mach-s5pc100/include/mach/map.h8
-rw-r--r--arch/arm/mach-s5pc100/setup-sdhci-gpio.c22
-rw-r--r--arch/arm/mach-s5pv210/Kconfig34
-rw-r--r--arch/arm/mach-s5pv210/cpu.c11
-rw-r--r--arch/arm/mach-s5pv210/dev-audio.c2
-rw-r--r--arch/arm/mach-s5pv210/dev-spi.c2
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h7
-rw-r--r--arch/arm/mach-s5pv210/setup-fb-24bpp.c2
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c0.c2
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c1.c2
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c2.c2
-rw-r--r--arch/arm/mach-s5pv210/setup-sdhci-gpio.c24
-rw-r--r--arch/arm/plat-s5p/Makefile5
-rw-r--r--arch/arm/plat-s5p/dev-fimc0.c36
-rw-r--r--arch/arm/plat-s5p/dev-fimc1.c36
-rw-r--r--arch/arm/plat-s5p/dev-fimc2.c36
-rw-r--r--arch/arm/plat-samsung/Kconfig15
-rw-r--r--arch/arm/plat-samsung/Makefile5
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c5
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c5
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c5
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c77
-rw-r--r--arch/arm/plat-samsung/dev-ide.c44
-rw-r--r--arch/arm/plat-samsung/dev-keypad.c50
-rw-r--r--arch/arm/plat-samsung/dev-wdt.c2
-rw-r--r--arch/arm/plat-samsung/gpiolib.c2
-rw-r--r--arch/arm/plat-samsung/include/plat/adc-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/ata-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/ata.h36
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h20
-rw-r--r--arch/arm/plat-samsung/include/plat/fimc-core.h44
-rw-r--r--arch/arm/plat-samsung/include/plat/keypad.h56
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-ata.h56
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-rtc.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h122
-rw-r--r--arch/arm/plat-samsung/platformdata.c37
-rw-r--r--drivers/char/keyboard.c6
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-input.c3
-rw-r--r--drivers/i2c/busses/Kconfig11
-rw-r--r--drivers/input/evdev.c54
-rw-r--r--drivers/input/input.c182
-rw-r--r--drivers/input/joydev.c7
-rw-r--r--drivers/input/joystick/xpad.c108
-rw-r--r--drivers/input/keyboard/Kconfig21
-rw-r--r--drivers/input/keyboard/Makefile2
-rw-r--r--drivers/input/keyboard/adp5588-keys.c351
-rw-r--r--drivers/input/keyboard/gpio_keys.c19
-rw-r--r--drivers/input/keyboard/lm8323.c12
-rw-r--r--drivers/input/keyboard/matrix_keypad.c108
-rw-r--r--drivers/input/keyboard/mcs_touchkey.c239
-rw-r--r--drivers/input/keyboard/samsung-keypad.c491
-rw-r--r--drivers/input/misc/Kconfig48
-rw-r--r--drivers/input/misc/Makefile4
-rw-r--r--drivers/input/misc/adxl34x-i2c.c163
-rw-r--r--drivers/input/misc/adxl34x-spi.c145
-rw-r--r--drivers/input/misc/adxl34x.c915
-rw-r--r--drivers/input/misc/adxl34x.h30
-rw-r--r--drivers/input/misc/atlas_btns.c38
-rw-r--r--drivers/input/misc/pwm-beeper.c199
-rw-r--r--drivers/input/misc/twl4030-pwrbutton.c12
-rw-r--r--drivers/input/misc/wistron_btns.c4
-rw-r--r--drivers/input/mouse/bcm5974.c23
-rw-r--r--drivers/input/mouse/synaptics.c8
-rw-r--r--drivers/input/mousedev.c15
-rw-r--r--drivers/input/serio/i8042-ppcio.h75
-rw-r--r--drivers/input/serio/i8042.c65
-rw-r--r--drivers/input/tablet/wacom_wac.c44
-rw-r--r--drivers/input/tablet/wacom_wac.h1
-rw-r--r--drivers/input/touchscreen/Kconfig67
-rw-r--r--drivers/input/touchscreen/Makefile6
-rw-r--r--drivers/input/touchscreen/ad7879-i2c.c143
-rw-r--r--drivers/input/touchscreen/ad7879-spi.c198
-rw-r--r--drivers/input/touchscreen/ad7879.c625
-rw-r--r--drivers/input/touchscreen/ad7879.h30
-rw-r--r--drivers/input/touchscreen/ads7846.c206
-rw-r--r--drivers/input/touchscreen/cy8ctmg110_ts.c363
-rw-r--r--drivers/input/touchscreen/mcs5000_ts.c6
-rw-r--r--drivers/input/touchscreen/qt602240_ts.c1401
-rw-r--r--drivers/input/touchscreen/tps6507x-ts.c3
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c215
-rw-r--r--drivers/rtc/Kconfig9
-rw-r--r--drivers/rtc/rtc-s3c.c44
-rw-r--r--include/linux/i2c/adp5588.h37
-rw-r--r--include/linux/i2c/mcs.h34
-rw-r--r--include/linux/i2c/mcs5000_ts.h24
-rw-r--r--include/linux/i2c/qt602240_ts.h38
-rw-r--r--include/linux/input.h60
-rw-r--r--include/linux/input/adxl34x.h349
-rw-r--r--include/linux/input/cy8ctmg110_pdata.h10
-rw-r--r--include/linux/input/matrix_keypad.h6
-rw-r--r--include/linux/spi/ads7846.h3
122 files changed, 7492 insertions, 1132 deletions
diff --git a/Documentation/input/multi-touch-protocol.txt b/Documentation/input/multi-touch-protocol.txt
index c0fc1c75fd8..bdcba154b83 100644
--- a/Documentation/input/multi-touch-protocol.txt
+++ b/Documentation/input/multi-touch-protocol.txt
@@ -6,31 +6,149 @@ Multi-touch (MT) Protocol
6Introduction 6Introduction
7------------ 7------------
8 8
9In order to utilize the full power of the new multi-touch devices, a way to 9In order to utilize the full power of the new multi-touch and multi-user
10report detailed finger data to user space is needed. This document 10devices, a way to report detailed data from multiple contacts, i.e.,
11describes the multi-touch (MT) protocol which allows kernel drivers to 11objects in direct contact with the device surface, is needed. This
12report details for an arbitrary number of fingers. 12document describes the multi-touch (MT) protocol which allows kernel
13drivers to report details for an arbitrary number of contacts.
14
15The protocol is divided into two types, depending on the capabilities of the
16hardware. For devices handling anonymous contacts (type A), the protocol
17describes how to send the raw data for all contacts to the receiver. For
18devices capable of tracking identifiable contacts (type B), the protocol
19describes how to send updates for individual contacts via event slots.
20
21
22Protocol Usage
23--------------
24
25Contact details are sent sequentially as separate packets of ABS_MT
26events. Only the ABS_MT events are recognized as part of a contact
27packet. Since these events are ignored by current single-touch (ST)
28applications, the MT protocol can be implemented on top of the ST protocol
29in an existing driver.
30
31Drivers for type A devices separate contact packets by calling
32input_mt_sync() at the end of each packet. This generates a SYN_MT_REPORT
33event, which instructs the receiver to accept the data for the current
34contact and prepare to receive another.
35
36Drivers for type B devices separate contact packets by calling
37input_mt_slot(), with a slot as argument, at the beginning of each packet.
38This generates an ABS_MT_SLOT event, which instructs the receiver to
39prepare for updates of the given slot.
40
41All drivers mark the end of a multi-touch transfer by calling the usual
42input_sync() function. This instructs the receiver to act upon events
43accumulated since last EV_SYN/SYN_REPORT and prepare to receive a new set
44of events/packets.
45
46The main difference between the stateless type A protocol and the stateful
47type B slot protocol lies in the usage of identifiable contacts to reduce
48the amount of data sent to userspace. The slot protocol requires the use of
49the ABS_MT_TRACKING_ID, either provided by the hardware or computed from
50the raw data [5].
51
52For type A devices, the kernel driver should generate an arbitrary
53enumeration of the full set of anonymous contacts currently on the
54surface. The order in which the packets appear in the event stream is not
55important. Event filtering and finger tracking is left to user space [3].
56
57For type B devices, the kernel driver should associate a slot with each
58identified contact, and use that slot to propagate changes for the contact.
59Creation, replacement and destruction of contacts is achieved by modifying
60the ABS_MT_TRACKING_ID of the associated slot. A non-negative tracking id
61is interpreted as a contact, and the value -1 denotes an unused slot. A
62tracking id not previously present is considered new, and a tracking id no
63longer present is considered removed. Since only changes are propagated,
64the full state of each initiated contact has to reside in the receiving
65end. Upon receiving an MT event, one simply updates the appropriate
66attribute of the current slot.
67
68
69Protocol Example A
70------------------
71
72Here is what a minimal event sequence for a two-contact touch would look
73like for a type A device:
74
75 ABS_MT_POSITION_X x[0]
76 ABS_MT_POSITION_Y y[0]
77 SYN_MT_REPORT
78 ABS_MT_POSITION_X x[1]
79 ABS_MT_POSITION_Y y[1]
80 SYN_MT_REPORT
81 SYN_REPORT
13 82
83The sequence after moving one of the contacts looks exactly the same; the
84raw data for all present contacts are sent between every synchronization
85with SYN_REPORT.
14 86
15Usage 87Here is the sequence after lifting the first contact:
16----- 88
89 ABS_MT_POSITION_X x[1]
90 ABS_MT_POSITION_Y y[1]
91 SYN_MT_REPORT
92 SYN_REPORT
93
94And here is the sequence after lifting the second contact:
95
96 SYN_MT_REPORT
97 SYN_REPORT
98
99If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
100ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
101last SYN_REPORT will be dropped by the input core, resulting in no
102zero-contact event reaching userland.
17 103
18Anonymous finger details are sent sequentially as separate packets of ABS 104
19events. Only the ABS_MT events are recognized as part of a finger 105Protocol Example B
20packet. The end of a packet is marked by calling the input_mt_sync() 106------------------
21function, which generates a SYN_MT_REPORT event. This instructs the 107
22receiver to accept the data for the current finger and prepare to receive 108Here is what a minimal event sequence for a two-contact touch would look
23another. The end of a multi-touch transfer is marked by calling the usual 109like for a type B device:
24input_sync() function. This instructs the receiver to act upon events 110
25accumulated since last EV_SYN/SYN_REPORT and prepare to receive a new 111 ABS_MT_SLOT 0
26set of events/packets. 112 ABS_MT_TRACKING_ID 45
113 ABS_MT_POSITION_X x[0]
114 ABS_MT_POSITION_Y y[0]
115 ABS_MT_SLOT 1
116 ABS_MT_TRACKING_ID 46
117 ABS_MT_POSITION_X x[1]
118 ABS_MT_POSITION_Y y[1]
119 SYN_REPORT
120
121Here is the sequence after moving contact 45 in the x direction:
122
123 ABS_MT_SLOT 0
124 ABS_MT_POSITION_X x[0]
125 SYN_REPORT
126
127Here is the sequence after lifting the contact in slot 0:
128
129 ABS_MT_TRACKING_ID -1
130 SYN_REPORT
131
132The slot being modified is already 0, so the ABS_MT_SLOT is omitted. The
133message removes the association of slot 0 with contact 45, thereby
134destroying contact 45 and freeing slot 0 to be reused for another contact.
135
136Finally, here is the sequence after lifting the second contact:
137
138 ABS_MT_SLOT 1
139 ABS_MT_TRACKING_ID -1
140 SYN_REPORT
141
142
143Event Usage
144-----------
27 145
28A set of ABS_MT events with the desired properties is defined. The events 146A set of ABS_MT events with the desired properties is defined. The events
29are divided into categories, to allow for partial implementation. The 147are divided into categories, to allow for partial implementation. The
30minimum set consists of ABS_MT_POSITION_X and ABS_MT_POSITION_Y, which 148minimum set consists of ABS_MT_POSITION_X and ABS_MT_POSITION_Y, which
31allows for multiple fingers to be tracked. If the device supports it, the 149allows for multiple contacts to be tracked. If the device supports it, the
32ABS_MT_TOUCH_MAJOR and ABS_MT_WIDTH_MAJOR may be used to provide the size 150ABS_MT_TOUCH_MAJOR and ABS_MT_WIDTH_MAJOR may be used to provide the size
33of the contact area and approaching finger, respectively. 151of the contact area and approaching contact, respectively.
34 152
35The TOUCH and WIDTH parameters have a geometrical interpretation; imagine 153The TOUCH and WIDTH parameters have a geometrical interpretation; imagine
36looking through a window at someone gently holding a finger against the 154looking through a window at someone gently holding a finger against the
@@ -41,56 +159,26 @@ ABS_MT_TOUCH_MAJOR, the diameter of the outer region is
41ABS_MT_WIDTH_MAJOR. Now imagine the person pressing the finger harder 159ABS_MT_WIDTH_MAJOR. Now imagine the person pressing the finger harder
42against the glass. The inner region will increase, and in general, the 160against the glass. The inner region will increase, and in general, the
43ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR, which is always smaller than 161ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR, which is always smaller than
44unity, is related to the finger pressure. For pressure-based devices, 162unity, is related to the contact pressure. For pressure-based devices,
45ABS_MT_PRESSURE may be used to provide the pressure on the contact area 163ABS_MT_PRESSURE may be used to provide the pressure on the contact area
46instead. 164instead.
47 165
48In addition to the MAJOR parameters, the oval shape of the finger can be 166In addition to the MAJOR parameters, the oval shape of the contact can be
49described by adding the MINOR parameters, such that MAJOR and MINOR are the 167described by adding the MINOR parameters, such that MAJOR and MINOR are the
50major and minor axis of an ellipse. Finally, the orientation of the oval 168major and minor axis of an ellipse. Finally, the orientation of the oval
51shape can be describe with the ORIENTATION parameter. 169shape can be describe with the ORIENTATION parameter.
52 170
53The ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a 171The ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a
54finger or a pen or something else. Devices with more granular information 172contact or a pen or something else. Devices with more granular information
55may specify general shapes as blobs, i.e., as a sequence of rectangular 173may specify general shapes as blobs, i.e., as a sequence of rectangular
56shapes grouped together by an ABS_MT_BLOB_ID. Finally, for the few devices 174shapes grouped together by an ABS_MT_BLOB_ID. Finally, for the few devices
57that currently support it, the ABS_MT_TRACKING_ID event may be used to 175that currently support it, the ABS_MT_TRACKING_ID event may be used to
58report finger tracking from hardware [5]. 176report contact tracking from hardware [5].
59 177
60Here is what a minimal event sequence for a two-finger touch would look
61like:
62
63 ABS_MT_POSITION_X
64 ABS_MT_POSITION_Y
65 SYN_MT_REPORT
66 ABS_MT_POSITION_X
67 ABS_MT_POSITION_Y
68 SYN_MT_REPORT
69 SYN_REPORT
70
71Here is the sequence after lifting one of the fingers:
72
73 ABS_MT_POSITION_X
74 ABS_MT_POSITION_Y
75 SYN_MT_REPORT
76 SYN_REPORT
77
78And here is the sequence after lifting the remaining finger:
79
80 SYN_MT_REPORT
81 SYN_REPORT
82
83If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
84ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
85last SYN_REPORT will be dropped by the input core, resulting in no
86zero-finger event reaching userland.
87 178
88Event Semantics 179Event Semantics
89--------------- 180---------------
90 181
91The word "contact" is used to describe a tool which is in direct contact
92with the surface. A finger, a pen or a rubber all classify as contacts.
93
94ABS_MT_TOUCH_MAJOR 182ABS_MT_TOUCH_MAJOR
95 183
96The length of the major axis of the contact. The length should be given in 184The length of the major axis of the contact. The length should be given in
@@ -157,15 +245,16 @@ MT_TOOL_PEN [2].
157ABS_MT_BLOB_ID 245ABS_MT_BLOB_ID
158 246
159The BLOB_ID groups several packets together into one arbitrarily shaped 247The BLOB_ID groups several packets together into one arbitrarily shaped
160contact. This is a low-level anonymous grouping, and should not be confused 248contact. This is a low-level anonymous grouping for type A devices, and
161with the high-level trackingID [5]. Most kernel drivers will not have blob 249should not be confused with the high-level trackingID [5]. Most type A
162capability, and can safely omit the event. 250devices do not have blob capability, so drivers can safely omit this event.
163 251
164ABS_MT_TRACKING_ID 252ABS_MT_TRACKING_ID
165 253
166The TRACKING_ID identifies an initiated contact throughout its life cycle 254The TRACKING_ID identifies an initiated contact throughout its life cycle
167[5]. There are currently only a few devices that support it, so this event 255[5]. This event is mandatory for type B devices. The value range of the
168should normally be omitted. 256TRACKING_ID should be large enough to ensure unique identification of a
257contact maintained over an extended period of time.
169 258
170 259
171Event Computation 260Event Computation
@@ -192,20 +281,11 @@ finger along the X axis (1).
192Finger Tracking 281Finger Tracking
193--------------- 282---------------
194 283
195The kernel driver should generate an arbitrary enumeration of the set of
196anonymous contacts currently on the surface. The order in which the packets
197appear in the event stream is not important.
198
199The process of finger tracking, i.e., to assign a unique trackingID to each 284The process of finger tracking, i.e., to assign a unique trackingID to each
200initiated contact on the surface, is left to user space; preferably the 285initiated contact on the surface, is a Euclidian Bipartite Matching
201multi-touch X driver [3]. In that driver, the trackingID stays the same and 286problem. At each event synchronization, the set of actual contacts is
202unique until the contact vanishes (when the finger leaves the surface). The 287matched to the set of contacts from the previous synchronization. A full
203problem of assigning a set of anonymous fingers to a set of identified 288implementation can be found in [3].
204fingers is a euclidian bipartite matching problem at each event update, and
205relies on a sufficiently rapid update rate.
206
207There are a few devices that support trackingID in hardware. User space can
208make use of these native identifiers to reduce bandwidth and cpu usage.
209 289
210 290
211Gestures 291Gestures
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3e68a93ce71..c797a8b4d8c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -634,6 +634,7 @@ config ARCH_S3C2410
634 select ARCH_HAS_CPUFREQ 634 select ARCH_HAS_CPUFREQ
635 select HAVE_CLK 635 select HAVE_CLK
636 select ARCH_USES_GETTIMEOFFSET 636 select ARCH_USES_GETTIMEOFFSET
637 select HAVE_S3C2410_I2C
637 help 638 help
638 Samsung S3C2410X CPU based systems, such as the Simtec Electronics 639 Samsung S3C2410X CPU based systems, such as the Simtec Electronics
639 BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or 640 BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
@@ -663,6 +664,8 @@ config ARCH_S3C64XX
663 select S3C_DEV_NAND 664 select S3C_DEV_NAND
664 select USB_ARCH_HAS_OHCI 665 select USB_ARCH_HAS_OHCI
665 select SAMSUNG_GPIOLIB_4BIT 666 select SAMSUNG_GPIOLIB_4BIT
667 select HAVE_S3C2410_I2C
668 select HAVE_S3C2410_WATCHDOG
666 help 669 help
667 Samsung S3C64XX series based systems 670 Samsung S3C64XX series based systems
668 671
@@ -671,7 +674,10 @@ config ARCH_S5P6440
671 select CPU_V6 674 select CPU_V6
672 select GENERIC_GPIO 675 select GENERIC_GPIO
673 select HAVE_CLK 676 select HAVE_CLK
677 select HAVE_S3C2410_WATCHDOG
674 select ARCH_USES_GETTIMEOFFSET 678 select ARCH_USES_GETTIMEOFFSET
679 select HAVE_S3C2410_I2C
680 select HAVE_S3C_RTC
675 help 681 help
676 Samsung S5P6440 CPU based systems 682 Samsung S5P6440 CPU based systems
677 683
@@ -681,6 +687,7 @@ config ARCH_S5P6442
681 select GENERIC_GPIO 687 select GENERIC_GPIO
682 select HAVE_CLK 688 select HAVE_CLK
683 select ARCH_USES_GETTIMEOFFSET 689 select ARCH_USES_GETTIMEOFFSET
690 select HAVE_S3C2410_WATCHDOG
684 help 691 help
685 Samsung S5P6442 CPU based systems 692 Samsung S5P6442 CPU based systems
686 693
@@ -691,6 +698,9 @@ config ARCH_S5PC100
691 select CPU_V7 698 select CPU_V7
692 select ARM_L1_CACHE_SHIFT_6 699 select ARM_L1_CACHE_SHIFT_6
693 select ARCH_USES_GETTIMEOFFSET 700 select ARCH_USES_GETTIMEOFFSET
701 select HAVE_S3C2410_I2C
702 select HAVE_S3C_RTC
703 select HAVE_S3C2410_WATCHDOG
694 help 704 help
695 Samsung S5PC100 series based systems 705 Samsung S5PC100 series based systems
696 706
@@ -701,6 +711,9 @@ config ARCH_S5PV210
701 select HAVE_CLK 711 select HAVE_CLK
702 select ARM_L1_CACHE_SHIFT_6 712 select ARM_L1_CACHE_SHIFT_6
703 select ARCH_USES_GETTIMEOFFSET 713 select ARCH_USES_GETTIMEOFFSET
714 select HAVE_S3C2410_I2C
715 select HAVE_S3C_RTC
716 select HAVE_S3C2410_WATCHDOG
704 help 717 help
705 Samsung S5PV210/S5PC110 series based systems 718 Samsung S5PV210/S5PC110 series based systems
706 719
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index f5a59727949..071e8a1e076 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -57,11 +57,21 @@ config S3C64XX_SETUP_I2C1
57 help 57 help
58 Common setup code for i2c bus 1. 58 Common setup code for i2c bus 1.
59 59
60config S3C64XX_SETUP_IDE
61 bool
62 help
63 Common setup code for S3C64XX IDE.
64
60config S3C64XX_SETUP_FB_24BPP 65config S3C64XX_SETUP_FB_24BPP
61 bool 66 bool
62 help 67 help
63 Common setup code for S3C64XX with an 24bpp RGB display helper. 68 Common setup code for S3C64XX with an 24bpp RGB display helper.
64 69
70config S3C64XX_SETUP_KEYPAD
71 bool
72 help
73 Common setup code for S3C64XX KEYPAD GPIO configurations
74
65config S3C64XX_SETUP_SDHCI_GPIO 75config S3C64XX_SETUP_SDHCI_GPIO
66 bool 76 bool
67 help 77 help
@@ -95,15 +105,20 @@ config MACH_SMDK6410
95 select S3C_DEV_HSMMC 105 select S3C_DEV_HSMMC
96 select S3C_DEV_HSMMC1 106 select S3C_DEV_HSMMC1
97 select S3C_DEV_I2C1 107 select S3C_DEV_I2C1
108 select SAMSUNG_DEV_IDE
98 select S3C_DEV_FB 109 select S3C_DEV_FB
110 select S3C_DEV_RTC
99 select SAMSUNG_DEV_TS 111 select SAMSUNG_DEV_TS
100 select S3C_DEV_USB_HOST 112 select S3C_DEV_USB_HOST
101 select S3C_DEV_USB_HSOTG 113 select S3C_DEV_USB_HSOTG
102 select S3C_DEV_WDT 114 select S3C_DEV_WDT
115 select SAMSUNG_DEV_KEYPAD
103 select HAVE_S3C2410_WATCHDOG 116 select HAVE_S3C2410_WATCHDOG
104 select S3C64XX_SETUP_SDHCI 117 select S3C64XX_SETUP_SDHCI
105 select S3C64XX_SETUP_I2C1 118 select S3C64XX_SETUP_I2C1
119 select S3C64XX_SETUP_IDE
106 select S3C64XX_SETUP_FB_24BPP 120 select S3C64XX_SETUP_FB_24BPP
121 select S3C64XX_SETUP_KEYPAD
107 help 122 help
108 Machine support for the Samsung SMDK6410 123 Machine support for the Samsung SMDK6410
109 124
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index 9d1006938f5..48d3dfac8dd 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -35,6 +35,8 @@ obj-$(CONFIG_S3C64XX_DMA) += dma.o
35 35
36obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o 36obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
37obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o 37obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
38obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o
39obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o
38obj-$(CONFIG_S3C64XX_SETUP_SDHCI) += setup-sdhci.o 40obj-$(CONFIG_S3C64XX_SETUP_SDHCI) += setup-sdhci.o
39obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o 41obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
40obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 42obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index fbd85a9b7bb..7e03f0ae2fc 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -133,6 +133,12 @@ static struct clk init_clocks_disable[] = {
133 .id = -1, 133 .id = -1,
134 .parent = &clk_h, 134 .parent = &clk_h,
135 }, { 135 }, {
136 .name = "rtc",
137 .id = -1,
138 .parent = &clk_p,
139 .enable = s3c64xx_pclk_ctrl,
140 .ctrlbit = S3C_CLKCON_PCLK_RTC,
141 }, {
136 .name = "adc", 142 .name = "adc",
137 .id = -1, 143 .id = -1,
138 .parent = &clk_p, 144 .parent = &clk_p,
@@ -165,6 +171,12 @@ static struct clk init_clocks_disable[] = {
165 .ctrlbit = S3C6410_CLKCON_PCLK_IIS2, 171 .ctrlbit = S3C6410_CLKCON_PCLK_IIS2,
166 }, { 172 }, {
167#endif 173#endif
174 .name = "keypad",
175 .id = -1,
176 .parent = &clk_p,
177 .enable = s3c64xx_pclk_ctrl,
178 .ctrlbit = S3C_CLKCON_PCLK_KEYPAD,
179 }, {
168 .name = "spi", 180 .name = "spi",
169 .id = 0, 181 .id = 0,
170 .parent = &clk_p, 182 .parent = &clk_p,
@@ -295,12 +307,6 @@ static struct clk init_clocks[] = {
295 .enable = s3c64xx_pclk_ctrl, 307 .enable = s3c64xx_pclk_ctrl,
296 .ctrlbit = S3C_CLKCON_PCLK_UART3, 308 .ctrlbit = S3C_CLKCON_PCLK_UART3,
297 }, { 309 }, {
298 .name = "rtc",
299 .id = -1,
300 .parent = &clk_p,
301 .enable = s3c64xx_pclk_ctrl,
302 .ctrlbit = S3C_CLKCON_PCLK_RTC,
303 }, {
304 .name = "watchdog", 310 .name = "watchdog",
305 .id = -1, 311 .id = -1,
306 .parent = &clk_p, 312 .parent = &clk_p,
@@ -310,6 +316,12 @@ static struct clk init_clocks[] = {
310 .id = -1, 316 .id = -1,
311 .parent = &clk_p, 317 .parent = &clk_p,
312 .ctrlbit = S3C_CLKCON_PCLK_AC97, 318 .ctrlbit = S3C_CLKCON_PCLK_AC97,
319 }, {
320 .name = "cfcon",
321 .id = -1,
322 .parent = &clk_h,
323 .enable = s3c64xx_hclk_ctrl,
324 .ctrlbit = S3C_CLKCON_HCLK_IHOST,
313 } 325 }
314}; 326};
315 327
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
index c3e9e73bd0f..9648fbc36ee 100644
--- a/arch/arm/mach-s3c64xx/dev-audio.c
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -12,11 +12,11 @@
12#include <linux/string.h> 12#include <linux/string.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
15#include <linux/gpio.h>
15 16
16#include <mach/irqs.h> 17#include <mach/irqs.h>
17#include <mach/map.h> 18#include <mach/map.h>
18#include <mach/dma.h> 19#include <mach/dma.h>
19#include <mach/gpio.h>
20 20
21#include <plat/devs.h> 21#include <plat/devs.h>
22#include <plat/audio.h> 22#include <plat/audio.h>
diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c
index 29c32d08851..a492b982aa0 100644
--- a/arch/arm/mach-s3c64xx/dev-spi.c
+++ b/arch/arm/mach-s3c64xx/dev-spi.c
@@ -12,10 +12,10 @@
12#include <linux/string.h> 12#include <linux/string.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
15#include <linux/gpio.h>
15 16
16#include <mach/dma.h> 17#include <mach/dma.h>
17#include <mach/map.h> 18#include <mach/map.h>
18#include <mach/gpio.h>
19#include <mach/gpio-bank-c.h> 19#include <mach/gpio-bank-c.h>
20#include <mach/spi-clocks.h> 20#include <mach/spi-clocks.h>
21 21
diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c
index 60c929a3cab..300dee4a667 100644
--- a/arch/arm/mach-s3c64xx/gpiolib.c
+++ b/arch/arm/mach-s3c64xx/gpiolib.c
@@ -15,9 +15,9 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/irq.h> 16#include <linux/irq.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/gpio.h>
18 19
19#include <mach/map.h> 20#include <mach/map.h>
20#include <mach/gpio.h>
21 21
22#include <plat/gpio-core.h> 22#include <plat/gpio-core.h>
23#include <plat/gpio-cfg.h> 23#include <plat/gpio-cfg.h>
diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h
index e1eab3c94ae..a1f13f02c84 100644
--- a/arch/arm/mach-s3c64xx/include/mach/map.h
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -67,6 +67,7 @@
67#define S3C64XX_PA_USB_HSOTG (0x7C000000) 67#define S3C64XX_PA_USB_HSOTG (0x7C000000)
68#define S3C64XX_PA_WATCHDOG (0x7E004000) 68#define S3C64XX_PA_WATCHDOG (0x7E004000)
69#define S3C64XX_PA_RTC (0x7E005000) 69#define S3C64XX_PA_RTC (0x7E005000)
70#define S3C64XX_PA_KEYPAD (0x7E00A000)
70#define S3C64XX_PA_ADC (0x7E00B000) 71#define S3C64XX_PA_ADC (0x7E00B000)
71#define S3C64XX_PA_SYSCON (0x7E00F000) 72#define S3C64XX_PA_SYSCON (0x7E00F000)
72#define S3C64XX_PA_AC97 (0x7F001000) 73#define S3C64XX_PA_AC97 (0x7F001000)
@@ -86,6 +87,9 @@
86#define S3C64XX_SZ_GPIO SZ_4K 87#define S3C64XX_SZ_GPIO SZ_4K
87 88
88#define S3C64XX_PA_SDRAM (0x50000000) 89#define S3C64XX_PA_SDRAM (0x50000000)
90
91#define S3C64XX_PA_CFCON (0x70300000)
92
89#define S3C64XX_PA_VIC0 (0x71200000) 93#define S3C64XX_PA_VIC0 (0x71200000)
90#define S3C64XX_PA_VIC1 (0x71300000) 94#define S3C64XX_PA_VIC1 (0x71300000)
91 95
@@ -120,5 +124,7 @@
120#define S3C_PA_WDT S3C64XX_PA_WATCHDOG 124#define S3C_PA_WDT S3C64XX_PA_WATCHDOG
121 125
122#define SAMSUNG_PA_ADC S3C64XX_PA_ADC 126#define SAMSUNG_PA_ADC S3C64XX_PA_ADC
127#define SAMSUNG_PA_CFCON S3C64XX_PA_CFCON
128#define SAMSUNG_PA_KEYPAD S3C64XX_PA_KEYPAD
123 129
124#endif /* __ASM_ARCH_6400_MAP_H */ 130#endif /* __ASM_ARCH_6400_MAP_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
index 0114eb0c1fe..05332b998ec 100644
--- a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
@@ -34,6 +34,7 @@
34#define S3C_SCLK_GATE S3C_CLKREG(0x38) 34#define S3C_SCLK_GATE S3C_CLKREG(0x38)
35#define S3C_MEM0_GATE S3C_CLKREG(0x3C) 35#define S3C_MEM0_GATE S3C_CLKREG(0x3C)
36#define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C) 36#define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C)
37#define S3C_MEM_SYS_CFG S3C_CLKREG(0x120)
37 38
38/* CLKDIV0 */ 39/* CLKDIV0 */
39#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12) 40#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12)
@@ -154,4 +155,8 @@
154#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2) 155#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2)
155#define S3C6400_CLKSRC_MFC (1 << 4) 156#define S3C6400_CLKSRC_MFC (1 << 4)
156 157
158/* MEM_SYS_CFG */
159#define MEM_SYS_CFG_INDEP_CF 0x4000
160#define MEM_SYS_CFG_EBI_FIX_PRI_CFCON 0x30
161
157#endif /* _PLAT_REGS_CLOCK_H */ 162#endif /* _PLAT_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index d9a03555f88..b5d78616c77 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -17,6 +17,7 @@
17#include <linux/list.h> 17#include <linux/list.h>
18#include <linux/timer.h> 18#include <linux/timer.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/input.h>
20#include <linux/serial_core.h> 21#include <linux/serial_core.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
22#include <linux/io.h> 23#include <linux/io.h>
@@ -56,6 +57,7 @@
56#include <mach/regs-gpio.h> 57#include <mach/regs-gpio.h>
57#include <mach/regs-sys.h> 58#include <mach/regs-sys.h>
58#include <mach/regs-srom.h> 59#include <mach/regs-srom.h>
60#include <plat/ata.h>
59#include <plat/iic.h> 61#include <plat/iic.h>
60#include <plat/fb.h> 62#include <plat/fb.h>
61#include <plat/gpio-cfg.h> 63#include <plat/gpio-cfg.h>
@@ -66,6 +68,7 @@
66#include <plat/cpu.h> 68#include <plat/cpu.h>
67#include <plat/adc.h> 69#include <plat/adc.h>
68#include <plat/ts.h> 70#include <plat/ts.h>
71#include <plat/keypad.h>
69 72
70#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK 73#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
71#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 74#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
@@ -242,6 +245,29 @@ static struct platform_device smdk6410_b_pwr_5v = {
242}; 245};
243#endif 246#endif
244 247
248static struct s3c_ide_platdata smdk6410_ide_pdata __initdata = {
249 .setup_gpio = s3c64xx_ide_setup_gpio,
250};
251
252static uint32_t smdk6410_keymap[] __initdata = {
253 /* KEY(row, col, keycode) */
254 KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
255 KEY(0, 6, KEY_4), KEY(0, 7, KEY_5),
256 KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C),
257 KEY(1, 6, KEY_D), KEY(1, 7, KEY_E)
258};
259
260static struct matrix_keymap_data smdk6410_keymap_data __initdata = {
261 .keymap = smdk6410_keymap,
262 .keymap_size = ARRAY_SIZE(smdk6410_keymap),
263};
264
265static struct samsung_keypad_platdata smdk6410_keypad_data __initdata = {
266 .keymap_data = &smdk6410_keymap_data,
267 .rows = 2,
268 .cols = 8,
269};
270
245static struct map_desc smdk6410_iodesc[] = {}; 271static struct map_desc smdk6410_iodesc[] = {};
246 272
247static struct platform_device *smdk6410_devices[] __initdata = { 273static struct platform_device *smdk6410_devices[] __initdata = {
@@ -257,6 +283,7 @@ static struct platform_device *smdk6410_devices[] __initdata = {
257 &s3c_device_ohci, 283 &s3c_device_ohci,
258 &s3c_device_usb_hsotg, 284 &s3c_device_usb_hsotg,
259 &s3c64xx_device_iisv4, 285 &s3c64xx_device_iisv4,
286 &samsung_device_keypad,
260 287
261#ifdef CONFIG_REGULATOR 288#ifdef CONFIG_REGULATOR
262 &smdk6410_b_pwr_5v, 289 &smdk6410_b_pwr_5v,
@@ -265,6 +292,8 @@ static struct platform_device *smdk6410_devices[] __initdata = {
265 292
266 &smdk6410_smsc911x, 293 &smdk6410_smsc911x,
267 &s3c_device_adc, 294 &s3c_device_adc,
295 &s3c_device_cfcon,
296 &s3c_device_rtc,
268 &s3c_device_ts, 297 &s3c_device_ts,
269 &s3c_device_wdt, 298 &s3c_device_wdt,
270}; 299};
@@ -636,6 +665,8 @@ static void __init smdk6410_machine_init(void)
636 s3c_i2c1_set_platdata(NULL); 665 s3c_i2c1_set_platdata(NULL);
637 s3c_fb_set_platdata(&smdk6410_lcd_pdata); 666 s3c_fb_set_platdata(&smdk6410_lcd_pdata);
638 667
668 samsung_keypad_set_platdata(&smdk6410_keypad_data);
669
639 s3c24xx_ts_set_platdata(&s3c_ts_platform); 670 s3c24xx_ts_set_platdata(&s3c_ts_platform);
640 671
641 /* configure nCS1 width to 16 bits */ 672 /* configure nCS1 width to 16 bits */
@@ -665,6 +696,8 @@ static void __init smdk6410_machine_init(void)
665 i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); 696 i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
666 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); 697 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
667 698
699 s3c_ide_set_platdata(&smdk6410_ide_pdata);
700
668 platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices)); 701 platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
669} 702}
670 703
diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c
index 014401c39f3..312aa6b115e 100644
--- a/arch/arm/mach-s3c64xx/s3c6410.c
+++ b/arch/arm/mach-s3c64xx/s3c6410.c
@@ -37,8 +37,9 @@
37#include <plat/devs.h> 37#include <plat/devs.h>
38#include <plat/clock.h> 38#include <plat/clock.h>
39#include <plat/sdhci.h> 39#include <plat/sdhci.h>
40#include <plat/ata-core.h>
41#include <plat/adc-core.h>
40#include <plat/iic-core.h> 42#include <plat/iic-core.h>
41#include <plat/adc.h>
42#include <plat/onenand-core.h> 43#include <plat/onenand-core.h>
43#include <mach/s3c6400.h> 44#include <mach/s3c6400.h>
44#include <mach/s3c6410.h> 45#include <mach/s3c6410.h>
@@ -54,10 +55,11 @@ void __init s3c6410_map_io(void)
54 s3c_i2c0_setname("s3c2440-i2c"); 55 s3c_i2c0_setname("s3c2440-i2c");
55 s3c_i2c1_setname("s3c2440-i2c"); 56 s3c_i2c1_setname("s3c2440-i2c");
56 57
57 s3c_device_adc.name = "s3c64xx-adc"; 58 s3c_adc_setname("s3c64xx-adc");
58 s3c_device_nand.name = "s3c6400-nand"; 59 s3c_device_nand.name = "s3c6400-nand";
59 s3c_onenand_setname("s3c6410-onenand"); 60 s3c_onenand_setname("s3c6410-onenand");
60 s3c64xx_onenand1_setname("s3c6410-onenand"); 61 s3c64xx_onenand1_setname("s3c6410-onenand");
62 s3c_cfcon_setname("s3c64xx-pata");
61} 63}
62 64
63void __init s3c6410_init_clocks(int xtal) 65void __init s3c6410_init_clocks(int xtal)
diff --git a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
index 8e28e448dd2..000736877df 100644
--- a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
+++ b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
@@ -15,9 +15,9 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/fb.h> 17#include <linux/fb.h>
18#include <linux/gpio.h>
18 19
19#include <mach/regs-fb.h> 20#include <mach/regs-fb.h>
20#include <mach/gpio.h>
21#include <plat/fb.h> 21#include <plat/fb.h>
22#include <plat/gpio-cfg.h> 22#include <plat/gpio-cfg.h>
23 23
diff --git a/arch/arm/mach-s3c64xx/setup-i2c0.c b/arch/arm/mach-s3c64xx/setup-i2c0.c
index d1b11e6e77e..406192a43c6 100644
--- a/arch/arm/mach-s3c64xx/setup-i2c0.c
+++ b/arch/arm/mach-s3c64xx/setup-i2c0.c
@@ -14,10 +14,10 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/gpio.h>
17 18
18struct platform_device; /* don't need the contents */ 19struct platform_device; /* don't need the contents */
19 20
20#include <mach/gpio.h>
21#include <mach/gpio-bank-b.h> 21#include <mach/gpio-bank-b.h>
22#include <plat/iic.h> 22#include <plat/iic.h>
23#include <plat/gpio-cfg.h> 23#include <plat/gpio-cfg.h>
diff --git a/arch/arm/mach-s3c64xx/setup-i2c1.c b/arch/arm/mach-s3c64xx/setup-i2c1.c
index 2dce57d8c6f..1ee62c97cd7 100644
--- a/arch/arm/mach-s3c64xx/setup-i2c1.c
+++ b/arch/arm/mach-s3c64xx/setup-i2c1.c
@@ -14,10 +14,10 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/gpio.h>
17 18
18struct platform_device; /* don't need the contents */ 19struct platform_device; /* don't need the contents */
19 20
20#include <mach/gpio.h>
21#include <mach/gpio-bank-b.h> 21#include <mach/gpio-bank-b.h>
22#include <plat/iic.h> 22#include <plat/iic.h>
23#include <plat/gpio-cfg.h> 23#include <plat/gpio-cfg.h>
diff --git a/arch/arm/mach-s3c64xx/setup-ide.c b/arch/arm/mach-s3c64xx/setup-ide.c
new file mode 100644
index 00000000000..c12c315f33b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-ide.c
@@ -0,0 +1,46 @@
1/* linux/arch/arm/mach-s3c64xx/setup-ide.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S3C64XX setup information for IDE
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 version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/gpio.h>
15#include <linux/io.h>
16
17#include <mach/map.h>
18#include <mach/regs-clock.h>
19#include <plat/gpio-cfg.h>
20
21void s3c64xx_ide_setup_gpio(void)
22{
23 u32 reg;
24 u32 gpio = 0;
25
26 reg = readl(S3C_MEM_SYS_CFG) & (~0x3f);
27
28 /* Independent CF interface, CF chip select configuration */
29 writel(reg | MEM_SYS_CFG_INDEP_CF |
30 MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S3C_MEM_SYS_CFG);
31
32 s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4));
33
34 /* Set XhiDATA[15:0] pins as CF Data[15:0] */
35 for (gpio = S3C64XX_GPK(0); gpio <= S3C64XX_GPK(15); gpio++)
36 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(5));
37
38 /* Set XhiADDR[2:0] pins as CF ADDR[2:0] */
39 for (gpio = S3C64XX_GPL(0); gpio <= S3C64XX_GPL(2); gpio++)
40 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
41
42 /* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */
43 s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1));
44 for (gpio = S3C64XX_GPM(0); gpio <= S3C64XX_GPM(4); gpio++)
45 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
46}
diff --git a/arch/arm/mach-s3c64xx/setup-keypad.c b/arch/arm/mach-s3c64xx/setup-keypad.c
new file mode 100644
index 00000000000..abc34e4e1a9
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-keypad.c
@@ -0,0 +1,34 @@
1/* linux/arch/arm/mach-s3c64xx/setup-keypad.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * GPIO configuration for S3C64XX KeyPad device
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 version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/gpio.h>
14#include <plat/gpio-cfg.h>
15
16void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
17{
18 unsigned int gpio;
19 unsigned int end;
20
21 /* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */
22 end = S3C64XX_GPK(8 + rows);
23 for (gpio = S3C64XX_GPK(8); gpio < end; gpio++) {
24 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
25 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
26 }
27
28 /* Set all the necessary GPL pins to special-function 3: KP_COL[x] */
29 end = S3C64XX_GPL(0 + cols);
30 for (gpio = S3C64XX_GPL(0); gpio < end; gpio++) {
31 s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
32 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
33 }
34}
diff --git a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
index a58c0cc7ba5..32235959137 100644
--- a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
@@ -16,12 +16,14 @@
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/gpio.h>
19 20
20#include <mach/gpio.h>
21#include <plat/gpio-cfg.h> 21#include <plat/gpio-cfg.h>
22#include <plat/sdhci.h>
22 23
23void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) 24void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
24{ 25{
26 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
25 unsigned int gpio; 27 unsigned int gpio;
26 unsigned int end; 28 unsigned int end;
27 29
@@ -33,12 +35,15 @@ void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
33 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 35 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
34 } 36 }
35 37
36 s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); 38 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
37 s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2)); 39 s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
40 s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2));
41 }
38} 42}
39 43
40void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) 44void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
41{ 45{
46 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
42 unsigned int gpio; 47 unsigned int gpio;
43 unsigned int end; 48 unsigned int end;
44 49
@@ -50,8 +55,10 @@ void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
50 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 55 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
51 } 56 }
52 57
53 s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); 58 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
54 s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3)); 59 s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
60 s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3));
61 }
55} 62}
56 63
57void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) 64void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
diff --git a/arch/arm/mach-s5p6440/Kconfig b/arch/arm/mach-s5p6440/Kconfig
index 153f8c9994c..6a4af7f5758 100644
--- a/arch/arm/mach-s5p6440/Kconfig
+++ b/arch/arm/mach-s5p6440/Kconfig
@@ -21,13 +21,11 @@ config S5P6440_SETUP_I2C1
21config MACH_SMDK6440 21config MACH_SMDK6440
22 bool "SMDK6440" 22 bool "SMDK6440"
23 select CPU_S5P6440 23 select CPU_S5P6440
24 select SAMSUNG_DEV_TS
25 select SAMSUNG_DEV_ADC
26 select S3C_DEV_RTC
27 select S3C_DEV_I2C1 24 select S3C_DEV_I2C1
25 select S3C_DEV_RTC
28 select S3C_DEV_WDT 26 select S3C_DEV_WDT
29 select HAVE_S3C_RTC 27 select SAMSUNG_DEV_ADC
30 select HAVE_S3C2410_WATCHDOG 28 select SAMSUNG_DEV_TS
31 select S5P6440_SETUP_I2C1 29 select S5P6440_SETUP_I2C1
32 help 30 help
33 Machine support for the Samsung SMDK6440 31 Machine support for the Samsung SMDK6440
diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c
index b2fe6a58155..526f33adb31 100644
--- a/arch/arm/mach-s5p6440/cpu.c
+++ b/arch/arm/mach-s5p6440/cpu.c
@@ -37,6 +37,7 @@
37#include <plat/devs.h> 37#include <plat/devs.h>
38#include <plat/clock.h> 38#include <plat/clock.h>
39#include <plat/s5p6440.h> 39#include <plat/s5p6440.h>
40#include <plat/adc-core.h>
40 41
41static void s5p6440_idle(void) 42static void s5p6440_idle(void)
42{ 43{
@@ -61,7 +62,7 @@ static void s5p6440_idle(void)
61void __init s5p6440_map_io(void) 62void __init s5p6440_map_io(void)
62{ 63{
63 /* initialize any device information early */ 64 /* initialize any device information early */
64 s3c_device_adc.name = "s3c64xx-adc"; 65 s3c_adc_setname("s3c64xx-adc");
65} 66}
66 67
67void __init s5p6440_init_clocks(int xtal) 68void __init s5p6440_init_clocks(int xtal)
diff --git a/arch/arm/mach-s5p6440/dev-audio.c b/arch/arm/mach-s5p6440/dev-audio.c
index 0c536796283..3ca0d2b8275 100644
--- a/arch/arm/mach-s5p6440/dev-audio.c
+++ b/arch/arm/mach-s5p6440/dev-audio.c
@@ -10,11 +10,11 @@
10 10
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h> 12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
13 14
14#include <plat/gpio-cfg.h> 15#include <plat/gpio-cfg.h>
15#include <plat/audio.h> 16#include <plat/audio.h>
16 17
17#include <mach/gpio.h>
18#include <mach/map.h> 18#include <mach/map.h>
19#include <mach/dma.h> 19#include <mach/dma.h>
20#include <mach/irqs.h> 20#include <mach/irqs.h>
diff --git a/arch/arm/mach-s5p6440/dev-spi.c b/arch/arm/mach-s5p6440/dev-spi.c
index 0a30280019c..510af44d180 100644
--- a/arch/arm/mach-s5p6440/dev-spi.c
+++ b/arch/arm/mach-s5p6440/dev-spi.c
@@ -10,11 +10,11 @@
10 10
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h> 12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
13 14
14#include <mach/dma.h> 15#include <mach/dma.h>
15#include <mach/map.h> 16#include <mach/map.h>
16#include <mach/irqs.h> 17#include <mach/irqs.h>
17#include <mach/gpio.h>
18#include <mach/spi-clocks.h> 18#include <mach/spi-clocks.h>
19 19
20#include <plat/s3c64xx-spi.h> 20#include <plat/s3c64xx-spi.h>
diff --git a/arch/arm/mach-s5p6440/gpio.c b/arch/arm/mach-s5p6440/gpio.c
index 92efc05b1ba..8bf6e0ce51c 100644
--- a/arch/arm/mach-s5p6440/gpio.c
+++ b/arch/arm/mach-s5p6440/gpio.c
@@ -13,9 +13,11 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/irq.h> 14#include <linux/irq.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/gpio.h>
17
16#include <mach/map.h> 18#include <mach/map.h>
17#include <mach/gpio.h>
18#include <mach/regs-gpio.h> 19#include <mach/regs-gpio.h>
20
19#include <plat/gpio-core.h> 21#include <plat/gpio-core.h>
20#include <plat/gpio-cfg.h> 22#include <plat/gpio-cfg.h>
21#include <plat/gpio-cfg-helpers.h> 23#include <plat/gpio-cfg-helpers.h>
diff --git a/arch/arm/mach-s5p6442/Kconfig b/arch/arm/mach-s5p6442/Kconfig
index 7cd28435b50..0fda0a5df96 100644
--- a/arch/arm/mach-s5p6442/Kconfig
+++ b/arch/arm/mach-s5p6442/Kconfig
@@ -20,7 +20,6 @@ config MACH_SMDK6442
20 bool "SMDK6442" 20 bool "SMDK6442"
21 select CPU_S5P6442 21 select CPU_S5P6442
22 select S3C_DEV_WDT 22 select S3C_DEV_WDT
23 select HAVE_S3C2410_WATCHDOG
24 help 23 help
25 Machine support for Samsung SMDK6442 24 Machine support for Samsung SMDK6442
26 25
diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c
index cb801e1f5e2..7a4e34720b7 100644
--- a/arch/arm/mach-s5p6442/dev-audio.c
+++ b/arch/arm/mach-s5p6442/dev-audio.c
@@ -10,11 +10,11 @@
10 10
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h> 12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
13 14
14#include <plat/gpio-cfg.h> 15#include <plat/gpio-cfg.h>
15#include <plat/audio.h> 16#include <plat/audio.h>
16 17
17#include <mach/gpio.h>
18#include <mach/map.h> 18#include <mach/map.h>
19#include <mach/dma.h> 19#include <mach/dma.h>
20#include <mach/irqs.h> 20#include <mach/irqs.h>
diff --git a/arch/arm/mach-s5p6442/dev-spi.c b/arch/arm/mach-s5p6442/dev-spi.c
index 30199525dac..e894651a88b 100644
--- a/arch/arm/mach-s5p6442/dev-spi.c
+++ b/arch/arm/mach-s5p6442/dev-spi.c
@@ -10,11 +10,11 @@
10 10
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h> 12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
13 14
14#include <mach/dma.h> 15#include <mach/dma.h>
15#include <mach/map.h> 16#include <mach/map.h>
16#include <mach/irqs.h> 17#include <mach/irqs.h>
17#include <mach/gpio.h>
18#include <mach/spi-clocks.h> 18#include <mach/spi-clocks.h>
19 19
20#include <plat/s3c64xx-spi.h> 20#include <plat/s3c64xx-spi.h>
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 25ca7c686e7..ab038d09076 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -49,24 +49,22 @@ config S5PC100_SETUP_SDHCI_GPIO
49config MACH_SMDKC100 49config MACH_SMDKC100
50 bool "SMDKC100" 50 bool "SMDKC100"
51 select CPU_S5PC100 51 select CPU_S5PC100
52 select SAMSUNG_DEV_ADC
53 select S3C_DEV_FB 52 select S3C_DEV_FB
54 select S3C_DEV_I2C1
55 select SAMSUNG_DEV_IDE
56 select S3C_DEV_HSMMC 53 select S3C_DEV_HSMMC
57 select S3C_DEV_HSMMC1 54 select S3C_DEV_HSMMC1
58 select S3C_DEV_HSMMC2 55 select S3C_DEV_HSMMC2
59 select SAMSUNG_DEV_KEYPAD 56 select S3C_DEV_I2C1
60 select S3C_DEV_RTC 57 select S3C_DEV_RTC
61 select SAMSUNG_DEV_TS
62 select S3C_DEV_WDT 58 select S3C_DEV_WDT
63 select HAVE_S3C2410_WATCHDOG 59 select SAMSUNG_DEV_ADC
60 select SAMSUNG_DEV_IDE
61 select SAMSUNG_DEV_KEYPAD
62 select SAMSUNG_DEV_TS
64 select S5PC100_SETUP_FB_24BPP 63 select S5PC100_SETUP_FB_24BPP
65 select S5PC100_SETUP_I2C1 64 select S5PC100_SETUP_I2C1
66 select S5PC100_SETUP_IDE 65 select S5PC100_SETUP_IDE
67 select S5PC100_SETUP_KEYPAD 66 select S5PC100_SETUP_KEYPAD
68 select S5PC100_SETUP_SDHCI 67 select S5PC100_SETUP_SDHCI
69 select HAVE_S3C_RTC
70 help 68 help
71 Machine support for the Samsung SMDKC100 69 Machine support for the Samsung SMDKC100
72 70
diff --git a/arch/arm/mach-s5pc100/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c
index 18cfe9ae193..a699ed6acc2 100644
--- a/arch/arm/mach-s5pc100/dev-audio.c
+++ b/arch/arm/mach-s5pc100/dev-audio.c
@@ -10,11 +10,11 @@
10 10
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h> 12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
13 14
14#include <plat/gpio-cfg.h> 15#include <plat/gpio-cfg.h>
15#include <plat/audio.h> 16#include <plat/audio.h>
16 17
17#include <mach/gpio.h>
18#include <mach/map.h> 18#include <mach/map.h>
19#include <mach/dma.h> 19#include <mach/dma.h>
20#include <mach/irqs.h> 20#include <mach/irqs.h>
diff --git a/arch/arm/mach-s5pc100/dev-spi.c b/arch/arm/mach-s5pc100/dev-spi.c
index 14618c34605..a0ef7c302c1 100644
--- a/arch/arm/mach-s5pc100/dev-spi.c
+++ b/arch/arm/mach-s5pc100/dev-spi.c
@@ -10,10 +10,10 @@
10 10
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h> 12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
13 14
14#include <mach/dma.h> 15#include <mach/dma.h>
15#include <mach/map.h> 16#include <mach/map.h>
16#include <mach/gpio.h>
17#include <mach/spi-clocks.h> 17#include <mach/spi-clocks.h>
18 18
19#include <plat/s3c64xx-spi.h> 19#include <plat/s3c64xx-spi.h>
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index c018697e79b..01b9134feff 100644
--- a/arch/arm/mach-s5pc100/include/mach/map.h
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -99,6 +99,10 @@
99 99
100#define S5PC100_PA_FB (0xEE000000) 100#define S5PC100_PA_FB (0xEE000000)
101 101
102#define S5PC100_PA_FIMC0 (0xEE200000)
103#define S5PC100_PA_FIMC1 (0xEE300000)
104#define S5PC100_PA_FIMC2 (0xEE400000)
105
102#define S5PC100_PA_I2S0 (0xF2000000) 106#define S5PC100_PA_I2S0 (0xF2000000)
103#define S5PC100_PA_I2S1 (0xF2100000) 107#define S5PC100_PA_I2S1 (0xF2100000)
104#define S5PC100_PA_I2S2 (0xF2200000) 108#define S5PC100_PA_I2S2 (0xF2200000)
@@ -148,4 +152,8 @@
148#define SAMSUNG_PA_CFCON S5PC100_PA_CFCON 152#define SAMSUNG_PA_CFCON S5PC100_PA_CFCON
149#define SAMSUNG_PA_KEYPAD S5PC100_PA_KEYPAD 153#define SAMSUNG_PA_KEYPAD S5PC100_PA_KEYPAD
150 154
155#define S5P_PA_FIMC0 S5PC100_PA_FIMC0
156#define S5P_PA_FIMC1 S5PC100_PA_FIMC1
157#define S5P_PA_FIMC2 S5PC100_PA_FIMC2
158
151#endif /* __ASM_ARCH_C100_MAP_H */ 159#endif /* __ASM_ARCH_C100_MAP_H */
diff --git a/arch/arm/mach-s5pc100/setup-sdhci-gpio.c b/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
index 7769c760c9e..dc7208c639e 100644
--- a/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
@@ -20,9 +20,11 @@
20 20
21#include <plat/gpio-cfg.h> 21#include <plat/gpio-cfg.h>
22#include <plat/regs-sdhci.h> 22#include <plat/regs-sdhci.h>
23#include <plat/sdhci.h>
23 24
24void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) 25void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
25{ 26{
27 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
26 unsigned int gpio; 28 unsigned int gpio;
27 unsigned int end; 29 unsigned int end;
28 unsigned int num; 30 unsigned int num;
@@ -47,12 +49,15 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
47 } 49 }
48 } 50 }
49 51
50 s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP); 52 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
51 s3c_gpio_cfgpin(S5PC100_GPG1(2), S3C_GPIO_SFN(2)); 53 s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP);
54 s3c_gpio_cfgpin(S5PC100_GPG1(2), S3C_GPIO_SFN(2));
55 }
52} 56}
53 57
54void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) 58void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
55{ 59{
60 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
56 unsigned int gpio; 61 unsigned int gpio;
57 unsigned int end; 62 unsigned int end;
58 63
@@ -64,12 +69,15 @@ void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
64 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 69 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
65 } 70 }
66 71
67 s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP); 72 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
68 s3c_gpio_cfgpin(S5PC100_GPG2(6), S3C_GPIO_SFN(2)); 73 s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP);
74 s3c_gpio_cfgpin(S5PC100_GPG2(6), S3C_GPIO_SFN(2));
75 }
69} 76}
70 77
71void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) 78void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
72{ 79{
80 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
73 unsigned int gpio; 81 unsigned int gpio;
74 unsigned int end; 82 unsigned int end;
75 83
@@ -81,6 +89,8 @@ void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
81 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 89 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
82 } 90 }
83 91
84 s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP); 92 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
85 s3c_gpio_cfgpin(S5PC100_GPG3(6), S3C_GPIO_SFN(2)); 93 s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
94 s3c_gpio_cfgpin(S5PC100_GPG3(6), S3C_GPIO_SFN(2));
95 }
86} 96}
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 9b84abf1a82..ea9d147d458 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -53,19 +53,24 @@ config S5PV210_SETUP_SDHCI_GPIO
53 help 53 help
54 Common setup code for SDHCI gpio. 54 Common setup code for SDHCI gpio.
55 55
56config S5PC110_DEV_ONENAND
57 bool
58 help
59 Compile in platform device definition for OneNAND1 controller
60
56menu "S5PC110 Machines" 61menu "S5PC110 Machines"
57 62
58config MACH_AQUILA 63config MACH_AQUILA
59 bool "Aquila" 64 bool "Aquila"
60 select CPU_S5PV210 65 select CPU_S5PV210
61 select ARCH_SPARSEMEM_ENABLE 66 select ARCH_SPARSEMEM_ENABLE
62 select S5PV210_SETUP_FB_24BPP
63 select S5PV210_SETUP_SDHCI
64 select S3C_DEV_FB 67 select S3C_DEV_FB
65 select S5PC110_DEV_ONENAND
66 select S3C_DEV_HSMMC 68 select S3C_DEV_HSMMC
67 select S3C_DEV_HSMMC1 69 select S3C_DEV_HSMMC1
68 select S3C_DEV_HSMMC2 70 select S3C_DEV_HSMMC2
71 select S5PC110_DEV_ONENAND
72 select S5PV210_SETUP_FB_24BPP
73 select S5PV210_SETUP_SDHCI
69 help 74 help
70 Machine support for the Samsung Aquila target based on S5PC110 SoC 75 Machine support for the Samsung Aquila target based on S5PC110 SoC
71 76
@@ -73,13 +78,13 @@ config MACH_GONI
73 bool "GONI" 78 bool "GONI"
74 select CPU_S5PV210 79 select CPU_S5PV210
75 select ARCH_SPARSEMEM_ENABLE 80 select ARCH_SPARSEMEM_ENABLE
76 select S5PV210_SETUP_FB_24BPP
77 select S5PV210_SETUP_SDHCI
78 select S3C_DEV_FB 81 select S3C_DEV_FB
79 select S5PC110_DEV_ONENAND
80 select S3C_DEV_HSMMC 82 select S3C_DEV_HSMMC
81 select S3C_DEV_HSMMC1 83 select S3C_DEV_HSMMC1
82 select S3C_DEV_HSMMC2 84 select S3C_DEV_HSMMC2
85 select S5PC110_DEV_ONENAND
86 select S5PV210_SETUP_FB_24BPP
87 select S5PV210_SETUP_SDHCI
83 help 88 help
84 Machine support for Samsung GONI board 89 Machine support for Samsung GONI board
85 S5PC110(MCP) is one of package option of S5PV210 90 S5PC110(MCP) is one of package option of S5PV210
@@ -90,11 +95,9 @@ config MACH_SMDKC110
90 select ARCH_SPARSEMEM_ENABLE 95 select ARCH_SPARSEMEM_ENABLE
91 select S3C_DEV_I2C1 96 select S3C_DEV_I2C1
92 select S3C_DEV_I2C2 97 select S3C_DEV_I2C2
93 select SAMSUNG_DEV_IDE
94 select S3C_DEV_RTC 98 select S3C_DEV_RTC
95 select S3C_DEV_WDT 99 select S3C_DEV_WDT
96 select HAVE_S3C_RTC 100 select SAMSUNG_DEV_IDE
97 select HAVE_S3C2410_WATCHDOG
98 select S5PV210_SETUP_I2C1 101 select S5PV210_SETUP_I2C1
99 select S5PV210_SETUP_I2C2 102 select S5PV210_SETUP_I2C2
100 select S5PV210_SETUP_IDE 103 select S5PV210_SETUP_IDE
@@ -104,31 +107,24 @@ config MACH_SMDKC110
104 107
105endmenu 108endmenu
106 109
107config S5PC110_DEV_ONENAND
108 bool
109 help
110 Compile in platform device definition for OneNAND1 controller
111
112menu "S5PV210 Machines" 110menu "S5PV210 Machines"
113 111
114config MACH_SMDKV210 112config MACH_SMDKV210
115 bool "SMDKV210" 113 bool "SMDKV210"
116 select CPU_S5PV210 114 select CPU_S5PV210
117 select ARCH_SPARSEMEM_ENABLE 115 select ARCH_SPARSEMEM_ENABLE
118 select SAMSUNG_DEV_ADC
119 select S3C_DEV_HSMMC 116 select S3C_DEV_HSMMC
120 select S3C_DEV_HSMMC1 117 select S3C_DEV_HSMMC1
121 select S3C_DEV_HSMMC2 118 select S3C_DEV_HSMMC2
122 select S3C_DEV_HSMMC3 119 select S3C_DEV_HSMMC3
123 select S3C_DEV_I2C1 120 select S3C_DEV_I2C1
124 select S3C_DEV_I2C2 121 select S3C_DEV_I2C2
122 select S3C_DEV_RTC
123 select S3C_DEV_WDT
124 select SAMSUNG_DEV_ADC
125 select SAMSUNG_DEV_IDE 125 select SAMSUNG_DEV_IDE
126 select SAMSUNG_DEV_KEYPAD 126 select SAMSUNG_DEV_KEYPAD
127 select SAMSUNG_DEV_TS 127 select SAMSUNG_DEV_TS
128 select S3C_DEV_RTC
129 select S3C_DEV_WDT
130 select HAVE_S3C_RTC
131 select HAVE_S3C2410_WATCHDOG
132 select S5PV210_SETUP_I2C1 128 select S5PV210_SETUP_I2C1
133 select S5PV210_SETUP_I2C2 129 select S5PV210_SETUP_I2C2
134 select S5PV210_SETUP_IDE 130 select S5PV210_SETUP_IDE
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index ede163707db..c7e0b8a65c4 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -32,7 +32,9 @@
32#include <plat/devs.h> 32#include <plat/devs.h>
33#include <plat/clock.h> 33#include <plat/clock.h>
34#include <plat/s5pv210.h> 34#include <plat/s5pv210.h>
35#include <plat/adc-core.h>
35#include <plat/ata-core.h> 36#include <plat/ata-core.h>
37#include <plat/fimc-core.h>
36#include <plat/iic-core.h> 38#include <plat/iic-core.h>
37#include <plat/keypad-core.h> 39#include <plat/keypad-core.h>
38#include <plat/sdhci.h> 40#include <plat/sdhci.h>
@@ -84,9 +86,6 @@ static void s5pv210_sw_reset(void)
84 86
85void __init s5pv210_map_io(void) 87void __init s5pv210_map_io(void)
86{ 88{
87#ifdef CONFIG_S3C_DEV_ADC
88 s3c_device_adc.name = "s3c64xx-adc";
89#endif
90 iotable_init(s5pv210_iodesc, ARRAY_SIZE(s5pv210_iodesc)); 89 iotable_init(s5pv210_iodesc, ARRAY_SIZE(s5pv210_iodesc));
91 90
92 /* initialise device information early */ 91 /* initialise device information early */
@@ -95,8 +94,14 @@ void __init s5pv210_map_io(void)
95 s5pv210_default_sdhci2(); 94 s5pv210_default_sdhci2();
96 s5pv210_default_sdhci3(); 95 s5pv210_default_sdhci3();
97 96
97 s3c_adc_setname("s3c64xx-adc");
98
98 s3c_cfcon_setname("s5pv210-pata"); 99 s3c_cfcon_setname("s5pv210-pata");
99 100
101 s3c_fimc_setname(0, "s5pv210-fimc");
102 s3c_fimc_setname(1, "s5pv210-fimc");
103 s3c_fimc_setname(2, "s5pv210-fimc");
104
100 /* the i2c devices are directly compatible with s3c2440 */ 105 /* the i2c devices are directly compatible with s3c2440 */
101 s3c_i2c0_setname("s3c2440-i2c"); 106 s3c_i2c0_setname("s3c2440-i2c");
102 s3c_i2c1_setname("s3c2440-i2c"); 107 s3c_i2c1_setname("s3c2440-i2c");
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
index 6e215330a1b..21dc6cf955c 100644
--- a/arch/arm/mach-s5pv210/dev-audio.c
+++ b/arch/arm/mach-s5pv210/dev-audio.c
@@ -10,11 +10,11 @@
10 10
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h> 12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
13 14
14#include <plat/gpio-cfg.h> 15#include <plat/gpio-cfg.h>
15#include <plat/audio.h> 16#include <plat/audio.h>
16 17
17#include <mach/gpio.h>
18#include <mach/map.h> 18#include <mach/map.h>
19#include <mach/dma.h> 19#include <mach/dma.h>
20#include <mach/irqs.h> 20#include <mach/irqs.h>
diff --git a/arch/arm/mach-s5pv210/dev-spi.c b/arch/arm/mach-s5pv210/dev-spi.c
index 337a62b57a0..826cdbc43e2 100644
--- a/arch/arm/mach-s5pv210/dev-spi.c
+++ b/arch/arm/mach-s5pv210/dev-spi.c
@@ -10,11 +10,11 @@
10 10
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h> 12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
13 14
14#include <mach/dma.h> 15#include <mach/dma.h>
15#include <mach/map.h> 16#include <mach/map.h>
16#include <mach/irqs.h> 17#include <mach/irqs.h>
17#include <mach/gpio.h>
18#include <mach/spi-clocks.h> 18#include <mach/spi-clocks.h>
19 19
20#include <plat/s3c64xx-spi.h> 20#include <plat/s3c64xx-spi.h>
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index 986b285fa57..dd4fb6bf14b 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -65,6 +65,10 @@
65 65
66#define S5PV210_PA_FB (0xF8000000) 66#define S5PV210_PA_FB (0xF8000000)
67 67
68#define S5PV210_PA_FIMC0 (0xFB200000)
69#define S5PV210_PA_FIMC1 (0xFB300000)
70#define S5PV210_PA_FIMC2 (0xFB400000)
71
68#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000)) 72#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000))
69 73
70#define S5PV210_PA_VIC0 (0xF2000000) 74#define S5PV210_PA_VIC0 (0xF2000000)
@@ -109,6 +113,9 @@
109#define S3C_PA_FB S5PV210_PA_FB 113#define S3C_PA_FB S5PV210_PA_FB
110#define S3C_PA_RTC S5PV210_PA_RTC 114#define S3C_PA_RTC S5PV210_PA_RTC
111#define S3C_PA_WDT S5PV210_PA_WATCHDOG 115#define S3C_PA_WDT S5PV210_PA_WATCHDOG
116#define S5P_PA_FIMC0 S5PV210_PA_FIMC0
117#define S5P_PA_FIMC1 S5PV210_PA_FIMC1
118#define S5P_PA_FIMC2 S5PV210_PA_FIMC2
112 119
113#define SAMSUNG_PA_ADC S5PV210_PA_ADC 120#define SAMSUNG_PA_ADC S5PV210_PA_ADC
114#define SAMSUNG_PA_CFCON S5PV210_PA_CFCON 121#define SAMSUNG_PA_CFCON S5PV210_PA_CFCON
diff --git a/arch/arm/mach-s5pv210/setup-fb-24bpp.c b/arch/arm/mach-s5pv210/setup-fb-24bpp.c
index a50cbac8720..928cf1f125f 100644
--- a/arch/arm/mach-s5pv210/setup-fb-24bpp.c
+++ b/arch/arm/mach-s5pv210/setup-fb-24bpp.c
@@ -13,9 +13,9 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/fb.h> 15#include <linux/fb.h>
16#include <linux/gpio.h>
16 17
17#include <mach/regs-fb.h> 18#include <mach/regs-fb.h>
18#include <mach/gpio.h>
19#include <mach/map.h> 19#include <mach/map.h>
20#include <plat/fb.h> 20#include <plat/fb.h>
21#include <mach/regs-clock.h> 21#include <mach/regs-clock.h>
diff --git a/arch/arm/mach-s5pv210/setup-i2c0.c b/arch/arm/mach-s5pv210/setup-i2c0.c
index c718253c70b..d38f7cb7e66 100644
--- a/arch/arm/mach-s5pv210/setup-i2c0.c
+++ b/arch/arm/mach-s5pv210/setup-i2c0.c
@@ -14,10 +14,10 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/gpio.h>
17 18
18struct platform_device; /* don't need the contents */ 19struct platform_device; /* don't need the contents */
19 20
20#include <mach/gpio.h>
21#include <plat/iic.h> 21#include <plat/iic.h>
22#include <plat/gpio-cfg.h> 22#include <plat/gpio-cfg.h>
23 23
diff --git a/arch/arm/mach-s5pv210/setup-i2c1.c b/arch/arm/mach-s5pv210/setup-i2c1.c
index 45e0e6ed2ed..148bb7857d8 100644
--- a/arch/arm/mach-s5pv210/setup-i2c1.c
+++ b/arch/arm/mach-s5pv210/setup-i2c1.c
@@ -14,10 +14,10 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/gpio.h>
17 18
18struct platform_device; /* don't need the contents */ 19struct platform_device; /* don't need the contents */
19 20
20#include <mach/gpio.h>
21#include <plat/iic.h> 21#include <plat/iic.h>
22#include <plat/gpio-cfg.h> 22#include <plat/gpio-cfg.h>
23 23
diff --git a/arch/arm/mach-s5pv210/setup-i2c2.c b/arch/arm/mach-s5pv210/setup-i2c2.c
index b11b4bff69a..2396cb8c373 100644
--- a/arch/arm/mach-s5pv210/setup-i2c2.c
+++ b/arch/arm/mach-s5pv210/setup-i2c2.c
@@ -14,10 +14,10 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/gpio.h>
17 18
18struct platform_device; /* don't need the contents */ 19struct platform_device; /* don't need the contents */
19 20
20#include <mach/gpio.h>
21#include <plat/iic.h> 21#include <plat/iic.h>
22#include <plat/gpio-cfg.h> 22#include <plat/gpio-cfg.h>
23 23
diff --git a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
index 143bfec1e05..9f0f63ddd66 100644
--- a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
@@ -15,15 +15,17 @@
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/gpio.h>
18#include <linux/mmc/host.h> 19#include <linux/mmc/host.h>
19#include <linux/mmc/card.h> 20#include <linux/mmc/card.h>
20 21
21#include <mach/gpio.h>
22#include <plat/gpio-cfg.h> 22#include <plat/gpio-cfg.h>
23#include <plat/regs-sdhci.h> 23#include <plat/regs-sdhci.h>
24#include <plat/sdhci.h>
24 25
25void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) 26void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
26{ 27{
28 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
27 unsigned int gpio; 29 unsigned int gpio;
28 30
29 /* Set all the necessary GPG0/GPG1 pins to special-function 2 */ 31 /* Set all the necessary GPG0/GPG1 pins to special-function 2 */
@@ -48,12 +50,15 @@ void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
48 break; 50 break;
49 } 51 }
50 52
51 s3c_gpio_setpull(S5PV210_GPG0(2), S3C_GPIO_PULL_UP); 53 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
52 s3c_gpio_cfgpin(S5PV210_GPG0(2), S3C_GPIO_SFN(2)); 54 s3c_gpio_setpull(S5PV210_GPG0(2), S3C_GPIO_PULL_UP);
55 s3c_gpio_cfgpin(S5PV210_GPG0(2), S3C_GPIO_SFN(2));
56 }
53} 57}
54 58
55void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) 59void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
56{ 60{
61 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
57 unsigned int gpio; 62 unsigned int gpio;
58 63
59 /* Set all the necessary GPG1[0:1] pins to special-function 2 */ 64 /* Set all the necessary GPG1[0:1] pins to special-function 2 */
@@ -68,12 +73,15 @@ void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
68 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); 73 s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
69 } 74 }
70 75
71 s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP); 76 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
72 s3c_gpio_cfgpin(S5PV210_GPG1(2), S3C_GPIO_SFN(2)); 77 s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
78 s3c_gpio_cfgpin(S5PV210_GPG1(2), S3C_GPIO_SFN(2));
79 }
73} 80}
74 81
75void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) 82void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
76{ 83{
84 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
77 unsigned int gpio; 85 unsigned int gpio;
78 86
79 /* Set all the necessary GPG2[0:1] pins to special-function 2 */ 87 /* Set all the necessary GPG2[0:1] pins to special-function 2 */
@@ -99,8 +107,10 @@ void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
99 break; 107 break;
100 } 108 }
101 109
102 s3c_gpio_setpull(S5PV210_GPG2(2), S3C_GPIO_PULL_UP); 110 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
103 s3c_gpio_cfgpin(S5PV210_GPG2(2), S3C_GPIO_SFN(2)); 111 s3c_gpio_setpull(S5PV210_GPG2(2), S3C_GPIO_PULL_UP);
112 s3c_gpio_cfgpin(S5PV210_GPG2(2), S3C_GPIO_SFN(2));
113 }
104} 114}
105 115
106void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width) 116void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index 7e34194b0aa..b2e02967395 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -19,3 +19,8 @@ obj-y += clock.o
19obj-y += irq.o 19obj-y += irq.o
20obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o 20obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
21 21
22# devices
23
24obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
25obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
26obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
diff --git a/arch/arm/plat-s5p/dev-fimc0.c b/arch/arm/plat-s5p/dev-fimc0.c
new file mode 100644
index 00000000000..d3f1a9b5d2b
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc0.c
@@ -0,0 +1,36 @@
1/* linux/arch/arm/plat-s5p/dev-fimc0.c
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 *
5 * Base S5P FIMC0 resource and device definitions
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/platform_device.h>
14#include <linux/interrupt.h>
15#include <linux/ioport.h>
16#include <mach/map.h>
17
18static struct resource s5p_fimc0_resource[] = {
19 [0] = {
20 .start = S5P_PA_FIMC0,
21 .end = S5P_PA_FIMC0 + SZ_1M - 1,
22 .flags = IORESOURCE_MEM,
23 },
24 [1] = {
25 .start = IRQ_FIMC0,
26 .end = IRQ_FIMC0,
27 .flags = IORESOURCE_IRQ,
28 },
29};
30
31struct platform_device s5p_device_fimc0 = {
32 .name = "s5p-fimc",
33 .id = 0,
34 .num_resources = ARRAY_SIZE(s5p_fimc0_resource),
35 .resource = s5p_fimc0_resource,
36};
diff --git a/arch/arm/plat-s5p/dev-fimc1.c b/arch/arm/plat-s5p/dev-fimc1.c
new file mode 100644
index 00000000000..41bd6986d0a
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc1.c
@@ -0,0 +1,36 @@
1/* linux/arch/arm/plat-s5p/dev-fimc1.c
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 *
5 * Base S5P FIMC1 resource and device definitions
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/platform_device.h>
14#include <linux/interrupt.h>
15#include <linux/ioport.h>
16#include <mach/map.h>
17
18static struct resource s5p_fimc1_resource[] = {
19 [0] = {
20 .start = S5P_PA_FIMC1,
21 .end = S5P_PA_FIMC1 + SZ_1M - 1,
22 .flags = IORESOURCE_MEM,
23 },
24 [1] = {
25 .start = IRQ_FIMC1,
26 .end = IRQ_FIMC1,
27 .flags = IORESOURCE_IRQ,
28 },
29};
30
31struct platform_device s5p_device_fimc1 = {
32 .name = "s5p-fimc",
33 .id = 1,
34 .num_resources = ARRAY_SIZE(s5p_fimc1_resource),
35 .resource = s5p_fimc1_resource,
36};
diff --git a/arch/arm/plat-s5p/dev-fimc2.c b/arch/arm/plat-s5p/dev-fimc2.c
new file mode 100644
index 00000000000..dfddeda6d4a
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc2.c
@@ -0,0 +1,36 @@
1/* linux/arch/arm/plat-s5p/dev-fimc2.c
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 *
5 * Base S5P FIMC2 resource and device definitions
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/platform_device.h>
14#include <linux/interrupt.h>
15#include <linux/ioport.h>
16#include <mach/map.h>
17
18static struct resource s5p_fimc2_resource[] = {
19 [0] = {
20 .start = S5P_PA_FIMC2,
21 .end = S5P_PA_FIMC2 + SZ_1M - 1,
22 .flags = IORESOURCE_MEM,
23 },
24 [1] = {
25 .start = IRQ_FIMC2,
26 .end = IRQ_FIMC2,
27 .flags = IORESOURCE_IRQ,
28 },
29};
30
31struct platform_device s5p_device_fimc2 = {
32 .name = "s5p-fimc",
33 .id = 2,
34 .num_resources = ARRAY_SIZE(s5p_fimc2_resource),
35 .resource = s5p_fimc2_resource,
36};
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 2753fb3e4f7..4529dd6232b 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -160,6 +160,11 @@ config S3C_DEV_HSMMC2
160 help 160 help
161 Compile in platform device definitions for HSMMC channel 2 161 Compile in platform device definitions for HSMMC channel 2
162 162
163config S3C_DEV_HSMMC3
164 bool
165 help
166 Compile in platform device definitions for HSMMC channel 3
167
163config S3C_DEV_HWMON 168config S3C_DEV_HWMON
164 bool 169 bool
165 help 170 help
@@ -216,6 +221,11 @@ config SAMSUNG_DEV_ADC
216 help 221 help
217 Compile in platform device definition for ADC controller 222 Compile in platform device definition for ADC controller
218 223
224config SAMSUNG_DEV_IDE
225 bool
226 help
227 Compile in platform device definitions for IDE
228
219config S3C64XX_DEV_SPI 229config S3C64XX_DEV_SPI
220 bool 230 bool
221 help 231 help
@@ -227,6 +237,11 @@ config SAMSUNG_DEV_TS
227 help 237 help
228 Common in platform device definitions for touchscreen device 238 Common in platform device definitions for touchscreen device
229 239
240config SAMSUNG_DEV_KEYPAD
241 bool
242 help
243 Compile in platform device definitions for keypad
244
230# DMA 245# DMA
231 246
232config S3C_DMA 247config S3C_DMA
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 0d5bf8a20a6..4d8ff923207 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -30,9 +30,12 @@ obj-$(CONFIG_S3C_ADC) += adc.o
30 30
31# devices 31# devices
32 32
33obj-y += platformdata.o
34
33obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o 35obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o
34obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o 36obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o
35obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o 37obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o
38obj-$(CONFIG_S3C_DEV_HSMMC3) += dev-hsmmc3.o
36obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o 39obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o
37obj-y += dev-i2c0.o 40obj-y += dev-i2c0.o
38obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o 41obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
@@ -47,7 +50,9 @@ obj-$(CONFIG_S3C_DEV_ONENAND) += dev-onenand.o
47obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o 50obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o
48 51
49obj-$(CONFIG_SAMSUNG_DEV_ADC) += dev-adc.o 52obj-$(CONFIG_SAMSUNG_DEV_ADC) += dev-adc.o
53obj-$(CONFIG_SAMSUNG_DEV_IDE) += dev-ide.o
50obj-$(CONFIG_SAMSUNG_DEV_TS) += dev-ts.o 54obj-$(CONFIG_SAMSUNG_DEV_TS) += dev-ts.o
55obj-$(CONFIG_SAMSUNG_DEV_KEYPAD) += dev-keypad.o
51 56
52# DMA support 57# DMA support
53 58
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
index 4c05b39810e..b0f93f11e28 100644
--- a/arch/arm/plat-samsung/dev-hsmmc.c
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -60,6 +60,11 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
60 struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata; 60 struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
61 61
62 set->max_width = pd->max_width; 62 set->max_width = pd->max_width;
63 set->cd_type = pd->cd_type;
64 set->ext_cd_init = pd->ext_cd_init;
65 set->ext_cd_cleanup = pd->ext_cd_cleanup;
66 set->ext_cd_gpio = pd->ext_cd_gpio;
67 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
63 68
64 if (pd->cfg_gpio) 69 if (pd->cfg_gpio)
65 set->cfg_gpio = pd->cfg_gpio; 70 set->cfg_gpio = pd->cfg_gpio;
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
index e49bc4cd0ee..1504fd80286 100644
--- a/arch/arm/plat-samsung/dev-hsmmc1.c
+++ b/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -60,6 +60,11 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
60 struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata; 60 struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
61 61
62 set->max_width = pd->max_width; 62 set->max_width = pd->max_width;
63 set->cd_type = pd->cd_type;
64 set->ext_cd_init = pd->ext_cd_init;
65 set->ext_cd_cleanup = pd->ext_cd_cleanup;
66 set->ext_cd_gpio = pd->ext_cd_gpio;
67 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
63 68
64 if (pd->cfg_gpio) 69 if (pd->cfg_gpio)
65 set->cfg_gpio = pd->cfg_gpio; 70 set->cfg_gpio = pd->cfg_gpio;
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
index 824580bc0e0..b28ef173444 100644
--- a/arch/arm/plat-samsung/dev-hsmmc2.c
+++ b/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -61,6 +61,11 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
61 struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata; 61 struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
62 62
63 set->max_width = pd->max_width; 63 set->max_width = pd->max_width;
64 set->cd_type = pd->cd_type;
65 set->ext_cd_init = pd->ext_cd_init;
66 set->ext_cd_cleanup = pd->ext_cd_cleanup;
67 set->ext_cd_gpio = pd->ext_cd_gpio;
68 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
64 69
65 if (pd->cfg_gpio) 70 if (pd->cfg_gpio)
66 set->cfg_gpio = pd->cfg_gpio; 71 set->cfg_gpio = pd->cfg_gpio;
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
new file mode 100644
index 00000000000..85aaf0f2842
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -0,0 +1,77 @@
1/* linux/arch/arm/plat-samsung/dev-hsmmc3.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (c) 2008 Simtec Electronics
7 * Ben Dooks <ben@simtec.co.uk>
8 * http://armlinux.simtec.co.uk/
9 *
10 * Based on arch/arm/plat-samsung/dev-hsmmc1.c
11 *
12 * Samsung device definition for hsmmc device 3
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17*/
18
19#include <linux/kernel.h>
20#include <linux/platform_device.h>
21#include <linux/mmc/host.h>
22
23#include <mach/map.h>
24#include <plat/sdhci.h>
25#include <plat/devs.h>
26
27#define S3C_SZ_HSMMC (0x1000)
28
29static struct resource s3c_hsmmc3_resource[] = {
30 [0] = {
31 .start = S3C_PA_HSMMC3,
32 .end = S3C_PA_HSMMC3 + S3C_SZ_HSMMC - 1,
33 .flags = IORESOURCE_MEM,
34 },
35 [1] = {
36 .start = IRQ_MMC3,
37 .end = IRQ_MMC3,
38 .flags = IORESOURCE_IRQ,
39 }
40};
41
42static u64 s3c_device_hsmmc3_dmamask = 0xffffffffUL;
43
44struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
45 .max_width = 4,
46 .host_caps = (MMC_CAP_4_BIT_DATA |
47 MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
48};
49
50struct platform_device s3c_device_hsmmc3 = {
51 .name = "s3c-sdhci",
52 .id = 3,
53 .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource),
54 .resource = s3c_hsmmc3_resource,
55 .dev = {
56 .dma_mask = &s3c_device_hsmmc3_dmamask,
57 .coherent_dma_mask = 0xffffffffUL,
58 .platform_data = &s3c_hsmmc3_def_platdata,
59 },
60};
61
62void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
63{
64 struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
65
66 set->max_width = pd->max_width;
67 set->cd_type = pd->cd_type;
68 set->ext_cd_init = pd->ext_cd_init;
69 set->ext_cd_cleanup = pd->ext_cd_cleanup;
70 set->ext_cd_gpio = pd->ext_cd_gpio;
71 set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
72
73 if (pd->cfg_gpio)
74 set->cfg_gpio = pd->cfg_gpio;
75 if (pd->cfg_card)
76 set->cfg_card = pd->cfg_card;
77}
diff --git a/arch/arm/plat-samsung/dev-ide.c b/arch/arm/plat-samsung/dev-ide.c
new file mode 100644
index 00000000000..b497982795a
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-ide.c
@@ -0,0 +1,44 @@
1/* linux/arch/arm/plat-samsung/dev-ide.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung CF-ATA device definition.
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 version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/platform_device.h>
16
17#include <mach/map.h>
18#include <plat/ata.h>
19#include <plat/devs.h>
20
21static struct resource s3c_cfcon_resource[] = {
22 [0] = {
23 .start = SAMSUNG_PA_CFCON,
24 .end = SAMSUNG_PA_CFCON + SZ_16K - 1,
25 .flags = IORESOURCE_MEM,
26 },
27 [1] = {
28 .start = IRQ_CFCON,
29 .end = IRQ_CFCON,
30 .flags = IORESOURCE_IRQ,
31 },
32};
33
34struct platform_device s3c_device_cfcon = {
35 .id = 0,
36 .num_resources = ARRAY_SIZE(s3c_cfcon_resource),
37 .resource = s3c_cfcon_resource,
38};
39
40void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
41{
42 s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
43 &s3c_device_cfcon);
44}
diff --git a/arch/arm/plat-samsung/dev-keypad.c b/arch/arm/plat-samsung/dev-keypad.c
new file mode 100644
index 00000000000..677c2d731b6
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-keypad.c
@@ -0,0 +1,50 @@
1/*
2 * linux/arch/arm/plat-samsung/dev-keypad.c
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/platform_device.h>
15#include <mach/irqs.h>
16#include <mach/map.h>
17#include <plat/cpu.h>
18#include <plat/devs.h>
19#include <plat/keypad.h>
20
21static struct resource samsung_keypad_resources[] = {
22 [0] = {
23 .start = SAMSUNG_PA_KEYPAD,
24 .end = SAMSUNG_PA_KEYPAD + 0x20 - 1,
25 .flags = IORESOURCE_MEM,
26 },
27 [1] = {
28 .start = IRQ_KEYPAD,
29 .end = IRQ_KEYPAD,
30 .flags = IORESOURCE_IRQ,
31 },
32};
33
34struct platform_device samsung_device_keypad = {
35 .name = "samsung-keypad",
36 .id = -1,
37 .num_resources = ARRAY_SIZE(samsung_keypad_resources),
38 .resource = samsung_keypad_resources,
39};
40
41void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd)
42{
43 struct samsung_keypad_platdata *npd;
44
45 npd = s3c_set_platdata(pd, sizeof(struct samsung_keypad_platdata),
46 &samsung_device_keypad);
47
48 if (!npd->cfg_gpio)
49 npd->cfg_gpio = samsung_keypad_cfg_gpio;
50}
diff --git a/arch/arm/plat-samsung/dev-wdt.c b/arch/arm/plat-samsung/dev-wdt.c
index 5efca87cddb..019b5b8cf14 100644
--- a/arch/arm/plat-samsung/dev-wdt.c
+++ b/arch/arm/plat-samsung/dev-wdt.c
@@ -21,7 +21,7 @@
21static struct resource s3c_wdt_resource[] = { 21static struct resource s3c_wdt_resource[] = {
22 [0] = { 22 [0] = {
23 .start = S3C_PA_WDT, 23 .start = S3C_PA_WDT,
24 .end = S3C_PA_WDT + SZ_1M - 1, 24 .end = S3C_PA_WDT + SZ_1K,
25 .flags = IORESOURCE_MEM, 25 .flags = IORESOURCE_MEM,
26 }, 26 },
27 [1] = { 27 [1] = {
diff --git a/arch/arm/plat-samsung/gpiolib.c b/arch/arm/plat-samsung/gpiolib.c
index 8a8ba8bc1d9..c354089254f 100644
--- a/arch/arm/plat-samsung/gpiolib.c
+++ b/arch/arm/plat-samsung/gpiolib.c
@@ -18,7 +18,7 @@
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/irq.h> 19#include <linux/irq.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <mach/gpio.h> 21#include <linux/gpio.h>
22#include <plat/gpio-core.h> 22#include <plat/gpio-core.h>
23#include <plat/gpio-cfg.h> 23#include <plat/gpio-cfg.h>
24#include <plat/gpio-cfg-helpers.h> 24#include <plat/gpio-cfg-helpers.h>
diff --git a/arch/arm/plat-samsung/include/plat/adc-core.h b/arch/arm/plat-samsung/include/plat/adc-core.h
new file mode 100644
index 00000000000..a281568d585
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/adc-core.h
@@ -0,0 +1,28 @@
1/* linux/arch/arm/plat-samsung/include/plat/adc-core.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Samsung ADC Controller core functions
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 version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_PLAT_ADC_CORE_H
14#define __ASM_PLAT_ADC_CORE_H __FILE__
15
16/* These functions are only for use with the core support code, such as
17 * the cpu specific initialisation code
18 */
19
20/* re-define device name depending on support. */
21static inline void s3c_adc_setname(char *name)
22{
23#ifdef CONFIG_SAMSUNG_DEV_ADC
24 s3c_device_adc.name = name;
25#endif
26}
27
28#endif /* __ASM_PLAT_ADC_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/ata-core.h b/arch/arm/plat-samsung/include/plat/ata-core.h
new file mode 100644
index 00000000000..f5a4ec7141b
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/ata-core.h
@@ -0,0 +1,28 @@
1/* linux/arch/arm/plat-samsung/include/plat/ata-core.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung CF-ATA Controller core functions
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 version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_PLAT_ATA_CORE_H
14#define __ASM_PLAT_ATA_CORE_H __FILE__
15
16/* These functions are only for use with the core support code, such as
17 * the cpu specific initialisation code
18*/
19
20/* re-define device name depending on support. */
21static inline void s3c_cfcon_setname(char *name)
22{
23#ifdef CONFIG_SAMSUNG_DEV_IDE
24 s3c_device_cfcon.name = name;
25#endif
26}
27
28#endif /* __ASM_PLAT_ATA_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/ata.h b/arch/arm/plat-samsung/include/plat/ata.h
new file mode 100644
index 00000000000..2a3855a8372
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/ata.h
@@ -0,0 +1,36 @@
1/* linux/arch/arm/plat-samsung/include/plat/ata.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung CF-ATA platform_device info
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 version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_PLAT_ATA_H
14#define __ASM_PLAT_ATA_H __FILE__
15
16/**
17 * struct s3c_ide_platdata - S3C IDE driver platform data.
18 * @setup_gpio: Setup the external GPIO pins to the right state for data
19 * transfer in true-ide mode.
20 */
21struct s3c_ide_platdata {
22 void (*setup_gpio)(void);
23};
24
25/*
26 * s3c_ide_set_platdata() - Setup the platform specifc data for IDE driver.
27 * @pdata: Platform data for IDE driver.
28 */
29extern void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata);
30
31/* architecture-specific IDE configuration */
32extern void s3c64xx_ide_setup_gpio(void);
33extern void s5pc100_ide_setup_gpio(void);
34extern void s5pv210_ide_setup_gpio(void);
35
36#endif /*__ASM_PLAT_ATA_H */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index e6144e4b911..85f6f23a510 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -54,6 +54,8 @@ extern struct platform_device s3c_device_hwmon;
54extern struct platform_device s3c_device_hsmmc0; 54extern struct platform_device s3c_device_hsmmc0;
55extern struct platform_device s3c_device_hsmmc1; 55extern struct platform_device s3c_device_hsmmc1;
56extern struct platform_device s3c_device_hsmmc2; 56extern struct platform_device s3c_device_hsmmc2;
57extern struct platform_device s3c_device_hsmmc3;
58extern struct platform_device s3c_device_cfcon;
57 59
58extern struct platform_device s3c_device_spi0; 60extern struct platform_device s3c_device_spi0;
59extern struct platform_device s3c_device_spi1; 61extern struct platform_device s3c_device_spi1;
@@ -100,6 +102,12 @@ extern struct platform_device s5pc100_device_iis0;
100extern struct platform_device s5pc100_device_iis1; 102extern struct platform_device s5pc100_device_iis1;
101extern struct platform_device s5pc100_device_iis2; 103extern struct platform_device s5pc100_device_iis2;
102 104
105extern struct platform_device samsung_device_keypad;
106
107extern struct platform_device s5p_device_fimc0;
108extern struct platform_device s5p_device_fimc1;
109extern struct platform_device s5p_device_fimc2;
110
103/* s3c2440 specific devices */ 111/* s3c2440 specific devices */
104 112
105#ifdef CONFIG_CPU_S3C2440 113#ifdef CONFIG_CPU_S3C2440
@@ -108,3 +116,15 @@ extern struct platform_device s3c_device_camif;
108extern struct platform_device s3c_device_ac97; 116extern struct platform_device s3c_device_ac97;
109 117
110#endif 118#endif
119
120/**
121 * s3c_set_platdata() - helper for setting platform data
122 * @pd: The default platform data for this device.
123 * @pdsize: The size of the platform data.
124 * @pdev: Pointer to the device to fill in.
125 *
126 * This helper replaces a number of calls that copy and then set the
127 * platform data of the device.
128 */
129extern void *s3c_set_platdata(void *pd, size_t pdsize,
130 struct platform_device *pdev);
diff --git a/arch/arm/plat-samsung/include/plat/fimc-core.h b/arch/arm/plat-samsung/include/plat/fimc-core.h
new file mode 100644
index 00000000000..81a3bfeecca
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/fimc-core.h
@@ -0,0 +1,44 @@
1/*
2 * arch/arm/plat-samsung/include/plat/fimc-core.h
3 *
4 * Copyright 2010 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 *
7 * Samsung camera interface driver core functions
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 version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#ifndef __ASM_PLAT_FIMC_CORE_H
15#define __ASM_PLAT_FIMC_CORE_H __FILE__
16
17/*
18 * These functions are only for use with the core support code, such as
19 * the CPU-specific initialization code.
20 */
21
22/* Re-define device name to differentiate the subsystem in various SoCs. */
23static inline void s3c_fimc_setname(int id, char *name)
24{
25 switch (id) {
26#ifdef CONFIG_S5P_DEV_FIMC0
27 case 0:
28 s5p_device_fimc0.name = name;
29 break;
30#endif
31#ifdef CONFIG_S5P_DEV_FIMC1
32 case 1:
33 s5p_device_fimc1.name = name;
34 break;
35#endif
36#ifdef CONFIG_S5P_DEV_FIMC2
37 case 2:
38 s5p_device_fimc2.name = name;
39 break;
40#endif
41 }
42}
43
44#endif /* __ASM_PLAT_FIMC_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/keypad.h b/arch/arm/plat-samsung/include/plat/keypad.h
new file mode 100644
index 00000000000..b59a6483cd8
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/keypad.h
@@ -0,0 +1,56 @@
1/*
2 * Samsung Platform - Keypad platform data definitions
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#ifndef __PLAT_SAMSUNG_KEYPAD_H
14#define __PLAT_SAMSUNG_KEYPAD_H
15
16#include <linux/input/matrix_keypad.h>
17
18#define SAMSUNG_MAX_ROWS 8
19#define SAMSUNG_MAX_COLS 8
20
21/**
22 * struct samsung_keypad_platdata - Platform device data for Samsung Keypad.
23 * @keymap_data: pointer to &matrix_keymap_data.
24 * @rows: number of keypad row supported.
25 * @cols: number of keypad col supported.
26 * @no_autorepeat: disable key autorepeat.
27 * @wakeup: controls whether the device should be set up as wakeup source.
28 * @cfg_gpio: configure the GPIO.
29 *
30 * Initialisation data specific to either the machine or the platform
31 * for the device driver to use or call-back when configuring gpio.
32 */
33struct samsung_keypad_platdata {
34 const struct matrix_keymap_data *keymap_data;
35 unsigned int rows;
36 unsigned int cols;
37 bool no_autorepeat;
38 bool wakeup;
39
40 void (*cfg_gpio)(unsigned int rows, unsigned int cols);
41};
42
43/**
44 * samsung_keypad_set_platdata - Set platform data for Samsung Keypad device.
45 * @pd: Platform data to register to device.
46 *
47 * Register the given platform data for use with Samsung Keypad device.
48 * The call will copy the platform data, so the board definitions can
49 * make the structure itself __initdata.
50 */
51extern void samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd);
52
53/* defined by architecture to configure gpio. */
54extern void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols);
55
56#endif /* __PLAT_SAMSUNG_KEYPAD_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-ata.h b/arch/arm/plat-samsung/include/plat/regs-ata.h
new file mode 100644
index 00000000000..f5df92fdae2
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-ata.h
@@ -0,0 +1,56 @@
1/* linux/arch/arm/plat-samsung/include/plat/regs-ata.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung CF-ATA register definitions
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 version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_PLAT_REGS_ATA_H
14#define __ASM_PLAT_REGS_ATA_H __FILE__
15
16#define S3C_CFATA_REG(x) (x)
17
18#define S3C_CFATA_MUX S3C_CFATA_REG(0x0)
19
20#define S3C_ATA_CTRL S3C_CFATA_REG(0x0)
21#define S3C_ATA_STATUS S3C_CFATA_REG(0x4)
22#define S3C_ATA_CMD S3C_CFATA_REG(0x8)
23#define S3C_ATA_SWRST S3C_CFATA_REG(0xc)
24#define S3C_ATA_IRQ S3C_CFATA_REG(0x10)
25#define S3C_ATA_IRQ_MSK S3C_CFATA_REG(0x14)
26#define S3C_ATA_CFG S3C_CFATA_REG(0x18)
27
28#define S3C_ATA_MDMA_TIME S3C_CFATA_REG(0x28)
29#define S3C_ATA_PIO_TIME S3C_CFATA_REG(0x2c)
30#define S3C_ATA_UDMA_TIME S3C_CFATA_REG(0x30)
31#define S3C_ATA_XFR_NUM S3C_CFATA_REG(0x34)
32#define S3C_ATA_XFR_CNT S3C_CFATA_REG(0x38)
33#define S3C_ATA_TBUF_START S3C_CFATA_REG(0x3c)
34#define S3C_ATA_TBUF_SIZE S3C_CFATA_REG(0x40)
35#define S3C_ATA_SBUF_START S3C_CFATA_REG(0x44)
36#define S3C_ATA_SBUF_SIZE S3C_CFATA_REG(0x48)
37#define S3C_ATA_CADR_TBUF S3C_CFATA_REG(0x4c)
38#define S3C_ATA_CADR_SBUF S3C_CFATA_REG(0x50)
39#define S3C_ATA_PIO_DTR S3C_CFATA_REG(0x54)
40#define S3C_ATA_PIO_FED S3C_CFATA_REG(0x58)
41#define S3C_ATA_PIO_SCR S3C_CFATA_REG(0x5c)
42#define S3C_ATA_PIO_LLR S3C_CFATA_REG(0x60)
43#define S3C_ATA_PIO_LMR S3C_CFATA_REG(0x64)
44#define S3C_ATA_PIO_LHR S3C_CFATA_REG(0x68)
45#define S3C_ATA_PIO_DVR S3C_CFATA_REG(0x6c)
46#define S3C_ATA_PIO_CSD S3C_CFATA_REG(0x70)
47#define S3C_ATA_PIO_DAD S3C_CFATA_REG(0x74)
48#define S3C_ATA_PIO_READY S3C_CFATA_REG(0x78)
49#define S3C_ATA_PIO_RDATA S3C_CFATA_REG(0x7c)
50
51#define S3C_CFATA_MUX_TRUEIDE 0x01
52
53#define S3C_ATA_CFG_SWAP 0x40
54#define S3C_ATA_CFG_IORDYEN 0x02
55
56#endif /* __ASM_PLAT_REGS_ATA_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-rtc.h b/arch/arm/plat-samsung/include/plat/regs-rtc.h
index 65c190d142d..30b7cc14cef 100644
--- a/arch/arm/plat-samsung/include/plat/regs-rtc.h
+++ b/arch/arm/plat-samsung/include/plat/regs-rtc.h
@@ -14,6 +14,9 @@
14#define __ASM_ARCH_REGS_RTC_H __FILE__ 14#define __ASM_ARCH_REGS_RTC_H __FILE__
15 15
16#define S3C2410_RTCREG(x) (x) 16#define S3C2410_RTCREG(x) (x)
17#define S3C2410_INTP S3C2410_RTCREG(0x30)
18#define S3C2410_INTP_ALM (1 << 1)
19#define S3C2410_INTP_TIC (1 << 0)
17 20
18#define S3C2410_RTCCON S3C2410_RTCREG(0x40) 21#define S3C2410_RTCCON S3C2410_RTCREG(0x40)
19#define S3C2410_RTCCON_RTCEN (1<<0) 22#define S3C2410_RTCCON_RTCEN (1<<0)
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 10413728530..30844c263d0 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -20,10 +20,31 @@ struct mmc_host;
20struct mmc_card; 20struct mmc_card;
21struct mmc_ios; 21struct mmc_ios;
22 22
23enum cd_types {
24 S3C_SDHCI_CD_INTERNAL, /* use mmc internal CD line */
25 S3C_SDHCI_CD_EXTERNAL, /* use external callback */
26 S3C_SDHCI_CD_GPIO, /* use external gpio pin for CD line */
27 S3C_SDHCI_CD_NONE, /* no CD line, use polling to detect card */
28 S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */
29};
30
23/** 31/**
24 * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI 32 * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
25 * @max_width: The maximum number of data bits supported. 33 * @max_width: The maximum number of data bits supported.
26 * @host_caps: Standard MMC host capabilities bit field. 34 * @host_caps: Standard MMC host capabilities bit field.
35 * @cd_type: Type of Card Detection method (see cd_types enum above)
36 * @ext_cd_init: Initialize external card detect subsystem. Called on
37 * sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL.
38 * notify_func argument is a callback to the sdhci-s3c driver
39 * that triggers the card detection event. Callback arguments:
40 * dev is pointer to platform device of the host controller,
41 * state is new state of the card (0 - removed, 1 - inserted).
42 * @ext_cd_cleanup: Cleanup external card detect subsystem. Called on
43 * sdhci-s3c driver remove when cd_type == S3C_SDHCI_CD_EXTERNAL.
44 * notify_func argument is the same callback as for ext_cd_init.
45 * @ext_cd_gpio: gpio pin used for external CD line, valid only if
46 * cd_type == S3C_SDHCI_CD_GPIO
47 * @ext_cd_gpio_invert: invert values for external CD gpio line
27 * @cfg_gpio: Configure the GPIO for a specific card bit-width 48 * @cfg_gpio: Configure the GPIO for a specific card bit-width
28 * @cfg_card: Configure the interface for a specific card and speed. This 49 * @cfg_card: Configure the interface for a specific card and speed. This
29 * is necessary the controllers and/or GPIO blocks require the 50 * is necessary the controllers and/or GPIO blocks require the
@@ -37,9 +58,17 @@ struct mmc_ios;
37struct s3c_sdhci_platdata { 58struct s3c_sdhci_platdata {
38 unsigned int max_width; 59 unsigned int max_width;
39 unsigned int host_caps; 60 unsigned int host_caps;
61 enum cd_types cd_type;
40 62
41 char **clocks; /* set of clock sources */ 63 char **clocks; /* set of clock sources */
42 64
65 int ext_cd_gpio;
66 bool ext_cd_gpio_invert;
67 int (*ext_cd_init)(void (*notify_func)(struct platform_device *,
68 int state));
69 int (*ext_cd_cleanup)(void (*notify_func)(struct platform_device *,
70 int state));
71
43 void (*cfg_gpio)(struct platform_device *dev, int width); 72 void (*cfg_gpio)(struct platform_device *dev, int width);
44 void (*cfg_card)(struct platform_device *dev, 73 void (*cfg_card)(struct platform_device *dev,
45 void __iomem *regbase, 74 void __iomem *regbase,
@@ -58,6 +87,7 @@ struct s3c_sdhci_platdata {
58extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd); 87extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd);
59extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd); 88extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
60extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd); 89extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
90extern void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd);
61 91
62/* Default platform data, exported so that per-cpu initialisation can 92/* Default platform data, exported so that per-cpu initialisation can
63 * set the correct one when there are more than one cpu type selected. 93 * set the correct one when there are more than one cpu type selected.
@@ -66,6 +96,7 @@ extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
66extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata; 96extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata;
67extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata; 97extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata;
68extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata; 98extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata;
99extern struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata;
69 100
70/* Helper function availablity */ 101/* Helper function availablity */
71 102
@@ -80,12 +111,11 @@ extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
80extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w); 111extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
81extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w); 112extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
82 113
83/* S3C6400 SDHCI setup */ 114/* S3C64XX SDHCI setup */
84 115
85#ifdef CONFIG_S3C64XX_SETUP_SDHCI 116#ifdef CONFIG_S3C64XX_SETUP_SDHCI
86extern char *s3c64xx_hsmmc_clksrcs[4]; 117extern char *s3c64xx_hsmmc_clksrcs[4];
87 118
88#ifdef CONFIG_S3C_DEV_HSMMC
89extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev, 119extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
90 void __iomem *r, 120 void __iomem *r,
91 struct mmc_ios *ios, 121 struct mmc_ios *ios,
@@ -93,76 +123,62 @@ extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
93 123
94static inline void s3c6400_default_sdhci0(void) 124static inline void s3c6400_default_sdhci0(void)
95{ 125{
126#ifdef CONFIG_S3C_DEV_HSMMC
96 s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 127 s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
97 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; 128 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
98 s3c_hsmmc0_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card; 129 s3c_hsmmc0_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
130#endif
99} 131}
100 132
101#else
102static inline void s3c6400_default_sdhci0(void) { }
103#endif /* CONFIG_S3C_DEV_HSMMC */
104
105#ifdef CONFIG_S3C_DEV_HSMMC1
106static inline void s3c6400_default_sdhci1(void) 133static inline void s3c6400_default_sdhci1(void)
107{ 134{
135#ifdef CONFIG_S3C_DEV_HSMMC1
108 s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 136 s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
109 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; 137 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
110 s3c_hsmmc1_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card; 138 s3c_hsmmc1_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
139#endif
111} 140}
112#else
113static inline void s3c6400_default_sdhci1(void) { }
114#endif /* CONFIG_S3C_DEV_HSMMC1 */
115 141
116#ifdef CONFIG_S3C_DEV_HSMMC2
117static inline void s3c6400_default_sdhci2(void) 142static inline void s3c6400_default_sdhci2(void)
118{ 143{
144#ifdef CONFIG_S3C_DEV_HSMMC2
119 s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 145 s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
120 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; 146 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
121 s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card; 147 s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
148#endif
122} 149}
123#else
124static inline void s3c6400_default_sdhci2(void) { }
125#endif /* CONFIG_S3C_DEV_HSMMC2 */
126
127/* S3C6410 SDHCI setup */
128 150
129extern void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev, 151extern void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
130 void __iomem *r, 152 void __iomem *r,
131 struct mmc_ios *ios, 153 struct mmc_ios *ios,
132 struct mmc_card *card); 154 struct mmc_card *card);
133 155
134#ifdef CONFIG_S3C_DEV_HSMMC
135static inline void s3c6410_default_sdhci0(void) 156static inline void s3c6410_default_sdhci0(void)
136{ 157{
158#ifdef CONFIG_S3C_DEV_HSMMC
137 s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 159 s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
138 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; 160 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
139 s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card; 161 s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
162#endif
140} 163}
141#else
142static inline void s3c6410_default_sdhci0(void) { }
143#endif /* CONFIG_S3C_DEV_HSMMC */
144 164
145#ifdef CONFIG_S3C_DEV_HSMMC1
146static inline void s3c6410_default_sdhci1(void) 165static inline void s3c6410_default_sdhci1(void)
147{ 166{
167#ifdef CONFIG_S3C_DEV_HSMMC1
148 s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 168 s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
149 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; 169 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
150 s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card; 170 s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
171#endif
151} 172}
152#else
153static inline void s3c6410_default_sdhci1(void) { }
154#endif /* CONFIG_S3C_DEV_HSMMC1 */
155 173
156#ifdef CONFIG_S3C_DEV_HSMMC2
157static inline void s3c6410_default_sdhci2(void) 174static inline void s3c6410_default_sdhci2(void)
158{ 175{
176#ifdef CONFIG_S3C_DEV_HSMMC2
159 s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs; 177 s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
160 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; 178 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
161 s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card; 179 s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
180#endif
162} 181}
163#else
164static inline void s3c6410_default_sdhci2(void) { }
165#endif /* CONFIG_S3C_DEV_HSMMC2 */
166 182
167#else 183#else
168static inline void s3c6410_default_sdhci0(void) { } 184static inline void s3c6410_default_sdhci0(void) { }
@@ -184,48 +200,42 @@ extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
184 struct mmc_ios *ios, 200 struct mmc_ios *ios,
185 struct mmc_card *card); 201 struct mmc_card *card);
186 202
187#ifdef CONFIG_S3C_DEV_HSMMC
188static inline void s5pc100_default_sdhci0(void) 203static inline void s5pc100_default_sdhci0(void)
189{ 204{
205#ifdef CONFIG_S3C_DEV_HSMMC
190 s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs; 206 s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
191 s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio; 207 s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
192 s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card; 208 s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
209#endif
193} 210}
194#else
195static inline void s5pc100_default_sdhci0(void) { }
196#endif /* CONFIG_S3C_DEV_HSMMC */
197 211
198#ifdef CONFIG_S3C_DEV_HSMMC1
199static inline void s5pc100_default_sdhci1(void) 212static inline void s5pc100_default_sdhci1(void)
200{ 213{
214#ifdef CONFIG_S3C_DEV_HSMMC1
201 s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs; 215 s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
202 s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio; 216 s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
203 s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card; 217 s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
218#endif
204} 219}
205#else
206static inline void s5pc100_default_sdhci1(void) { }
207#endif /* CONFIG_S3C_DEV_HSMMC1 */
208 220
209#ifdef CONFIG_S3C_DEV_HSMMC2
210static inline void s5pc100_default_sdhci2(void) 221static inline void s5pc100_default_sdhci2(void)
211{ 222{
223#ifdef CONFIG_S3C_DEV_HSMMC2
212 s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs; 224 s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
213 s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio; 225 s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
214 s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card; 226 s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
227#endif
215} 228}
216#else
217static inline void s5pc100_default_sdhci2(void) { }
218#endif /* CONFIG_S3C_DEV_HSMMC1 */
219
220 229
221#else 230#else
222static inline void s5pc100_default_sdhci0(void) { } 231static inline void s5pc100_default_sdhci0(void) { }
223static inline void s5pc100_default_sdhci1(void) { } 232static inline void s5pc100_default_sdhci1(void) { }
224static inline void s5pc100_default_sdhci2(void) { } 233static inline void s5pc100_default_sdhci2(void) { }
234
225#endif /* CONFIG_S5PC100_SETUP_SDHCI */ 235#endif /* CONFIG_S5PC100_SETUP_SDHCI */
226 236
237/* S5PV210 SDHCI setup */
227 238
228/* S5PC110 SDHCI setup */
229#ifdef CONFIG_S5PV210_SETUP_SDHCI 239#ifdef CONFIG_S5PV210_SETUP_SDHCI
230extern char *s5pv210_hsmmc_clksrcs[4]; 240extern char *s5pv210_hsmmc_clksrcs[4];
231 241
@@ -234,58 +244,48 @@ extern void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
234 struct mmc_ios *ios, 244 struct mmc_ios *ios,
235 struct mmc_card *card); 245 struct mmc_card *card);
236 246
237#ifdef CONFIG_S3C_DEV_HSMMC
238static inline void s5pv210_default_sdhci0(void) 247static inline void s5pv210_default_sdhci0(void)
239{ 248{
249#ifdef CONFIG_S3C_DEV_HSMMC
240 s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs; 250 s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
241 s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio; 251 s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio;
242 s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card; 252 s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
253#endif
243} 254}
244#else
245static inline void s5pv210_default_sdhci0(void) { }
246#endif /* CONFIG_S3C_DEV_HSMMC */
247 255
248#ifdef CONFIG_S3C_DEV_HSMMC1
249static inline void s5pv210_default_sdhci1(void) 256static inline void s5pv210_default_sdhci1(void)
250{ 257{
258#ifdef CONFIG_S3C_DEV_HSMMC1
251 s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs; 259 s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
252 s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio; 260 s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio;
253 s3c_hsmmc1_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card; 261 s3c_hsmmc1_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
262#endif
254} 263}
255#else
256static inline void s5pv210_default_sdhci1(void) { }
257#endif /* CONFIG_S3C_DEV_HSMMC1 */
258 264
259#ifdef CONFIG_S3C_DEV_HSMMC2
260static inline void s5pv210_default_sdhci2(void) 265static inline void s5pv210_default_sdhci2(void)
261{ 266{
267#ifdef CONFIG_S3C_DEV_HSMMC2
262 s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs; 268 s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
263 s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio; 269 s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio;
264 s3c_hsmmc2_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card; 270 s3c_hsmmc2_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
271#endif
265} 272}
266#else
267static inline void s5pv210_default_sdhci2(void) { }
268#endif /* CONFIG_S3C_DEV_HSMMC2 */
269 273
270#ifdef CONFIG_S3C_DEV_HSMMC3
271static inline void s5pv210_default_sdhci3(void) 274static inline void s5pv210_default_sdhci3(void)
272{ 275{
276#ifdef CONFIG_S3C_DEV_HSMMC3
273 s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs; 277 s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
274 s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio; 278 s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
275 s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card; 279 s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
280#endif
276} 281}
277#else
278static inline void s5pv210_default_sdhci3(void) { }
279#endif /* CONFIG_S3C_DEV_HSMMC3 */
280 282
281#else 283#else
282static inline void s5pv210_default_sdhci0(void) { } 284static inline void s5pv210_default_sdhci0(void) { }
283static inline void s5pv210_default_sdhci1(void) { } 285static inline void s5pv210_default_sdhci1(void) { }
284static inline void s5pv210_default_sdhci2(void) { } 286static inline void s5pv210_default_sdhci2(void) { }
285static inline void s5pv210_default_sdhci3(void) { } 287static inline void s5pv210_default_sdhci3(void) { }
286#endif /* CONFIG_S5PC100_SETUP_SDHCI */
287
288
289 288
289#endif /* CONFIG_S5PV210_SETUP_SDHCI */
290 290
291#endif /* __PLAT_S3C_SDHCI_H */ 291#endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c
new file mode 100644
index 00000000000..7cf2e1e3b20
--- /dev/null
+++ b/arch/arm/plat-samsung/platformdata.c
@@ -0,0 +1,37 @@
1/* linux/arch/arm/plat-samsung/platformdata.c
2 *
3 * Copyright 2010 Ben Dooks <ben-linux <at> fluff.org>
4 *
5 * Helper for platform data setting
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#include <linux/kernel.h>
13#include <linux/string.h>
14#include <linux/platform_device.h>
15
16#include <plat/devs.h>
17
18void __init *s3c_set_platdata(void *pd, size_t pdsize,
19 struct platform_device *pdev)
20{
21 void *npd;
22
23 if (!pd) {
24 /* too early to use dev_name(), may not be registered */
25 printk(KERN_ERR "%s: no platform data supplied\n", pdev->name);
26 return NULL;
27 }
28
29 npd = kmemdup(pd, pdsize, GFP_KERNEL);
30 if (!npd) {
31 printk(KERN_ERR "%s: cannot clone platform data\n", pdev->name);
32 return NULL;
33 }
34
35 pdev->dev.platform_data = npd;
36 return npd;
37}
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 54109dc9240..25be2102a60 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1315,10 +1315,14 @@ static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
1315 if (test_bit(EV_SND, dev->evbit)) 1315 if (test_bit(EV_SND, dev->evbit))
1316 return true; 1316 return true;
1317 1317
1318 if (test_bit(EV_KEY, dev->evbit)) 1318 if (test_bit(EV_KEY, dev->evbit)) {
1319 for (i = KEY_RESERVED; i < BTN_MISC; i++) 1319 for (i = KEY_RESERVED; i < BTN_MISC; i++)
1320 if (test_bit(i, dev->keybit)) 1320 if (test_bit(i, dev->keybit))
1321 return true; 1321 return true;
1322 for (i = KEY_BRL_DOT1; i <= KEY_BRL_DOT10; i++)
1323 if (test_bit(i, dev->keybit))
1324 return true;
1325 }
1322 1326
1323 return false; 1327 return false;
1324} 1328}
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 866e54ec5fb..b54a9a608ac 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1586,6 +1586,7 @@ static const struct hid_device_id hid_ignore_list[] = {
1586 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, 1586 { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
1587 { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, 1587 { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
1588 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, 1588 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
1589 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
1589 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, 1590 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) },
1590 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, 1591 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) },
1591 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, 1592 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 31601eef25d..8aee2577c1a 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -198,6 +198,7 @@
198 198
199#define USB_VENDOR_ID_ETT 0x0664 199#define USB_VENDOR_ID_ETT 0x0664
200#define USB_DEVICE_ID_TC5UH 0x0309 200#define USB_DEVICE_ID_TC5UH 0x0309
201#define USB_DEVICE_ID_TC4UM 0x0306
201 202
202#define USB_VENDOR_ID_EZKEY 0x0518 203#define USB_VENDOR_ID_EZKEY 0x0518
203#define USB_DEVICE_ID_BTC_8193 0x0002 204#define USB_DEVICE_ID_BTC_8193 0x0002
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 7a0d2e4661a..69d152e16a6 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -534,6 +534,9 @@ mapped:
534 input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4); 534 input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4);
535 else input_set_abs_params(input, usage->code, a, b, 0, 0); 535 else input_set_abs_params(input, usage->code, a, b, 0, 0);
536 536
537 /* use a larger default input buffer for MT devices */
538 if (usage->code == ABS_MT_POSITION_X && input->hint_events_per_packet == 0)
539 input_set_events_per_packet(input, 60);
537 } 540 }
538 541
539 if (usage->type == EV_ABS && 542 if (usage->type == EV_ABS &&
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index bceafbfa726..80143899cce 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -521,12 +521,19 @@ config I2C_PXA_SLAVE
521 is necessary for systems where the PXA may be a target on the 521 is necessary for systems where the PXA may be a target on the
522 I2C bus. 522 I2C bus.
523 523
524config HAVE_S3C2410_I2C
525 bool
526 help
527 This will include I2C support for Samsung SoCs. If you want to
528 include I2C support for any machine, kindly select this in the
529 respective Kconfig file.
530
524config I2C_S3C2410 531config I2C_S3C2410
525 tristate "S3C2410 I2C Driver" 532 tristate "S3C2410 I2C Driver"
526 depends on ARCH_S3C2410 || ARCH_S3C64XX 533 depends on HAVE_S3C2410_I2C
527 help 534 help
528 Say Y here to include support for I2C controller in the 535 Say Y here to include support for I2C controller in the
529 Samsung S3C2410 based System-on-Chip devices. 536 Samsung SoCs.
530 537
531config I2C_S6000 538config I2C_S6000
532 tristate "S6000 I2C support" 539 tristate "S6000 I2C support"
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 2ee6c7a68bd..054edf346e0 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -10,7 +10,8 @@
10 10
11#define EVDEV_MINOR_BASE 64 11#define EVDEV_MINOR_BASE 64
12#define EVDEV_MINORS 32 12#define EVDEV_MINORS 32
13#define EVDEV_BUFFER_SIZE 64 13#define EVDEV_MIN_BUFFER_SIZE 64U
14#define EVDEV_BUF_PACKETS 8
14 15
15#include <linux/poll.h> 16#include <linux/poll.h>
16#include <linux/sched.h> 17#include <linux/sched.h>
@@ -23,7 +24,6 @@
23#include "input-compat.h" 24#include "input-compat.h"
24 25
25struct evdev { 26struct evdev {
26 int exist;
27 int open; 27 int open;
28 int minor; 28 int minor;
29 struct input_handle handle; 29 struct input_handle handle;
@@ -33,16 +33,18 @@ struct evdev {
33 spinlock_t client_lock; /* protects client_list */ 33 spinlock_t client_lock; /* protects client_list */
34 struct mutex mutex; 34 struct mutex mutex;
35 struct device dev; 35 struct device dev;
36 bool exist;
36}; 37};
37 38
38struct evdev_client { 39struct evdev_client {
39 struct input_event buffer[EVDEV_BUFFER_SIZE];
40 int head; 40 int head;
41 int tail; 41 int tail;
42 spinlock_t buffer_lock; /* protects access to buffer, head and tail */ 42 spinlock_t buffer_lock; /* protects access to buffer, head and tail */
43 struct fasync_struct *fasync; 43 struct fasync_struct *fasync;
44 struct evdev *evdev; 44 struct evdev *evdev;
45 struct list_head node; 45 struct list_head node;
46 int bufsize;
47 struct input_event buffer[];
46}; 48};
47 49
48static struct evdev *evdev_table[EVDEV_MINORS]; 50static struct evdev *evdev_table[EVDEV_MINORS];
@@ -52,11 +54,15 @@ static void evdev_pass_event(struct evdev_client *client,
52 struct input_event *event) 54 struct input_event *event)
53{ 55{
54 /* 56 /*
55 * Interrupts are disabled, just acquire the lock 57 * Interrupts are disabled, just acquire the lock.
58 * Make sure we don't leave with the client buffer
59 * "empty" by having client->head == client->tail.
56 */ 60 */
57 spin_lock(&client->buffer_lock); 61 spin_lock(&client->buffer_lock);
58 client->buffer[client->head++] = *event; 62 do {
59 client->head &= EVDEV_BUFFER_SIZE - 1; 63 client->buffer[client->head++] = *event;
64 client->head &= client->bufsize - 1;
65 } while (client->head == client->tail);
60 spin_unlock(&client->buffer_lock); 66 spin_unlock(&client->buffer_lock);
61 67
62 if (event->type == EV_SYN) 68 if (event->type == EV_SYN)
@@ -242,11 +248,21 @@ static int evdev_release(struct inode *inode, struct file *file)
242 return 0; 248 return 0;
243} 249}
244 250
251static unsigned int evdev_compute_buffer_size(struct input_dev *dev)
252{
253 unsigned int n_events =
254 max(dev->hint_events_per_packet * EVDEV_BUF_PACKETS,
255 EVDEV_MIN_BUFFER_SIZE);
256
257 return roundup_pow_of_two(n_events);
258}
259
245static int evdev_open(struct inode *inode, struct file *file) 260static int evdev_open(struct inode *inode, struct file *file)
246{ 261{
247 struct evdev *evdev; 262 struct evdev *evdev;
248 struct evdev_client *client; 263 struct evdev_client *client;
249 int i = iminor(inode) - EVDEV_MINOR_BASE; 264 int i = iminor(inode) - EVDEV_MINOR_BASE;
265 unsigned int bufsize;
250 int error; 266 int error;
251 267
252 if (i >= EVDEV_MINORS) 268 if (i >= EVDEV_MINORS)
@@ -263,12 +279,17 @@ static int evdev_open(struct inode *inode, struct file *file)
263 if (!evdev) 279 if (!evdev)
264 return -ENODEV; 280 return -ENODEV;
265 281
266 client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); 282 bufsize = evdev_compute_buffer_size(evdev->handle.dev);
283
284 client = kzalloc(sizeof(struct evdev_client) +
285 bufsize * sizeof(struct input_event),
286 GFP_KERNEL);
267 if (!client) { 287 if (!client) {
268 error = -ENOMEM; 288 error = -ENOMEM;
269 goto err_put_evdev; 289 goto err_put_evdev;
270 } 290 }
271 291
292 client->bufsize = bufsize;
272 spin_lock_init(&client->buffer_lock); 293 spin_lock_init(&client->buffer_lock);
273 client->evdev = evdev; 294 client->evdev = evdev;
274 evdev_attach_client(evdev, client); 295 evdev_attach_client(evdev, client);
@@ -334,7 +355,7 @@ static int evdev_fetch_next_event(struct evdev_client *client,
334 have_event = client->head != client->tail; 355 have_event = client->head != client->tail;
335 if (have_event) { 356 if (have_event) {
336 *event = client->buffer[client->tail++]; 357 *event = client->buffer[client->tail++];
337 client->tail &= EVDEV_BUFFER_SIZE - 1; 358 client->tail &= client->bufsize - 1;
338 } 359 }
339 360
340 spin_unlock_irq(&client->buffer_lock); 361 spin_unlock_irq(&client->buffer_lock);
@@ -382,10 +403,15 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait)
382{ 403{
383 struct evdev_client *client = file->private_data; 404 struct evdev_client *client = file->private_data;
384 struct evdev *evdev = client->evdev; 405 struct evdev *evdev = client->evdev;
406 unsigned int mask;
385 407
386 poll_wait(file, &evdev->wait, wait); 408 poll_wait(file, &evdev->wait, wait);
387 return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) | 409
388 (evdev->exist ? 0 : (POLLHUP | POLLERR)); 410 mask = evdev->exist ? POLLOUT | POLLWRNORM : POLLHUP | POLLERR;
411 if (client->head != client->tail)
412 mask |= POLLIN | POLLRDNORM;
413
414 return mask;
389} 415}
390 416
391#ifdef CONFIG_COMPAT 417#ifdef CONFIG_COMPAT
@@ -665,6 +691,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
665 sizeof(struct input_absinfo)))) 691 sizeof(struct input_absinfo))))
666 return -EFAULT; 692 return -EFAULT;
667 693
694 /* We can't change number of reserved MT slots */
695 if (t == ABS_MT_SLOT)
696 return -EINVAL;
697
668 /* 698 /*
669 * Take event lock to ensure that we are not 699 * Take event lock to ensure that we are not
670 * changing device parameters in the middle 700 * changing device parameters in the middle
@@ -768,7 +798,7 @@ static void evdev_remove_chrdev(struct evdev *evdev)
768static void evdev_mark_dead(struct evdev *evdev) 798static void evdev_mark_dead(struct evdev *evdev)
769{ 799{
770 mutex_lock(&evdev->mutex); 800 mutex_lock(&evdev->mutex);
771 evdev->exist = 0; 801 evdev->exist = false;
772 mutex_unlock(&evdev->mutex); 802 mutex_unlock(&evdev->mutex);
773} 803}
774 804
@@ -817,7 +847,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
817 init_waitqueue_head(&evdev->wait); 847 init_waitqueue_head(&evdev->wait);
818 848
819 dev_set_name(&evdev->dev, "event%d", minor); 849 dev_set_name(&evdev->dev, "event%d", minor);
820 evdev->exist = 1; 850 evdev->exist = true;
821 evdev->minor = minor; 851 evdev->minor = minor;
822 852
823 evdev->handle.dev = input_get_device(dev); 853 evdev->handle.dev = input_get_device(dev);
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 9c79bd56b51..e1243b4b32a 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -33,25 +33,6 @@ MODULE_LICENSE("GPL");
33 33
34#define INPUT_DEVICES 256 34#define INPUT_DEVICES 256
35 35
36/*
37 * EV_ABS events which should not be cached are listed here.
38 */
39static unsigned int input_abs_bypass_init_data[] __initdata = {
40 ABS_MT_TOUCH_MAJOR,
41 ABS_MT_TOUCH_MINOR,
42 ABS_MT_WIDTH_MAJOR,
43 ABS_MT_WIDTH_MINOR,
44 ABS_MT_ORIENTATION,
45 ABS_MT_POSITION_X,
46 ABS_MT_POSITION_Y,
47 ABS_MT_TOOL_TYPE,
48 ABS_MT_BLOB_ID,
49 ABS_MT_TRACKING_ID,
50 ABS_MT_PRESSURE,
51 0
52};
53static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)];
54
55static LIST_HEAD(input_dev_list); 36static LIST_HEAD(input_dev_list);
56static LIST_HEAD(input_handler_list); 37static LIST_HEAD(input_handler_list);
57 38
@@ -181,6 +162,56 @@ static void input_stop_autorepeat(struct input_dev *dev)
181#define INPUT_PASS_TO_DEVICE 2 162#define INPUT_PASS_TO_DEVICE 2
182#define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) 163#define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
183 164
165static int input_handle_abs_event(struct input_dev *dev,
166 unsigned int code, int *pval)
167{
168 bool is_mt_event;
169 int *pold;
170
171 if (code == ABS_MT_SLOT) {
172 /*
173 * "Stage" the event; we'll flush it later, when we
174 * get actiual touch data.
175 */
176 if (*pval >= 0 && *pval < dev->mtsize)
177 dev->slot = *pval;
178
179 return INPUT_IGNORE_EVENT;
180 }
181
182 is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST;
183
184 if (!is_mt_event) {
185 pold = &dev->abs[code];
186 } else if (dev->mt) {
187 struct input_mt_slot *mtslot = &dev->mt[dev->slot];
188 pold = &mtslot->abs[code - ABS_MT_FIRST];
189 } else {
190 /*
191 * Bypass filtering for multitouch events when
192 * not employing slots.
193 */
194 pold = NULL;
195 }
196
197 if (pold) {
198 *pval = input_defuzz_abs_event(*pval, *pold,
199 dev->absfuzz[code]);
200 if (*pold == *pval)
201 return INPUT_IGNORE_EVENT;
202
203 *pold = *pval;
204 }
205
206 /* Flush pending "slot" event */
207 if (is_mt_event && dev->slot != dev->abs[ABS_MT_SLOT]) {
208 dev->abs[ABS_MT_SLOT] = dev->slot;
209 input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
210 }
211
212 return INPUT_PASS_TO_HANDLERS;
213}
214
184static void input_handle_event(struct input_dev *dev, 215static void input_handle_event(struct input_dev *dev,
185 unsigned int type, unsigned int code, int value) 216 unsigned int type, unsigned int code, int value)
186{ 217{
@@ -196,12 +227,12 @@ static void input_handle_event(struct input_dev *dev,
196 227
197 case SYN_REPORT: 228 case SYN_REPORT:
198 if (!dev->sync) { 229 if (!dev->sync) {
199 dev->sync = 1; 230 dev->sync = true;
200 disposition = INPUT_PASS_TO_HANDLERS; 231 disposition = INPUT_PASS_TO_HANDLERS;
201 } 232 }
202 break; 233 break;
203 case SYN_MT_REPORT: 234 case SYN_MT_REPORT:
204 dev->sync = 0; 235 dev->sync = false;
205 disposition = INPUT_PASS_TO_HANDLERS; 236 disposition = INPUT_PASS_TO_HANDLERS;
206 break; 237 break;
207 } 238 }
@@ -233,21 +264,9 @@ static void input_handle_event(struct input_dev *dev,
233 break; 264 break;
234 265
235 case EV_ABS: 266 case EV_ABS:
236 if (is_event_supported(code, dev->absbit, ABS_MAX)) { 267 if (is_event_supported(code, dev->absbit, ABS_MAX))
237 268 disposition = input_handle_abs_event(dev, code, &value);
238 if (test_bit(code, input_abs_bypass)) {
239 disposition = INPUT_PASS_TO_HANDLERS;
240 break;
241 }
242 269
243 value = input_defuzz_abs_event(value,
244 dev->abs[code], dev->absfuzz[code]);
245
246 if (dev->abs[code] != value) {
247 dev->abs[code] = value;
248 disposition = INPUT_PASS_TO_HANDLERS;
249 }
250 }
251 break; 270 break;
252 271
253 case EV_REL: 272 case EV_REL:
@@ -298,7 +317,7 @@ static void input_handle_event(struct input_dev *dev,
298 } 317 }
299 318
300 if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) 319 if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
301 dev->sync = 0; 320 dev->sync = false;
302 321
303 if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) 322 if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
304 dev->event(dev, type, code, value); 323 dev->event(dev, type, code, value);
@@ -528,12 +547,30 @@ void input_close_device(struct input_handle *handle)
528EXPORT_SYMBOL(input_close_device); 547EXPORT_SYMBOL(input_close_device);
529 548
530/* 549/*
550 * Simulate keyup events for all keys that are marked as pressed.
551 * The function must be called with dev->event_lock held.
552 */
553static void input_dev_release_keys(struct input_dev *dev)
554{
555 int code;
556
557 if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
558 for (code = 0; code <= KEY_MAX; code++) {
559 if (is_event_supported(code, dev->keybit, KEY_MAX) &&
560 __test_and_clear_bit(code, dev->key)) {
561 input_pass_event(dev, EV_KEY, code, 0);
562 }
563 }
564 input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
565 }
566}
567
568/*
531 * Prepare device for unregistering 569 * Prepare device for unregistering
532 */ 570 */
533static void input_disconnect_device(struct input_dev *dev) 571static void input_disconnect_device(struct input_dev *dev)
534{ 572{
535 struct input_handle *handle; 573 struct input_handle *handle;
536 int code;
537 574
538 /* 575 /*
539 * Mark device as going away. Note that we take dev->mutex here 576 * Mark device as going away. Note that we take dev->mutex here
@@ -552,15 +589,7 @@ static void input_disconnect_device(struct input_dev *dev)
552 * generate events even after we done here but they will not 589 * generate events even after we done here but they will not
553 * reach any handlers. 590 * reach any handlers.
554 */ 591 */
555 if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) { 592 input_dev_release_keys(dev);
556 for (code = 0; code <= KEY_MAX; code++) {
557 if (is_event_supported(code, dev->keybit, KEY_MAX) &&
558 __test_and_clear_bit(code, dev->key)) {
559 input_pass_event(dev, EV_KEY, code, 0);
560 }
561 }
562 input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
563 }
564 593
565 list_for_each_entry(handle, &dev->h_list, d_node) 594 list_for_each_entry(handle, &dev->h_list, d_node)
566 handle->open = 0; 595 handle->open = 0;
@@ -684,7 +713,7 @@ int input_set_keycode(struct input_dev *dev,
684 unsigned int scancode, unsigned int keycode) 713 unsigned int scancode, unsigned int keycode)
685{ 714{
686 unsigned long flags; 715 unsigned long flags;
687 int old_keycode; 716 unsigned int old_keycode;
688 int retval; 717 int retval;
689 718
690 if (keycode > KEY_MAX) 719 if (keycode > KEY_MAX)
@@ -1278,6 +1307,7 @@ static void input_dev_release(struct device *device)
1278 struct input_dev *dev = to_input_dev(device); 1307 struct input_dev *dev = to_input_dev(device);
1279 1308
1280 input_ff_destroy(dev); 1309 input_ff_destroy(dev);
1310 input_mt_destroy_slots(dev);
1281 kfree(dev); 1311 kfree(dev);
1282 1312
1283 module_put(THIS_MODULE); 1313 module_put(THIS_MODULE);
@@ -1433,6 +1463,15 @@ static int input_dev_resume(struct device *dev)
1433 1463
1434 mutex_lock(&input_dev->mutex); 1464 mutex_lock(&input_dev->mutex);
1435 input_dev_reset(input_dev, true); 1465 input_dev_reset(input_dev, true);
1466
1467 /*
1468 * Keys that have been pressed at suspend time are unlikely
1469 * to be still pressed when we resume.
1470 */
1471 spin_lock_irq(&input_dev->event_lock);
1472 input_dev_release_keys(input_dev);
1473 spin_unlock_irq(&input_dev->event_lock);
1474
1436 mutex_unlock(&input_dev->mutex); 1475 mutex_unlock(&input_dev->mutex);
1437 1476
1438 return 0; 1477 return 0;
@@ -1518,6 +1557,45 @@ void input_free_device(struct input_dev *dev)
1518EXPORT_SYMBOL(input_free_device); 1557EXPORT_SYMBOL(input_free_device);
1519 1558
1520/** 1559/**
1560 * input_mt_create_slots() - create MT input slots
1561 * @dev: input device supporting MT events and finger tracking
1562 * @num_slots: number of slots used by the device
1563 *
1564 * This function allocates all necessary memory for MT slot handling
1565 * in the input device, and adds ABS_MT_SLOT to the device capabilities.
1566 */
1567int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots)
1568{
1569 if (!num_slots)
1570 return 0;
1571
1572 dev->mt = kcalloc(num_slots, sizeof(struct input_mt_slot), GFP_KERNEL);
1573 if (!dev->mt)
1574 return -ENOMEM;
1575
1576 dev->mtsize = num_slots;
1577 input_set_abs_params(dev, ABS_MT_SLOT, 0, num_slots - 1, 0, 0);
1578
1579 return 0;
1580}
1581EXPORT_SYMBOL(input_mt_create_slots);
1582
1583/**
1584 * input_mt_destroy_slots() - frees the MT slots of the input device
1585 * @dev: input device with allocated MT slots
1586 *
1587 * This function is only needed in error path as the input core will
1588 * automatically free the MT slots when the device is destroyed.
1589 */
1590void input_mt_destroy_slots(struct input_dev *dev)
1591{
1592 kfree(dev->mt);
1593 dev->mt = NULL;
1594 dev->mtsize = 0;
1595}
1596EXPORT_SYMBOL(input_mt_destroy_slots);
1597
1598/**
1521 * input_set_capability - mark device as capable of a certain event 1599 * input_set_capability - mark device as capable of a certain event
1522 * @dev: device that is capable of emitting or accepting event 1600 * @dev: device that is capable of emitting or accepting event
1523 * @type: type of the event (EV_KEY, EV_REL, etc...) 1601 * @type: type of the event (EV_KEY, EV_REL, etc...)
@@ -1926,20 +2004,10 @@ static const struct file_operations input_fops = {
1926 .open = input_open_file, 2004 .open = input_open_file,
1927}; 2005};
1928 2006
1929static void __init input_init_abs_bypass(void)
1930{
1931 const unsigned int *p;
1932
1933 for (p = input_abs_bypass_init_data; *p; p++)
1934 input_abs_bypass[BIT_WORD(*p)] |= BIT_MASK(*p);
1935}
1936
1937static int __init input_init(void) 2007static int __init input_init(void)
1938{ 2008{
1939 int err; 2009 int err;
1940 2010
1941 input_init_abs_bypass();
1942
1943 err = class_register(&input_class); 2011 err = class_register(&input_class);
1944 if (err) { 2012 if (err) {
1945 printk(KERN_ERR "input: unable to register input_dev class\n"); 2013 printk(KERN_ERR "input: unable to register input_dev class\n");
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 34157bb97ed..63834585c28 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -37,7 +37,6 @@ MODULE_LICENSE("GPL");
37#define JOYDEV_BUFFER_SIZE 64 37#define JOYDEV_BUFFER_SIZE 64
38 38
39struct joydev { 39struct joydev {
40 int exist;
41 int open; 40 int open;
42 int minor; 41 int minor;
43 struct input_handle handle; 42 struct input_handle handle;
@@ -46,6 +45,7 @@ struct joydev {
46 spinlock_t client_lock; /* protects client_list */ 45 spinlock_t client_lock; /* protects client_list */
47 struct mutex mutex; 46 struct mutex mutex;
48 struct device dev; 47 struct device dev;
48 bool exist;
49 49
50 struct js_corr corr[ABS_CNT]; 50 struct js_corr corr[ABS_CNT];
51 struct JS_DATA_SAVE_TYPE glue; 51 struct JS_DATA_SAVE_TYPE glue;
@@ -760,7 +760,7 @@ static void joydev_remove_chrdev(struct joydev *joydev)
760static void joydev_mark_dead(struct joydev *joydev) 760static void joydev_mark_dead(struct joydev *joydev)
761{ 761{
762 mutex_lock(&joydev->mutex); 762 mutex_lock(&joydev->mutex);
763 joydev->exist = 0; 763 joydev->exist = false;
764 mutex_unlock(&joydev->mutex); 764 mutex_unlock(&joydev->mutex);
765} 765}
766 766
@@ -817,10 +817,9 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
817 init_waitqueue_head(&joydev->wait); 817 init_waitqueue_head(&joydev->wait);
818 818
819 dev_set_name(&joydev->dev, "js%d", minor); 819 dev_set_name(&joydev->dev, "js%d", minor);
820 joydev->exist = 1; 820 joydev->exist = true;
821 joydev->minor = minor; 821 joydev->minor = minor;
822 822
823 joydev->exist = 1;
824 joydev->handle.dev = input_get_device(dev); 823 joydev->handle.dev = input_get_device(dev);
825 joydev->handle.name = dev_name(&joydev->dev); 824 joydev->handle.name = dev_name(&joydev->dev);
826 joydev->handle.handler = handler; 825 joydev->handle.handler = handler;
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index c1087ce4cef..269a846f369 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -9,6 +9,7 @@
9 * 2005 Dominic Cerquetti <binary1230@yahoo.com> 9 * 2005 Dominic Cerquetti <binary1230@yahoo.com>
10 * 2006 Adam Buchbinder <adam.buchbinder@gmail.com> 10 * 2006 Adam Buchbinder <adam.buchbinder@gmail.com>
11 * 2007 Jan Kratochvil <honza@jikos.cz> 11 * 2007 Jan Kratochvil <honza@jikos.cz>
12 * 2010 Christoph Fritz <chf.fritz@googlemail.com>
12 * 13 *
13 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as 15 * modify it under the terms of the GNU General Public License as
@@ -88,6 +89,9 @@
88 but we map them to axes when possible to simplify things */ 89 but we map them to axes when possible to simplify things */
89#define MAP_DPAD_TO_BUTTONS (1 << 0) 90#define MAP_DPAD_TO_BUTTONS (1 << 0)
90#define MAP_TRIGGERS_TO_BUTTONS (1 << 1) 91#define MAP_TRIGGERS_TO_BUTTONS (1 << 1)
92#define MAP_STICKS_TO_NULL (1 << 2)
93#define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \
94 MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL)
91 95
92#define XTYPE_XBOX 0 96#define XTYPE_XBOX 0
93#define XTYPE_XBOX360 1 97#define XTYPE_XBOX360 1
@@ -102,6 +106,10 @@ static int triggers_to_buttons;
102module_param(triggers_to_buttons, bool, S_IRUGO); 106module_param(triggers_to_buttons, bool, S_IRUGO);
103MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads"); 107MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads");
104 108
109static int sticks_to_null;
110module_param(sticks_to_null, bool, S_IRUGO);
111MODULE_PARM_DESC(sticks_to_null, "Do not map sticks at all for unknown pads");
112
105static const struct xpad_device { 113static const struct xpad_device {
106 u16 idVendor; 114 u16 idVendor;
107 u16 idProduct; 115 u16 idProduct;
@@ -114,7 +122,7 @@ static const struct xpad_device {
114 { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX }, 122 { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX },
115 { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, 123 { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX },
116 { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, 124 { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
117 { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, 125 { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", DANCEPAD_MAP_CONFIG, XTYPE_XBOX },
118 { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, 126 { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
119 { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, 127 { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 },
120 { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, 128 { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX },
@@ -151,6 +159,7 @@ static const struct xpad_device {
151 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, 159 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
152 { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, 160 { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
153 { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, 161 { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
162 { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
154 { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, 163 { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
155 { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } 164 { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
156}; 165};
@@ -158,7 +167,7 @@ static const struct xpad_device {
158/* buttons shared with xbox and xbox360 */ 167/* buttons shared with xbox and xbox360 */
159static const signed short xpad_common_btn[] = { 168static const signed short xpad_common_btn[] = {
160 BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */ 169 BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */
161 BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */ 170 BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */
162 -1 /* terminating entry */ 171 -1 /* terminating entry */
163}; 172};
164 173
@@ -168,10 +177,10 @@ static const signed short xpad_btn[] = {
168 -1 /* terminating entry */ 177 -1 /* terminating entry */
169}; 178};
170 179
171/* used when dpad is mapped to nuttons */ 180/* used when dpad is mapped to buttons */
172static const signed short xpad_btn_pad[] = { 181static const signed short xpad_btn_pad[] = {
173 BTN_LEFT, BTN_RIGHT, /* d-pad left, right */ 182 BTN_TRIGGER_HAPPY1, BTN_TRIGGER_HAPPY2, /* d-pad left, right */
174 BTN_0, BTN_1, /* d-pad up, down (XXX names??) */ 183 BTN_TRIGGER_HAPPY3, BTN_TRIGGER_HAPPY4, /* d-pad up, down */
175 -1 /* terminating entry */ 184 -1 /* terminating entry */
176}; 185};
177 186
@@ -279,17 +288,19 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
279{ 288{
280 struct input_dev *dev = xpad->dev; 289 struct input_dev *dev = xpad->dev;
281 290
282 /* left stick */ 291 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
283 input_report_abs(dev, ABS_X, 292 /* left stick */
284 (__s16) le16_to_cpup((__le16 *)(data + 12))); 293 input_report_abs(dev, ABS_X,
285 input_report_abs(dev, ABS_Y, 294 (__s16) le16_to_cpup((__le16 *)(data + 12)));
286 ~(__s16) le16_to_cpup((__le16 *)(data + 14))); 295 input_report_abs(dev, ABS_Y,
287 296 ~(__s16) le16_to_cpup((__le16 *)(data + 14)));
288 /* right stick */ 297
289 input_report_abs(dev, ABS_RX, 298 /* right stick */
290 (__s16) le16_to_cpup((__le16 *)(data + 16))); 299 input_report_abs(dev, ABS_RX,
291 input_report_abs(dev, ABS_RY, 300 (__s16) le16_to_cpup((__le16 *)(data + 16)));
292 ~(__s16) le16_to_cpup((__le16 *)(data + 18))); 301 input_report_abs(dev, ABS_RY,
302 ~(__s16) le16_to_cpup((__le16 *)(data + 18)));
303 }
293 304
294 /* triggers left/right */ 305 /* triggers left/right */
295 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { 306 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
@@ -302,10 +313,11 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
302 313
303 /* digital pad */ 314 /* digital pad */
304 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { 315 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
305 input_report_key(dev, BTN_LEFT, data[2] & 0x04); 316 /* dpad as buttons (left, right, up, down) */
306 input_report_key(dev, BTN_RIGHT, data[2] & 0x08); 317 input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
307 input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ 318 input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
308 input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ 319 input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
320 input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
309 } else { 321 } else {
310 input_report_abs(dev, ABS_HAT0X, 322 input_report_abs(dev, ABS_HAT0X,
311 !!(data[2] & 0x08) - !!(data[2] & 0x04)); 323 !!(data[2] & 0x08) - !!(data[2] & 0x04));
@@ -315,7 +327,7 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
315 327
316 /* start/back buttons and stick press left/right */ 328 /* start/back buttons and stick press left/right */
317 input_report_key(dev, BTN_START, data[2] & 0x10); 329 input_report_key(dev, BTN_START, data[2] & 0x10);
318 input_report_key(dev, BTN_BACK, data[2] & 0x20); 330 input_report_key(dev, BTN_SELECT, data[2] & 0x20);
319 input_report_key(dev, BTN_THUMBL, data[2] & 0x40); 331 input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
320 input_report_key(dev, BTN_THUMBR, data[2] & 0x80); 332 input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
321 333
@@ -349,11 +361,11 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
349 361
350 /* digital pad */ 362 /* digital pad */
351 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { 363 if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
352 /* dpad as buttons (right, left, down, up) */ 364 /* dpad as buttons (left, right, up, down) */
353 input_report_key(dev, BTN_LEFT, data[2] & 0x04); 365 input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
354 input_report_key(dev, BTN_RIGHT, data[2] & 0x08); 366 input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
355 input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ 367 input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
356 input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ 368 input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
357 } else { 369 } else {
358 input_report_abs(dev, ABS_HAT0X, 370 input_report_abs(dev, ABS_HAT0X,
359 !!(data[2] & 0x08) - !!(data[2] & 0x04)); 371 !!(data[2] & 0x08) - !!(data[2] & 0x04));
@@ -363,7 +375,7 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
363 375
364 /* start/back buttons */ 376 /* start/back buttons */
365 input_report_key(dev, BTN_START, data[2] & 0x10); 377 input_report_key(dev, BTN_START, data[2] & 0x10);
366 input_report_key(dev, BTN_BACK, data[2] & 0x20); 378 input_report_key(dev, BTN_SELECT, data[2] & 0x20);
367 379
368 /* stick press left/right */ 380 /* stick press left/right */
369 input_report_key(dev, BTN_THUMBL, data[2] & 0x40); 381 input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
@@ -378,17 +390,19 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
378 input_report_key(dev, BTN_TR, data[3] & 0x02); 390 input_report_key(dev, BTN_TR, data[3] & 0x02);
379 input_report_key(dev, BTN_MODE, data[3] & 0x04); 391 input_report_key(dev, BTN_MODE, data[3] & 0x04);
380 392
381 /* left stick */ 393 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
382 input_report_abs(dev, ABS_X, 394 /* left stick */
383 (__s16) le16_to_cpup((__le16 *)(data + 6))); 395 input_report_abs(dev, ABS_X,
384 input_report_abs(dev, ABS_Y, 396 (__s16) le16_to_cpup((__le16 *)(data + 6)));
385 ~(__s16) le16_to_cpup((__le16 *)(data + 8))); 397 input_report_abs(dev, ABS_Y,
386 398 ~(__s16) le16_to_cpup((__le16 *)(data + 8)));
387 /* right stick */ 399
388 input_report_abs(dev, ABS_RX, 400 /* right stick */
389 (__s16) le16_to_cpup((__le16 *)(data + 10))); 401 input_report_abs(dev, ABS_RX,
390 input_report_abs(dev, ABS_RY, 402 (__s16) le16_to_cpup((__le16 *)(data + 10)));
391 ~(__s16) le16_to_cpup((__le16 *)(data + 12))); 403 input_report_abs(dev, ABS_RY,
404 ~(__s16) le16_to_cpup((__le16 *)(data + 12)));
405 }
392 406
393 /* triggers left/right */ 407 /* triggers left/right */
394 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { 408 if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
@@ -814,6 +828,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
814 xpad->mapping |= MAP_DPAD_TO_BUTTONS; 828 xpad->mapping |= MAP_DPAD_TO_BUTTONS;
815 if (triggers_to_buttons) 829 if (triggers_to_buttons)
816 xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS; 830 xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
831 if (sticks_to_null)
832 xpad->mapping |= MAP_STICKS_TO_NULL;
817 } 833 }
818 834
819 xpad->dev = input_dev; 835 xpad->dev = input_dev;
@@ -830,16 +846,20 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
830 input_dev->open = xpad_open; 846 input_dev->open = xpad_open;
831 input_dev->close = xpad_close; 847 input_dev->close = xpad_close;
832 848
833 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 849 input_dev->evbit[0] = BIT_MASK(EV_KEY);
850
851 if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
852 input_dev->evbit[0] |= BIT_MASK(EV_ABS);
853 /* set up axes */
854 for (i = 0; xpad_abs[i] >= 0; i++)
855 xpad_set_up_abs(input_dev, xpad_abs[i]);
856 }
834 857
835 /* set up standard buttons and axes */ 858 /* set up standard buttons */
836 for (i = 0; xpad_common_btn[i] >= 0; i++) 859 for (i = 0; xpad_common_btn[i] >= 0; i++)
837 __set_bit(xpad_common_btn[i], input_dev->keybit); 860 __set_bit(xpad_common_btn[i], input_dev->keybit);
838 861
839 for (i = 0; xpad_abs[i] >= 0; i++) 862 /* set up model-specific ones */
840 xpad_set_up_abs(input_dev, xpad_abs[i]);
841
842 /* Now set up model-specific ones */
843 if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { 863 if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
844 for (i = 0; xpad360_btn[i] >= 0; i++) 864 for (i = 0; xpad360_btn[i] >= 0; i++)
845 __set_bit(xpad360_btn[i], input_dev->keybit); 865 __set_bit(xpad360_btn[i], input_dev->keybit);
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 1ba25145b33..b171f63fe4d 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -297,6 +297,18 @@ config KEYBOARD_MAX7359
297 To compile this driver as a module, choose M here: the 297 To compile this driver as a module, choose M here: the
298 module will be called max7359_keypad. 298 module will be called max7359_keypad.
299 299
300config KEYBOARD_MCS
301 tristate "MELFAS MCS Touchkey"
302 depends on I2C
303 help
304 Say Y here if you have the MELFAS MCS5000/5080 touchkey controller
305 chip in your system.
306
307 If unsure, say N.
308
309 To compile this driver as a module, choose M here: the
310 module will be called mcs_touchkey.
311
300config KEYBOARD_IMX 312config KEYBOARD_IMX
301 tristate "IMX keypad support" 313 tristate "IMX keypad support"
302 depends on ARCH_MXC 314 depends on ARCH_MXC
@@ -342,6 +354,15 @@ config KEYBOARD_PXA930_ROTARY
342 To compile this driver as a module, choose M here: the 354 To compile this driver as a module, choose M here: the
343 module will be called pxa930_rotary. 355 module will be called pxa930_rotary.
344 356
357config KEYBOARD_SAMSUNG
358 tristate "Samsung keypad support"
359 depends on SAMSUNG_DEV_KEYPAD
360 help
361 Say Y here if you want to use the Samsung keypad.
362
363 To compile this driver as a module, choose M here: the
364 module will be called samsung-keypad.
365
345config KEYBOARD_STOWAWAY 366config KEYBOARD_STOWAWAY
346 tristate "Stowaway keyboard" 367 tristate "Stowaway keyboard"
347 select SERIO 368 select SERIO
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 4596d0c6f92..1a66d5f1ca8 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -26,12 +26,14 @@ obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o
26obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o 26obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
27obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o 27obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o
28obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o 28obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o
29obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o
29obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o 30obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
30obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o 31obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
31obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o 32obj-$(CONFIG_KEYBOARD_OPENCORES) += opencores-kbd.o
32obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o 33obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o
33obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o 34obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o
34obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o 35obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o
36obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o
35obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o 37obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
36obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o 38obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
37obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o 39obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c
index 744600eff22..d6918cb966c 100644
--- a/drivers/input/keyboard/adp5588-keys.c
+++ b/drivers/input/keyboard/adp5588-keys.c
@@ -19,6 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/input.h> 20#include <linux/input.h>
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/gpio.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
23 24
24#include <linux/i2c/adp5588.h> 25#include <linux/i2c/adp5588.h>
@@ -54,6 +55,10 @@
54 55
55#define KEYP_MAX_EVENT 10 56#define KEYP_MAX_EVENT 10
56 57
58#define MAXGPIO 18
59#define ADP_BANK(offs) ((offs) >> 3)
60#define ADP_BIT(offs) (1u << ((offs) & 0x7))
61
57/* 62/*
58 * Early pre 4.0 Silicon required to delay readout by at least 25ms, 63 * Early pre 4.0 Silicon required to delay readout by at least 25ms,
59 * since the Event Counter Register updated 25ms after the interrupt 64 * since the Event Counter Register updated 25ms after the interrupt
@@ -67,6 +72,16 @@ struct adp5588_kpad {
67 struct delayed_work work; 72 struct delayed_work work;
68 unsigned long delay; 73 unsigned long delay;
69 unsigned short keycode[ADP5588_KEYMAPSIZE]; 74 unsigned short keycode[ADP5588_KEYMAPSIZE];
75 const struct adp5588_gpi_map *gpimap;
76 unsigned short gpimapsize;
77#ifdef CONFIG_GPIOLIB
78 unsigned char gpiomap[MAXGPIO];
79 bool export_gpio;
80 struct gpio_chip gc;
81 struct mutex gpio_lock; /* Protect cached dir, dat_out */
82 u8 dat_out[3];
83 u8 dir[3];
84#endif
70}; 85};
71 86
72static int adp5588_read(struct i2c_client *client, u8 reg) 87static int adp5588_read(struct i2c_client *client, u8 reg)
@@ -84,12 +99,222 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val)
84 return i2c_smbus_write_byte_data(client, reg, val); 99 return i2c_smbus_write_byte_data(client, reg, val);
85} 100}
86 101
102#ifdef CONFIG_GPIOLIB
103static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
104{
105 struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
106 unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
107 unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
108
109 return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit);
110}
111
112static void adp5588_gpio_set_value(struct gpio_chip *chip,
113 unsigned off, int val)
114{
115 struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
116 unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
117 unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
118
119 mutex_lock(&kpad->gpio_lock);
120
121 if (val)
122 kpad->dat_out[bank] |= bit;
123 else
124 kpad->dat_out[bank] &= ~bit;
125
126 adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank,
127 kpad->dat_out[bank]);
128
129 mutex_unlock(&kpad->gpio_lock);
130}
131
132static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off)
133{
134 struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
135 unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
136 unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
137 int ret;
138
139 mutex_lock(&kpad->gpio_lock);
140
141 kpad->dir[bank] &= ~bit;
142 ret = adp5588_write(kpad->client, GPIO_DIR1 + bank, kpad->dir[bank]);
143
144 mutex_unlock(&kpad->gpio_lock);
145
146 return ret;
147}
148
149static int adp5588_gpio_direction_output(struct gpio_chip *chip,
150 unsigned off, int val)
151{
152 struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
153 unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
154 unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
155 int ret;
156
157 mutex_lock(&kpad->gpio_lock);
158
159 kpad->dir[bank] |= bit;
160
161 if (val)
162 kpad->dat_out[bank] |= bit;
163 else
164 kpad->dat_out[bank] &= ~bit;
165
166 ret = adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank,
167 kpad->dat_out[bank]);
168 ret |= adp5588_write(kpad->client, GPIO_DIR1 + bank,
169 kpad->dir[bank]);
170
171 mutex_unlock(&kpad->gpio_lock);
172
173 return ret;
174}
175
176static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad,
177 const struct adp5588_kpad_platform_data *pdata)
178{
179 bool pin_used[MAXGPIO];
180 int n_unused = 0;
181 int i;
182
183 memset(pin_used, 0, sizeof(pin_used));
184
185 for (i = 0; i < pdata->rows; i++)
186 pin_used[i] = true;
187
188 for (i = 0; i < pdata->cols; i++)
189 pin_used[i + GPI_PIN_COL_BASE - GPI_PIN_BASE] = true;
190
191 for (i = 0; i < kpad->gpimapsize; i++)
192 pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true;
193
194 for (i = 0; i < MAXGPIO; i++)
195 if (!pin_used[i])
196 kpad->gpiomap[n_unused++] = i;
197
198 return n_unused;
199}
200
201static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad)
202{
203 struct device *dev = &kpad->client->dev;
204 const struct adp5588_kpad_platform_data *pdata = dev->platform_data;
205 const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
206 int i, error;
207
208 if (!gpio_data)
209 return 0;
210
211 kpad->gc.ngpio = adp5588_build_gpiomap(kpad, pdata);
212 if (kpad->gc.ngpio == 0) {
213 dev_info(dev, "No unused gpios left to export\n");
214 return 0;
215 }
216
217 kpad->export_gpio = true;
218
219 kpad->gc.direction_input = adp5588_gpio_direction_input;
220 kpad->gc.direction_output = adp5588_gpio_direction_output;
221 kpad->gc.get = adp5588_gpio_get_value;
222 kpad->gc.set = adp5588_gpio_set_value;
223 kpad->gc.can_sleep = 1;
224
225 kpad->gc.base = gpio_data->gpio_start;
226 kpad->gc.label = kpad->client->name;
227 kpad->gc.owner = THIS_MODULE;
228
229 mutex_init(&kpad->gpio_lock);
230
231 error = gpiochip_add(&kpad->gc);
232 if (error) {
233 dev_err(dev, "gpiochip_add failed, err: %d\n", error);
234 return error;
235 }
236
237 for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
238 kpad->dat_out[i] = adp5588_read(kpad->client,
239 GPIO_DAT_OUT1 + i);
240 kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i);
241 }
242
243 if (gpio_data->setup) {
244 error = gpio_data->setup(kpad->client,
245 kpad->gc.base, kpad->gc.ngpio,
246 gpio_data->context);
247 if (error)
248 dev_warn(dev, "setup failed, %d\n", error);
249 }
250
251 return 0;
252}
253
254static void __devexit adp5588_gpio_remove(struct adp5588_kpad *kpad)
255{
256 struct device *dev = &kpad->client->dev;
257 const struct adp5588_kpad_platform_data *pdata = dev->platform_data;
258 const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
259 int error;
260
261 if (!kpad->export_gpio)
262 return;
263
264 if (gpio_data->teardown) {
265 error = gpio_data->teardown(kpad->client,
266 kpad->gc.base, kpad->gc.ngpio,
267 gpio_data->context);
268 if (error)
269 dev_warn(dev, "teardown failed %d\n", error);
270 }
271
272 error = gpiochip_remove(&kpad->gc);
273 if (error)
274 dev_warn(dev, "gpiochip_remove failed %d\n", error);
275}
276#else
277static inline int adp5588_gpio_add(struct adp5588_kpad *kpad)
278{
279 return 0;
280}
281
282static inline void adp5588_gpio_remove(struct adp5588_kpad *kpad)
283{
284}
285#endif
286
287static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt)
288{
289 int i, j;
290
291 for (i = 0; i < ev_cnt; i++) {
292 int key = adp5588_read(kpad->client, Key_EVENTA + i);
293 int key_val = key & KEY_EV_MASK;
294
295 if (key_val >= GPI_PIN_BASE && key_val <= GPI_PIN_END) {
296 for (j = 0; j < kpad->gpimapsize; j++) {
297 if (key_val == kpad->gpimap[j].pin) {
298 input_report_switch(kpad->input,
299 kpad->gpimap[j].sw_evt,
300 key & KEY_EV_PRESSED);
301 break;
302 }
303 }
304 } else {
305 input_report_key(kpad->input,
306 kpad->keycode[key_val - 1],
307 key & KEY_EV_PRESSED);
308 }
309 }
310}
311
87static void adp5588_work(struct work_struct *work) 312static void adp5588_work(struct work_struct *work)
88{ 313{
89 struct adp5588_kpad *kpad = container_of(work, 314 struct adp5588_kpad *kpad = container_of(work,
90 struct adp5588_kpad, work.work); 315 struct adp5588_kpad, work.work);
91 struct i2c_client *client = kpad->client; 316 struct i2c_client *client = kpad->client;
92 int i, key, status, ev_cnt; 317 int status, ev_cnt;
93 318
94 status = adp5588_read(client, INT_STAT); 319 status = adp5588_read(client, INT_STAT);
95 320
@@ -99,12 +324,7 @@ static void adp5588_work(struct work_struct *work)
99 if (status & KE_INT) { 324 if (status & KE_INT) {
100 ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC; 325 ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC;
101 if (ev_cnt) { 326 if (ev_cnt) {
102 for (i = 0; i < ev_cnt; i++) { 327 adp5588_report_events(kpad, ev_cnt);
103 key = adp5588_read(client, Key_EVENTA + i);
104 input_report_key(kpad->input,
105 kpad->keycode[(key & KEY_EV_MASK) - 1],
106 key & KEY_EV_PRESSED);
107 }
108 input_sync(kpad->input); 328 input_sync(kpad->input);
109 } 329 }
110 } 330 }
@@ -128,8 +348,10 @@ static irqreturn_t adp5588_irq(int irq, void *handle)
128 348
129static int __devinit adp5588_setup(struct i2c_client *client) 349static int __devinit adp5588_setup(struct i2c_client *client)
130{ 350{
131 struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; 351 const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data;
352 const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
132 int i, ret; 353 int i, ret;
354 unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0;
133 355
134 ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows)); 356 ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows));
135 ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF); 357 ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF);
@@ -144,6 +366,32 @@ static int __devinit adp5588_setup(struct i2c_client *client)
144 for (i = 0; i < KEYP_MAX_EVENT; i++) 366 for (i = 0; i < KEYP_MAX_EVENT; i++)
145 ret |= adp5588_read(client, Key_EVENTA); 367 ret |= adp5588_read(client, Key_EVENTA);
146 368
369 for (i = 0; i < pdata->gpimapsize; i++) {
370 unsigned short pin = pdata->gpimap[i].pin;
371
372 if (pin <= GPI_PIN_ROW_END) {
373 evt_mode1 |= (1 << (pin - GPI_PIN_ROW_BASE));
374 } else {
375 evt_mode2 |= ((1 << (pin - GPI_PIN_COL_BASE)) & 0xFF);
376 evt_mode3 |= ((1 << (pin - GPI_PIN_COL_BASE)) >> 8);
377 }
378 }
379
380 if (pdata->gpimapsize) {
381 ret |= adp5588_write(client, GPI_EM1, evt_mode1);
382 ret |= adp5588_write(client, GPI_EM2, evt_mode2);
383 ret |= adp5588_write(client, GPI_EM3, evt_mode3);
384 }
385
386 if (gpio_data) {
387 for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
388 int pull_mask = gpio_data->pullup_dis_mask;
389
390 ret |= adp5588_write(client, GPIO_PULL1 + i,
391 (pull_mask >> (8 * i)) & 0xFF);
392 }
393 }
394
147 ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT | 395 ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT |
148 OVR_FLOW_INT | K_LCK_INT | 396 OVR_FLOW_INT | K_LCK_INT |
149 GPI_INT | KE_INT); /* Status is W1C */ 397 GPI_INT | KE_INT); /* Status is W1C */
@@ -158,11 +406,49 @@ static int __devinit adp5588_setup(struct i2c_client *client)
158 return 0; 406 return 0;
159} 407}
160 408
409static void __devinit adp5588_report_switch_state(struct adp5588_kpad *kpad)
410{
411 int gpi_stat1 = adp5588_read(kpad->client, GPIO_DAT_STAT1);
412 int gpi_stat2 = adp5588_read(kpad->client, GPIO_DAT_STAT2);
413 int gpi_stat3 = adp5588_read(kpad->client, GPIO_DAT_STAT3);
414 int gpi_stat_tmp, pin_loc;
415 int i;
416
417 for (i = 0; i < kpad->gpimapsize; i++) {
418 unsigned short pin = kpad->gpimap[i].pin;
419
420 if (pin <= GPI_PIN_ROW_END) {
421 gpi_stat_tmp = gpi_stat1;
422 pin_loc = pin - GPI_PIN_ROW_BASE;
423 } else if ((pin - GPI_PIN_COL_BASE) < 8) {
424 gpi_stat_tmp = gpi_stat2;
425 pin_loc = pin - GPI_PIN_COL_BASE;
426 } else {
427 gpi_stat_tmp = gpi_stat3;
428 pin_loc = pin - GPI_PIN_COL_BASE - 8;
429 }
430
431 if (gpi_stat_tmp < 0) {
432 dev_err(&kpad->client->dev,
433 "Can't read GPIO_DAT_STAT switch %d default to OFF\n",
434 pin);
435 gpi_stat_tmp = 0;
436 }
437
438 input_report_switch(kpad->input,
439 kpad->gpimap[i].sw_evt,
440 !(gpi_stat_tmp & (1 << pin_loc)));
441 }
442
443 input_sync(kpad->input);
444}
445
446
161static int __devinit adp5588_probe(struct i2c_client *client, 447static int __devinit adp5588_probe(struct i2c_client *client,
162 const struct i2c_device_id *id) 448 const struct i2c_device_id *id)
163{ 449{
164 struct adp5588_kpad *kpad; 450 struct adp5588_kpad *kpad;
165 struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; 451 const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data;
166 struct input_dev *input; 452 struct input_dev *input;
167 unsigned int revid; 453 unsigned int revid;
168 int ret, i; 454 int ret, i;
@@ -189,6 +475,37 @@ static int __devinit adp5588_probe(struct i2c_client *client,
189 return -EINVAL; 475 return -EINVAL;
190 } 476 }
191 477
478 if (!pdata->gpimap && pdata->gpimapsize) {
479 dev_err(&client->dev, "invalid gpimap from pdata\n");
480 return -EINVAL;
481 }
482
483 if (pdata->gpimapsize > ADP5588_GPIMAPSIZE_MAX) {
484 dev_err(&client->dev, "invalid gpimapsize\n");
485 return -EINVAL;
486 }
487
488 for (i = 0; i < pdata->gpimapsize; i++) {
489 unsigned short pin = pdata->gpimap[i].pin;
490
491 if (pin < GPI_PIN_BASE || pin > GPI_PIN_END) {
492 dev_err(&client->dev, "invalid gpi pin data\n");
493 return -EINVAL;
494 }
495
496 if (pin <= GPI_PIN_ROW_END) {
497 if (pin - GPI_PIN_ROW_BASE + 1 <= pdata->rows) {
498 dev_err(&client->dev, "invalid gpi row data\n");
499 return -EINVAL;
500 }
501 } else {
502 if (pin - GPI_PIN_COL_BASE + 1 <= pdata->cols) {
503 dev_err(&client->dev, "invalid gpi col data\n");
504 return -EINVAL;
505 }
506 }
507 }
508
192 if (!client->irq) { 509 if (!client->irq) {
193 dev_err(&client->dev, "no IRQ?\n"); 510 dev_err(&client->dev, "no IRQ?\n");
194 return -EINVAL; 511 return -EINVAL;
@@ -233,6 +550,9 @@ static int __devinit adp5588_probe(struct i2c_client *client,
233 memcpy(kpad->keycode, pdata->keymap, 550 memcpy(kpad->keycode, pdata->keymap,
234 pdata->keymapsize * input->keycodesize); 551 pdata->keymapsize * input->keycodesize);
235 552
553 kpad->gpimap = pdata->gpimap;
554 kpad->gpimapsize = pdata->gpimapsize;
555
236 /* setup input device */ 556 /* setup input device */
237 __set_bit(EV_KEY, input->evbit); 557 __set_bit(EV_KEY, input->evbit);
238 558
@@ -243,6 +563,11 @@ static int __devinit adp5588_probe(struct i2c_client *client,
243 __set_bit(kpad->keycode[i] & KEY_MAX, input->keybit); 563 __set_bit(kpad->keycode[i] & KEY_MAX, input->keybit);
244 __clear_bit(KEY_RESERVED, input->keybit); 564 __clear_bit(KEY_RESERVED, input->keybit);
245 565
566 if (kpad->gpimapsize)
567 __set_bit(EV_SW, input->evbit);
568 for (i = 0; i < kpad->gpimapsize; i++)
569 __set_bit(kpad->gpimap[i].sw_evt, input->swbit);
570
246 error = input_register_device(input); 571 error = input_register_device(input);
247 if (error) { 572 if (error) {
248 dev_err(&client->dev, "unable to register input device\n"); 573 dev_err(&client->dev, "unable to register input device\n");
@@ -261,6 +586,13 @@ static int __devinit adp5588_probe(struct i2c_client *client,
261 if (error) 586 if (error)
262 goto err_free_irq; 587 goto err_free_irq;
263 588
589 if (kpad->gpimapsize)
590 adp5588_report_switch_state(kpad);
591
592 error = adp5588_gpio_add(kpad);
593 if (error)
594 goto err_free_irq;
595
264 device_init_wakeup(&client->dev, 1); 596 device_init_wakeup(&client->dev, 1);
265 i2c_set_clientdata(client, kpad); 597 i2c_set_clientdata(client, kpad);
266 598
@@ -287,6 +619,7 @@ static int __devexit adp5588_remove(struct i2c_client *client)
287 free_irq(client->irq, kpad); 619 free_irq(client->irq, kpad);
288 cancel_delayed_work_sync(&kpad->work); 620 cancel_delayed_work_sync(&kpad->work);
289 input_unregister_device(kpad->input); 621 input_unregister_device(kpad->input);
622 adp5588_gpio_remove(kpad);
290 kfree(kpad); 623 kfree(kpad);
291 624
292 return 0; 625 return 0;
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index b8213fd13c3..a9fd147f2ba 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -31,6 +31,7 @@ struct gpio_button_data {
31 struct input_dev *input; 31 struct input_dev *input;
32 struct timer_list timer; 32 struct timer_list timer;
33 struct work_struct work; 33 struct work_struct work;
34 int timer_debounce; /* in msecs */
34 bool disabled; 35 bool disabled;
35}; 36};
36 37
@@ -109,7 +110,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
109 * Disable IRQ and possible debouncing timer. 110 * Disable IRQ and possible debouncing timer.
110 */ 111 */
111 disable_irq(gpio_to_irq(bdata->button->gpio)); 112 disable_irq(gpio_to_irq(bdata->button->gpio));
112 if (bdata->button->debounce_interval) 113 if (bdata->timer_debounce)
113 del_timer_sync(&bdata->timer); 114 del_timer_sync(&bdata->timer);
114 115
115 bdata->disabled = true; 116 bdata->disabled = true;
@@ -347,9 +348,9 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
347 348
348 BUG_ON(irq != gpio_to_irq(button->gpio)); 349 BUG_ON(irq != gpio_to_irq(button->gpio));
349 350
350 if (button->debounce_interval) 351 if (bdata->timer_debounce)
351 mod_timer(&bdata->timer, 352 mod_timer(&bdata->timer,
352 jiffies + msecs_to_jiffies(button->debounce_interval)); 353 jiffies + msecs_to_jiffies(bdata->timer_debounce));
353 else 354 else
354 schedule_work(&bdata->work); 355 schedule_work(&bdata->work);
355 356
@@ -383,6 +384,14 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev,
383 goto fail3; 384 goto fail3;
384 } 385 }
385 386
387 if (button->debounce_interval) {
388 error = gpio_set_debounce(button->gpio,
389 button->debounce_interval * 1000);
390 /* use timer if gpiolib doesn't provide debounce */
391 if (error < 0)
392 bdata->timer_debounce = button->debounce_interval;
393 }
394
386 irq = gpio_to_irq(button->gpio); 395 irq = gpio_to_irq(button->gpio);
387 if (irq < 0) { 396 if (irq < 0) {
388 error = irq; 397 error = irq;
@@ -498,7 +507,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
498 fail2: 507 fail2:
499 while (--i >= 0) { 508 while (--i >= 0) {
500 free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); 509 free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
501 if (pdata->buttons[i].debounce_interval) 510 if (ddata->data[i].timer_debounce)
502 del_timer_sync(&ddata->data[i].timer); 511 del_timer_sync(&ddata->data[i].timer);
503 cancel_work_sync(&ddata->data[i].work); 512 cancel_work_sync(&ddata->data[i].work);
504 gpio_free(pdata->buttons[i].gpio); 513 gpio_free(pdata->buttons[i].gpio);
@@ -526,7 +535,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
526 for (i = 0; i < pdata->nbuttons; i++) { 535 for (i = 0; i < pdata->nbuttons; i++) {
527 int irq = gpio_to_irq(pdata->buttons[i].gpio); 536 int irq = gpio_to_irq(pdata->buttons[i].gpio);
528 free_irq(irq, &ddata->data[i]); 537 free_irq(irq, &ddata->data[i]);
529 if (pdata->buttons[i].debounce_interval) 538 if (ddata->data[i].timer_debounce)
530 del_timer_sync(&ddata->data[i].timer); 539 del_timer_sync(&ddata->data[i].timer);
531 cancel_work_sync(&ddata->data[i].work); 540 cancel_work_sync(&ddata->data[i].work);
532 gpio_free(pdata->buttons[i].gpio); 541 gpio_free(pdata->buttons[i].gpio);
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c
index 40b032f0e32..f7c2a166576 100644
--- a/drivers/input/keyboard/lm8323.c
+++ b/drivers/input/keyboard/lm8323.c
@@ -642,6 +642,7 @@ static int __devinit lm8323_probe(struct i2c_client *client,
642 struct lm8323_platform_data *pdata = client->dev.platform_data; 642 struct lm8323_platform_data *pdata = client->dev.platform_data;
643 struct input_dev *idev; 643 struct input_dev *idev;
644 struct lm8323_chip *lm; 644 struct lm8323_chip *lm;
645 int pwm;
645 int i, err; 646 int i, err;
646 unsigned long tmo; 647 unsigned long tmo;
647 u8 data[2]; 648 u8 data[2];
@@ -710,8 +711,9 @@ static int __devinit lm8323_probe(struct i2c_client *client,
710 goto fail1; 711 goto fail1;
711 } 712 }
712 713
713 for (i = 0; i < LM8323_NUM_PWMS; i++) { 714 for (pwm = 0; pwm < LM8323_NUM_PWMS; pwm++) {
714 err = init_pwm(lm, i + 1, &client->dev, pdata->pwm_names[i]); 715 err = init_pwm(lm, pwm + 1, &client->dev,
716 pdata->pwm_names[pwm]);
715 if (err < 0) 717 if (err < 0)
716 goto fail2; 718 goto fail2;
717 } 719 }
@@ -764,9 +766,9 @@ fail4:
764fail3: 766fail3:
765 device_remove_file(&client->dev, &dev_attr_disable_kp); 767 device_remove_file(&client->dev, &dev_attr_disable_kp);
766fail2: 768fail2:
767 while (--i >= 0) 769 while (--pwm >= 0)
768 if (lm->pwm[i].enabled) 770 if (lm->pwm[pwm].enabled)
769 led_classdev_unregister(&lm->pwm[i].cdev); 771 led_classdev_unregister(&lm->pwm[pwm].cdev);
770fail1: 772fail1:
771 input_free_device(idev); 773 input_free_device(idev);
772 kfree(lm); 774 kfree(lm);
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index b443e088fd3..b02e4268e18 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -37,6 +37,7 @@ struct matrix_keypad {
37 spinlock_t lock; 37 spinlock_t lock;
38 bool scan_pending; 38 bool scan_pending;
39 bool stopped; 39 bool stopped;
40 bool gpio_all_disabled;
40}; 41};
41 42
42/* 43/*
@@ -87,8 +88,12 @@ static void enable_row_irqs(struct matrix_keypad *keypad)
87 const struct matrix_keypad_platform_data *pdata = keypad->pdata; 88 const struct matrix_keypad_platform_data *pdata = keypad->pdata;
88 int i; 89 int i;
89 90
90 for (i = 0; i < pdata->num_row_gpios; i++) 91 if (pdata->clustered_irq > 0)
91 enable_irq(gpio_to_irq(pdata->row_gpios[i])); 92 enable_irq(pdata->clustered_irq);
93 else {
94 for (i = 0; i < pdata->num_row_gpios; i++)
95 enable_irq(gpio_to_irq(pdata->row_gpios[i]));
96 }
92} 97}
93 98
94static void disable_row_irqs(struct matrix_keypad *keypad) 99static void disable_row_irqs(struct matrix_keypad *keypad)
@@ -96,8 +101,12 @@ static void disable_row_irqs(struct matrix_keypad *keypad)
96 const struct matrix_keypad_platform_data *pdata = keypad->pdata; 101 const struct matrix_keypad_platform_data *pdata = keypad->pdata;
97 int i; 102 int i;
98 103
99 for (i = 0; i < pdata->num_row_gpios; i++) 104 if (pdata->clustered_irq > 0)
100 disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i])); 105 disable_irq_nosync(pdata->clustered_irq);
106 else {
107 for (i = 0; i < pdata->num_row_gpios; i++)
108 disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i]));
109 }
101} 110}
102 111
103/* 112/*
@@ -216,45 +225,69 @@ static void matrix_keypad_stop(struct input_dev *dev)
216} 225}
217 226
218#ifdef CONFIG_PM 227#ifdef CONFIG_PM
219static int matrix_keypad_suspend(struct device *dev) 228static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad)
220{ 229{
221 struct platform_device *pdev = to_platform_device(dev);
222 struct matrix_keypad *keypad = platform_get_drvdata(pdev);
223 const struct matrix_keypad_platform_data *pdata = keypad->pdata; 230 const struct matrix_keypad_platform_data *pdata = keypad->pdata;
231 unsigned int gpio;
224 int i; 232 int i;
225 233
226 matrix_keypad_stop(keypad->input_dev); 234 if (pdata->clustered_irq > 0) {
235 if (enable_irq_wake(pdata->clustered_irq) == 0)
236 keypad->gpio_all_disabled = true;
237 } else {
227 238
228 if (device_may_wakeup(&pdev->dev)) {
229 for (i = 0; i < pdata->num_row_gpios; i++) { 239 for (i = 0; i < pdata->num_row_gpios; i++) {
230 if (!test_bit(i, keypad->disabled_gpios)) { 240 if (!test_bit(i, keypad->disabled_gpios)) {
231 unsigned int gpio = pdata->row_gpios[i]; 241 gpio = pdata->row_gpios[i];
232 242
233 if (enable_irq_wake(gpio_to_irq(gpio)) == 0) 243 if (enable_irq_wake(gpio_to_irq(gpio)) == 0)
234 __set_bit(i, keypad->disabled_gpios); 244 __set_bit(i, keypad->disabled_gpios);
235 } 245 }
236 } 246 }
237 } 247 }
238
239 return 0;
240} 248}
241 249
242static int matrix_keypad_resume(struct device *dev) 250static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad)
243{ 251{
244 struct platform_device *pdev = to_platform_device(dev);
245 struct matrix_keypad *keypad = platform_get_drvdata(pdev);
246 const struct matrix_keypad_platform_data *pdata = keypad->pdata; 252 const struct matrix_keypad_platform_data *pdata = keypad->pdata;
253 unsigned int gpio;
247 int i; 254 int i;
248 255
249 if (device_may_wakeup(&pdev->dev)) { 256 if (pdata->clustered_irq > 0) {
257 if (keypad->gpio_all_disabled) {
258 disable_irq_wake(pdata->clustered_irq);
259 keypad->gpio_all_disabled = false;
260 }
261 } else {
250 for (i = 0; i < pdata->num_row_gpios; i++) { 262 for (i = 0; i < pdata->num_row_gpios; i++) {
251 if (test_and_clear_bit(i, keypad->disabled_gpios)) { 263 if (test_and_clear_bit(i, keypad->disabled_gpios)) {
252 unsigned int gpio = pdata->row_gpios[i]; 264 gpio = pdata->row_gpios[i];
253
254 disable_irq_wake(gpio_to_irq(gpio)); 265 disable_irq_wake(gpio_to_irq(gpio));
255 } 266 }
256 } 267 }
257 } 268 }
269}
270
271static int matrix_keypad_suspend(struct device *dev)
272{
273 struct platform_device *pdev = to_platform_device(dev);
274 struct matrix_keypad *keypad = platform_get_drvdata(pdev);
275
276 matrix_keypad_stop(keypad->input_dev);
277
278 if (device_may_wakeup(&pdev->dev))
279 matrix_keypad_enable_wakeup(keypad);
280
281 return 0;
282}
283
284static int matrix_keypad_resume(struct device *dev)
285{
286 struct platform_device *pdev = to_platform_device(dev);
287 struct matrix_keypad *keypad = platform_get_drvdata(pdev);
288
289 if (device_may_wakeup(&pdev->dev))
290 matrix_keypad_disable_wakeup(keypad);
258 291
259 matrix_keypad_start(keypad->input_dev); 292 matrix_keypad_start(keypad->input_dev);
260 293
@@ -296,17 +329,31 @@ static int __devinit init_matrix_gpio(struct platform_device *pdev,
296 gpio_direction_input(pdata->row_gpios[i]); 329 gpio_direction_input(pdata->row_gpios[i]);
297 } 330 }
298 331
299 for (i = 0; i < pdata->num_row_gpios; i++) { 332 if (pdata->clustered_irq > 0) {
300 err = request_irq(gpio_to_irq(pdata->row_gpios[i]), 333 err = request_irq(pdata->clustered_irq,
301 matrix_keypad_interrupt, 334 matrix_keypad_interrupt,
302 IRQF_DISABLED | 335 pdata->clustered_irq_flags,
303 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
304 "matrix-keypad", keypad); 336 "matrix-keypad", keypad);
305 if (err) { 337 if (err) {
306 dev_err(&pdev->dev, 338 dev_err(&pdev->dev,
307 "Unable to acquire interrupt for GPIO line %i\n", 339 "Unable to acquire clustered interrupt\n");
308 pdata->row_gpios[i]); 340 goto err_free_rows;
309 goto err_free_irqs; 341 }
342 } else {
343 for (i = 0; i < pdata->num_row_gpios; i++) {
344 err = request_irq(gpio_to_irq(pdata->row_gpios[i]),
345 matrix_keypad_interrupt,
346 IRQF_DISABLED |
347 IRQF_TRIGGER_RISING |
348 IRQF_TRIGGER_FALLING,
349 "matrix-keypad", keypad);
350 if (err) {
351 dev_err(&pdev->dev,
352 "Unable to acquire interrupt "
353 "for GPIO line %i\n",
354 pdata->row_gpios[i]);
355 goto err_free_irqs;
356 }
310 } 357 }
311 } 358 }
312 359
@@ -418,11 +465,16 @@ static int __devexit matrix_keypad_remove(struct platform_device *pdev)
418 465
419 device_init_wakeup(&pdev->dev, 0); 466 device_init_wakeup(&pdev->dev, 0);
420 467
421 for (i = 0; i < pdata->num_row_gpios; i++) { 468 if (pdata->clustered_irq > 0) {
422 free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); 469 free_irq(pdata->clustered_irq, keypad);
423 gpio_free(pdata->row_gpios[i]); 470 } else {
471 for (i = 0; i < pdata->num_row_gpios; i++)
472 free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad);
424 } 473 }
425 474
475 for (i = 0; i < pdata->num_row_gpios; i++)
476 gpio_free(pdata->row_gpios[i]);
477
426 for (i = 0; i < pdata->num_col_gpios; i++) 478 for (i = 0; i < pdata->num_col_gpios; i++)
427 gpio_free(pdata->col_gpios[i]); 479 gpio_free(pdata->col_gpios[i]);
428 480
diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c
new file mode 100644
index 00000000000..63b849d7e90
--- /dev/null
+++ b/drivers/input/keyboard/mcs_touchkey.c
@@ -0,0 +1,239 @@
1/*
2 * mcs_touchkey.c - Touchkey driver for MELFAS MCS5000/5080 controller
3 *
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5 * Author: HeungJun Kim <riverful.kim@samsung.com>
6 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/i2c.h>
17#include <linux/i2c/mcs.h>
18#include <linux/interrupt.h>
19#include <linux/input.h>
20#include <linux/irq.h>
21#include <linux/slab.h>
22
23/* MCS5000 Touchkey */
24#define MCS5000_TOUCHKEY_STATUS 0x04
25#define MCS5000_TOUCHKEY_STATUS_PRESS 7
26#define MCS5000_TOUCHKEY_FW 0x0a
27#define MCS5000_TOUCHKEY_BASE_VAL 0x61
28
29/* MCS5080 Touchkey */
30#define MCS5080_TOUCHKEY_STATUS 0x00
31#define MCS5080_TOUCHKEY_STATUS_PRESS 3
32#define MCS5080_TOUCHKEY_FW 0x01
33#define MCS5080_TOUCHKEY_BASE_VAL 0x1
34
35enum mcs_touchkey_type {
36 MCS5000_TOUCHKEY,
37 MCS5080_TOUCHKEY,
38};
39
40struct mcs_touchkey_chip {
41 unsigned int status_reg;
42 unsigned int pressbit;
43 unsigned int press_invert;
44 unsigned int baseval;
45};
46
47struct mcs_touchkey_data {
48 struct i2c_client *client;
49 struct input_dev *input_dev;
50 struct mcs_touchkey_chip chip;
51 unsigned int key_code;
52 unsigned int key_val;
53 unsigned short keycodes[];
54};
55
56static irqreturn_t mcs_touchkey_interrupt(int irq, void *dev_id)
57{
58 struct mcs_touchkey_data *data = dev_id;
59 struct mcs_touchkey_chip *chip = &data->chip;
60 struct i2c_client *client = data->client;
61 struct input_dev *input = data->input_dev;
62 unsigned int key_val;
63 unsigned int pressed;
64 int val;
65
66 val = i2c_smbus_read_byte_data(client, chip->status_reg);
67 if (val < 0) {
68 dev_err(&client->dev, "i2c read error [%d]\n", val);
69 goto out;
70 }
71
72 pressed = (val & (1 << chip->pressbit)) >> chip->pressbit;
73 if (chip->press_invert)
74 pressed ^= chip->press_invert;
75
76 /* key_val is 0 when released, so we should use key_val of press. */
77 if (pressed) {
78 key_val = val & (0xff >> (8 - chip->pressbit));
79 if (!key_val)
80 goto out;
81 key_val -= chip->baseval;
82 data->key_code = data->keycodes[key_val];
83 data->key_val = key_val;
84 }
85
86 input_event(input, EV_MSC, MSC_SCAN, data->key_val);
87 input_report_key(input, data->key_code, pressed);
88 input_sync(input);
89
90 dev_dbg(&client->dev, "key %d %d %s\n", data->key_val, data->key_code,
91 pressed ? "pressed" : "released");
92
93 out:
94 return IRQ_HANDLED;
95}
96
97static int __devinit mcs_touchkey_probe(struct i2c_client *client,
98 const struct i2c_device_id *id)
99{
100 const struct mcs_platform_data *pdata;
101 struct mcs_touchkey_data *data;
102 struct input_dev *input_dev;
103 unsigned int fw_reg;
104 int fw_ver;
105 int error;
106 int i;
107
108 pdata = client->dev.platform_data;
109 if (!pdata) {
110 dev_err(&client->dev, "no platform data defined\n");
111 return -EINVAL;
112 }
113
114 data = kzalloc(sizeof(struct mcs_touchkey_data) +
115 sizeof(data->keycodes[0]) * (pdata->key_maxval + 1),
116 GFP_KERNEL);
117 input_dev = input_allocate_device();
118 if (!data || !input_dev) {
119 dev_err(&client->dev, "Failed to allocate memory\n");
120 error = -ENOMEM;
121 goto err_free_mem;
122 }
123
124 data->client = client;
125 data->input_dev = input_dev;
126
127 if (id->driver_data == MCS5000_TOUCHKEY) {
128 data->chip.status_reg = MCS5000_TOUCHKEY_STATUS;
129 data->chip.pressbit = MCS5000_TOUCHKEY_STATUS_PRESS;
130 data->chip.baseval = MCS5000_TOUCHKEY_BASE_VAL;
131 fw_reg = MCS5000_TOUCHKEY_FW;
132 } else {
133 data->chip.status_reg = MCS5080_TOUCHKEY_STATUS;
134 data->chip.pressbit = MCS5080_TOUCHKEY_STATUS_PRESS;
135 data->chip.press_invert = 1;
136 data->chip.baseval = MCS5080_TOUCHKEY_BASE_VAL;
137 fw_reg = MCS5080_TOUCHKEY_FW;
138 }
139
140 fw_ver = i2c_smbus_read_byte_data(client, fw_reg);
141 if (fw_ver < 0) {
142 error = fw_ver;
143 dev_err(&client->dev, "i2c read error[%d]\n", error);
144 goto err_free_mem;
145 }
146 dev_info(&client->dev, "Firmware version: %d\n", fw_ver);
147
148 input_dev->name = "MELPAS MCS Touchkey";
149 input_dev->id.bustype = BUS_I2C;
150 input_dev->dev.parent = &client->dev;
151 input_dev->evbit[0] = BIT_MASK(EV_KEY);
152 if (!pdata->no_autorepeat)
153 input_dev->evbit[0] |= BIT_MASK(EV_REP);
154 input_dev->keycode = data->keycodes;
155 input_dev->keycodesize = sizeof(data->keycodes[0]);
156 input_dev->keycodemax = pdata->key_maxval + 1;
157
158 for (i = 0; i < pdata->keymap_size; i++) {
159 unsigned int val = MCS_KEY_VAL(pdata->keymap[i]);
160 unsigned int code = MCS_KEY_CODE(pdata->keymap[i]);
161
162 data->keycodes[val] = code;
163 __set_bit(code, input_dev->keybit);
164 }
165
166 input_set_capability(input_dev, EV_MSC, MSC_SCAN);
167 input_set_drvdata(input_dev, data);
168
169 if (pdata->cfg_pin)
170 pdata->cfg_pin();
171
172 error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt,
173 IRQF_TRIGGER_FALLING, client->dev.driver->name, data);
174 if (error) {
175 dev_err(&client->dev, "Failed to register interrupt\n");
176 goto err_free_mem;
177 }
178
179 error = input_register_device(input_dev);
180 if (error)
181 goto err_free_irq;
182
183 i2c_set_clientdata(client, data);
184 return 0;
185
186err_free_irq:
187 free_irq(client->irq, data);
188err_free_mem:
189 input_free_device(input_dev);
190 kfree(data);
191 return error;
192}
193
194static int __devexit mcs_touchkey_remove(struct i2c_client *client)
195{
196 struct mcs_touchkey_data *data = i2c_get_clientdata(client);
197
198 free_irq(client->irq, data);
199 input_unregister_device(data->input_dev);
200 kfree(data);
201
202 return 0;
203}
204
205static const struct i2c_device_id mcs_touchkey_id[] = {
206 { "mcs5000_touchkey", MCS5000_TOUCHKEY },
207 { "mcs5080_touchkey", MCS5080_TOUCHKEY },
208 { }
209};
210MODULE_DEVICE_TABLE(i2c, mcs_touchkey_id);
211
212static struct i2c_driver mcs_touchkey_driver = {
213 .driver = {
214 .name = "mcs_touchkey",
215 .owner = THIS_MODULE,
216 },
217 .probe = mcs_touchkey_probe,
218 .remove = __devexit_p(mcs_touchkey_remove),
219 .id_table = mcs_touchkey_id,
220};
221
222static int __init mcs_touchkey_init(void)
223{
224 return i2c_add_driver(&mcs_touchkey_driver);
225}
226
227static void __exit mcs_touchkey_exit(void)
228{
229 i2c_del_driver(&mcs_touchkey_driver);
230}
231
232module_init(mcs_touchkey_init);
233module_exit(mcs_touchkey_exit);
234
235/* Module information */
236MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
237MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>");
238MODULE_DESCRIPTION("Touchkey driver for MELFAS MCS5000/5080 controller");
239MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c
new file mode 100644
index 00000000000..f689f49e310
--- /dev/null
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -0,0 +1,491 @@
1/*
2 * Samsung keypad driver
3 *
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 * Author: Donghwa Lee <dh09.lee@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/err.h>
17#include <linux/init.h>
18#include <linux/input.h>
19#include <linux/interrupt.h>
20#include <linux/io.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/slab.h>
24#include <linux/sched.h>
25#include <plat/keypad.h>
26
27#define SAMSUNG_KEYIFCON 0x00
28#define SAMSUNG_KEYIFSTSCLR 0x04
29#define SAMSUNG_KEYIFCOL 0x08
30#define SAMSUNG_KEYIFROW 0x0c
31#define SAMSUNG_KEYIFFC 0x10
32
33/* SAMSUNG_KEYIFCON */
34#define SAMSUNG_KEYIFCON_INT_F_EN (1 << 0)
35#define SAMSUNG_KEYIFCON_INT_R_EN (1 << 1)
36#define SAMSUNG_KEYIFCON_DF_EN (1 << 2)
37#define SAMSUNG_KEYIFCON_FC_EN (1 << 3)
38#define SAMSUNG_KEYIFCON_WAKEUPEN (1 << 4)
39
40/* SAMSUNG_KEYIFSTSCLR */
41#define SAMSUNG_KEYIFSTSCLR_P_INT_MASK (0xff << 0)
42#define SAMSUNG_KEYIFSTSCLR_R_INT_MASK (0xff << 8)
43#define SAMSUNG_KEYIFSTSCLR_R_INT_OFFSET 8
44#define S5PV210_KEYIFSTSCLR_P_INT_MASK (0x3fff << 0)
45#define S5PV210_KEYIFSTSCLR_R_INT_MASK (0x3fff << 16)
46#define S5PV210_KEYIFSTSCLR_R_INT_OFFSET 16
47
48/* SAMSUNG_KEYIFCOL */
49#define SAMSUNG_KEYIFCOL_MASK (0xff << 0)
50#define S5PV210_KEYIFCOLEN_MASK (0xff << 8)
51
52/* SAMSUNG_KEYIFROW */
53#define SAMSUNG_KEYIFROW_MASK (0xff << 0)
54#define S5PV210_KEYIFROW_MASK (0x3fff << 0)
55
56/* SAMSUNG_KEYIFFC */
57#define SAMSUNG_KEYIFFC_MASK (0x3ff << 0)
58
59enum samsung_keypad_type {
60 KEYPAD_TYPE_SAMSUNG,
61 KEYPAD_TYPE_S5PV210,
62};
63
64struct samsung_keypad {
65 struct input_dev *input_dev;
66 struct clk *clk;
67 void __iomem *base;
68 wait_queue_head_t wait;
69 bool stopped;
70 int irq;
71 unsigned int row_shift;
72 unsigned int rows;
73 unsigned int cols;
74 unsigned int row_state[SAMSUNG_MAX_COLS];
75 unsigned short keycodes[];
76};
77
78static int samsung_keypad_is_s5pv210(struct device *dev)
79{
80 struct platform_device *pdev = to_platform_device(dev);
81 enum samsung_keypad_type type =
82 platform_get_device_id(pdev)->driver_data;
83
84 return type == KEYPAD_TYPE_S5PV210;
85}
86
87static void samsung_keypad_scan(struct samsung_keypad *keypad,
88 unsigned int *row_state)
89{
90 struct device *dev = keypad->input_dev->dev.parent;
91 unsigned int col;
92 unsigned int val;
93
94 for (col = 0; col < keypad->cols; col++) {
95 if (samsung_keypad_is_s5pv210(dev)) {
96 val = S5PV210_KEYIFCOLEN_MASK;
97 val &= ~(1 << col) << 8;
98 } else {
99 val = SAMSUNG_KEYIFCOL_MASK;
100 val &= ~(1 << col);
101 }
102
103 writel(val, keypad->base + SAMSUNG_KEYIFCOL);
104 mdelay(1);
105
106 val = readl(keypad->base + SAMSUNG_KEYIFROW);
107 row_state[col] = ~val & ((1 << keypad->rows) - 1);
108 }
109
110 /* KEYIFCOL reg clear */
111 writel(0, keypad->base + SAMSUNG_KEYIFCOL);
112}
113
114static bool samsung_keypad_report(struct samsung_keypad *keypad,
115 unsigned int *row_state)
116{
117 struct input_dev *input_dev = keypad->input_dev;
118 unsigned int changed;
119 unsigned int pressed;
120 unsigned int key_down = 0;
121 unsigned int val;
122 unsigned int col, row;
123
124 for (col = 0; col < keypad->cols; col++) {
125 changed = row_state[col] ^ keypad->row_state[col];
126 key_down |= row_state[col];
127 if (!changed)
128 continue;
129
130 for (row = 0; row < keypad->rows; row++) {
131 if (!(changed & (1 << row)))
132 continue;
133
134 pressed = row_state[col] & (1 << row);
135
136 dev_dbg(&keypad->input_dev->dev,
137 "key %s, row: %d, col: %d\n",
138 pressed ? "pressed" : "released", row, col);
139
140 val = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
141
142 input_event(input_dev, EV_MSC, MSC_SCAN, val);
143 input_report_key(input_dev,
144 keypad->keycodes[val], pressed);
145 }
146 input_sync(keypad->input_dev);
147 }
148
149 memcpy(keypad->row_state, row_state, sizeof(keypad->row_state));
150
151 return key_down;
152}
153
154static irqreturn_t samsung_keypad_irq(int irq, void *dev_id)
155{
156 struct samsung_keypad *keypad = dev_id;
157 unsigned int row_state[SAMSUNG_MAX_COLS];
158 unsigned int val;
159 bool key_down;
160
161 do {
162 val = readl(keypad->base + SAMSUNG_KEYIFSTSCLR);
163 /* Clear interrupt. */
164 writel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR);
165
166 samsung_keypad_scan(keypad, row_state);
167
168 key_down = samsung_keypad_report(keypad, row_state);
169 if (key_down)
170 wait_event_timeout(keypad->wait, keypad->stopped,
171 msecs_to_jiffies(50));
172
173 } while (key_down && !keypad->stopped);
174
175 return IRQ_HANDLED;
176}
177
178static void samsung_keypad_start(struct samsung_keypad *keypad)
179{
180 unsigned int val;
181
182 /* Tell IRQ thread that it may poll the device. */
183 keypad->stopped = false;
184
185 clk_enable(keypad->clk);
186
187 /* Enable interrupt bits. */
188 val = readl(keypad->base + SAMSUNG_KEYIFCON);
189 val |= SAMSUNG_KEYIFCON_INT_F_EN | SAMSUNG_KEYIFCON_INT_R_EN;
190 writel(val, keypad->base + SAMSUNG_KEYIFCON);
191
192 /* KEYIFCOL reg clear. */
193 writel(0, keypad->base + SAMSUNG_KEYIFCOL);
194}
195
196static void samsung_keypad_stop(struct samsung_keypad *keypad)
197{
198 unsigned int val;
199
200 /* Signal IRQ thread to stop polling and disable the handler. */
201 keypad->stopped = true;
202 wake_up(&keypad->wait);
203 disable_irq(keypad->irq);
204
205 /* Clear interrupt. */
206 writel(~0x0, keypad->base + SAMSUNG_KEYIFSTSCLR);
207
208 /* Disable interrupt bits. */
209 val = readl(keypad->base + SAMSUNG_KEYIFCON);
210 val &= ~(SAMSUNG_KEYIFCON_INT_F_EN | SAMSUNG_KEYIFCON_INT_R_EN);
211 writel(val, keypad->base + SAMSUNG_KEYIFCON);
212
213 clk_disable(keypad->clk);
214
215 /*
216 * Now that chip should not generate interrupts we can safely
217 * re-enable the handler.
218 */
219 enable_irq(keypad->irq);
220}
221
222static int samsung_keypad_open(struct input_dev *input_dev)
223{
224 struct samsung_keypad *keypad = input_get_drvdata(input_dev);
225
226 samsung_keypad_start(keypad);
227
228 return 0;
229}
230
231static void samsung_keypad_close(struct input_dev *input_dev)
232{
233 struct samsung_keypad *keypad = input_get_drvdata(input_dev);
234
235 samsung_keypad_stop(keypad);
236}
237
238static int __devinit samsung_keypad_probe(struct platform_device *pdev)
239{
240 const struct samsung_keypad_platdata *pdata;
241 const struct matrix_keymap_data *keymap_data;
242 struct samsung_keypad *keypad;
243 struct resource *res;
244 struct input_dev *input_dev;
245 unsigned int row_shift;
246 unsigned int keymap_size;
247 int error;
248
249 pdata = pdev->dev.platform_data;
250 if (!pdata) {
251 dev_err(&pdev->dev, "no platform data defined\n");
252 return -EINVAL;
253 }
254
255 keymap_data = pdata->keymap_data;
256 if (!keymap_data) {
257 dev_err(&pdev->dev, "no keymap data defined\n");
258 return -EINVAL;
259 }
260
261 if (!pdata->rows || pdata->rows > SAMSUNG_MAX_ROWS)
262 return -EINVAL;
263
264 if (!pdata->cols || pdata->cols > SAMSUNG_MAX_COLS)
265 return -EINVAL;
266
267 /* initialize the gpio */
268 if (pdata->cfg_gpio)
269 pdata->cfg_gpio(pdata->rows, pdata->cols);
270
271 row_shift = get_count_order(pdata->cols);
272 keymap_size = (pdata->rows << row_shift) * sizeof(keypad->keycodes[0]);
273
274 keypad = kzalloc(sizeof(*keypad) + keymap_size, GFP_KERNEL);
275 input_dev = input_allocate_device();
276 if (!keypad || !input_dev) {
277 error = -ENOMEM;
278 goto err_free_mem;
279 }
280
281 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
282 if (!res) {
283 error = -ENODEV;
284 goto err_free_mem;
285 }
286
287 keypad->base = ioremap(res->start, resource_size(res));
288 if (!keypad->base) {
289 error = -EBUSY;
290 goto err_free_mem;
291 }
292
293 keypad->clk = clk_get(&pdev->dev, "keypad");
294 if (IS_ERR(keypad->clk)) {
295 dev_err(&pdev->dev, "failed to get keypad clk\n");
296 error = PTR_ERR(keypad->clk);
297 goto err_unmap_base;
298 }
299
300 keypad->input_dev = input_dev;
301 keypad->row_shift = row_shift;
302 keypad->rows = pdata->rows;
303 keypad->cols = pdata->cols;
304 init_waitqueue_head(&keypad->wait);
305
306 input_dev->name = pdev->name;
307 input_dev->id.bustype = BUS_HOST;
308 input_dev->dev.parent = &pdev->dev;
309 input_set_drvdata(input_dev, keypad);
310
311 input_dev->open = samsung_keypad_open;
312 input_dev->close = samsung_keypad_close;
313
314 input_dev->evbit[0] = BIT_MASK(EV_KEY);
315 if (!pdata->no_autorepeat)
316 input_dev->evbit[0] |= BIT_MASK(EV_REP);
317
318 input_set_capability(input_dev, EV_MSC, MSC_SCAN);
319
320 input_dev->keycode = keypad->keycodes;
321 input_dev->keycodesize = sizeof(keypad->keycodes[0]);
322 input_dev->keycodemax = pdata->rows << row_shift;
323
324 matrix_keypad_build_keymap(keymap_data, row_shift,
325 input_dev->keycode, input_dev->keybit);
326
327 keypad->irq = platform_get_irq(pdev, 0);
328 if (keypad->irq < 0) {
329 error = keypad->irq;
330 goto err_put_clk;
331 }
332
333 error = request_threaded_irq(keypad->irq, NULL, samsung_keypad_irq,
334 IRQF_ONESHOT, dev_name(&pdev->dev), keypad);
335 if (error) {
336 dev_err(&pdev->dev, "failed to register keypad interrupt\n");
337 goto err_put_clk;
338 }
339
340 error = input_register_device(keypad->input_dev);
341 if (error)
342 goto err_free_irq;
343
344 device_init_wakeup(&pdev->dev, pdata->wakeup);
345 platform_set_drvdata(pdev, keypad);
346 return 0;
347
348err_free_irq:
349 free_irq(keypad->irq, keypad);
350err_put_clk:
351 clk_put(keypad->clk);
352err_unmap_base:
353 iounmap(keypad->base);
354err_free_mem:
355 input_free_device(input_dev);
356 kfree(keypad);
357
358 return error;
359}
360
361static int __devexit samsung_keypad_remove(struct platform_device *pdev)
362{
363 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
364
365 device_init_wakeup(&pdev->dev, 0);
366 platform_set_drvdata(pdev, NULL);
367
368 input_unregister_device(keypad->input_dev);
369
370 /*
371 * It is safe to free IRQ after unregistering device because
372 * samsung_keypad_close will shut off interrupts.
373 */
374 free_irq(keypad->irq, keypad);
375
376 clk_put(keypad->clk);
377
378 iounmap(keypad->base);
379 kfree(keypad);
380
381 return 0;
382}
383
384#ifdef CONFIG_PM
385static void samsung_keypad_toggle_wakeup(struct samsung_keypad *keypad,
386 bool enable)
387{
388 struct device *dev = keypad->input_dev->dev.parent;
389 unsigned int val;
390
391 clk_enable(keypad->clk);
392
393 val = readl(keypad->base + SAMSUNG_KEYIFCON);
394 if (enable) {
395 val |= SAMSUNG_KEYIFCON_WAKEUPEN;
396 if (device_may_wakeup(dev))
397 enable_irq_wake(keypad->irq);
398 } else {
399 val &= ~SAMSUNG_KEYIFCON_WAKEUPEN;
400 if (device_may_wakeup(dev))
401 disable_irq_wake(keypad->irq);
402 }
403 writel(val, keypad->base + SAMSUNG_KEYIFCON);
404
405 clk_disable(keypad->clk);
406}
407
408static int samsung_keypad_suspend(struct device *dev)
409{
410 struct platform_device *pdev = to_platform_device(dev);
411 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
412 struct input_dev *input_dev = keypad->input_dev;
413
414 mutex_lock(&input_dev->mutex);
415
416 if (input_dev->users)
417 samsung_keypad_stop(keypad);
418
419 samsung_keypad_toggle_wakeup(keypad, true);
420
421 mutex_unlock(&input_dev->mutex);
422
423 return 0;
424}
425
426static int samsung_keypad_resume(struct device *dev)
427{
428 struct platform_device *pdev = to_platform_device(dev);
429 struct samsung_keypad *keypad = platform_get_drvdata(pdev);
430 struct input_dev *input_dev = keypad->input_dev;
431
432 mutex_lock(&input_dev->mutex);
433
434 samsung_keypad_toggle_wakeup(keypad, false);
435
436 if (input_dev->users)
437 samsung_keypad_start(keypad);
438
439 mutex_unlock(&input_dev->mutex);
440
441 return 0;
442}
443
444static const struct dev_pm_ops samsung_keypad_pm_ops = {
445 .suspend = samsung_keypad_suspend,
446 .resume = samsung_keypad_resume,
447};
448#endif
449
450static struct platform_device_id samsung_keypad_driver_ids[] = {
451 {
452 .name = "samsung-keypad",
453 .driver_data = KEYPAD_TYPE_SAMSUNG,
454 }, {
455 .name = "s5pv210-keypad",
456 .driver_data = KEYPAD_TYPE_S5PV210,
457 },
458 { },
459};
460MODULE_DEVICE_TABLE(platform, samsung_keypad_driver_ids);
461
462static struct platform_driver samsung_keypad_driver = {
463 .probe = samsung_keypad_probe,
464 .remove = __devexit_p(samsung_keypad_remove),
465 .driver = {
466 .name = "samsung-keypad",
467 .owner = THIS_MODULE,
468#ifdef CONFIG_PM
469 .pm = &samsung_keypad_pm_ops,
470#endif
471 },
472 .id_table = samsung_keypad_driver_ids,
473};
474
475static int __init samsung_keypad_init(void)
476{
477 return platform_driver_register(&samsung_keypad_driver);
478}
479module_init(samsung_keypad_init);
480
481static void __exit samsung_keypad_exit(void)
482{
483 platform_driver_unregister(&samsung_keypad_driver);
484}
485module_exit(samsung_keypad_exit);
486
487MODULE_DESCRIPTION("Samsung keypad driver");
488MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
489MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
490MODULE_LICENSE("GPL");
491MODULE_ALIAS("platform:samsung-keypad");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index c44b9eafc55..b49e2337972 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -327,6 +327,17 @@ config INPUT_PCF8574
327 To compile this driver as a module, choose M here: the 327 To compile this driver as a module, choose M here: the
328 module will be called pcf8574_keypad. 328 module will be called pcf8574_keypad.
329 329
330config INPUT_PWM_BEEPER
331 tristate "PWM beeper support"
332 depends on HAVE_PWM
333 help
334 Say Y here to get support for PWM based beeper devices.
335
336 If unsure, say N.
337
338 To compile this driver as a module, choose M here: the module will be
339 called pwm-beeper.
340
330config INPUT_GPIO_ROTARY_ENCODER 341config INPUT_GPIO_ROTARY_ENCODER
331 tristate "Rotary encoders connected to GPIO pins" 342 tristate "Rotary encoders connected to GPIO pins"
332 depends on GPIOLIB && GENERIC_GPIO 343 depends on GPIOLIB && GENERIC_GPIO
@@ -390,4 +401,41 @@ config INPUT_PCAP
390 To compile this driver as a module, choose M here: the 401 To compile this driver as a module, choose M here: the
391 module will be called pcap_keys. 402 module will be called pcap_keys.
392 403
404config INPUT_ADXL34X
405 tristate "Analog Devices ADXL34x Three-Axis Digital Accelerometer"
406 default n
407 help
408 Say Y here if you have a Accelerometer interface using the
409 ADXL345/6 controller, and your board-specific initialization
410 code includes that in its table of devices.
411
412 This driver can use either I2C or SPI communication to the
413 ADXL345/6 controller. Select the appropriate method for
414 your system.
415
416 If unsure, say N (but it's safe to say "Y").
417
418 To compile this driver as a module, choose M here: the
419 module will be called adxl34x.
420
421config INPUT_ADXL34X_I2C
422 tristate "support I2C bus connection"
423 depends on INPUT_ADXL34X && I2C
424 default y
425 help
426 Say Y here if you have ADXL345/6 hooked to an I2C bus.
427
428 To compile this driver as a module, choose M here: the
429 module will be called adxl34x-i2c.
430
431config INPUT_ADXL34X_SPI
432 tristate "support SPI bus connection"
433 depends on INPUT_ADXL34X && SPI
434 default y
435 help
436 Say Y here if you have ADXL345/6 hooked to a SPI bus.
437
438 To compile this driver as a module, choose M here: the
439 module will be called adxl34x-spi.
440
393endif 441endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 71fe57d8023..19ccca78fa7 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -8,6 +8,9 @@ obj-$(CONFIG_INPUT_88PM860X_ONKEY) += 88pm860x_onkey.o
8obj-$(CONFIG_INPUT_AD714X) += ad714x.o 8obj-$(CONFIG_INPUT_AD714X) += ad714x.o
9obj-$(CONFIG_INPUT_AD714X_I2C) += ad714x-i2c.o 9obj-$(CONFIG_INPUT_AD714X_I2C) += ad714x-i2c.o
10obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o 10obj-$(CONFIG_INPUT_AD714X_SPI) += ad714x-spi.o
11obj-$(CONFIG_INPUT_ADXL34X) += adxl34x.o
12obj-$(CONFIG_INPUT_ADXL34X_I2C) += adxl34x-i2c.o
13obj-$(CONFIG_INPUT_ADXL34X_SPI) += adxl34x-spi.o
11obj-$(CONFIG_INPUT_APANEL) += apanel.o 14obj-$(CONFIG_INPUT_APANEL) += apanel.o
12obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o 15obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
13obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o 16obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
@@ -26,6 +29,7 @@ obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
26obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o 29obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o
27obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o 30obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
28obj-$(CONFIG_INPUT_POWERMATE) += powermate.o 31obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
32obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o
29obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o 33obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o
30obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o 34obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
31obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o 35obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c
new file mode 100644
index 00000000000..0779724af7e
--- /dev/null
+++ b/drivers/input/misc/adxl34x-i2c.c
@@ -0,0 +1,163 @@
1/*
2 * ADLX345/346 Three-Axis Digital Accelerometers (I2C Interface)
3 *
4 * Enter bugs at http://blackfin.uclinux.org/
5 *
6 * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc.
7 * Licensed under the GPL-2 or later.
8 */
9
10#include <linux/input.h> /* BUS_I2C */
11#include <linux/i2c.h>
12#include <linux/module.h>
13#include <linux/types.h>
14#include "adxl34x.h"
15
16static int adxl34x_smbus_read(struct device *dev, unsigned char reg)
17{
18 struct i2c_client *client = to_i2c_client(dev);
19
20 return i2c_smbus_read_byte_data(client, reg);
21}
22
23static int adxl34x_smbus_write(struct device *dev,
24 unsigned char reg, unsigned char val)
25{
26 struct i2c_client *client = to_i2c_client(dev);
27
28 return i2c_smbus_write_byte_data(client, reg, val);
29}
30
31static int adxl34x_smbus_read_block(struct device *dev,
32 unsigned char reg, int count,
33 void *buf)
34{
35 struct i2c_client *client = to_i2c_client(dev);
36
37 return i2c_smbus_read_i2c_block_data(client, reg, count, buf);
38}
39
40static int adxl34x_i2c_read_block(struct device *dev,
41 unsigned char reg, int count,
42 void *buf)
43{
44 struct i2c_client *client = to_i2c_client(dev);
45 int ret;
46
47 ret = i2c_master_send(client, &reg, 1);
48 if (ret < 0)
49 return ret;
50
51 ret = i2c_master_recv(client, buf, count);
52 if (ret < 0)
53 return ret;
54
55 if (ret != count)
56 return -EIO;
57
58 return 0;
59}
60
61static const struct adxl34x_bus_ops adxl34x_smbus_bops = {
62 .bustype = BUS_I2C,
63 .write = adxl34x_smbus_write,
64 .read = adxl34x_smbus_read,
65 .read_block = adxl34x_smbus_read_block,
66};
67
68static const struct adxl34x_bus_ops adxl34x_i2c_bops = {
69 .bustype = BUS_I2C,
70 .write = adxl34x_smbus_write,
71 .read = adxl34x_smbus_read,
72 .read_block = adxl34x_i2c_read_block,
73};
74
75static int __devinit adxl34x_i2c_probe(struct i2c_client *client,
76 const struct i2c_device_id *id)
77{
78 struct adxl34x *ac;
79 int error;
80
81 error = i2c_check_functionality(client->adapter,
82 I2C_FUNC_SMBUS_BYTE_DATA);
83 if (!error) {
84 dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
85 return -EIO;
86 }
87
88 ac = adxl34x_probe(&client->dev, client->irq, false,
89 i2c_check_functionality(client->adapter,
90 I2C_FUNC_SMBUS_READ_I2C_BLOCK) ?
91 &adxl34x_smbus_bops : &adxl34x_i2c_bops);
92 if (IS_ERR(ac))
93 return PTR_ERR(ac);
94
95 i2c_set_clientdata(client, ac);
96
97 return 0;
98}
99
100static int __devexit adxl34x_i2c_remove(struct i2c_client *client)
101{
102 struct adxl34x *ac = i2c_get_clientdata(client);
103
104 return adxl34x_remove(ac);
105}
106
107#ifdef CONFIG_PM
108static int adxl34x_i2c_suspend(struct i2c_client *client, pm_message_t message)
109{
110 struct adxl34x *ac = i2c_get_clientdata(client);
111
112 adxl34x_suspend(ac);
113
114 return 0;
115}
116
117static int adxl34x_i2c_resume(struct i2c_client *client)
118{
119 struct adxl34x *ac = i2c_get_clientdata(client);
120
121 adxl34x_resume(ac);
122
123 return 0;
124}
125#else
126# define adxl34x_i2c_suspend NULL
127# define adxl34x_i2c_resume NULL
128#endif
129
130static const struct i2c_device_id adxl34x_id[] = {
131 { "adxl34x", 0 },
132 { }
133};
134
135MODULE_DEVICE_TABLE(i2c, adxl34x_id);
136
137static struct i2c_driver adxl34x_driver = {
138 .driver = {
139 .name = "adxl34x",
140 .owner = THIS_MODULE,
141 },
142 .probe = adxl34x_i2c_probe,
143 .remove = __devexit_p(adxl34x_i2c_remove),
144 .suspend = adxl34x_i2c_suspend,
145 .resume = adxl34x_i2c_resume,
146 .id_table = adxl34x_id,
147};
148
149static int __init adxl34x_i2c_init(void)
150{
151 return i2c_add_driver(&adxl34x_driver);
152}
153module_init(adxl34x_i2c_init);
154
155static void __exit adxl34x_i2c_exit(void)
156{
157 i2c_del_driver(&adxl34x_driver);
158}
159module_exit(adxl34x_i2c_exit);
160
161MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
162MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer I2C Bus Driver");
163MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c
new file mode 100644
index 00000000000..782de9e8982
--- /dev/null
+++ b/drivers/input/misc/adxl34x-spi.c
@@ -0,0 +1,145 @@
1/*
2 * ADLX345/346 Three-Axis Digital Accelerometers (SPI Interface)
3 *
4 * Enter bugs at http://blackfin.uclinux.org/
5 *
6 * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc.
7 * Licensed under the GPL-2 or later.
8 */
9
10#include <linux/input.h> /* BUS_SPI */
11#include <linux/module.h>
12#include <linux/spi/spi.h>
13#include <linux/types.h>
14#include "adxl34x.h"
15
16#define MAX_SPI_FREQ_HZ 5000000
17#define MAX_FREQ_NO_FIFODELAY 1500000
18#define ADXL34X_CMD_MULTB (1 << 6)
19#define ADXL34X_CMD_READ (1 << 7)
20#define ADXL34X_WRITECMD(reg) (reg & 0x3F)
21#define ADXL34X_READCMD(reg) (ADXL34X_CMD_READ | (reg & 0x3F))
22#define ADXL34X_READMB_CMD(reg) (ADXL34X_CMD_READ | ADXL34X_CMD_MULTB \
23 | (reg & 0x3F))
24
25static int adxl34x_spi_read(struct device *dev, unsigned char reg)
26{
27 struct spi_device *spi = to_spi_device(dev);
28 unsigned char cmd;
29
30 cmd = ADXL34X_READCMD(reg);
31
32 return spi_w8r8(spi, cmd);
33}
34
35static int adxl34x_spi_write(struct device *dev,
36 unsigned char reg, unsigned char val)
37{
38 struct spi_device *spi = to_spi_device(dev);
39 unsigned char buf[2];
40
41 buf[0] = ADXL34X_WRITECMD(reg);
42 buf[1] = val;
43
44 return spi_write(spi, buf, sizeof(buf));
45}
46
47static int adxl34x_spi_read_block(struct device *dev,
48 unsigned char reg, int count,
49 void *buf)
50{
51 struct spi_device *spi = to_spi_device(dev);
52 ssize_t status;
53
54 reg = ADXL34X_READMB_CMD(reg);
55 status = spi_write_then_read(spi, &reg, 1, buf, count);
56
57 return (status < 0) ? status : 0;
58}
59
60static const struct adxl34x_bus_ops adx134x_spi_bops = {
61 .bustype = BUS_SPI,
62 .write = adxl34x_spi_write,
63 .read = adxl34x_spi_read,
64 .read_block = adxl34x_spi_read_block,
65};
66
67static int __devinit adxl34x_spi_probe(struct spi_device *spi)
68{
69 struct adxl34x *ac;
70
71 /* don't exceed max specified SPI CLK frequency */
72 if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
73 dev_err(&spi->dev, "SPI CLK %d Hz too fast\n", spi->max_speed_hz);
74 return -EINVAL;
75 }
76
77 ac = adxl34x_probe(&spi->dev, spi->irq,
78 spi->max_speed_hz > MAX_FREQ_NO_FIFODELAY,
79 &adx134x_spi_bops);
80
81 if (IS_ERR(ac))
82 return PTR_ERR(ac);
83
84 spi_set_drvdata(spi, ac);
85
86 return 0;
87}
88
89static int __devexit adxl34x_spi_remove(struct spi_device *spi)
90{
91 struct adxl34x *ac = dev_get_drvdata(&spi->dev);
92
93 return adxl34x_remove(ac);
94}
95
96#ifdef CONFIG_PM
97static int adxl34x_spi_suspend(struct spi_device *spi, pm_message_t message)
98{
99 struct adxl34x *ac = dev_get_drvdata(&spi->dev);
100
101 adxl34x_suspend(ac);
102
103 return 0;
104}
105
106static int adxl34x_spi_resume(struct spi_device *spi)
107{
108 struct adxl34x *ac = dev_get_drvdata(&spi->dev);
109
110 adxl34x_resume(ac);
111
112 return 0;
113}
114#else
115# define adxl34x_spi_suspend NULL
116# define adxl34x_spi_resume NULL
117#endif
118
119static struct spi_driver adxl34x_driver = {
120 .driver = {
121 .name = "adxl34x",
122 .bus = &spi_bus_type,
123 .owner = THIS_MODULE,
124 },
125 .probe = adxl34x_spi_probe,
126 .remove = __devexit_p(adxl34x_spi_remove),
127 .suspend = adxl34x_spi_suspend,
128 .resume = adxl34x_spi_resume,
129};
130
131static int __init adxl34x_spi_init(void)
132{
133 return spi_register_driver(&adxl34x_driver);
134}
135module_init(adxl34x_spi_init);
136
137static void __exit adxl34x_spi_exit(void)
138{
139 spi_unregister_driver(&adxl34x_driver);
140}
141module_exit(adxl34x_spi_exit);
142
143MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
144MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer SPI Bus Driver");
145MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c
new file mode 100644
index 00000000000..e2ca0170808
--- /dev/null
+++ b/drivers/input/misc/adxl34x.c
@@ -0,0 +1,915 @@
1/*
2 * ADXL345/346 Three-Axis Digital Accelerometers
3 *
4 * Enter bugs at http://blackfin.uclinux.org/
5 *
6 * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc.
7 * Licensed under the GPL-2 or later.
8 */
9
10#include <linux/device.h>
11#include <linux/init.h>
12#include <linux/delay.h>
13#include <linux/input.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/slab.h>
17#include <linux/workqueue.h>
18#include <linux/input/adxl34x.h>
19
20#include "adxl34x.h"
21
22/* ADXL345/6 Register Map */
23#define DEVID 0x00 /* R Device ID */
24#define THRESH_TAP 0x1D /* R/W Tap threshold */
25#define OFSX 0x1E /* R/W X-axis offset */
26#define OFSY 0x1F /* R/W Y-axis offset */
27#define OFSZ 0x20 /* R/W Z-axis offset */
28#define DUR 0x21 /* R/W Tap duration */
29#define LATENT 0x22 /* R/W Tap latency */
30#define WINDOW 0x23 /* R/W Tap window */
31#define THRESH_ACT 0x24 /* R/W Activity threshold */
32#define THRESH_INACT 0x25 /* R/W Inactivity threshold */
33#define TIME_INACT 0x26 /* R/W Inactivity time */
34#define ACT_INACT_CTL 0x27 /* R/W Axis enable control for activity and */
35 /* inactivity detection */
36#define THRESH_FF 0x28 /* R/W Free-fall threshold */
37#define TIME_FF 0x29 /* R/W Free-fall time */
38#define TAP_AXES 0x2A /* R/W Axis control for tap/double tap */
39#define ACT_TAP_STATUS 0x2B /* R Source of tap/double tap */
40#define BW_RATE 0x2C /* R/W Data rate and power mode control */
41#define POWER_CTL 0x2D /* R/W Power saving features control */
42#define INT_ENABLE 0x2E /* R/W Interrupt enable control */
43#define INT_MAP 0x2F /* R/W Interrupt mapping control */
44#define INT_SOURCE 0x30 /* R Source of interrupts */
45#define DATA_FORMAT 0x31 /* R/W Data format control */
46#define DATAX0 0x32 /* R X-Axis Data 0 */
47#define DATAX1 0x33 /* R X-Axis Data 1 */
48#define DATAY0 0x34 /* R Y-Axis Data 0 */
49#define DATAY1 0x35 /* R Y-Axis Data 1 */
50#define DATAZ0 0x36 /* R Z-Axis Data 0 */
51#define DATAZ1 0x37 /* R Z-Axis Data 1 */
52#define FIFO_CTL 0x38 /* R/W FIFO control */
53#define FIFO_STATUS 0x39 /* R FIFO status */
54#define TAP_SIGN 0x3A /* R Sign and source for tap/double tap */
55/* Orientation ADXL346 only */
56#define ORIENT_CONF 0x3B /* R/W Orientation configuration */
57#define ORIENT 0x3C /* R Orientation status */
58
59/* DEVIDs */
60#define ID_ADXL345 0xE5
61#define ID_ADXL346 0xE6
62
63/* INT_ENABLE/INT_MAP/INT_SOURCE Bits */
64#define DATA_READY (1 << 7)
65#define SINGLE_TAP (1 << 6)
66#define DOUBLE_TAP (1 << 5)
67#define ACTIVITY (1 << 4)
68#define INACTIVITY (1 << 3)
69#define FREE_FALL (1 << 2)
70#define WATERMARK (1 << 1)
71#define OVERRUN (1 << 0)
72
73/* ACT_INACT_CONTROL Bits */
74#define ACT_ACDC (1 << 7)
75#define ACT_X_EN (1 << 6)
76#define ACT_Y_EN (1 << 5)
77#define ACT_Z_EN (1 << 4)
78#define INACT_ACDC (1 << 3)
79#define INACT_X_EN (1 << 2)
80#define INACT_Y_EN (1 << 1)
81#define INACT_Z_EN (1 << 0)
82
83/* TAP_AXES Bits */
84#define SUPPRESS (1 << 3)
85#define TAP_X_EN (1 << 2)
86#define TAP_Y_EN (1 << 1)
87#define TAP_Z_EN (1 << 0)
88
89/* ACT_TAP_STATUS Bits */
90#define ACT_X_SRC (1 << 6)
91#define ACT_Y_SRC (1 << 5)
92#define ACT_Z_SRC (1 << 4)
93#define ASLEEP (1 << 3)
94#define TAP_X_SRC (1 << 2)
95#define TAP_Y_SRC (1 << 1)
96#define TAP_Z_SRC (1 << 0)
97
98/* BW_RATE Bits */
99#define LOW_POWER (1 << 4)
100#define RATE(x) ((x) & 0xF)
101
102/* POWER_CTL Bits */
103#define PCTL_LINK (1 << 5)
104#define PCTL_AUTO_SLEEP (1 << 4)
105#define PCTL_MEASURE (1 << 3)
106#define PCTL_SLEEP (1 << 2)
107#define PCTL_WAKEUP(x) ((x) & 0x3)
108
109/* DATA_FORMAT Bits */
110#define SELF_TEST (1 << 7)
111#define SPI (1 << 6)
112#define INT_INVERT (1 << 5)
113#define FULL_RES (1 << 3)
114#define JUSTIFY (1 << 2)
115#define RANGE(x) ((x) & 0x3)
116#define RANGE_PM_2g 0
117#define RANGE_PM_4g 1
118#define RANGE_PM_8g 2
119#define RANGE_PM_16g 3
120
121/*
122 * Maximum value our axis may get in full res mode for the input device
123 * (signed 13 bits)
124 */
125#define ADXL_FULLRES_MAX_VAL 4096
126
127/*
128 * Maximum value our axis may get in fixed res mode for the input device
129 * (signed 10 bits)
130 */
131#define ADXL_FIXEDRES_MAX_VAL 512
132
133/* FIFO_CTL Bits */
134#define FIFO_MODE(x) (((x) & 0x3) << 6)
135#define FIFO_BYPASS 0
136#define FIFO_FIFO 1
137#define FIFO_STREAM 2
138#define FIFO_TRIGGER 3
139#define TRIGGER (1 << 5)
140#define SAMPLES(x) ((x) & 0x1F)
141
142/* FIFO_STATUS Bits */
143#define FIFO_TRIG (1 << 7)
144#define ENTRIES(x) ((x) & 0x3F)
145
146/* TAP_SIGN Bits ADXL346 only */
147#define XSIGN (1 << 6)
148#define YSIGN (1 << 5)
149#define ZSIGN (1 << 4)
150#define XTAP (1 << 3)
151#define YTAP (1 << 2)
152#define ZTAP (1 << 1)
153
154/* ORIENT_CONF ADXL346 only */
155#define ORIENT_DEADZONE(x) (((x) & 0x7) << 4)
156#define ORIENT_DIVISOR(x) ((x) & 0x7)
157
158/* ORIENT ADXL346 only */
159#define ADXL346_2D_VALID (1 << 6)
160#define ADXL346_2D_ORIENT(x) (((x) & 0x3) >> 4)
161#define ADXL346_3D_VALID (1 << 3)
162#define ADXL346_3D_ORIENT(x) ((x) & 0x7)
163#define ADXL346_2D_PORTRAIT_POS 0 /* +X */
164#define ADXL346_2D_PORTRAIT_NEG 1 /* -X */
165#define ADXL346_2D_LANDSCAPE_POS 2 /* +Y */
166#define ADXL346_2D_LANDSCAPE_NEG 3 /* -Y */
167
168#define ADXL346_3D_FRONT 3 /* +X */
169#define ADXL346_3D_BACK 4 /* -X */
170#define ADXL346_3D_RIGHT 2 /* +Y */
171#define ADXL346_3D_LEFT 5 /* -Y */
172#define ADXL346_3D_TOP 1 /* +Z */
173#define ADXL346_3D_BOTTOM 6 /* -Z */
174
175#undef ADXL_DEBUG
176
177#define ADXL_X_AXIS 0
178#define ADXL_Y_AXIS 1
179#define ADXL_Z_AXIS 2
180
181#define AC_READ(ac, reg) ((ac)->bops->read((ac)->dev, reg))
182#define AC_WRITE(ac, reg, val) ((ac)->bops->write((ac)->dev, reg, val))
183
184struct axis_triple {
185 int x;
186 int y;
187 int z;
188};
189
190struct adxl34x {
191 struct device *dev;
192 struct input_dev *input;
193 struct mutex mutex; /* reentrant protection for struct */
194 struct adxl34x_platform_data pdata;
195 struct axis_triple swcal;
196 struct axis_triple hwcal;
197 struct axis_triple saved;
198 char phys[32];
199 unsigned orient2d_saved;
200 unsigned orient3d_saved;
201 bool disabled; /* P: mutex */
202 bool opened; /* P: mutex */
203 bool suspended; /* P: mutex */
204 bool fifo_delay;
205 int irq;
206 unsigned model;
207 unsigned int_mask;
208
209 const struct adxl34x_bus_ops *bops;
210};
211
212static const struct adxl34x_platform_data adxl34x_default_init = {
213 .tap_threshold = 35,
214 .tap_duration = 3,
215 .tap_latency = 20,
216 .tap_window = 20,
217 .tap_axis_control = ADXL_TAP_X_EN | ADXL_TAP_Y_EN | ADXL_TAP_Z_EN,
218 .act_axis_control = 0xFF,
219 .activity_threshold = 6,
220 .inactivity_threshold = 4,
221 .inactivity_time = 3,
222 .free_fall_threshold = 8,
223 .free_fall_time = 0x20,
224 .data_rate = 8,
225 .data_range = ADXL_FULL_RES,
226
227 .ev_type = EV_ABS,
228 .ev_code_x = ABS_X, /* EV_REL */
229 .ev_code_y = ABS_Y, /* EV_REL */
230 .ev_code_z = ABS_Z, /* EV_REL */
231
232 .ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY {x,y,z} */
233 .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK,
234 .fifo_mode = FIFO_STREAM,
235 .watermark = 0,
236};
237
238static void adxl34x_get_triple(struct adxl34x *ac, struct axis_triple *axis)
239{
240 short buf[3];
241
242 ac->bops->read_block(ac->dev, DATAX0, DATAZ1 - DATAX0 + 1, buf);
243
244 mutex_lock(&ac->mutex);
245 ac->saved.x = (s16) le16_to_cpu(buf[0]);
246 axis->x = ac->saved.x;
247
248 ac->saved.y = (s16) le16_to_cpu(buf[1]);
249 axis->y = ac->saved.y;
250
251 ac->saved.z = (s16) le16_to_cpu(buf[2]);
252 axis->z = ac->saved.z;
253 mutex_unlock(&ac->mutex);
254}
255
256static void adxl34x_service_ev_fifo(struct adxl34x *ac)
257{
258 struct adxl34x_platform_data *pdata = &ac->pdata;
259 struct axis_triple axis;
260
261 adxl34x_get_triple(ac, &axis);
262
263 input_event(ac->input, pdata->ev_type, pdata->ev_code_x,
264 axis.x - ac->swcal.x);
265 input_event(ac->input, pdata->ev_type, pdata->ev_code_y,
266 axis.y - ac->swcal.y);
267 input_event(ac->input, pdata->ev_type, pdata->ev_code_z,
268 axis.z - ac->swcal.z);
269}
270
271static void adxl34x_report_key_single(struct input_dev *input, int key)
272{
273 input_report_key(input, key, true);
274 input_sync(input);
275 input_report_key(input, key, false);
276}
277
278static void adxl34x_send_key_events(struct adxl34x *ac,
279 struct adxl34x_platform_data *pdata, int status, int press)
280{
281 int i;
282
283 for (i = ADXL_X_AXIS; i <= ADXL_Z_AXIS; i++) {
284 if (status & (1 << (ADXL_Z_AXIS - i)))
285 input_report_key(ac->input,
286 pdata->ev_code_tap[i], press);
287 }
288}
289
290static void adxl34x_do_tap(struct adxl34x *ac,
291 struct adxl34x_platform_data *pdata, int status)
292{
293 adxl34x_send_key_events(ac, pdata, status, true);
294 input_sync(ac->input);
295 adxl34x_send_key_events(ac, pdata, status, false);
296}
297
298static irqreturn_t adxl34x_irq(int irq, void *handle)
299{
300 struct adxl34x *ac = handle;
301 struct adxl34x_platform_data *pdata = &ac->pdata;
302 int int_stat, tap_stat, samples, orient, orient_code;
303
304 /*
305 * ACT_TAP_STATUS should be read before clearing the interrupt
306 * Avoid reading ACT_TAP_STATUS in case TAP detection is disabled
307 */
308
309 if (pdata->tap_axis_control & (TAP_X_EN | TAP_Y_EN | TAP_Z_EN))
310 tap_stat = AC_READ(ac, ACT_TAP_STATUS);
311 else
312 tap_stat = 0;
313
314 int_stat = AC_READ(ac, INT_SOURCE);
315
316 if (int_stat & FREE_FALL)
317 adxl34x_report_key_single(ac->input, pdata->ev_code_ff);
318
319 if (int_stat & OVERRUN)
320 dev_dbg(ac->dev, "OVERRUN\n");
321
322 if (int_stat & (SINGLE_TAP | DOUBLE_TAP)) {
323 adxl34x_do_tap(ac, pdata, tap_stat);
324
325 if (int_stat & DOUBLE_TAP)
326 adxl34x_do_tap(ac, pdata, tap_stat);
327 }
328
329 if (pdata->ev_code_act_inactivity) {
330 if (int_stat & ACTIVITY)
331 input_report_key(ac->input,
332 pdata->ev_code_act_inactivity, 1);
333 if (int_stat & INACTIVITY)
334 input_report_key(ac->input,
335 pdata->ev_code_act_inactivity, 0);
336 }
337
338 /*
339 * ORIENTATION SENSING ADXL346 only
340 */
341 if (pdata->orientation_enable) {
342 orient = AC_READ(ac, ORIENT);
343 if ((pdata->orientation_enable & ADXL_EN_ORIENTATION_2D) &&
344 (orient & ADXL346_2D_VALID)) {
345
346 orient_code = ADXL346_2D_ORIENT(orient);
347 /* Report orientation only when it changes */
348 if (ac->orient2d_saved != orient_code) {
349 ac->orient2d_saved = orient_code;
350 adxl34x_report_key_single(ac->input,
351 pdata->ev_codes_orient_2d[orient_code]);
352 }
353 }
354
355 if ((pdata->orientation_enable & ADXL_EN_ORIENTATION_3D) &&
356 (orient & ADXL346_3D_VALID)) {
357
358 orient_code = ADXL346_3D_ORIENT(orient) - 1;
359 /* Report orientation only when it changes */
360 if (ac->orient3d_saved != orient_code) {
361 ac->orient3d_saved = orient_code;
362 adxl34x_report_key_single(ac->input,
363 pdata->ev_codes_orient_3d[orient_code]);
364 }
365 }
366 }
367
368 if (int_stat & (DATA_READY | WATERMARK)) {
369
370 if (pdata->fifo_mode)
371 samples = ENTRIES(AC_READ(ac, FIFO_STATUS)) + 1;
372 else
373 samples = 1;
374
375 for (; samples > 0; samples--) {
376 adxl34x_service_ev_fifo(ac);
377 /*
378 * To ensure that the FIFO has
379 * completely popped, there must be at least 5 us between
380 * the end of reading the data registers, signified by the
381 * transition to register 0x38 from 0x37 or the CS pin
382 * going high, and the start of new reads of the FIFO or
383 * reading the FIFO_STATUS register. For SPI operation at
384 * 1.5 MHz or lower, the register addressing portion of the
385 * transmission is sufficient delay to ensure the FIFO has
386 * completely popped. It is necessary for SPI operation
387 * greater than 1.5 MHz to de-assert the CS pin to ensure a
388 * total of 5 us, which is at most 3.4 us at 5 MHz
389 * operation.
390 */
391 if (ac->fifo_delay && (samples > 1))
392 udelay(3);
393 }
394 }
395
396 input_sync(ac->input);
397
398 return IRQ_HANDLED;
399}
400
401static void __adxl34x_disable(struct adxl34x *ac)
402{
403 /*
404 * A '0' places the ADXL34x into standby mode
405 * with minimum power consumption.
406 */
407 AC_WRITE(ac, POWER_CTL, 0);
408}
409
410static void __adxl34x_enable(struct adxl34x *ac)
411{
412 AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
413}
414
415void adxl34x_suspend(struct adxl34x *ac)
416{
417 mutex_lock(&ac->mutex);
418
419 if (!ac->suspended && !ac->disabled && ac->opened)
420 __adxl34x_disable(ac);
421
422 ac->suspended = true;
423
424 mutex_unlock(&ac->mutex);
425}
426EXPORT_SYMBOL_GPL(adxl34x_suspend);
427
428void adxl34x_resume(struct adxl34x *ac)
429{
430 mutex_lock(&ac->mutex);
431
432 if (ac->suspended && !ac->disabled && ac->opened)
433 __adxl34x_enable(ac);
434
435 ac->suspended = false;
436
437 mutex_unlock(&ac->mutex);
438}
439EXPORT_SYMBOL_GPL(adxl34x_resume);
440
441static ssize_t adxl34x_disable_show(struct device *dev,
442 struct device_attribute *attr, char *buf)
443{
444 struct adxl34x *ac = dev_get_drvdata(dev);
445
446 return sprintf(buf, "%u\n", ac->disabled);
447}
448
449static ssize_t adxl34x_disable_store(struct device *dev,
450 struct device_attribute *attr,
451 const char *buf, size_t count)
452{
453 struct adxl34x *ac = dev_get_drvdata(dev);
454 unsigned long val;
455 int error;
456
457 error = strict_strtoul(buf, 10, &val);
458 if (error)
459 return error;
460
461 mutex_lock(&ac->mutex);
462
463 if (!ac->suspended && ac->opened) {
464 if (val) {
465 if (!ac->disabled)
466 __adxl34x_disable(ac);
467 } else {
468 if (ac->disabled)
469 __adxl34x_enable(ac);
470 }
471 }
472
473 ac->disabled = !!val;
474
475 mutex_unlock(&ac->mutex);
476
477 return count;
478}
479
480static DEVICE_ATTR(disable, 0664, adxl34x_disable_show, adxl34x_disable_store);
481
482static ssize_t adxl34x_calibrate_show(struct device *dev,
483 struct device_attribute *attr, char *buf)
484{
485 struct adxl34x *ac = dev_get_drvdata(dev);
486 ssize_t count;
487
488 mutex_lock(&ac->mutex);
489 count = sprintf(buf, "%d,%d,%d\n",
490 ac->hwcal.x * 4 + ac->swcal.x,
491 ac->hwcal.y * 4 + ac->swcal.y,
492 ac->hwcal.z * 4 + ac->swcal.z);
493 mutex_unlock(&ac->mutex);
494
495 return count;
496}
497
498static ssize_t adxl34x_calibrate_store(struct device *dev,
499 struct device_attribute *attr,
500 const char *buf, size_t count)
501{
502 struct adxl34x *ac = dev_get_drvdata(dev);
503
504 /*
505 * Hardware offset calibration has a resolution of 15.6 mg/LSB.
506 * We use HW calibration and handle the remaining bits in SW. (4mg/LSB)
507 */
508
509 mutex_lock(&ac->mutex);
510 ac->hwcal.x -= (ac->saved.x / 4);
511 ac->swcal.x = ac->saved.x % 4;
512
513 ac->hwcal.y -= (ac->saved.y / 4);
514 ac->swcal.y = ac->saved.y % 4;
515
516 ac->hwcal.z -= (ac->saved.z / 4);
517 ac->swcal.z = ac->saved.z % 4;
518
519 AC_WRITE(ac, OFSX, (s8) ac->hwcal.x);
520 AC_WRITE(ac, OFSY, (s8) ac->hwcal.y);
521 AC_WRITE(ac, OFSZ, (s8) ac->hwcal.z);
522 mutex_unlock(&ac->mutex);
523
524 return count;
525}
526
527static DEVICE_ATTR(calibrate, 0664,
528 adxl34x_calibrate_show, adxl34x_calibrate_store);
529
530static ssize_t adxl34x_rate_show(struct device *dev,
531 struct device_attribute *attr, char *buf)
532{
533 struct adxl34x *ac = dev_get_drvdata(dev);
534
535 return sprintf(buf, "%u\n", RATE(ac->pdata.data_rate));
536}
537
538static ssize_t adxl34x_rate_store(struct device *dev,
539 struct device_attribute *attr,
540 const char *buf, size_t count)
541{
542 struct adxl34x *ac = dev_get_drvdata(dev);
543 unsigned long val;
544 int error;
545
546 error = strict_strtoul(buf, 10, &val);
547 if (error)
548 return error;
549
550 mutex_lock(&ac->mutex);
551
552 ac->pdata.data_rate = RATE(val);
553 AC_WRITE(ac, BW_RATE,
554 ac->pdata.data_rate |
555 (ac->pdata.low_power_mode ? LOW_POWER : 0));
556
557 mutex_unlock(&ac->mutex);
558
559 return count;
560}
561
562static DEVICE_ATTR(rate, 0664, adxl34x_rate_show, adxl34x_rate_store);
563
564static ssize_t adxl34x_autosleep_show(struct device *dev,
565 struct device_attribute *attr, char *buf)
566{
567 struct adxl34x *ac = dev_get_drvdata(dev);
568
569 return sprintf(buf, "%u\n",
570 ac->pdata.power_mode & (PCTL_AUTO_SLEEP | PCTL_LINK) ? 1 : 0);
571}
572
573static ssize_t adxl34x_autosleep_store(struct device *dev,
574 struct device_attribute *attr,
575 const char *buf, size_t count)
576{
577 struct adxl34x *ac = dev_get_drvdata(dev);
578 unsigned long val;
579 int error;
580
581 error = strict_strtoul(buf, 10, &val);
582 if (error)
583 return error;
584
585 mutex_lock(&ac->mutex);
586
587 if (val)
588 ac->pdata.power_mode |= (PCTL_AUTO_SLEEP | PCTL_LINK);
589 else
590 ac->pdata.power_mode &= ~(PCTL_AUTO_SLEEP | PCTL_LINK);
591
592 if (!ac->disabled && !ac->suspended && ac->opened)
593 AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
594
595 mutex_unlock(&ac->mutex);
596
597 return count;
598}
599
600static DEVICE_ATTR(autosleep, 0664,
601 adxl34x_autosleep_show, adxl34x_autosleep_store);
602
603static ssize_t adxl34x_position_show(struct device *dev,
604 struct device_attribute *attr, char *buf)
605{
606 struct adxl34x *ac = dev_get_drvdata(dev);
607 ssize_t count;
608
609 mutex_lock(&ac->mutex);
610 count = sprintf(buf, "(%d, %d, %d)\n",
611 ac->saved.x, ac->saved.y, ac->saved.z);
612 mutex_unlock(&ac->mutex);
613
614 return count;
615}
616
617static DEVICE_ATTR(position, S_IRUGO, adxl34x_position_show, NULL);
618
619#ifdef ADXL_DEBUG
620static ssize_t adxl34x_write_store(struct device *dev,
621 struct device_attribute *attr,
622 const char *buf, size_t count)
623{
624 struct adxl34x *ac = dev_get_drvdata(dev);
625 unsigned long val;
626 int error;
627
628 /*
629 * This allows basic ADXL register write access for debug purposes.
630 */
631 error = strict_strtoul(buf, 16, &val);
632 if (error)
633 return error;
634
635 mutex_lock(&ac->mutex);
636 AC_WRITE(ac, val >> 8, val & 0xFF);
637 mutex_unlock(&ac->mutex);
638
639 return count;
640}
641
642static DEVICE_ATTR(write, 0664, NULL, adxl34x_write_store);
643#endif
644
645static struct attribute *adxl34x_attributes[] = {
646 &dev_attr_disable.attr,
647 &dev_attr_calibrate.attr,
648 &dev_attr_rate.attr,
649 &dev_attr_autosleep.attr,
650 &dev_attr_position.attr,
651#ifdef ADXL_DEBUG
652 &dev_attr_write.attr,
653#endif
654 NULL
655};
656
657static const struct attribute_group adxl34x_attr_group = {
658 .attrs = adxl34x_attributes,
659};
660
661static int adxl34x_input_open(struct input_dev *input)
662{
663 struct adxl34x *ac = input_get_drvdata(input);
664
665 mutex_lock(&ac->mutex);
666
667 if (!ac->suspended && !ac->disabled)
668 __adxl34x_enable(ac);
669
670 ac->opened = true;
671
672 mutex_unlock(&ac->mutex);
673
674 return 0;
675}
676
677static void adxl34x_input_close(struct input_dev *input)
678{
679 struct adxl34x *ac = input_get_drvdata(input);
680
681 mutex_lock(&ac->mutex);
682
683 if (!ac->suspended && !ac->disabled)
684 __adxl34x_disable(ac);
685
686 ac->opened = false;
687
688 mutex_unlock(&ac->mutex);
689}
690
691struct adxl34x *adxl34x_probe(struct device *dev, int irq,
692 bool fifo_delay_default,
693 const struct adxl34x_bus_ops *bops)
694{
695 struct adxl34x *ac;
696 struct input_dev *input_dev;
697 const struct adxl34x_platform_data *pdata;
698 int err, range, i;
699 unsigned char revid;
700
701 if (!irq) {
702 dev_err(dev, "no IRQ?\n");
703 err = -ENODEV;
704 goto err_out;
705 }
706
707 ac = kzalloc(sizeof(*ac), GFP_KERNEL);
708 input_dev = input_allocate_device();
709 if (!ac || !input_dev) {
710 err = -ENOMEM;
711 goto err_free_mem;
712 }
713
714 ac->fifo_delay = fifo_delay_default;
715
716 pdata = dev->platform_data;
717 if (!pdata) {
718 dev_dbg(dev,
719 "No platfrom data: Using default initialization\n");
720 pdata = &adxl34x_default_init;
721 }
722
723 ac->pdata = *pdata;
724 pdata = &ac->pdata;
725
726 ac->input = input_dev;
727 ac->disabled = true;
728 ac->dev = dev;
729 ac->irq = irq;
730 ac->bops = bops;
731
732 mutex_init(&ac->mutex);
733
734 input_dev->name = "ADXL34x accelerometer";
735 revid = ac->bops->read(dev, DEVID);
736
737 switch (revid) {
738 case ID_ADXL345:
739 ac->model = 345;
740 break;
741 case ID_ADXL346:
742 ac->model = 346;
743 break;
744 default:
745 dev_err(dev, "Failed to probe %s\n", input_dev->name);
746 err = -ENODEV;
747 goto err_free_mem;
748 }
749
750 snprintf(ac->phys, sizeof(ac->phys), "%s/input0", dev_name(dev));
751
752 input_dev->phys = ac->phys;
753 input_dev->dev.parent = dev;
754 input_dev->id.product = ac->model;
755 input_dev->id.bustype = bops->bustype;
756 input_dev->open = adxl34x_input_open;
757 input_dev->close = adxl34x_input_close;
758
759 input_set_drvdata(input_dev, ac);
760
761 __set_bit(ac->pdata.ev_type, input_dev->evbit);
762
763 if (ac->pdata.ev_type == EV_REL) {
764 __set_bit(REL_X, input_dev->relbit);
765 __set_bit(REL_Y, input_dev->relbit);
766 __set_bit(REL_Z, input_dev->relbit);
767 } else {
768 /* EV_ABS */
769 __set_bit(ABS_X, input_dev->absbit);
770 __set_bit(ABS_Y, input_dev->absbit);
771 __set_bit(ABS_Z, input_dev->absbit);
772
773 if (pdata->data_range & FULL_RES)
774 range = ADXL_FULLRES_MAX_VAL; /* Signed 13-bit */
775 else
776 range = ADXL_FIXEDRES_MAX_VAL; /* Signed 10-bit */
777
778 input_set_abs_params(input_dev, ABS_X, -range, range, 3, 3);
779 input_set_abs_params(input_dev, ABS_Y, -range, range, 3, 3);
780 input_set_abs_params(input_dev, ABS_Z, -range, range, 3, 3);
781 }
782
783 __set_bit(EV_KEY, input_dev->evbit);
784 __set_bit(pdata->ev_code_tap[ADXL_X_AXIS], input_dev->keybit);
785 __set_bit(pdata->ev_code_tap[ADXL_Y_AXIS], input_dev->keybit);
786 __set_bit(pdata->ev_code_tap[ADXL_Z_AXIS], input_dev->keybit);
787
788 if (pdata->ev_code_ff) {
789 ac->int_mask = FREE_FALL;
790 __set_bit(pdata->ev_code_ff, input_dev->keybit);
791 }
792
793 if (pdata->ev_code_act_inactivity)
794 __set_bit(pdata->ev_code_act_inactivity, input_dev->keybit);
795
796 ac->int_mask |= ACTIVITY | INACTIVITY;
797
798 if (pdata->watermark) {
799 ac->int_mask |= WATERMARK;
800 if (!FIFO_MODE(pdata->fifo_mode))
801 ac->pdata.fifo_mode |= FIFO_STREAM;
802 } else {
803 ac->int_mask |= DATA_READY;
804 }
805
806 if (pdata->tap_axis_control & (TAP_X_EN | TAP_Y_EN | TAP_Z_EN))
807 ac->int_mask |= SINGLE_TAP | DOUBLE_TAP;
808
809 if (FIFO_MODE(pdata->fifo_mode) == FIFO_BYPASS)
810 ac->fifo_delay = false;
811
812 ac->bops->write(dev, POWER_CTL, 0);
813
814 err = request_threaded_irq(ac->irq, NULL, adxl34x_irq,
815 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
816 dev_name(dev), ac);
817 if (err) {
818 dev_err(dev, "irq %d busy?\n", ac->irq);
819 goto err_free_mem;
820 }
821
822 err = sysfs_create_group(&dev->kobj, &adxl34x_attr_group);
823 if (err)
824 goto err_free_irq;
825
826 err = input_register_device(input_dev);
827 if (err)
828 goto err_remove_attr;
829
830 AC_WRITE(ac, THRESH_TAP, pdata->tap_threshold);
831 AC_WRITE(ac, OFSX, pdata->x_axis_offset);
832 ac->hwcal.x = pdata->x_axis_offset;
833 AC_WRITE(ac, OFSY, pdata->y_axis_offset);
834 ac->hwcal.y = pdata->y_axis_offset;
835 AC_WRITE(ac, OFSZ, pdata->z_axis_offset);
836 ac->hwcal.z = pdata->z_axis_offset;
837 AC_WRITE(ac, THRESH_TAP, pdata->tap_threshold);
838 AC_WRITE(ac, DUR, pdata->tap_duration);
839 AC_WRITE(ac, LATENT, pdata->tap_latency);
840 AC_WRITE(ac, WINDOW, pdata->tap_window);
841 AC_WRITE(ac, THRESH_ACT, pdata->activity_threshold);
842 AC_WRITE(ac, THRESH_INACT, pdata->inactivity_threshold);
843 AC_WRITE(ac, TIME_INACT, pdata->inactivity_time);
844 AC_WRITE(ac, THRESH_FF, pdata->free_fall_threshold);
845 AC_WRITE(ac, TIME_FF, pdata->free_fall_time);
846 AC_WRITE(ac, TAP_AXES, pdata->tap_axis_control);
847 AC_WRITE(ac, ACT_INACT_CTL, pdata->act_axis_control);
848 AC_WRITE(ac, BW_RATE, RATE(ac->pdata.data_rate) |
849 (pdata->low_power_mode ? LOW_POWER : 0));
850 AC_WRITE(ac, DATA_FORMAT, pdata->data_range);
851 AC_WRITE(ac, FIFO_CTL, FIFO_MODE(pdata->fifo_mode) |
852 SAMPLES(pdata->watermark));
853
854 if (pdata->use_int2) {
855 /* Map all INTs to INT2 */
856 AC_WRITE(ac, INT_MAP, ac->int_mask | OVERRUN);
857 } else {
858 /* Map all INTs to INT1 */
859 AC_WRITE(ac, INT_MAP, 0);
860 }
861
862 if (ac->model == 346 && ac->pdata.orientation_enable) {
863 AC_WRITE(ac, ORIENT_CONF,
864 ORIENT_DEADZONE(ac->pdata.deadzone_angle) |
865 ORIENT_DIVISOR(ac->pdata.divisor_length));
866
867 ac->orient2d_saved = 1234;
868 ac->orient3d_saved = 1234;
869
870 if (pdata->orientation_enable & ADXL_EN_ORIENTATION_3D)
871 for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_3d); i++)
872 __set_bit(pdata->ev_codes_orient_3d[i],
873 input_dev->keybit);
874
875 if (pdata->orientation_enable & ADXL_EN_ORIENTATION_2D)
876 for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_2d); i++)
877 __set_bit(pdata->ev_codes_orient_2d[i],
878 input_dev->keybit);
879 } else {
880 ac->pdata.orientation_enable = 0;
881 }
882
883 AC_WRITE(ac, INT_ENABLE, ac->int_mask | OVERRUN);
884
885 ac->pdata.power_mode &= (PCTL_AUTO_SLEEP | PCTL_LINK);
886
887 return ac;
888
889 err_remove_attr:
890 sysfs_remove_group(&dev->kobj, &adxl34x_attr_group);
891 err_free_irq:
892 free_irq(ac->irq, ac);
893 err_free_mem:
894 input_free_device(input_dev);
895 kfree(ac);
896 err_out:
897 return ERR_PTR(err);
898}
899EXPORT_SYMBOL_GPL(adxl34x_probe);
900
901int adxl34x_remove(struct adxl34x *ac)
902{
903 sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group);
904 free_irq(ac->irq, ac);
905 input_unregister_device(ac->input);
906 dev_dbg(ac->dev, "unregistered accelerometer\n");
907 kfree(ac);
908
909 return 0;
910}
911EXPORT_SYMBOL_GPL(adxl34x_remove);
912
913MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
914MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer Driver");
915MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/adxl34x.h b/drivers/input/misc/adxl34x.h
new file mode 100644
index 00000000000..bbbc80fda16
--- /dev/null
+++ b/drivers/input/misc/adxl34x.h
@@ -0,0 +1,30 @@
1/*
2 * ADXL345/346 Three-Axis Digital Accelerometers (I2C/SPI Interface)
3 *
4 * Enter bugs at http://blackfin.uclinux.org/
5 *
6 * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc.
7 * Licensed under the GPL-2 or later.
8 */
9
10#ifndef _ADXL34X_H_
11#define _ADXL34X_H_
12
13struct device;
14struct adxl34x;
15
16struct adxl34x_bus_ops {
17 u16 bustype;
18 int (*read)(struct device *, unsigned char);
19 int (*read_block)(struct device *, unsigned char, int, void *);
20 int (*write)(struct device *, unsigned char, unsigned char);
21};
22
23void adxl34x_suspend(struct adxl34x *ac);
24void adxl34x_resume(struct adxl34x *ac);
25struct adxl34x *adxl34x_probe(struct device *dev, int irq,
26 bool fifo_delay_default,
27 const struct adxl34x_bus_ops *bops);
28int adxl34x_remove(struct adxl34x *ac);
29
30#endif
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
index dfaa9a045ed..601f7372f9c 100644
--- a/drivers/input/misc/atlas_btns.c
+++ b/drivers/input/misc/atlas_btns.c
@@ -21,6 +21,8 @@
21 * 21 *
22 */ 22 */
23 23
24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
24#include <linux/kernel.h> 26#include <linux/kernel.h>
25#include <linux/module.h> 27#include <linux/module.h>
26#include <linux/init.h> 28#include <linux/init.h>
@@ -60,12 +62,11 @@ static acpi_status acpi_atlas_button_handler(u32 function,
60 input_report_key(input_dev, atlas_keymap[code], key_down); 62 input_report_key(input_dev, atlas_keymap[code], key_down);
61 input_sync(input_dev); 63 input_sync(input_dev);
62 64
63 status = 0; 65 status = AE_OK;
64 } else { 66 } else {
65 printk(KERN_WARNING "atlas: shrugged on unexpected function" 67 pr_warn("shrugged on unexpected function: function=%x,address=%lx,value=%x\n",
66 ":function=%x,address=%lx,value=%x\n",
67 function, (unsigned long)address, (u32)*value); 68 function, (unsigned long)address, (u32)*value);
68 status = -EINVAL; 69 status = AE_BAD_PARAMETER;
69 } 70 }
70 71
71 return status; 72 return status;
@@ -79,7 +80,7 @@ static int atlas_acpi_button_add(struct acpi_device *device)
79 80
80 input_dev = input_allocate_device(); 81 input_dev = input_allocate_device();
81 if (!input_dev) { 82 if (!input_dev) {
82 printk(KERN_ERR "atlas: unable to allocate input device\n"); 83 pr_err("unable to allocate input device\n");
83 return -ENOMEM; 84 return -ENOMEM;
84 } 85 }
85 86
@@ -102,7 +103,7 @@ static int atlas_acpi_button_add(struct acpi_device *device)
102 103
103 err = input_register_device(input_dev); 104 err = input_register_device(input_dev);
104 if (err) { 105 if (err) {
105 printk(KERN_ERR "atlas: couldn't register input device\n"); 106 pr_err("couldn't register input device\n");
106 input_free_device(input_dev); 107 input_free_device(input_dev);
107 return err; 108 return err;
108 } 109 }
@@ -112,12 +113,12 @@ static int atlas_acpi_button_add(struct acpi_device *device)
112 0x81, &acpi_atlas_button_handler, 113 0x81, &acpi_atlas_button_handler,
113 &acpi_atlas_button_setup, device); 114 &acpi_atlas_button_setup, device);
114 if (ACPI_FAILURE(status)) { 115 if (ACPI_FAILURE(status)) {
115 printk(KERN_ERR "Atlas: Error installing addr spc handler\n"); 116 pr_err("error installing addr spc handler\n");
116 input_unregister_device(input_dev); 117 input_unregister_device(input_dev);
117 status = -EINVAL; 118 err = -EINVAL;
118 } 119 }
119 120
120 return status; 121 return err;
121} 122}
122 123
123static int atlas_acpi_button_remove(struct acpi_device *device, int type) 124static int atlas_acpi_button_remove(struct acpi_device *device, int type)
@@ -126,14 +127,12 @@ static int atlas_acpi_button_remove(struct acpi_device *device, int type)
126 127
127 status = acpi_remove_address_space_handler(device->handle, 128 status = acpi_remove_address_space_handler(device->handle,
128 0x81, &acpi_atlas_button_handler); 129 0x81, &acpi_atlas_button_handler);
129 if (ACPI_FAILURE(status)) { 130 if (ACPI_FAILURE(status))
130 printk(KERN_ERR "Atlas: Error removing addr spc handler\n"); 131 pr_err("error removing addr spc handler\n");
131 status = -EINVAL;
132 }
133 132
134 input_unregister_device(input_dev); 133 input_unregister_device(input_dev);
135 134
136 return status; 135 return 0;
137} 136}
138 137
139static const struct acpi_device_id atlas_device_ids[] = { 138static const struct acpi_device_id atlas_device_ids[] = {
@@ -145,6 +144,7 @@ MODULE_DEVICE_TABLE(acpi, atlas_device_ids);
145static struct acpi_driver atlas_acpi_driver = { 144static struct acpi_driver atlas_acpi_driver = {
146 .name = ACPI_ATLAS_NAME, 145 .name = ACPI_ATLAS_NAME,
147 .class = ACPI_ATLAS_CLASS, 146 .class = ACPI_ATLAS_CLASS,
147 .owner = THIS_MODULE,
148 .ids = atlas_device_ids, 148 .ids = atlas_device_ids,
149 .ops = { 149 .ops = {
150 .add = atlas_acpi_button_add, 150 .add = atlas_acpi_button_add,
@@ -154,18 +154,10 @@ static struct acpi_driver atlas_acpi_driver = {
154 154
155static int __init atlas_acpi_init(void) 155static int __init atlas_acpi_init(void)
156{ 156{
157 int result;
158
159 if (acpi_disabled) 157 if (acpi_disabled)
160 return -ENODEV; 158 return -ENODEV;
161 159
162 result = acpi_bus_register_driver(&atlas_acpi_driver); 160 return acpi_bus_register_driver(&atlas_acpi_driver);
163 if (result < 0) {
164 printk(KERN_ERR "Atlas ACPI: Unable to register driver\n");
165 return -ENODEV;
166 }
167
168 return 0;
169} 161}
170 162
171static void __exit atlas_acpi_exit(void) 163static void __exit atlas_acpi_exit(void)
diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c
new file mode 100644
index 00000000000..57c294f0719
--- /dev/null
+++ b/drivers/input/misc/pwm-beeper.c
@@ -0,0 +1,199 @@
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * PWM beeper driver
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/input.h>
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/platform_device.h>
20#include <linux/pwm.h>
21#include <linux/slab.h>
22
23struct pwm_beeper {
24 struct input_dev *input;
25 struct pwm_device *pwm;
26 unsigned long period;
27};
28
29#define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
30
31static int pwm_beeper_event(struct input_dev *input,
32 unsigned int type, unsigned int code, int value)
33{
34 int ret = 0;
35 struct pwm_beeper *beeper = input_get_drvdata(input);
36 unsigned long period;
37
38 if (type != EV_SND || value < 0)
39 return -EINVAL;
40
41 switch (code) {
42 case SND_BELL:
43 value = value ? 1000 : 0;
44 break;
45 case SND_TONE:
46 break;
47 default:
48 return -EINVAL;
49 }
50
51 if (value == 0) {
52 pwm_config(beeper->pwm, 0, 0);
53 pwm_disable(beeper->pwm);
54 } else {
55 period = HZ_TO_NANOSECONDS(value);
56 ret = pwm_config(beeper->pwm, period / 2, period);
57 if (ret)
58 return ret;
59 ret = pwm_enable(beeper->pwm);
60 if (ret)
61 return ret;
62 beeper->period = period;
63 }
64
65 return 0;
66}
67
68static int __devinit pwm_beeper_probe(struct platform_device *pdev)
69{
70 unsigned long pwm_id = (unsigned long)pdev->dev.platform_data;
71 struct pwm_beeper *beeper;
72 int error;
73
74 beeper = kzalloc(sizeof(*beeper), GFP_KERNEL);
75 if (!beeper)
76 return -ENOMEM;
77
78 beeper->pwm = pwm_request(pwm_id, "pwm beeper");
79
80 if (IS_ERR(beeper->pwm)) {
81 error = PTR_ERR(beeper->pwm);
82 dev_err(&pdev->dev, "Failed to request pwm device: %d\n", error);
83 goto err_free;
84 }
85
86 beeper->input = input_allocate_device();
87 if (!beeper->input) {
88 dev_err(&pdev->dev, "Failed to allocate input device\n");
89 error = -ENOMEM;
90 goto err_pwm_free;
91 }
92 beeper->input->dev.parent = &pdev->dev;
93
94 beeper->input->name = "pwm-beeper";
95 beeper->input->phys = "pwm/input0";
96 beeper->input->id.bustype = BUS_HOST;
97 beeper->input->id.vendor = 0x001f;
98 beeper->input->id.product = 0x0001;
99 beeper->input->id.version = 0x0100;
100
101 beeper->input->evbit[0] = BIT(EV_SND);
102 beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL);
103
104 beeper->input->event = pwm_beeper_event;
105
106 input_set_drvdata(beeper->input, beeper);
107
108 error = input_register_device(beeper->input);
109 if (error) {
110 dev_err(&pdev->dev, "Failed to register input device: %d\n", error);
111 goto err_input_free;
112 }
113
114 platform_set_drvdata(pdev, beeper);
115
116 return 0;
117
118err_input_free:
119 input_free_device(beeper->input);
120err_pwm_free:
121 pwm_free(beeper->pwm);
122err_free:
123 kfree(beeper);
124
125 return error;
126}
127
128static int __devexit pwm_beeper_remove(struct platform_device *pdev)
129{
130 struct pwm_beeper *beeper = platform_get_drvdata(pdev);
131
132 platform_set_drvdata(pdev, NULL);
133 input_unregister_device(beeper->input);
134
135 pwm_disable(beeper->pwm);
136 pwm_free(beeper->pwm);
137
138 kfree(beeper);
139
140 return 0;
141}
142
143#ifdef CONFIG_PM
144static int pwm_beeper_suspend(struct device *dev)
145{
146 struct pwm_beeper *beeper = dev_get_drvdata(dev);
147
148 if (beeper->period)
149 pwm_disable(beeper->pwm);
150
151 return 0;
152}
153
154static int pwm_beeper_resume(struct device *dev)
155{
156 struct pwm_beeper *beeper = dev_get_drvdata(dev);
157
158 if (beeper->period) {
159 pwm_config(beeper->pwm, beeper->period / 2, beeper->period);
160 pwm_enable(beeper->pwm);
161 }
162
163 return 0;
164}
165
166static SIMPLE_DEV_PM_OPS(pwm_beeper_pm_ops,
167 pwm_beeper_suspend, pwm_beeper_resume);
168
169#define PWM_BEEPER_PM_OPS (&pwm_beeper_pm_ops)
170#else
171#define PWM_BEEPER_PM_OPS NULL
172#endif
173
174static struct platform_driver pwm_beeper_driver = {
175 .probe = pwm_beeper_probe,
176 .remove = __devexit_p(pwm_beeper_remove),
177 .driver = {
178 .name = "pwm-beeper",
179 .owner = THIS_MODULE,
180 .pm = PWM_BEEPER_PM_OPS,
181 },
182};
183
184static int __init pwm_beeper_init(void)
185{
186 return platform_driver_register(&pwm_beeper_driver);
187}
188module_init(pwm_beeper_init);
189
190static void __exit pwm_beeper_exit(void)
191{
192 platform_driver_unregister(&pwm_beeper_driver);
193}
194module_exit(pwm_beeper_exit);
195
196MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
197MODULE_DESCRIPTION("PWM beeper driver");
198MODULE_LICENSE("GPL");
199MODULE_ALIAS("platform:pwm-beeper");
diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c
index e9069b87fde..f16972bddca 100644
--- a/drivers/input/misc/twl4030-pwrbutton.c
+++ b/drivers/input/misc/twl4030-pwrbutton.c
@@ -52,7 +52,7 @@ static irqreturn_t powerbutton_irq(int irq, void *_pwr)
52 return IRQ_HANDLED; 52 return IRQ_HANDLED;
53} 53}
54 54
55static int __devinit twl4030_pwrbutton_probe(struct platform_device *pdev) 55static int __init twl4030_pwrbutton_probe(struct platform_device *pdev)
56{ 56{
57 struct input_dev *pwr; 57 struct input_dev *pwr;
58 int irq = platform_get_irq(pdev, 0); 58 int irq = platform_get_irq(pdev, 0);
@@ -95,7 +95,7 @@ free_input_dev:
95 return err; 95 return err;
96} 96}
97 97
98static int __devexit twl4030_pwrbutton_remove(struct platform_device *pdev) 98static int __exit twl4030_pwrbutton_remove(struct platform_device *pdev)
99{ 99{
100 struct input_dev *pwr = platform_get_drvdata(pdev); 100 struct input_dev *pwr = platform_get_drvdata(pdev);
101 int irq = platform_get_irq(pdev, 0); 101 int irq = platform_get_irq(pdev, 0);
@@ -106,9 +106,8 @@ static int __devexit twl4030_pwrbutton_remove(struct platform_device *pdev)
106 return 0; 106 return 0;
107} 107}
108 108
109struct platform_driver twl4030_pwrbutton_driver = { 109static struct platform_driver twl4030_pwrbutton_driver = {
110 .probe = twl4030_pwrbutton_probe, 110 .remove = __exit_p(twl4030_pwrbutton_remove),
111 .remove = __devexit_p(twl4030_pwrbutton_remove),
112 .driver = { 111 .driver = {
113 .name = "twl4030_pwrbutton", 112 .name = "twl4030_pwrbutton",
114 .owner = THIS_MODULE, 113 .owner = THIS_MODULE,
@@ -117,7 +116,8 @@ struct platform_driver twl4030_pwrbutton_driver = {
117 116
118static int __init twl4030_pwrbutton_init(void) 117static int __init twl4030_pwrbutton_init(void)
119{ 118{
120 return platform_driver_register(&twl4030_pwrbutton_driver); 119 return platform_driver_probe(&twl4030_pwrbutton_driver,
120 twl4030_pwrbutton_probe);
121} 121}
122module_init(twl4030_pwrbutton_init); 122module_init(twl4030_pwrbutton_init);
123 123
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index 4dac8b79fcd..12501de0c5c 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -1347,7 +1347,7 @@ static int __init wb_module_init(void)
1347 1347
1348 err = map_bios(); 1348 err = map_bios();
1349 if (err) 1349 if (err)
1350 return err; 1350 goto err_free_keymap;
1351 1351
1352 err = platform_driver_register(&wistron_driver); 1352 err = platform_driver_register(&wistron_driver);
1353 if (err) 1353 if (err)
@@ -1371,6 +1371,8 @@ static int __init wb_module_init(void)
1371 platform_driver_unregister(&wistron_driver); 1371 platform_driver_unregister(&wistron_driver);
1372 err_unmap_bios: 1372 err_unmap_bios:
1373 unmap_bios(); 1373 unmap_bios();
1374 err_free_keymap:
1375 kfree(keymap);
1374 1376
1375 return err; 1377 return err;
1376} 1378}
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 6dedded2722..ea67c49146a 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -312,6 +312,8 @@ static void setup_events_to_report(struct input_dev *input_dev,
312 __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); 312 __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
313 __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); 313 __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
314 __set_bit(BTN_LEFT, input_dev->keybit); 314 __set_bit(BTN_LEFT, input_dev->keybit);
315
316 input_set_events_per_packet(input_dev, 60);
315} 317}
316 318
317/* report button data as logical button state */ 319/* report button data as logical button state */
@@ -580,23 +582,30 @@ exit:
580 */ 582 */
581static int bcm5974_start_traffic(struct bcm5974 *dev) 583static int bcm5974_start_traffic(struct bcm5974 *dev)
582{ 584{
583 if (bcm5974_wellspring_mode(dev, true)) { 585 int error;
586
587 error = bcm5974_wellspring_mode(dev, true);
588 if (error) {
584 dprintk(1, "bcm5974: mode switch failed\n"); 589 dprintk(1, "bcm5974: mode switch failed\n");
585 goto error; 590 goto err_out;
586 } 591 }
587 592
588 if (usb_submit_urb(dev->bt_urb, GFP_KERNEL)) 593 error = usb_submit_urb(dev->bt_urb, GFP_KERNEL);
589 goto error; 594 if (error)
595 goto err_reset_mode;
590 596
591 if (usb_submit_urb(dev->tp_urb, GFP_KERNEL)) 597 error = usb_submit_urb(dev->tp_urb, GFP_KERNEL);
598 if (error)
592 goto err_kill_bt; 599 goto err_kill_bt;
593 600
594 return 0; 601 return 0;
595 602
596err_kill_bt: 603err_kill_bt:
597 usb_kill_urb(dev->bt_urb); 604 usb_kill_urb(dev->bt_urb);
598error: 605err_reset_mode:
599 return -EIO; 606 bcm5974_wellspring_mode(dev, false);
607err_out:
608 return error;
600} 609}
601 610
602static void bcm5974_pause_traffic(struct bcm5974 *dev) 611static void bcm5974_pause_traffic(struct bcm5974 *dev)
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 705589dc9ac..8c324403b9f 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -502,7 +502,9 @@ static void synaptics_process_packet(struct psmouse *psmouse)
502 } 502 }
503 input_report_abs(dev, ABS_PRESSURE, hw.z); 503 input_report_abs(dev, ABS_PRESSURE, hw.z);
504 504
505 input_report_abs(dev, ABS_TOOL_WIDTH, finger_width); 505 if (SYN_CAP_PALMDETECT(priv->capabilities))
506 input_report_abs(dev, ABS_TOOL_WIDTH, finger_width);
507
506 input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1); 508 input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1);
507 input_report_key(dev, BTN_LEFT, hw.left); 509 input_report_key(dev, BTN_LEFT, hw.left);
508 input_report_key(dev, BTN_RIGHT, hw.right); 510 input_report_key(dev, BTN_RIGHT, hw.right);
@@ -602,7 +604,9 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
602 input_set_abs_params(dev, ABS_Y, 604 input_set_abs_params(dev, ABS_Y,
603 YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); 605 YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0);
604 input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); 606 input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
605 __set_bit(ABS_TOOL_WIDTH, dev->absbit); 607
608 if (SYN_CAP_PALMDETECT(priv->capabilities))
609 input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
606 610
607 __set_bit(EV_KEY, dev->evbit); 611 __set_bit(EV_KEY, dev->evbit);
608 __set_bit(BTN_TOUCH, dev->keybit); 612 __set_bit(BTN_TOUCH, dev->keybit);
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index f34b22bce4f..d8f68f77007 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -57,7 +57,6 @@ struct mousedev_hw_data {
57}; 57};
58 58
59struct mousedev { 59struct mousedev {
60 int exist;
61 int open; 60 int open;
62 int minor; 61 int minor;
63 struct input_handle handle; 62 struct input_handle handle;
@@ -66,6 +65,7 @@ struct mousedev {
66 spinlock_t client_lock; /* protects client_list */ 65 spinlock_t client_lock; /* protects client_list */
67 struct mutex mutex; 66 struct mutex mutex;
68 struct device dev; 67 struct device dev;
68 bool exist;
69 69
70 struct list_head mixdev_node; 70 struct list_head mixdev_node;
71 int mixdev_open; 71 int mixdev_open;
@@ -765,10 +765,15 @@ static unsigned int mousedev_poll(struct file *file, poll_table *wait)
765{ 765{
766 struct mousedev_client *client = file->private_data; 766 struct mousedev_client *client = file->private_data;
767 struct mousedev *mousedev = client->mousedev; 767 struct mousedev *mousedev = client->mousedev;
768 unsigned int mask;
768 769
769 poll_wait(file, &mousedev->wait, wait); 770 poll_wait(file, &mousedev->wait, wait);
770 return ((client->ready || client->buffer) ? (POLLIN | POLLRDNORM) : 0) | 771
771 (mousedev->exist ? 0 : (POLLHUP | POLLERR)); 772 mask = mousedev->exist ? POLLOUT | POLLWRNORM : POLLHUP | POLLERR;
773 if (client->ready || client->buffer)
774 mask |= POLLIN | POLLRDNORM;
775
776 return mask;
772} 777}
773 778
774static const struct file_operations mousedev_fops = { 779static const struct file_operations mousedev_fops = {
@@ -802,7 +807,7 @@ static void mousedev_remove_chrdev(struct mousedev *mousedev)
802static void mousedev_mark_dead(struct mousedev *mousedev) 807static void mousedev_mark_dead(struct mousedev *mousedev)
803{ 808{
804 mutex_lock(&mousedev->mutex); 809 mutex_lock(&mousedev->mutex);
805 mousedev->exist = 0; 810 mousedev->exist = false;
806 mutex_unlock(&mousedev->mutex); 811 mutex_unlock(&mousedev->mutex);
807} 812}
808 813
@@ -862,7 +867,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
862 dev_set_name(&mousedev->dev, "mouse%d", minor); 867 dev_set_name(&mousedev->dev, "mouse%d", minor);
863 868
864 mousedev->minor = minor; 869 mousedev->minor = minor;
865 mousedev->exist = 1; 870 mousedev->exist = true;
866 mousedev->handle.dev = input_get_device(dev); 871 mousedev->handle.dev = input_get_device(dev);
867 mousedev->handle.name = dev_name(&mousedev->dev); 872 mousedev->handle.name = dev_name(&mousedev->dev);
868 mousedev->handle.handler = handler; 873 mousedev->handle.handler = handler;
diff --git a/drivers/input/serio/i8042-ppcio.h b/drivers/input/serio/i8042-ppcio.h
index 2906e1b60c0..f708c75d16f 100644
--- a/drivers/input/serio/i8042-ppcio.h
+++ b/drivers/input/serio/i8042-ppcio.h
@@ -52,81 +52,6 @@ static inline void i8042_platform_exit(void)
52{ 52{
53} 53}
54 54
55#elif defined(CONFIG_SPRUCE)
56
57#define I8042_KBD_IRQ 22
58#define I8042_AUX_IRQ 21
59
60#define I8042_KBD_PHYS_DESC "spruceps2/serio0"
61#define I8042_AUX_PHYS_DESC "spruceps2/serio1"
62#define I8042_MUX_PHYS_DESC "spruceps2/serio%d"
63
64#define I8042_COMMAND_REG 0xff810000
65#define I8042_DATA_REG 0xff810001
66
67static inline int i8042_read_data(void)
68{
69 unsigned long kbd_data;
70
71 __raw_writel(0x00000088, 0xff500008);
72 eieio();
73
74 __raw_writel(0x03000000, 0xff50000c);
75 eieio();
76
77 asm volatile("lis 7,0xff88 \n\
78 lswi 6,7,0x8 \n\
79 mr %0,6"
80 : "=r" (kbd_data) :: "6", "7");
81
82 __raw_writel(0x00000000, 0xff50000c);
83 eieio();
84
85 return (unsigned char)(kbd_data >> 24);
86}
87
88static inline int i8042_read_status(void)
89{
90 unsigned long kbd_status;
91
92 __raw_writel(0x00000088, 0xff500008);
93 eieio();
94
95 __raw_writel(0x03000000, 0xff50000c);
96 eieio();
97
98 asm volatile("lis 7,0xff88 \n\
99 ori 7,7,0x8 \n\
100 lswi 6,7,0x8 \n\
101 mr %0,6"
102 : "=r" (kbd_status) :: "6", "7");
103
104 __raw_writel(0x00000000, 0xff50000c);
105 eieio();
106
107 return (unsigned char)(kbd_status >> 24);
108}
109
110static inline void i8042_write_data(int val)
111{
112 *((unsigned char *)0xff810000) = (char)val;
113}
114
115static inline void i8042_write_command(int val)
116{
117 *((unsigned char *)0xff810001) = (char)val;
118}
119
120static inline int i8042_platform_init(void)
121{
122 i8042_reset = 1;
123 return 0;
124}
125
126static inline void i8042_platform_exit(void)
127{
128}
129
130#else 55#else
131 56
132#include "i8042-io.h" 57#include "i8042-io.h"
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 6440a8f5568..258b98b9d7c 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -861,9 +861,6 @@ static int i8042_controller_selftest(void)
861 unsigned char param; 861 unsigned char param;
862 int i = 0; 862 int i = 0;
863 863
864 if (!i8042_reset)
865 return 0;
866
867 /* 864 /*
868 * We try this 5 times; on some really fragile systems this does not 865 * We try this 5 times; on some really fragile systems this does not
869 * take the first time... 866 * take the first time...
@@ -1020,7 +1017,8 @@ static void i8042_controller_reset(void)
1020 * Reset the controller if requested. 1017 * Reset the controller if requested.
1021 */ 1018 */
1022 1019
1023 i8042_controller_selftest(); 1020 if (i8042_reset)
1021 i8042_controller_selftest();
1024 1022
1025/* 1023/*
1026 * Restore the original control register setting. 1024 * Restore the original control register setting.
@@ -1094,23 +1092,11 @@ static void i8042_dritek_enable(void)
1094#ifdef CONFIG_PM 1092#ifdef CONFIG_PM
1095 1093
1096/* 1094/*
1097 * Here we try to restore the original BIOS settings to avoid
1098 * upsetting it.
1099 */
1100
1101static int i8042_pm_reset(struct device *dev)
1102{
1103 i8042_controller_reset();
1104
1105 return 0;
1106}
1107
1108/*
1109 * Here we try to reset everything back to a state we had 1095 * Here we try to reset everything back to a state we had
1110 * before suspending. 1096 * before suspending.
1111 */ 1097 */
1112 1098
1113static int i8042_pm_restore(struct device *dev) 1099static int i8042_controller_resume(bool force_reset)
1114{ 1100{
1115 int error; 1101 int error;
1116 1102
@@ -1118,9 +1104,11 @@ static int i8042_pm_restore(struct device *dev)
1118 if (error) 1104 if (error)
1119 return error; 1105 return error;
1120 1106
1121 error = i8042_controller_selftest(); 1107 if (i8042_reset || force_reset) {
1122 if (error) 1108 error = i8042_controller_selftest();
1123 return error; 1109 if (error)
1110 return error;
1111 }
1124 1112
1125/* 1113/*
1126 * Restore original CTR value and disable all ports 1114 * Restore original CTR value and disable all ports
@@ -1162,6 +1150,28 @@ static int i8042_pm_restore(struct device *dev)
1162 return 0; 1150 return 0;
1163} 1151}
1164 1152
1153/*
1154 * Here we try to restore the original BIOS settings to avoid
1155 * upsetting it.
1156 */
1157
1158static int i8042_pm_reset(struct device *dev)
1159{
1160 i8042_controller_reset();
1161
1162 return 0;
1163}
1164
1165static int i8042_pm_resume(struct device *dev)
1166{
1167 /*
1168 * On resume from S2R we always try to reset the controller
1169 * to bring it in a sane state. (In case of S2D we expect
1170 * BIOS to reset the controller for us.)
1171 */
1172 return i8042_controller_resume(true);
1173}
1174
1165static int i8042_pm_thaw(struct device *dev) 1175static int i8042_pm_thaw(struct device *dev)
1166{ 1176{
1167 i8042_interrupt(0, NULL); 1177 i8042_interrupt(0, NULL);
@@ -1169,9 +1179,14 @@ static int i8042_pm_thaw(struct device *dev)
1169 return 0; 1179 return 0;
1170} 1180}
1171 1181
1182static int i8042_pm_restore(struct device *dev)
1183{
1184 return i8042_controller_resume(false);
1185}
1186
1172static const struct dev_pm_ops i8042_pm_ops = { 1187static const struct dev_pm_ops i8042_pm_ops = {
1173 .suspend = i8042_pm_reset, 1188 .suspend = i8042_pm_reset,
1174 .resume = i8042_pm_restore, 1189 .resume = i8042_pm_resume,
1175 .thaw = i8042_pm_thaw, 1190 .thaw = i8042_pm_thaw,
1176 .poweroff = i8042_pm_reset, 1191 .poweroff = i8042_pm_reset,
1177 .restore = i8042_pm_restore, 1192 .restore = i8042_pm_restore,
@@ -1389,9 +1404,11 @@ static int __init i8042_probe(struct platform_device *dev)
1389 1404
1390 i8042_platform_device = dev; 1405 i8042_platform_device = dev;
1391 1406
1392 error = i8042_controller_selftest(); 1407 if (i8042_reset) {
1393 if (error) 1408 error = i8042_controller_selftest();
1394 return error; 1409 if (error)
1410 return error;
1411 }
1395 1412
1396 error = i8042_controller_init(); 1413 error = i8042_controller_init();
1397 if (error) 1414 if (error)
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 415f6306105..ce0b4608dad 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -158,6 +158,39 @@ static int wacom_ptu_irq(struct wacom_wac *wacom)
158 return 1; 158 return 1;
159} 159}
160 160
161static int wacom_dtu_irq(struct wacom_wac *wacom)
162{
163 struct wacom_features *features = &wacom->features;
164 char *data = wacom->data;
165 struct input_dev *input = wacom->input;
166 int prox = data[1] & 0x20, pressure;
167
168 dbg("wacom_dtu_irq: received report #%d", data[0]);
169
170 if (prox) {
171 /* Going into proximity select tool */
172 wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
173 if (wacom->tool[0] == BTN_TOOL_PEN)
174 wacom->id[0] = STYLUS_DEVICE_ID;
175 else
176 wacom->id[0] = ERASER_DEVICE_ID;
177 }
178 input_report_key(input, BTN_STYLUS, data[1] & 0x02);
179 input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
180 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
181 input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
182 pressure = ((data[7] & 0x01) << 8) | data[6];
183 if (pressure < 0)
184 pressure = features->pressure_max + pressure + 1;
185 input_report_abs(input, ABS_PRESSURE, pressure);
186 input_report_key(input, BTN_TOUCH, data[1] & 0x05);
187 if (!prox) /* out-prox */
188 wacom->id[0] = 0;
189 input_report_key(input, wacom->tool[0], prox);
190 input_report_abs(input, ABS_MISC, wacom->id[0]);
191 return 1;
192}
193
161static int wacom_graphire_irq(struct wacom_wac *wacom) 194static int wacom_graphire_irq(struct wacom_wac *wacom)
162{ 195{
163 struct wacom_features *features = &wacom->features; 196 struct wacom_features *features = &wacom->features;
@@ -845,6 +878,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
845 sync = wacom_ptu_irq(wacom_wac); 878 sync = wacom_ptu_irq(wacom_wac);
846 break; 879 break;
847 880
881 case DTU:
882 sync = wacom_dtu_irq(wacom_wac);
883 break;
884
848 case INTUOS: 885 case INTUOS:
849 case INTUOS3S: 886 case INTUOS3S:
850 case INTUOS3: 887 case INTUOS3:
@@ -1030,6 +1067,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
1030 1067
1031 case PL: 1068 case PL:
1032 case PTU: 1069 case PTU:
1070 case DTU:
1033 __set_bit(BTN_TOOL_PEN, input_dev->keybit); 1071 __set_bit(BTN_TOOL_PEN, input_dev->keybit);
1034 __set_bit(BTN_STYLUS, input_dev->keybit); 1072 __set_bit(BTN_STYLUS, input_dev->keybit);
1035 __set_bit(BTN_STYLUS2, input_dev->keybit); 1073 __set_bit(BTN_STYLUS2, input_dev->keybit);
@@ -1155,6 +1193,10 @@ static const struct wacom_features wacom_features_0xC6 =
1155 { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }; 1193 { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE };
1156static const struct wacom_features wacom_features_0xC7 = 1194static const struct wacom_features wacom_features_0xC7 =
1157 { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }; 1195 { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL };
1196static const struct wacom_features wacom_features_0xCE =
1197 { "Wacom DTU2231", WACOM_PKGLEN_GRAPHIRE, 47864, 27011, 511, 0, DTU };
1198static const struct wacom_features wacom_features_0xF0 =
1199 { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, 0, DTU };
1158static const struct wacom_features wacom_features_0xCC = 1200static const struct wacom_features wacom_features_0xCC =
1159 { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, 63, WACOM_21UX2 }; 1201 { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, 63, WACOM_21UX2 };
1160static const struct wacom_features wacom_features_0x90 = 1202static const struct wacom_features wacom_features_0x90 =
@@ -1234,6 +1276,8 @@ const struct usb_device_id wacom_ids[] = {
1234 { USB_DEVICE_WACOM(0xC5) }, 1276 { USB_DEVICE_WACOM(0xC5) },
1235 { USB_DEVICE_WACOM(0xC6) }, 1277 { USB_DEVICE_WACOM(0xC6) },
1236 { USB_DEVICE_WACOM(0xC7) }, 1278 { USB_DEVICE_WACOM(0xC7) },
1279 { USB_DEVICE_WACOM(0xCE) },
1280 { USB_DEVICE_WACOM(0xF0) },
1237 { USB_DEVICE_WACOM(0xCC) }, 1281 { USB_DEVICE_WACOM(0xCC) },
1238 { USB_DEVICE_WACOM(0x90) }, 1282 { USB_DEVICE_WACOM(0x90) },
1239 { USB_DEVICE_WACOM(0x93) }, 1283 { USB_DEVICE_WACOM(0x93) },
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 854b92092df..99e1a54cd30 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -43,6 +43,7 @@ enum {
43 WACOM_G4, 43 WACOM_G4,
44 PTU, 44 PTU,
45 PL, 45 PL,
46 DTU,
46 INTUOS, 47 INTUOS,
47 INTUOS3S, 48 INTUOS3S,
48 INTUOS3, 49 INTUOS3,
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 3b9d5e2105d..61f35184f76 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -55,37 +55,36 @@ config TOUCHSCREEN_AD7877
55 To compile this driver as a module, choose M here: the 55 To compile this driver as a module, choose M here: the
56 module will be called ad7877. 56 module will be called ad7877.
57 57
58config TOUCHSCREEN_AD7879_I2C 58config TOUCHSCREEN_AD7879
59 tristate "AD7879 based touchscreens: AD7879-1 I2C Interface" 59 tristate "Analog Devices AD7879-1/AD7889-1 touchscreen interface"
60 depends on I2C
61 select TOUCHSCREEN_AD7879
62 help 60 help
63 Say Y here if you have a touchscreen interface using the 61 Say Y here if you want to support a touchscreen interface using
64 AD7879-1/AD7889-1 controller, and your board-specific 62 the AD7879-1/AD7889-1 controller.
65 initialization code includes that in its table of I2C devices.
66 63
67 If unsure, say N (but it's safe to say "Y"). 64 You should select a bus connection too.
68 65
69 To compile this driver as a module, choose M here: the 66 To compile this driver as a module, choose M here: the
70 module will be called ad7879. 67 module will be called ad7879.
71 68
69config TOUCHSCREEN_AD7879_I2C
70 tristate "support I2C bus connection"
71 depends on TOUCHSCREEN_AD7879 && I2C
72 help
73 Say Y here if you have AD7879-1/AD7889-1 hooked to an I2C bus.
74
75 To compile this driver as a module, choose M here: the
76 module will be called ad7879-i2c.
77
72config TOUCHSCREEN_AD7879_SPI 78config TOUCHSCREEN_AD7879_SPI
73 tristate "AD7879 based touchscreens: AD7879 SPI Interface" 79 tristate "support SPI bus connection"
74 depends on SPI_MASTER && TOUCHSCREEN_AD7879_I2C = n 80 depends on TOUCHSCREEN_AD7879 && SPI_MASTER
75 select TOUCHSCREEN_AD7879
76 help 81 help
77 Say Y here if you have a touchscreen interface using the 82 Say Y here if you have AD7879-1/AD7889-1 hooked to a SPI bus.
78 AD7879/AD7889 controller, and your board-specific initialization
79 code includes that in its table of SPI devices.
80 83
81 If unsure, say N (but it's safe to say "Y"). 84 If unsure, say N (but it's safe to say "Y").
82 85
83 To compile this driver as a module, choose M here: the 86 To compile this driver as a module, choose M here: the
84 module will be called ad7879. 87 module will be called ad7879-spi.
85
86config TOUCHSCREEN_AD7879
87 tristate
88 default n
89 88
90config TOUCHSCREEN_BITSY 89config TOUCHSCREEN_BITSY
91 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" 90 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen"
@@ -99,6 +98,20 @@ config TOUCHSCREEN_BITSY
99 To compile this driver as a module, choose M here: the 98 To compile this driver as a module, choose M here: the
100 module will be called h3600_ts_input. 99 module will be called h3600_ts_input.
101 100
101config TOUCHSCREEN_CY8CTMG110
102 tristate "cy8ctmg110 touchscreen"
103 depends on I2C
104 depends on GPIOLIB
105
106 help
107 Say Y here if you have a cy8ctmg110 capacitive touchscreen on
108 an AAVA device.
109
110 If unsure, say N.
111
112 To compile this driver as a module, choose M here: the
113 module will be called cy8ctmg110_ts.
114
102config TOUCHSCREEN_DA9034 115config TOUCHSCREEN_DA9034
103 tristate "Touchscreen support for Dialog Semiconductor DA9034" 116 tristate "Touchscreen support for Dialog Semiconductor DA9034"
104 depends on PMIC_DA903X 117 depends on PMIC_DA903X
@@ -292,6 +305,18 @@ config TOUCHSCREEN_PENMOUNT
292 To compile this driver as a module, choose M here: the 305 To compile this driver as a module, choose M here: the
293 module will be called penmount. 306 module will be called penmount.
294 307
308config 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
295config TOUCHSCREEN_MIGOR 320config TOUCHSCREEN_MIGOR
296 tristate "Renesas MIGO-R touchscreen" 321 tristate "Renesas MIGO-R touchscreen"
297 depends on SH_MIGOR && I2C 322 depends on SH_MIGOR && I2C
@@ -540,9 +565,9 @@ config TOUCHSCREEN_USB_ZYTRONIC
540 bool "Zytronic controller" if EMBEDDED 565 bool "Zytronic controller" if EMBEDDED
541 depends on TOUCHSCREEN_USB_COMPOSITE 566 depends on TOUCHSCREEN_USB_COMPOSITE
542 567
543config TOUCHSCREEN_USB_ETT_TC5UH 568config TOUCHSCREEN_USB_ETT_TC45USB
544 default y 569 default y
545 bool "ET&T TC5UH touchscreen controler support" if EMBEDDED 570 bool "ET&T USB series TC4UM/TC5UH touchscreen controler support" if EMBEDDED
546 depends on TOUCHSCREEN_USB_COMPOSITE 571 depends on TOUCHSCREEN_USB_COMPOSITE
547 572
548config TOUCHSCREEN_USB_NEXIO 573config TOUCHSCREEN_USB_NEXIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 497964a7a21..bd6f30b4ff7 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -9,9 +9,13 @@ wm97xx-ts-y := wm97xx-core.o
9obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o 9obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o
10obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o 10obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o
11obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o 11obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o
12obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o
13obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o
12obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o 14obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
13obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o 15obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o
14obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o 16obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
17obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o
18obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o
15obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o 19obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o
16obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o 20obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o
17obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o 21obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
@@ -30,6 +34,7 @@ obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o
30obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o 34obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
31obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o 35obj-$(CONFIG_TOUCHSCREEN_PCAP) += pcap_ts.o
32obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o 36obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
37obj-$(CONFIG_TOUCHSCREEN_QT602240) += qt602240_ts.o
33obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o 38obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
34obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o 39obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o
35obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o 40obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
@@ -38,7 +43,6 @@ obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o
38obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o 43obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
39obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o 44obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o
40obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o 45obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
41obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o
42wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o 46wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
43wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o 47wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o
44wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o 48wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o
diff --git a/drivers/input/touchscreen/ad7879-i2c.c b/drivers/input/touchscreen/ad7879-i2c.c
new file mode 100644
index 00000000000..d82a38ee9a3
--- /dev/null
+++ b/drivers/input/touchscreen/ad7879-i2c.c
@@ -0,0 +1,143 @@
1/*
2 * AD7879-1/AD7889-1 touchscreen (I2C bus)
3 *
4 * Copyright (C) 2008-2010 Michael Hennerich, Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/input.h> /* BUS_I2C */
10#include <linux/i2c.h>
11#include <linux/module.h>
12#include <linux/types.h>
13
14#include "ad7879.h"
15
16#define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */
17
18#ifdef CONFIG_PM
19static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message)
20{
21 struct ad7879 *ts = i2c_get_clientdata(client);
22
23 ad7879_suspend(ts);
24
25 return 0;
26}
27
28static int ad7879_i2c_resume(struct i2c_client *client)
29{
30 struct ad7879 *ts = i2c_get_clientdata(client);
31
32 ad7879_resume(ts);
33
34 return 0;
35}
36#else
37# define ad7879_i2c_suspend NULL
38# define ad7879_i2c_resume NULL
39#endif
40
41/* All registers are word-sized.
42 * AD7879 uses a high-byte first convention.
43 */
44static int ad7879_i2c_read(struct device *dev, u8 reg)
45{
46 struct i2c_client *client = to_i2c_client(dev);
47
48 return swab16(i2c_smbus_read_word_data(client, reg));
49}
50
51static int ad7879_i2c_multi_read(struct device *dev,
52 u8 first_reg, u8 count, u16 *buf)
53{
54 struct i2c_client *client = to_i2c_client(dev);
55 u8 idx;
56
57 i2c_smbus_read_i2c_block_data(client, first_reg, count * 2, (u8 *)buf);
58
59 for (idx = 0; idx < count; ++idx)
60 buf[idx] = swab16(buf[idx]);
61
62 return 0;
63}
64
65static int ad7879_i2c_write(struct device *dev, u8 reg, u16 val)
66{
67 struct i2c_client *client = to_i2c_client(dev);
68
69 return i2c_smbus_write_word_data(client, reg, swab16(val));
70}
71
72static const struct ad7879_bus_ops ad7879_i2c_bus_ops = {
73 .bustype = BUS_I2C,
74 .read = ad7879_i2c_read,
75 .multi_read = ad7879_i2c_multi_read,
76 .write = ad7879_i2c_write,
77};
78
79static int __devinit ad7879_i2c_probe(struct i2c_client *client,
80 const struct i2c_device_id *id)
81{
82 struct ad7879 *ts;
83
84 if (!i2c_check_functionality(client->adapter,
85 I2C_FUNC_SMBUS_WORD_DATA)) {
86 dev_err(&client->dev, "SMBUS Word Data not Supported\n");
87 return -EIO;
88 }
89
90 ts = ad7879_probe(&client->dev, AD7879_DEVID, client->irq,
91 &ad7879_i2c_bus_ops);
92 if (IS_ERR(ts))
93 return PTR_ERR(ts);
94
95 i2c_set_clientdata(client, ts);
96
97 return 0;
98}
99
100static int __devexit ad7879_i2c_remove(struct i2c_client *client)
101{
102 struct ad7879 *ts = i2c_get_clientdata(client);
103
104 ad7879_remove(ts);
105
106 return 0;
107}
108
109static const struct i2c_device_id ad7879_id[] = {
110 { "ad7879", 0 },
111 { "ad7889", 0 },
112 { }
113};
114MODULE_DEVICE_TABLE(i2c, ad7879_id);
115
116static struct i2c_driver ad7879_i2c_driver = {
117 .driver = {
118 .name = "ad7879",
119 .owner = THIS_MODULE,
120 },
121 .probe = ad7879_i2c_probe,
122 .remove = __devexit_p(ad7879_i2c_remove),
123 .suspend = ad7879_i2c_suspend,
124 .resume = ad7879_i2c_resume,
125 .id_table = ad7879_id,
126};
127
128static int __init ad7879_i2c_init(void)
129{
130 return i2c_add_driver(&ad7879_i2c_driver);
131}
132module_init(ad7879_i2c_init);
133
134static void __exit ad7879_i2c_exit(void)
135{
136 i2c_del_driver(&ad7879_i2c_driver);
137}
138module_exit(ad7879_i2c_exit);
139
140MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
141MODULE_DESCRIPTION("AD7879(-1) touchscreen I2C bus driver");
142MODULE_LICENSE("GPL");
143MODULE_ALIAS("i2c:ad7879");
diff --git a/drivers/input/touchscreen/ad7879-spi.c b/drivers/input/touchscreen/ad7879-spi.c
new file mode 100644
index 00000000000..59c6e68c432
--- /dev/null
+++ b/drivers/input/touchscreen/ad7879-spi.c
@@ -0,0 +1,198 @@
1/*
2 * AD7879/AD7889 touchscreen (SPI bus)
3 *
4 * Copyright (C) 2008-2010 Michael Hennerich, Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/input.h> /* BUS_SPI */
10#include <linux/spi/spi.h>
11
12#include "ad7879.h"
13
14#define AD7879_DEVID 0x7A /* AD7879/AD7889 */
15
16#define MAX_SPI_FREQ_HZ 5000000
17#define AD7879_CMD_MAGIC 0xE000
18#define AD7879_CMD_READ (1 << 10)
19#define AD7879_CMD(reg) (AD7879_CMD_MAGIC | ((reg) & 0xF))
20#define AD7879_WRITECMD(reg) (AD7879_CMD(reg))
21#define AD7879_READCMD(reg) (AD7879_CMD(reg) | AD7879_CMD_READ)
22
23#ifdef CONFIG_PM
24static int ad7879_spi_suspend(struct spi_device *spi, pm_message_t message)
25{
26 struct ad7879 *ts = spi_get_drvdata(spi);
27
28 ad7879_suspend(ts);
29
30 return 0;
31}
32
33static int ad7879_spi_resume(struct spi_device *spi)
34{
35 struct ad7879 *ts = spi_get_drvdata(spi);
36
37 ad7879_resume(ts);
38
39 return 0;
40}
41#else
42# define ad7879_spi_suspend NULL
43# define ad7879_spi_resume NULL
44#endif
45
46/*
47 * ad7879_read/write are only used for initial setup and for sysfs controls.
48 * The main traffic is done in ad7879_collect().
49 */
50
51static int ad7879_spi_xfer(struct spi_device *spi,
52 u16 cmd, u8 count, u16 *tx_buf, u16 *rx_buf)
53{
54 struct spi_message msg;
55 struct spi_transfer *xfers;
56 void *spi_data;
57 u16 *command;
58 u16 *_rx_buf = _rx_buf; /* shut gcc up */
59 u8 idx;
60 int ret;
61
62 xfers = spi_data = kzalloc(sizeof(*xfers) * (count + 2), GFP_KERNEL);
63 if (!spi_data)
64 return -ENOMEM;
65
66 spi_message_init(&msg);
67
68 command = spi_data;
69 command[0] = cmd;
70 if (count == 1) {
71 /* ad7879_spi_{read,write} gave us buf on stack */
72 command[1] = *tx_buf;
73 tx_buf = &command[1];
74 _rx_buf = rx_buf;
75 rx_buf = &command[2];
76 }
77
78 ++xfers;
79 xfers[0].tx_buf = command;
80 xfers[0].len = 2;
81 spi_message_add_tail(&xfers[0], &msg);
82 ++xfers;
83
84 for (idx = 0; idx < count; ++idx) {
85 if (rx_buf)
86 xfers[idx].rx_buf = &rx_buf[idx];
87 if (tx_buf)
88 xfers[idx].tx_buf = &tx_buf[idx];
89 xfers[idx].len = 2;
90 spi_message_add_tail(&xfers[idx], &msg);
91 }
92
93 ret = spi_sync(spi, &msg);
94
95 if (count == 1)
96 _rx_buf[0] = command[2];
97
98 kfree(spi_data);
99
100 return ret;
101}
102
103static int ad7879_spi_multi_read(struct device *dev,
104 u8 first_reg, u8 count, u16 *buf)
105{
106 struct spi_device *spi = to_spi_device(dev);
107
108 return ad7879_spi_xfer(spi, AD7879_READCMD(first_reg), count, NULL, buf);
109}
110
111static int ad7879_spi_read(struct device *dev, u8 reg)
112{
113 struct spi_device *spi = to_spi_device(dev);
114 u16 ret, dummy;
115
116 return ad7879_spi_xfer(spi, AD7879_READCMD(reg), 1, &dummy, &ret) ? : ret;
117}
118
119static int ad7879_spi_write(struct device *dev, u8 reg, u16 val)
120{
121 struct spi_device *spi = to_spi_device(dev);
122 u16 dummy;
123
124 return ad7879_spi_xfer(spi, AD7879_WRITECMD(reg), 1, &val, &dummy);
125}
126
127static const struct ad7879_bus_ops ad7879_spi_bus_ops = {
128 .bustype = BUS_SPI,
129 .read = ad7879_spi_read,
130 .multi_read = ad7879_spi_multi_read,
131 .write = ad7879_spi_write,
132};
133
134static int __devinit ad7879_spi_probe(struct spi_device *spi)
135{
136 struct ad7879 *ts;
137 int err;
138
139 /* don't exceed max specified SPI CLK frequency */
140 if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
141 dev_err(&spi->dev, "SPI CLK %d Hz?\n", spi->max_speed_hz);
142 return -EINVAL;
143 }
144
145 spi->bits_per_word = 16;
146 err = spi_setup(spi);
147 if (err) {
148 dev_dbg(&spi->dev, "spi master doesn't support 16 bits/word\n");
149 return err;
150 }
151
152 ts = ad7879_probe(&spi->dev, AD7879_DEVID, spi->irq, &ad7879_spi_bus_ops);
153 if (IS_ERR(ts))
154 return PTR_ERR(ts);
155
156 spi_set_drvdata(spi, ts);
157
158 return 0;
159}
160
161static int __devexit ad7879_spi_remove(struct spi_device *spi)
162{
163 struct ad7879 *ts = spi_get_drvdata(spi);
164
165 ad7879_remove(ts);
166 spi_set_drvdata(spi, NULL);
167
168 return 0;
169}
170
171static struct spi_driver ad7879_spi_driver = {
172 .driver = {
173 .name = "ad7879",
174 .bus = &spi_bus_type,
175 .owner = THIS_MODULE,
176 },
177 .probe = ad7879_spi_probe,
178 .remove = __devexit_p(ad7879_spi_remove),
179 .suspend = ad7879_spi_suspend,
180 .resume = ad7879_spi_resume,
181};
182
183static int __init ad7879_spi_init(void)
184{
185 return spi_register_driver(&ad7879_spi_driver);
186}
187module_init(ad7879_spi_init);
188
189static void __exit ad7879_spi_exit(void)
190{
191 spi_unregister_driver(&ad7879_spi_driver);
192}
193module_exit(ad7879_spi_exit);
194
195MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
196MODULE_DESCRIPTION("AD7879(-1) touchscreen SPI bus driver");
197MODULE_LICENSE("GPL");
198MODULE_ALIAS("spi:ad7879");
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
index 4b32fb4704c..ba6f0bd1e76 100644
--- a/drivers/input/touchscreen/ad7879.c
+++ b/drivers/input/touchscreen/ad7879.c
@@ -1,25 +1,9 @@
1/* 1/*
2 * Copyright (C) 2008-2009 Michael Hennerich, Analog Devices Inc. 2 * AD7879/AD7889 based touchscreen and GPIO driver
3 * 3 *
4 * Description: AD7879/AD7889 based touchscreen, and GPIO driver 4 * Copyright (C) 2008-2010 Michael Hennerich, Analog Devices Inc.
5 * (I2C/SPI Interface)
6 * 5 *
7 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 6 * Licensed under the GPL-2 or later.
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, see the file COPYING, or write
21 * to the Free Software Foundation, Inc.,
22 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 * 7 *
24 * History: 8 * History:
25 * Copyright (c) 2005 David Brownell 9 * Copyright (c) 2005 David Brownell
@@ -44,12 +28,12 @@
44#include <linux/interrupt.h> 28#include <linux/interrupt.h>
45#include <linux/irq.h> 29#include <linux/irq.h>
46#include <linux/slab.h> 30#include <linux/slab.h>
47#include <linux/workqueue.h>
48#include <linux/spi/spi.h> 31#include <linux/spi/spi.h>
49#include <linux/i2c.h> 32#include <linux/i2c.h>
50#include <linux/gpio.h> 33#include <linux/gpio.h>
51 34
52#include <linux/spi/ad7879.h> 35#include <linux/spi/ad7879.h>
36#include "ad7879.h"
53 37
54#define AD7879_REG_ZEROS 0 38#define AD7879_REG_ZEROS 0
55#define AD7879_REG_CTRL1 1 39#define AD7879_REG_CTRL1 1
@@ -120,30 +104,19 @@ enum {
120#define MAX_12BIT ((1<<12)-1) 104#define MAX_12BIT ((1<<12)-1)
121#define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50) 105#define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50)
122 106
123#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
124#define AD7879_DEVID 0x7A
125typedef struct spi_device bus_device;
126#elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
127#define AD7879_DEVID 0x79
128typedef struct i2c_client bus_device;
129#endif
130
131struct ad7879 { 107struct ad7879 {
132 bus_device *bus; 108 const struct ad7879_bus_ops *bops;
109
110 struct device *dev;
133 struct input_dev *input; 111 struct input_dev *input;
134 struct work_struct work;
135 struct timer_list timer; 112 struct timer_list timer;
136#ifdef CONFIG_GPIOLIB 113#ifdef CONFIG_GPIOLIB
137 struct gpio_chip gc; 114 struct gpio_chip gc;
138#endif
139 struct mutex mutex; 115 struct mutex mutex;
140 unsigned disabled:1; /* P: mutex */
141
142#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
143 struct spi_message msg;
144 struct spi_transfer xfer[AD7879_NR_SENSE + 1];
145 u16 cmd;
146#endif 116#endif
117 unsigned int irq;
118 bool disabled; /* P: input->mutex */
119 bool suspended; /* P: input->mutex */
147 u16 conversion_data[AD7879_NR_SENSE]; 120 u16 conversion_data[AD7879_NR_SENSE];
148 char phys[32]; 121 char phys[32];
149 u8 first_conversion_delay; 122 u8 first_conversion_delay;
@@ -158,11 +131,22 @@ struct ad7879 {
158 u16 cmd_crtl3; 131 u16 cmd_crtl3;
159}; 132};
160 133
161static int ad7879_read(bus_device *, u8); 134static int ad7879_read(struct ad7879 *ts, u8 reg)
162static int ad7879_write(bus_device *, u8, u16); 135{
163static void ad7879_collect(struct ad7879 *); 136 return ts->bops->read(ts->dev, reg);
137}
138
139static int ad7879_multi_read(struct ad7879 *ts, u8 first_reg, u8 count, u16 *buf)
140{
141 return ts->bops->multi_read(ts->dev, first_reg, count, buf);
142}
164 143
165static void ad7879_report(struct ad7879 *ts) 144static int ad7879_write(struct ad7879 *ts, u8 reg, u16 val)
145{
146 return ts->bops->write(ts->dev, reg, val);
147}
148
149static int ad7879_report(struct ad7879 *ts)
166{ 150{
167 struct input_dev *input_dev = ts->input; 151 struct input_dev *input_dev = ts->input;
168 unsigned Rt; 152 unsigned Rt;
@@ -175,12 +159,14 @@ static void ad7879_report(struct ad7879 *ts)
175 159
176 /* 160 /*
177 * The samples processed here are already preprocessed by the AD7879. 161 * The samples processed here are already preprocessed by the AD7879.
178 * The preprocessing function consists of a median and an averaging filter. 162 * The preprocessing function consists of a median and an averaging
179 * The combination of these two techniques provides a robust solution, 163 * filter. The combination of these two techniques provides a robust
180 * discarding the spurious noise in the signal and keeping only the data of interest. 164 * solution, discarding the spurious noise in the signal and keeping
181 * The size of both filters is programmable. (dev.platform_data, see linux/spi/ad7879.h) 165 * only the data of interest. The size of both filters is
182 * Other user-programmable conversion controls include variable acquisition time, 166 * programmable. (dev.platform_data, see linux/spi/ad7879.h) Other
183 * and first conversion delay. Up to 16 averages can be taken per conversion. 167 * user-programmable conversion controls include variable acquisition
168 * time, and first conversion delay. Up to 16 averages can be taken
169 * per conversion.
184 */ 170 */
185 171
186 if (likely(x && z1)) { 172 if (likely(x && z1)) {
@@ -189,21 +175,17 @@ static void ad7879_report(struct ad7879 *ts)
189 Rt /= z1; 175 Rt /= z1;
190 Rt = (Rt + 2047) >> 12; 176 Rt = (Rt + 2047) >> 12;
191 177
178 if (!timer_pending(&ts->timer))
179 input_report_key(input_dev, BTN_TOUCH, 1);
180
192 input_report_abs(input_dev, ABS_X, x); 181 input_report_abs(input_dev, ABS_X, x);
193 input_report_abs(input_dev, ABS_Y, y); 182 input_report_abs(input_dev, ABS_Y, y);
194 input_report_abs(input_dev, ABS_PRESSURE, Rt); 183 input_report_abs(input_dev, ABS_PRESSURE, Rt);
195 input_sync(input_dev); 184 input_sync(input_dev);
185 return 0;
196 } 186 }
197}
198
199static void ad7879_work(struct work_struct *work)
200{
201 struct ad7879 *ts = container_of(work, struct ad7879, work);
202 187
203 /* use keventd context to read the result registers */ 188 return -EINVAL;
204 ad7879_collect(ts);
205 ad7879_report(ts);
206 mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT);
207} 189}
208 190
209static void ad7879_ts_event_release(struct ad7879 *ts) 191static void ad7879_ts_event_release(struct ad7879 *ts)
@@ -211,6 +193,7 @@ static void ad7879_ts_event_release(struct ad7879 *ts)
211 struct input_dev *input_dev = ts->input; 193 struct input_dev *input_dev = ts->input;
212 194
213 input_report_abs(input_dev, ABS_PRESSURE, 0); 195 input_report_abs(input_dev, ABS_PRESSURE, 0);
196 input_report_key(input_dev, BTN_TOUCH, 0);
214 input_sync(input_dev); 197 input_sync(input_dev);
215} 198}
216 199
@@ -225,56 +208,98 @@ static irqreturn_t ad7879_irq(int irq, void *handle)
225{ 208{
226 struct ad7879 *ts = handle; 209 struct ad7879 *ts = handle;
227 210
228 /* The repeated conversion sequencer controlled by TMR kicked off too fast. 211 ad7879_multi_read(ts, AD7879_REG_XPLUS, AD7879_NR_SENSE, ts->conversion_data);
229 * We ignore the last and process the sample sequence currently in the queue.
230 * It can't be older than 9.4ms
231 */
232 212
233 if (!work_pending(&ts->work)) 213 if (!ad7879_report(ts))
234 schedule_work(&ts->work); 214 mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT);
235 215
236 return IRQ_HANDLED; 216 return IRQ_HANDLED;
237} 217}
238 218
239static void ad7879_setup(struct ad7879 *ts) 219static void __ad7879_enable(struct ad7879 *ts)
240{ 220{
241 ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); 221 ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2);
242 ad7879_write(ts->bus, AD7879_REG_CTRL3, ts->cmd_crtl3); 222 ad7879_write(ts, AD7879_REG_CTRL3, ts->cmd_crtl3);
243 ad7879_write(ts->bus, AD7879_REG_CTRL1, ts->cmd_crtl1); 223 ad7879_write(ts, AD7879_REG_CTRL1, ts->cmd_crtl1);
224
225 enable_irq(ts->irq);
244} 226}
245 227
246static void ad7879_disable(struct ad7879 *ts) 228static void __ad7879_disable(struct ad7879 *ts)
247{ 229{
248 mutex_lock(&ts->mutex); 230 disable_irq(ts->irq);
231
232 if (del_timer_sync(&ts->timer))
233 ad7879_ts_event_release(ts);
234
235 ad7879_write(ts, AD7879_REG_CTRL2, AD7879_PM(AD7879_PM_SHUTDOWN));
236}
249 237
250 if (!ts->disabled) {
251 238
252 ts->disabled = 1; 239static int ad7879_open(struct input_dev *input)
253 disable_irq(ts->bus->irq); 240{
241 struct ad7879 *ts = input_get_drvdata(input);
254 242
255 cancel_work_sync(&ts->work); 243 /* protected by input->mutex */
244 if (!ts->disabled && !ts->suspended)
245 __ad7879_enable(ts);
256 246
257 if (del_timer_sync(&ts->timer)) 247 return 0;
258 ad7879_ts_event_release(ts); 248}
259 249
260 ad7879_write(ts->bus, AD7879_REG_CTRL2, 250static void ad7879_close(struct input_dev* input)
261 AD7879_PM(AD7879_PM_SHUTDOWN)); 251{
262 } 252 struct ad7879 *ts = input_get_drvdata(input);
263 253
264 mutex_unlock(&ts->mutex); 254 /* protected by input->mutex */
255 if (!ts->disabled && !ts->suspended)
256 __ad7879_disable(ts);
265} 257}
266 258
267static void ad7879_enable(struct ad7879 *ts) 259void ad7879_suspend(struct ad7879 *ts)
268{ 260{
269 mutex_lock(&ts->mutex); 261 mutex_lock(&ts->input->mutex);
262
263 if (!ts->suspended && !ts->disabled && ts->input->users)
264 __ad7879_disable(ts);
265
266 ts->suspended = true;
270 267
271 if (ts->disabled) { 268 mutex_unlock(&ts->input->mutex);
272 ad7879_setup(ts); 269}
273 ts->disabled = 0; 270EXPORT_SYMBOL(ad7879_suspend);
274 enable_irq(ts->bus->irq); 271
272void ad7879_resume(struct ad7879 *ts)
273{
274 mutex_lock(&ts->input->mutex);
275
276 if (ts->suspended && !ts->disabled && ts->input->users)
277 __ad7879_enable(ts);
278
279 ts->suspended = false;
280
281 mutex_unlock(&ts->input->mutex);
282}
283EXPORT_SYMBOL(ad7879_resume);
284
285static void ad7879_toggle(struct ad7879 *ts, bool disable)
286{
287 mutex_lock(&ts->input->mutex);
288
289 if (!ts->suspended && ts->input->users != 0) {
290
291 if (disable) {
292 if (ts->disabled)
293 __ad7879_enable(ts);
294 } else {
295 if (!ts->disabled)
296 __ad7879_disable(ts);
297 }
275 } 298 }
276 299
277 mutex_unlock(&ts->mutex); 300 ts->disabled = disable;
301
302 mutex_unlock(&ts->input->mutex);
278} 303}
279 304
280static ssize_t ad7879_disable_show(struct device *dev, 305static ssize_t ad7879_disable_show(struct device *dev,
@@ -297,10 +322,7 @@ static ssize_t ad7879_disable_store(struct device *dev,
297 if (error) 322 if (error)
298 return error; 323 return error;
299 324
300 if (val) 325 ad7879_toggle(ts, val);
301 ad7879_disable(ts);
302 else
303 ad7879_enable(ts);
304 326
305 return count; 327 return count;
306} 328}
@@ -325,7 +347,7 @@ static int ad7879_gpio_direction_input(struct gpio_chip *chip,
325 347
326 mutex_lock(&ts->mutex); 348 mutex_lock(&ts->mutex);
327 ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIODIR | AD7879_GPIOPOL; 349 ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIODIR | AD7879_GPIOPOL;
328 err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); 350 err = ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2);
329 mutex_unlock(&ts->mutex); 351 mutex_unlock(&ts->mutex);
330 352
331 return err; 353 return err;
@@ -345,7 +367,7 @@ static int ad7879_gpio_direction_output(struct gpio_chip *chip,
345 else 367 else
346 ts->cmd_crtl2 &= ~AD7879_GPIO_DATA; 368 ts->cmd_crtl2 &= ~AD7879_GPIO_DATA;
347 369
348 err = ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); 370 err = ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2);
349 mutex_unlock(&ts->mutex); 371 mutex_unlock(&ts->mutex);
350 372
351 return err; 373 return err;
@@ -357,7 +379,7 @@ static int ad7879_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
357 u16 val; 379 u16 val;
358 380
359 mutex_lock(&ts->mutex); 381 mutex_lock(&ts->mutex);
360 val = ad7879_read(ts->bus, AD7879_REG_CTRL2); 382 val = ad7879_read(ts, AD7879_REG_CTRL2);
361 mutex_unlock(&ts->mutex); 383 mutex_unlock(&ts->mutex);
362 384
363 return !!(val & AD7879_GPIO_DATA); 385 return !!(val & AD7879_GPIO_DATA);
@@ -374,16 +396,17 @@ static void ad7879_gpio_set_value(struct gpio_chip *chip,
374 else 396 else
375 ts->cmd_crtl2 &= ~AD7879_GPIO_DATA; 397 ts->cmd_crtl2 &= ~AD7879_GPIO_DATA;
376 398
377 ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); 399 ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2);
378 mutex_unlock(&ts->mutex); 400 mutex_unlock(&ts->mutex);
379} 401}
380 402
381static int __devinit ad7879_gpio_add(struct device *dev) 403static int ad7879_gpio_add(struct ad7879 *ts,
404 const struct ad7879_platform_data *pdata)
382{ 405{
383 struct ad7879 *ts = dev_get_drvdata(dev);
384 struct ad7879_platform_data *pdata = dev->platform_data;
385 int ret = 0; 406 int ret = 0;
386 407
408 mutex_init(&ts->mutex);
409
387 if (pdata->gpio_export) { 410 if (pdata->gpio_export) {
388 ts->gc.direction_input = ad7879_gpio_direction_input; 411 ts->gc.direction_input = ad7879_gpio_direction_input;
389 ts->gc.direction_output = ad7879_gpio_direction_output; 412 ts->gc.direction_output = ad7879_gpio_direction_output;
@@ -394,72 +417,75 @@ static int __devinit ad7879_gpio_add(struct device *dev)
394 ts->gc.ngpio = 1; 417 ts->gc.ngpio = 1;
395 ts->gc.label = "AD7879-GPIO"; 418 ts->gc.label = "AD7879-GPIO";
396 ts->gc.owner = THIS_MODULE; 419 ts->gc.owner = THIS_MODULE;
397 ts->gc.dev = dev; 420 ts->gc.dev = ts->dev;
398 421
399 ret = gpiochip_add(&ts->gc); 422 ret = gpiochip_add(&ts->gc);
400 if (ret) 423 if (ret)
401 dev_err(dev, "failed to register gpio %d\n", 424 dev_err(ts->dev, "failed to register gpio %d\n",
402 ts->gc.base); 425 ts->gc.base);
403 } 426 }
404 427
405 return ret; 428 return ret;
406} 429}
407 430
408/* 431static void ad7879_gpio_remove(struct ad7879 *ts)
409 * We mark ad7879_gpio_remove inline so there is a chance the code
410 * gets discarded when not needed. We can't do __devinit/__devexit
411 * markup since it is used in both probe and remove methods.
412 */
413static inline void ad7879_gpio_remove(struct device *dev)
414{ 432{
415 struct ad7879 *ts = dev_get_drvdata(dev); 433 const struct ad7879_platform_data *pdata = ts->dev->platform_data;
416 struct ad7879_platform_data *pdata = dev->platform_data;
417 int ret; 434 int ret;
418 435
419 if (pdata->gpio_export) { 436 if (pdata->gpio_export) {
420 ret = gpiochip_remove(&ts->gc); 437 ret = gpiochip_remove(&ts->gc);
421 if (ret) 438 if (ret)
422 dev_err(dev, "failed to remove gpio %d\n", 439 dev_err(ts->dev, "failed to remove gpio %d\n",
423 ts->gc.base); 440 ts->gc.base);
424 } 441 }
425} 442}
426#else 443#else
427static inline int ad7879_gpio_add(struct device *dev) 444static inline int ad7879_gpio_add(struct ad7879 *ts,
445 const struct ad7879_platform_data *pdata)
428{ 446{
429 return 0; 447 return 0;
430} 448}
431 449
432static inline void ad7879_gpio_remove(struct device *dev) 450static inline void ad7879_gpio_remove(struct ad7879 *ts)
433{ 451{
434} 452}
435#endif 453#endif
436 454
437static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) 455struct ad7879 *ad7879_probe(struct device *dev, u8 devid, unsigned int irq,
456 const struct ad7879_bus_ops *bops)
438{ 457{
458 struct ad7879_platform_data *pdata = dev->platform_data;
459 struct ad7879 *ts;
439 struct input_dev *input_dev; 460 struct input_dev *input_dev;
440 struct ad7879_platform_data *pdata = bus->dev.platform_data;
441 int err; 461 int err;
442 u16 revid; 462 u16 revid;
443 463
444 if (!bus->irq) { 464 if (!irq) {
445 dev_err(&bus->dev, "no IRQ?\n"); 465 dev_err(dev, "no IRQ?\n");
446 return -ENODEV; 466 err = -EINVAL;
467 goto err_out;
447 } 468 }
448 469
449 if (!pdata) { 470 if (!pdata) {
450 dev_err(&bus->dev, "no platform data?\n"); 471 dev_err(dev, "no platform data?\n");
451 return -ENODEV; 472 err = -EINVAL;
473 goto err_out;
452 } 474 }
453 475
476 ts = kzalloc(sizeof(*ts), GFP_KERNEL);
454 input_dev = input_allocate_device(); 477 input_dev = input_allocate_device();
455 if (!input_dev) 478 if (!ts || !input_dev) {
456 return -ENOMEM; 479 err = -ENOMEM;
480 goto err_free_mem;
481 }
457 482
483 ts->bops = bops;
484 ts->dev = dev;
458 ts->input = input_dev; 485 ts->input = input_dev;
486 ts->irq = irq;
459 487
460 setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts); 488 setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts);
461 INIT_WORK(&ts->work, ad7879_work);
462 mutex_init(&ts->mutex);
463 489
464 ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; 490 ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
465 ts->pressure_max = pdata->pressure_max ? : ~0; 491 ts->pressure_max = pdata->pressure_max ? : ~0;
@@ -470,17 +496,26 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts)
470 ts->pen_down_acc_interval = pdata->pen_down_acc_interval; 496 ts->pen_down_acc_interval = pdata->pen_down_acc_interval;
471 ts->median = pdata->median; 497 ts->median = pdata->median;
472 498
473 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&bus->dev)); 499 snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev));
474 500
475 input_dev->name = "AD7879 Touchscreen"; 501 input_dev->name = "AD7879 Touchscreen";
476 input_dev->phys = ts->phys; 502 input_dev->phys = ts->phys;
477 input_dev->dev.parent = &bus->dev; 503 input_dev->dev.parent = dev;
504 input_dev->id.bustype = bops->bustype;
505
506 input_dev->open = ad7879_open;
507 input_dev->close = ad7879_close;
508
509 input_set_drvdata(input_dev, ts);
478 510
479 __set_bit(EV_ABS, input_dev->evbit); 511 __set_bit(EV_ABS, input_dev->evbit);
480 __set_bit(ABS_X, input_dev->absbit); 512 __set_bit(ABS_X, input_dev->absbit);
481 __set_bit(ABS_Y, input_dev->absbit); 513 __set_bit(ABS_Y, input_dev->absbit);
482 __set_bit(ABS_PRESSURE, input_dev->absbit); 514 __set_bit(ABS_PRESSURE, input_dev->absbit);
483 515
516 __set_bit(EV_KEY, input_dev->evbit);
517 __set_bit(BTN_TOUCH, input_dev->keybit);
518
484 input_set_abs_params(input_dev, ABS_X, 519 input_set_abs_params(input_dev, ABS_X,
485 pdata->x_min ? : 0, 520 pdata->x_min ? : 0,
486 pdata->x_max ? : MAX_12BIT, 521 pdata->x_max ? : MAX_12BIT,
@@ -492,17 +527,18 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts)
492 input_set_abs_params(input_dev, ABS_PRESSURE, 527 input_set_abs_params(input_dev, ABS_PRESSURE,
493 pdata->pressure_min, pdata->pressure_max, 0, 0); 528 pdata->pressure_min, pdata->pressure_max, 0, 0);
494 529
495 err = ad7879_write(bus, AD7879_REG_CTRL2, AD7879_RESET); 530 err = ad7879_write(ts, AD7879_REG_CTRL2, AD7879_RESET);
496
497 if (err < 0) { 531 if (err < 0) {
498 dev_err(&bus->dev, "Failed to write %s\n", input_dev->name); 532 dev_err(dev, "Failed to write %s\n", input_dev->name);
499 goto err_free_mem; 533 goto err_free_mem;
500 } 534 }
501 535
502 revid = ad7879_read(bus, AD7879_REG_REVID); 536 revid = ad7879_read(ts, AD7879_REG_REVID);
503 537 input_dev->id.product = (revid & 0xff);
504 if ((revid & 0xFF) != AD7879_DEVID) { 538 input_dev->id.version = revid >> 8;
505 dev_err(&bus->dev, "Failed to probe %s\n", input_dev->name); 539 if (input_dev->id.product != devid) {
540 dev_err(dev, "Failed to probe %s (%x vs %x)\n",
541 input_dev->name, devid, revid);
506 err = -ENODEV; 542 err = -ENODEV;
507 goto err_free_mem; 543 goto err_free_mem;
508 } 544 }
@@ -524,21 +560,21 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts)
524 AD7879_ACQ(ts->acquisition_time) | 560 AD7879_ACQ(ts->acquisition_time) |
525 AD7879_TMR(ts->pen_down_acc_interval); 561 AD7879_TMR(ts->pen_down_acc_interval);
526 562
527 ad7879_setup(ts); 563 err = request_threaded_irq(ts->irq, NULL, ad7879_irq,
528 564 IRQF_TRIGGER_FALLING,
529 err = request_irq(bus->irq, ad7879_irq, 565 dev_name(dev), ts);
530 IRQF_TRIGGER_FALLING, bus->dev.driver->name, ts);
531
532 if (err) { 566 if (err) {
533 dev_err(&bus->dev, "irq %d busy?\n", bus->irq); 567 dev_err(dev, "irq %d busy?\n", ts->irq);
534 goto err_free_mem; 568 goto err_free_mem;
535 } 569 }
536 570
537 err = sysfs_create_group(&bus->dev.kobj, &ad7879_attr_group); 571 __ad7879_disable(ts);
572
573 err = sysfs_create_group(&dev->kobj, &ad7879_attr_group);
538 if (err) 574 if (err)
539 goto err_free_irq; 575 goto err_free_irq;
540 576
541 err = ad7879_gpio_add(&bus->dev); 577 err = ad7879_gpio_add(ts, pdata);
542 if (err) 578 if (err)
543 goto err_remove_attr; 579 goto err_remove_attr;
544 580
@@ -546,321 +582,32 @@ static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts)
546 if (err) 582 if (err)
547 goto err_remove_gpio; 583 goto err_remove_gpio;
548 584
549 dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n", 585 return ts;
550 revid >> 8, bus->irq);
551
552 return 0;
553 586
554err_remove_gpio: 587err_remove_gpio:
555 ad7879_gpio_remove(&bus->dev); 588 ad7879_gpio_remove(ts);
556err_remove_attr: 589err_remove_attr:
557 sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group); 590 sysfs_remove_group(&dev->kobj, &ad7879_attr_group);
558err_free_irq: 591err_free_irq:
559 free_irq(bus->irq, ts); 592 free_irq(ts->irq, ts);
560err_free_mem: 593err_free_mem:
561 input_free_device(input_dev); 594 input_free_device(input_dev);
562
563 return err;
564}
565
566static int __devexit ad7879_destroy(bus_device *bus, struct ad7879 *ts)
567{
568 ad7879_gpio_remove(&bus->dev);
569 ad7879_disable(ts);
570 sysfs_remove_group(&ts->bus->dev.kobj, &ad7879_attr_group);
571 free_irq(ts->bus->irq, ts);
572 input_unregister_device(ts->input);
573 dev_dbg(&bus->dev, "unregistered touchscreen\n");
574
575 return 0;
576}
577
578#ifdef CONFIG_PM
579static int ad7879_suspend(bus_device *bus, pm_message_t message)
580{
581 struct ad7879 *ts = dev_get_drvdata(&bus->dev);
582
583 ad7879_disable(ts);
584
585 return 0;
586}
587
588static int ad7879_resume(bus_device *bus)
589{
590 struct ad7879 *ts = dev_get_drvdata(&bus->dev);
591
592 ad7879_enable(ts);
593
594 return 0;
595}
596#else
597#define ad7879_suspend NULL
598#define ad7879_resume NULL
599#endif
600
601#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
602#define MAX_SPI_FREQ_HZ 5000000
603#define AD7879_CMD_MAGIC 0xE000
604#define AD7879_CMD_READ (1 << 10)
605#define AD7879_WRITECMD(reg) (AD7879_CMD_MAGIC | (reg & 0xF))
606#define AD7879_READCMD(reg) (AD7879_CMD_MAGIC | AD7879_CMD_READ | (reg & 0xF))
607
608struct ser_req {
609 u16 command;
610 u16 data;
611 struct spi_message msg;
612 struct spi_transfer xfer[2];
613};
614
615/*
616 * ad7879_read/write are only used for initial setup and for sysfs controls.
617 * The main traffic is done in ad7879_collect().
618 */
619
620static int ad7879_read(struct spi_device *spi, u8 reg)
621{
622 struct ser_req *req;
623 int status, ret;
624
625 req = kzalloc(sizeof *req, GFP_KERNEL);
626 if (!req)
627 return -ENOMEM;
628
629 spi_message_init(&req->msg);
630
631 req->command = (u16) AD7879_READCMD(reg);
632 req->xfer[0].tx_buf = &req->command;
633 req->xfer[0].len = 2;
634
635 req->xfer[1].rx_buf = &req->data;
636 req->xfer[1].len = 2;
637
638 spi_message_add_tail(&req->xfer[0], &req->msg);
639 spi_message_add_tail(&req->xfer[1], &req->msg);
640
641 status = spi_sync(spi, &req->msg);
642 ret = status ? : req->data;
643
644 kfree(req);
645
646 return ret;
647}
648
649static int ad7879_write(struct spi_device *spi, u8 reg, u16 val)
650{
651 struct ser_req *req;
652 int status;
653
654 req = kzalloc(sizeof *req, GFP_KERNEL);
655 if (!req)
656 return -ENOMEM;
657
658 spi_message_init(&req->msg);
659
660 req->command = (u16) AD7879_WRITECMD(reg);
661 req->xfer[0].tx_buf = &req->command;
662 req->xfer[0].len = 2;
663
664 req->data = val;
665 req->xfer[1].tx_buf = &req->data;
666 req->xfer[1].len = 2;
667
668 spi_message_add_tail(&req->xfer[0], &req->msg);
669 spi_message_add_tail(&req->xfer[1], &req->msg);
670
671 status = spi_sync(spi, &req->msg);
672
673 kfree(req);
674
675 return status;
676}
677
678static void ad7879_collect(struct ad7879 *ts)
679{
680 int status = spi_sync(ts->bus, &ts->msg);
681
682 if (status)
683 dev_err(&ts->bus->dev, "spi_sync --> %d\n", status);
684}
685
686static void ad7879_setup_ts_def_msg(struct ad7879 *ts)
687{
688 struct spi_message *m;
689 int i;
690
691 ts->cmd = (u16) AD7879_READCMD(AD7879_REG_XPLUS);
692
693 m = &ts->msg;
694 spi_message_init(m);
695 ts->xfer[0].tx_buf = &ts->cmd;
696 ts->xfer[0].len = 2;
697
698 spi_message_add_tail(&ts->xfer[0], m);
699
700 for (i = 0; i < AD7879_NR_SENSE; i++) {
701 ts->xfer[i + 1].rx_buf = &ts->conversion_data[i];
702 ts->xfer[i + 1].len = 2;
703 spi_message_add_tail(&ts->xfer[i + 1], m);
704 }
705}
706
707static int __devinit ad7879_probe(struct spi_device *spi)
708{
709 struct ad7879 *ts;
710 int error;
711
712 /* don't exceed max specified SPI CLK frequency */
713 if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) {
714 dev_err(&spi->dev, "SPI CLK %d Hz?\n", spi->max_speed_hz);
715 return -EINVAL;
716 }
717
718 ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL);
719 if (!ts)
720 return -ENOMEM;
721
722 dev_set_drvdata(&spi->dev, ts);
723 ts->bus = spi;
724
725 ad7879_setup_ts_def_msg(ts);
726
727 error = ad7879_construct(spi, ts);
728 if (error) {
729 dev_set_drvdata(&spi->dev, NULL);
730 kfree(ts);
731 }
732
733 return error;
734}
735
736static int __devexit ad7879_remove(struct spi_device *spi)
737{
738 struct ad7879 *ts = dev_get_drvdata(&spi->dev);
739
740 ad7879_destroy(spi, ts);
741 dev_set_drvdata(&spi->dev, NULL);
742 kfree(ts); 595 kfree(ts);
743 596err_out:
744 return 0; 597 return ERR_PTR(err);
745} 598}
599EXPORT_SYMBOL(ad7879_probe);
746 600
747static struct spi_driver ad7879_driver = { 601void ad7879_remove(struct ad7879 *ts)
748 .driver = {
749 .name = "ad7879",
750 .bus = &spi_bus_type,
751 .owner = THIS_MODULE,
752 },
753 .probe = ad7879_probe,
754 .remove = __devexit_p(ad7879_remove),
755 .suspend = ad7879_suspend,
756 .resume = ad7879_resume,
757};
758
759static int __init ad7879_init(void)
760{
761 return spi_register_driver(&ad7879_driver);
762}
763module_init(ad7879_init);
764
765static void __exit ad7879_exit(void)
766{
767 spi_unregister_driver(&ad7879_driver);
768}
769module_exit(ad7879_exit);
770
771#elif defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
772
773/* All registers are word-sized.
774 * AD7879 uses a high-byte first convention.
775 */
776static int ad7879_read(struct i2c_client *client, u8 reg)
777{ 602{
778 return swab16(i2c_smbus_read_word_data(client, reg)); 603 ad7879_gpio_remove(ts);
779} 604 sysfs_remove_group(&ts->dev->kobj, &ad7879_attr_group);
780 605 free_irq(ts->irq, ts);
781static int ad7879_write(struct i2c_client *client, u8 reg, u16 val) 606 input_unregister_device(ts->input);
782{
783 return i2c_smbus_write_word_data(client, reg, swab16(val));
784}
785
786static void ad7879_collect(struct ad7879 *ts)
787{
788 int i;
789
790 for (i = 0; i < AD7879_NR_SENSE; i++)
791 ts->conversion_data[i] = ad7879_read(ts->bus,
792 AD7879_REG_XPLUS + i);
793}
794
795static int __devinit ad7879_probe(struct i2c_client *client,
796 const struct i2c_device_id *id)
797{
798 struct ad7879 *ts;
799 int error;
800
801 if (!i2c_check_functionality(client->adapter,
802 I2C_FUNC_SMBUS_WORD_DATA)) {
803 dev_err(&client->dev, "SMBUS Word Data not Supported\n");
804 return -EIO;
805 }
806
807 ts = kzalloc(sizeof(struct ad7879), GFP_KERNEL);
808 if (!ts)
809 return -ENOMEM;
810
811 i2c_set_clientdata(client, ts);
812 ts->bus = client;
813
814 error = ad7879_construct(client, ts);
815 if (error)
816 kfree(ts);
817
818 return error;
819}
820
821static int __devexit ad7879_remove(struct i2c_client *client)
822{
823 struct ad7879 *ts = dev_get_drvdata(&client->dev);
824
825 ad7879_destroy(client, ts);
826 kfree(ts); 607 kfree(ts);
827
828 return 0;
829}
830
831static const struct i2c_device_id ad7879_id[] = {
832 { "ad7879", 0 },
833 { "ad7889", 0 },
834 { }
835};
836MODULE_DEVICE_TABLE(i2c, ad7879_id);
837
838static struct i2c_driver ad7879_driver = {
839 .driver = {
840 .name = "ad7879",
841 .owner = THIS_MODULE,
842 },
843 .probe = ad7879_probe,
844 .remove = __devexit_p(ad7879_remove),
845 .suspend = ad7879_suspend,
846 .resume = ad7879_resume,
847 .id_table = ad7879_id,
848};
849
850static int __init ad7879_init(void)
851{
852 return i2c_add_driver(&ad7879_driver);
853}
854module_init(ad7879_init);
855
856static void __exit ad7879_exit(void)
857{
858 i2c_del_driver(&ad7879_driver);
859} 608}
860module_exit(ad7879_exit); 609EXPORT_SYMBOL(ad7879_remove);
861#endif
862 610
863MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 611MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
864MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver"); 612MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver");
865MODULE_LICENSE("GPL"); 613MODULE_LICENSE("GPL");
866MODULE_ALIAS("spi:ad7879");
diff --git a/drivers/input/touchscreen/ad7879.h b/drivers/input/touchscreen/ad7879.h
new file mode 100644
index 00000000000..6b45a27236c
--- /dev/null
+++ b/drivers/input/touchscreen/ad7879.h
@@ -0,0 +1,30 @@
1/*
2 * AD7879/AD7889 touchscreen (bus interfaces)
3 *
4 * Copyright (C) 2008-2010 Michael Hennerich, Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#ifndef _AD7879_H_
10#define _AD7879_H_
11
12#include <linux/types.h>
13
14struct ad7879;
15struct device;
16
17struct ad7879_bus_ops {
18 u16 bustype;
19 int (*read)(struct device *dev, u8 reg);
20 int (*multi_read)(struct device *dev, u8 first_reg, u8 count, u16 *buf);
21 int (*write)(struct device *dev, u8 reg, u16 val);
22};
23
24void ad7879_suspend(struct ad7879 *);
25void ad7879_resume(struct ad7879 *);
26struct ad7879 *ad7879_probe(struct device *dev, u8 devid, unsigned irq,
27 const struct ad7879_bus_ops *bops);
28void ad7879_remove(struct ad7879 *);
29
30#endif
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index a9fdf55c023..16031933a8f 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -68,6 +68,8 @@ struct ts_event {
68 u16 y; 68 u16 y;
69 u16 z1, z2; 69 u16 z1, z2;
70 int ignore; 70 int ignore;
71 u8 x_buf[3];
72 u8 y_buf[3];
71}; 73};
72 74
73/* 75/*
@@ -79,6 +81,8 @@ struct ads7846_packet {
79 u8 read_x, read_y, read_z1, read_z2, pwrdown; 81 u8 read_x, read_y, read_z1, read_z2, pwrdown;
80 u16 dummy; /* for the pwrdown read */ 82 u16 dummy; /* for the pwrdown read */
81 struct ts_event tc; 83 struct ts_event tc;
84 /* for ads7845 with mpc5121 psc spi we use 3-byte buffers */
85 u8 read_x_cmd[3], read_y_cmd[3], pwrdown_cmd[3];
82}; 86};
83 87
84struct ads7846 { 88struct ads7846 {
@@ -207,6 +211,14 @@ struct ser_req {
207 struct spi_transfer xfer[6]; 211 struct spi_transfer xfer[6];
208}; 212};
209 213
214struct ads7845_ser_req {
215 u8 command[3];
216 u8 pwrdown[3];
217 u8 sample[3];
218 struct spi_message msg;
219 struct spi_transfer xfer[2];
220};
221
210static void ads7846_enable(struct ads7846 *ts); 222static void ads7846_enable(struct ads7846 *ts);
211static void ads7846_disable(struct ads7846 *ts); 223static void ads7846_disable(struct ads7846 *ts);
212 224
@@ -287,6 +299,41 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
287 return status; 299 return status;
288} 300}
289 301
302static int ads7845_read12_ser(struct device *dev, unsigned command)
303{
304 struct spi_device *spi = to_spi_device(dev);
305 struct ads7846 *ts = dev_get_drvdata(dev);
306 struct ads7845_ser_req *req = kzalloc(sizeof *req, GFP_KERNEL);
307 int status;
308
309 if (!req)
310 return -ENOMEM;
311
312 spi_message_init(&req->msg);
313
314 req->command[0] = (u8) command;
315 req->xfer[0].tx_buf = req->command;
316 req->xfer[0].rx_buf = req->sample;
317 req->xfer[0].len = 3;
318 spi_message_add_tail(&req->xfer[0], &req->msg);
319
320 ts->irq_disabled = 1;
321 disable_irq(spi->irq);
322 status = spi_sync(spi, &req->msg);
323 ts->irq_disabled = 0;
324 enable_irq(spi->irq);
325
326 if (status == 0) {
327 /* BE12 value, then padding */
328 status = be16_to_cpu(*((u16 *)&req->sample[1]));
329 status = status >> 3;
330 status &= 0x0fff;
331 }
332
333 kfree(req);
334 return status;
335}
336
290#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) 337#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
291 338
292#define SHOW(name, var, adjust) static ssize_t \ 339#define SHOW(name, var, adjust) static ssize_t \
@@ -540,10 +587,17 @@ static void ads7846_rx(void *ads)
540 /* ads7846_rx_val() did in-place conversion (including byteswap) from 587 /* ads7846_rx_val() did in-place conversion (including byteswap) from
541 * on-the-wire format as part of debouncing to get stable readings. 588 * on-the-wire format as part of debouncing to get stable readings.
542 */ 589 */
543 x = packet->tc.x; 590 if (ts->model == 7845) {
544 y = packet->tc.y; 591 x = *(u16 *)packet->tc.x_buf;
545 z1 = packet->tc.z1; 592 y = *(u16 *)packet->tc.y_buf;
546 z2 = packet->tc.z2; 593 z1 = 0;
594 z2 = 0;
595 } else {
596 x = packet->tc.x;
597 y = packet->tc.y;
598 z1 = packet->tc.z1;
599 z2 = packet->tc.z2;
600 }
547 601
548 /* range filtering */ 602 /* range filtering */
549 if (x == MAX_12BIT) 603 if (x == MAX_12BIT)
@@ -551,6 +605,12 @@ static void ads7846_rx(void *ads)
551 605
552 if (ts->model == 7843) { 606 if (ts->model == 7843) {
553 Rt = ts->pressure_max / 2; 607 Rt = ts->pressure_max / 2;
608 } else if (ts->model == 7845) {
609 if (get_pendown_state(ts))
610 Rt = ts->pressure_max / 2;
611 else
612 Rt = 0;
613 dev_vdbg(&ts->spi->dev, "x/y: %d/%d, PD %d\n", x, y, Rt);
554 } else if (likely(x && z1)) { 614 } else if (likely(x && z1)) {
555 /* compute touch pressure resistance using equation #2 */ 615 /* compute touch pressure resistance using equation #2 */
556 Rt = z2; 616 Rt = z2;
@@ -671,10 +731,14 @@ static void ads7846_rx_val(void *ads)
671 m = &ts->msg[ts->msg_idx]; 731 m = &ts->msg[ts->msg_idx];
672 t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); 732 t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
673 733
674 /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; 734 if (ts->model == 7845) {
675 * built from two 8 bit values written msb-first. 735 val = be16_to_cpup((__be16 *)&(((char*)t->rx_buf)[1])) >> 3;
676 */ 736 } else {
677 val = be16_to_cpup((__be16 *)t->rx_buf) >> 3; 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 }
678 742
679 action = ts->filter(ts->filter_data, ts->msg_idx, &val); 743 action = ts->filter(ts->filter_data, ts->msg_idx, &val);
680 switch (action) { 744 switch (action) {
@@ -878,14 +942,15 @@ static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts)
878 942
879static int __devinit ads7846_probe(struct spi_device *spi) 943static int __devinit ads7846_probe(struct spi_device *spi)
880{ 944{
881 struct ads7846 *ts; 945 struct ads7846 *ts;
882 struct ads7846_packet *packet; 946 struct ads7846_packet *packet;
883 struct input_dev *input_dev; 947 struct input_dev *input_dev;
884 struct ads7846_platform_data *pdata = spi->dev.platform_data; 948 const struct ads7846_platform_data *pdata = spi->dev.platform_data;
885 struct spi_message *m; 949 struct spi_message *m;
886 struct spi_transfer *x; 950 struct spi_transfer *x;
887 int vref; 951 unsigned long irq_flags;
888 int err; 952 int vref;
953 int err;
889 954
890 if (!spi->irq) { 955 if (!spi->irq) {
891 dev_dbg(&spi->dev, "no IRQ?\n"); 956 dev_dbg(&spi->dev, "no IRQ?\n");
@@ -1008,16 +1073,26 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1008 1073
1009 spi_message_init(m); 1074 spi_message_init(m);
1010 1075
1011 /* y- still on; turn on only y+ (and ADC) */ 1076 if (ts->model == 7845) {
1012 packet->read_y = READ_Y(vref); 1077 packet->read_y_cmd[0] = READ_Y(vref);
1013 x->tx_buf = &packet->read_y; 1078 packet->read_y_cmd[1] = 0;
1014 x->len = 1; 1079 packet->read_y_cmd[2] = 0;
1015 spi_message_add_tail(x, m); 1080 x->tx_buf = &packet->read_y_cmd[0];
1081 x->rx_buf = &packet->tc.y_buf[0];
1082 x->len = 3;
1083 spi_message_add_tail(x, m);
1084 } else {
1085 /* y- still on; turn on only y+ (and ADC) */
1086 packet->read_y = READ_Y(vref);
1087 x->tx_buf = &packet->read_y;
1088 x->len = 1;
1089 spi_message_add_tail(x, m);
1016 1090
1017 x++; 1091 x++;
1018 x->rx_buf = &packet->tc.y; 1092 x->rx_buf = &packet->tc.y;
1019 x->len = 2; 1093 x->len = 2;
1020 spi_message_add_tail(x, m); 1094 spi_message_add_tail(x, m);
1095 }
1021 1096
1022 /* the first sample after switching drivers can be low quality; 1097 /* the first sample after switching drivers can be low quality;
1023 * optionally discard it, using a second one after the signals 1098 * optionally discard it, using a second one after the signals
@@ -1043,17 +1118,28 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1043 m++; 1118 m++;
1044 spi_message_init(m); 1119 spi_message_init(m);
1045 1120
1046 /* turn y- off, x+ on, then leave in lowpower */ 1121 if (ts->model == 7845) {
1047 x++; 1122 x++;
1048 packet->read_x = READ_X(vref); 1123 packet->read_x_cmd[0] = READ_X(vref);
1049 x->tx_buf = &packet->read_x; 1124 packet->read_x_cmd[1] = 0;
1050 x->len = 1; 1125 packet->read_x_cmd[2] = 0;
1051 spi_message_add_tail(x, m); 1126 x->tx_buf = &packet->read_x_cmd[0];
1127 x->rx_buf = &packet->tc.x_buf[0];
1128 x->len = 3;
1129 spi_message_add_tail(x, m);
1130 } else {
1131 /* turn y- off, x+ on, then leave in lowpower */
1132 x++;
1133 packet->read_x = READ_X(vref);
1134 x->tx_buf = &packet->read_x;
1135 x->len = 1;
1136 spi_message_add_tail(x, m);
1052 1137
1053 x++; 1138 x++;
1054 x->rx_buf = &packet->tc.x; 1139 x->rx_buf = &packet->tc.x;
1055 x->len = 2; 1140 x->len = 2;
1056 spi_message_add_tail(x, m); 1141 spi_message_add_tail(x, m);
1142 }
1057 1143
1058 /* ... maybe discard first sample ... */ 1144 /* ... maybe discard first sample ... */
1059 if (pdata->settle_delay_usecs) { 1145 if (pdata->settle_delay_usecs) {
@@ -1144,15 +1230,25 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1144 m++; 1230 m++;
1145 spi_message_init(m); 1231 spi_message_init(m);
1146 1232
1147 x++; 1233 if (ts->model == 7845) {
1148 packet->pwrdown = PWRDOWN; 1234 x++;
1149 x->tx_buf = &packet->pwrdown; 1235 packet->pwrdown_cmd[0] = PWRDOWN;
1150 x->len = 1; 1236 packet->pwrdown_cmd[1] = 0;
1151 spi_message_add_tail(x, m); 1237 packet->pwrdown_cmd[2] = 0;
1238 x->tx_buf = &packet->pwrdown_cmd[0];
1239 x->len = 3;
1240 } else {
1241 x++;
1242 packet->pwrdown = PWRDOWN;
1243 x->tx_buf = &packet->pwrdown;
1244 x->len = 1;
1245 spi_message_add_tail(x, m);
1246
1247 x++;
1248 x->rx_buf = &packet->dummy;
1249 x->len = 2;
1250 }
1152 1251
1153 x++;
1154 x->rx_buf = &packet->dummy;
1155 x->len = 2;
1156 CS_CHANGE(*x); 1252 CS_CHANGE(*x);
1157 spi_message_add_tail(x, m); 1253 spi_message_add_tail(x, m);
1158 1254
@@ -1174,17 +1270,22 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1174 goto err_put_regulator; 1270 goto err_put_regulator;
1175 } 1271 }
1176 1272
1177 if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING, 1273 irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING;
1178 spi->dev.driver->name, ts)) { 1274
1275 err = request_irq(spi->irq, ads7846_irq, irq_flags,
1276 spi->dev.driver->name, ts);
1277
1278 if (err && !pdata->irq_flags) {
1179 dev_info(&spi->dev, 1279 dev_info(&spi->dev,
1180 "trying pin change workaround on irq %d\n", spi->irq); 1280 "trying pin change workaround on irq %d\n", spi->irq);
1181 err = request_irq(spi->irq, ads7846_irq, 1281 err = request_irq(spi->irq, ads7846_irq,
1182 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 1282 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
1183 spi->dev.driver->name, ts); 1283 spi->dev.driver->name, ts);
1184 if (err) { 1284 }
1185 dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); 1285
1186 goto err_disable_regulator; 1286 if (err) {
1187 } 1287 dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
1288 goto err_disable_regulator;
1188 } 1289 }
1189 1290
1190 err = ads784x_hwmon_register(spi, ts); 1291 err = ads784x_hwmon_register(spi, ts);
@@ -1196,8 +1297,11 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1196 /* take a first sample, leaving nPENIRQ active and vREF off; avoid 1297 /* take a first sample, leaving nPENIRQ active and vREF off; avoid
1197 * the touchscreen, in case it's not connected. 1298 * the touchscreen, in case it's not connected.
1198 */ 1299 */
1199 (void) ads7846_read12_ser(&spi->dev, 1300 if (ts->model == 7845)
1200 READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); 1301 ads7845_read12_ser(&spi->dev, PWRDOWN);
1302 else
1303 (void) ads7846_read12_ser(&spi->dev,
1304 READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
1201 1305
1202 err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); 1306 err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group);
1203 if (err) 1307 if (err)
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c
new file mode 100644
index 00000000000..4eb7df0b7f8
--- /dev/null
+++ b/drivers/input/touchscreen/cy8ctmg110_ts.c
@@ -0,0 +1,363 @@
1/*
2 * Driver for cypress touch screen controller
3 *
4 * Copyright (c) 2009 Aava Mobile
5 *
6 * Some cleanups by Alan Cox <alan@linux.intel.com>
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 version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/kernel.h>
24#include <linux/input.h>
25#include <linux/slab.h>
26#include <linux/interrupt.h>
27#include <linux/io.h>
28#include <linux/i2c.h>
29#include <linux/gpio.h>
30#include <linux/input/cy8ctmg110_pdata.h>
31
32#define CY8CTMG110_DRIVER_NAME "cy8ctmg110"
33
34/* Touch coordinates */
35#define CY8CTMG110_X_MIN 0
36#define CY8CTMG110_Y_MIN 0
37#define CY8CTMG110_X_MAX 759
38#define CY8CTMG110_Y_MAX 465
39
40
41/* cy8ctmg110 register definitions */
42#define CY8CTMG110_TOUCH_WAKEUP_TIME 0
43#define CY8CTMG110_TOUCH_SLEEP_TIME 2
44#define CY8CTMG110_TOUCH_X1 3
45#define CY8CTMG110_TOUCH_Y1 5
46#define CY8CTMG110_TOUCH_X2 7
47#define CY8CTMG110_TOUCH_Y2 9
48#define CY8CTMG110_FINGERS 11
49#define CY8CTMG110_GESTURE 12
50#define CY8CTMG110_REG_MAX 13
51
52
53/*
54 * The touch driver structure.
55 */
56struct cy8ctmg110 {
57 struct input_dev *input;
58 char phys[32];
59 struct i2c_client *client;
60 int reset_pin;
61 int irq_pin;
62};
63
64/*
65 * cy8ctmg110_power is the routine that is called when touch hardware
66 * will powered off or on.
67 */
68static void cy8ctmg110_power(struct cy8ctmg110 *ts, bool poweron)
69{
70 if (ts->reset_pin)
71 gpio_direction_output(ts->reset_pin, 1 - poweron);
72}
73
74static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg,
75 unsigned char len, unsigned char *value)
76{
77 struct i2c_client *client = tsc->client;
78 unsigned int ret;
79 unsigned char i2c_data[6];
80
81 BUG_ON(len > 5);
82
83 i2c_data[0] = reg;
84 memcpy(i2c_data + 1, value, len);
85
86 ret = i2c_master_send(client, i2c_data, len + 1);
87 if (ret != 1) {
88 dev_err(&client->dev, "i2c write data cmd failed\n");
89 return ret;
90 }
91
92 return 0;
93}
94
95static int cy8ctmg110_read_regs(struct cy8ctmg110 *tsc,
96 unsigned char *data, unsigned char len, unsigned char cmd)
97{
98 struct i2c_client *client = tsc->client;
99 unsigned int ret;
100 struct i2c_msg msg[2] = {
101 /* first write slave position to i2c devices */
102 { client->addr, 0, 1, &cmd },
103 /* Second read data from position */
104 { client->addr, I2C_M_RD, len, data }
105 };
106
107 ret = i2c_transfer(client->adapter, msg, 2);
108 if (ret < 0)
109 return ret;
110
111 return 0;
112}
113
114static int cy8ctmg110_touch_pos(struct cy8ctmg110 *tsc)
115{
116 struct input_dev *input = tsc->input;
117 unsigned char reg_p[CY8CTMG110_REG_MAX];
118 int x, y;
119
120 memset(reg_p, 0, CY8CTMG110_REG_MAX);
121
122 /* Reading coordinates */
123 if (cy8ctmg110_read_regs(tsc, reg_p, 9, CY8CTMG110_TOUCH_X1) != 0)
124 return -EIO;
125
126 y = reg_p[2] << 8 | reg_p[3];
127 x = reg_p[0] << 8 | reg_p[1];
128
129 /* Number of touch */
130 if (reg_p[8] == 0) {
131 input_report_key(input, BTN_TOUCH, 0);
132 } else {
133 input_report_key(input, BTN_TOUCH, 1);
134 input_report_abs(input, ABS_X, x);
135 input_report_abs(input, ABS_Y, y);
136 }
137
138 input_sync(input);
139
140 return 0;
141}
142
143static int cy8ctmg110_set_sleepmode(struct cy8ctmg110 *ts, bool sleep)
144{
145 unsigned char reg_p[3];
146
147 if (sleep) {
148 reg_p[0] = 0x00;
149 reg_p[1] = 0xff;
150 reg_p[2] = 5;
151 } else {
152 reg_p[0] = 0x10;
153 reg_p[1] = 0xff;
154 reg_p[2] = 0;
155 }
156
157 return cy8ctmg110_write_regs(ts, CY8CTMG110_TOUCH_WAKEUP_TIME, 3, reg_p);
158}
159
160static irqreturn_t cy8ctmg110_irq_thread(int irq, void *dev_id)
161{
162 struct cy8ctmg110 *tsc = dev_id;
163
164 cy8ctmg110_touch_pos(tsc);
165
166 return IRQ_HANDLED;
167}
168
169static int __devinit cy8ctmg110_probe(struct i2c_client *client,
170 const struct i2c_device_id *id)
171{
172 const struct cy8ctmg110_pdata *pdata = client->dev.platform_data;
173 struct cy8ctmg110 *ts;
174 struct input_dev *input_dev;
175 int err;
176
177 /* No pdata no way forward */
178 if (pdata == NULL) {
179 dev_err(&client->dev, "no pdata\n");
180 return -ENODEV;
181 }
182
183 if (!i2c_check_functionality(client->adapter,
184 I2C_FUNC_SMBUS_READ_WORD_DATA))
185 return -EIO;
186
187 ts = kzalloc(sizeof(struct cy8ctmg110), GFP_KERNEL);
188 input_dev = input_allocate_device();
189 if (!ts || !input_dev) {
190 err = -ENOMEM;
191 goto err_free_mem;
192 }
193
194 ts->client = client;
195 ts->input = input_dev;
196
197 snprintf(ts->phys, sizeof(ts->phys),
198 "%s/input0", dev_name(&client->dev));
199
200 input_dev->name = CY8CTMG110_DRIVER_NAME " Touchscreen";
201 input_dev->phys = ts->phys;
202 input_dev->id.bustype = BUS_I2C;
203 input_dev->dev.parent = &client->dev;
204
205 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
206 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
207
208 input_set_abs_params(input_dev, ABS_X,
209 CY8CTMG110_X_MIN, CY8CTMG110_X_MAX, 0, 0);
210 input_set_abs_params(input_dev, ABS_Y,
211 CY8CTMG110_Y_MIN, CY8CTMG110_Y_MAX, 0, 0);
212
213 if (ts->reset_pin) {
214 err = gpio_request(ts->reset_pin, NULL);
215 if (err) {
216 dev_err(&client->dev,
217 "Unable to request GPIO pin %d.\n",
218 ts->reset_pin);
219 goto err_free_mem;
220 }
221 }
222
223 cy8ctmg110_power(ts, true);
224 cy8ctmg110_set_sleepmode(ts, false);
225
226 err = gpio_request(ts->irq_pin, "touch_irq_key");
227 if (err < 0) {
228 dev_err(&client->dev,
229 "Failed to request GPIO %d, error %d\n",
230 ts->irq_pin, err);
231 goto err_shutoff_device;
232 }
233
234 err = gpio_direction_input(ts->irq_pin);
235 if (err < 0) {
236 dev_err(&client->dev,
237 "Failed to configure input direction for GPIO %d, error %d\n",
238 ts->irq_pin, err);
239 goto err_free_irq_gpio;
240 }
241
242 client->irq = gpio_to_irq(ts->irq_pin);
243 if (client->irq < 0) {
244 err = client->irq;
245 dev_err(&client->dev,
246 "Unable to get irq number for GPIO %d, error %d\n",
247 ts->irq_pin, err);
248 goto err_free_irq_gpio;
249 }
250
251 err = request_threaded_irq(client->irq, NULL, cy8ctmg110_irq_thread,
252 IRQF_TRIGGER_RISING, "touch_reset_key", ts);
253 if (err < 0) {
254 dev_err(&client->dev,
255 "irq %d busy? error %d\n", client->irq, err);
256 goto err_free_irq_gpio;
257 }
258
259 err = input_register_device(input_dev);
260 if (err)
261 goto err_free_irq;
262
263 i2c_set_clientdata(client, ts);
264 device_init_wakeup(&client->dev, 1);
265 return 0;
266
267err_free_irq:
268 free_irq(client->irq, ts);
269err_free_irq_gpio:
270 gpio_free(ts->irq_pin);
271err_shutoff_device:
272 cy8ctmg110_set_sleepmode(ts, true);
273 cy8ctmg110_power(ts, false);
274 if (ts->reset_pin)
275 gpio_free(ts->reset_pin);
276err_free_mem:
277 input_free_device(input_dev);
278 kfree(ts);
279 return err;
280}
281
282#ifdef CONFIG_PM
283static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg)
284{
285 struct cy8ctmg110 *ts = i2c_get_clientdata(client);
286
287 if (device_may_wakeup(&client->dev))
288 enable_irq_wake(client->irq);
289 else {
290 cy8ctmg110_set_sleepmode(ts, true);
291 cy8ctmg110_power(ts, false);
292 }
293 return 0;
294}
295
296static int cy8ctmg110_resume(struct i2c_client *client)
297{
298 struct cy8ctmg110 *ts = i2c_get_clientdata(client);
299
300 if (device_may_wakeup(&client->dev))
301 disable_irq_wake(client->irq);
302 else {
303 cy8ctmg110_power(ts, true);
304 cy8ctmg110_set_sleepmode(ts, false);
305 }
306 return 0;
307}
308#endif
309
310static int __devexit cy8ctmg110_remove(struct i2c_client *client)
311{
312 struct cy8ctmg110 *ts = i2c_get_clientdata(client);
313
314 cy8ctmg110_set_sleepmode(ts, true);
315 cy8ctmg110_power(ts, false);
316
317 free_irq(client->irq, ts);
318 input_unregister_device(ts->input);
319 gpio_free(ts->irq_pin);
320 if (ts->reset_pin)
321 gpio_free(ts->reset_pin);
322 kfree(ts);
323
324 return 0;
325}
326
327static struct i2c_device_id cy8ctmg110_idtable[] = {
328 { CY8CTMG110_DRIVER_NAME, 1 },
329 { }
330};
331
332MODULE_DEVICE_TABLE(i2c, cy8ctmg110_idtable);
333
334static struct i2c_driver cy8ctmg110_driver = {
335 .driver = {
336 .owner = THIS_MODULE,
337 .name = CY8CTMG110_DRIVER_NAME,
338 },
339 .id_table = cy8ctmg110_idtable,
340 .probe = cy8ctmg110_probe,
341 .remove = __devexit_p(cy8ctmg110_remove),
342#ifdef CONFIG_PM
343 .suspend = cy8ctmg110_suspend,
344 .resume = cy8ctmg110_resume,
345#endif
346};
347
348static int __init cy8ctmg110_init(void)
349{
350 return i2c_add_driver(&cy8ctmg110_driver);
351}
352
353static void __exit cy8ctmg110_exit(void)
354{
355 i2c_del_driver(&cy8ctmg110_driver);
356}
357
358module_init(cy8ctmg110_init);
359module_exit(cy8ctmg110_exit);
360
361MODULE_AUTHOR("Samuli Konttila <samuli.konttila@aavamobile.com>");
362MODULE_DESCRIPTION("cy8ctmg110 TouchScreen Driver");
363MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c
index 1fb0c2f06a4..6ee9940aaf5 100644
--- a/drivers/input/touchscreen/mcs5000_ts.c
+++ b/drivers/input/touchscreen/mcs5000_ts.c
@@ -16,7 +16,7 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/i2c/mcs5000_ts.h> 19#include <linux/i2c/mcs.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/input.h> 21#include <linux/input.h>
22#include <linux/irq.h> 22#include <linux/irq.h>
@@ -105,7 +105,7 @@ enum mcs5000_ts_read_offset {
105struct mcs5000_ts_data { 105struct mcs5000_ts_data {
106 struct i2c_client *client; 106 struct i2c_client *client;
107 struct input_dev *input_dev; 107 struct input_dev *input_dev;
108 const struct mcs5000_ts_platform_data *platform_data; 108 const struct mcs_platform_data *platform_data;
109}; 109};
110 110
111static irqreturn_t mcs5000_ts_interrupt(int irq, void *dev_id) 111static irqreturn_t mcs5000_ts_interrupt(int irq, void *dev_id)
@@ -164,7 +164,7 @@ static irqreturn_t mcs5000_ts_interrupt(int irq, void *dev_id)
164 164
165static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data) 165static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data)
166{ 166{
167 const struct mcs5000_ts_platform_data *platform_data = 167 const struct mcs_platform_data *platform_data =
168 data->platform_data; 168 data->platform_data;
169 struct i2c_client *client = data->client; 169 struct i2c_client *client = data->client;
170 170
diff --git a/drivers/input/touchscreen/qt602240_ts.c b/drivers/input/touchscreen/qt602240_ts.c
new file mode 100644
index 00000000000..66b26ad3032
--- /dev/null
+++ b/drivers/input/touchscreen/qt602240_ts.c
@@ -0,0 +1,1401 @@
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 */
203static 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
241static 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
279static 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
318struct 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
328struct 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
339struct qt602240_message {
340 u8 reportid;
341 u8 message[7];
342 u8 checksum;
343};
344
345struct qt602240_finger {
346 int status;
347 int x;
348 int y;
349 int area;
350};
351
352/* Each client has this additional data */
353struct 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
363static 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
388static 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
410static 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
424static int qt602240_check_bootloader(struct i2c_client *client,
425 unsigned int state)
426{
427 u8 val;
428
429recheck:
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
456static 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
471static 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
482static 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
511static int qt602240_read_reg(struct i2c_client *client, u16 reg, u8 *val)
512{
513 return __qt602240_read_reg(client, reg, 1, val);
514}
515
516static 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
532static 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
539static struct qt602240_object *
540qt602240_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
555static 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
570static 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
584static 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
598static 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
635static 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
677static 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
711end:
712 return IRQ_HANDLED;
713}
714
715static 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
755static 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
823static 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
845static 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
893static 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
928static 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
960static 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
1035static 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
1073static 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
1132out:
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
1144static 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
1185static DEVICE_ATTR(object, 0444, qt602240_object_show, NULL);
1186static DEVICE_ATTR(update_fw, 0664, NULL, qt602240_update_fw_store);
1187
1188static struct attribute *qt602240_attrs[] = {
1189 &dev_attr_object.attr,
1190 &dev_attr_update_fw.attr,
1191 NULL
1192};
1193
1194static const struct attribute_group qt602240_attr_group = {
1195 .attrs = qt602240_attrs,
1196};
1197
1198static 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
1205static 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
1212static 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
1221static 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
1228static 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
1300err_unregister_device:
1301 input_unregister_device(input_dev);
1302 input_dev = NULL;
1303err_free_irq:
1304 free_irq(client->irq, data);
1305err_free_object:
1306 kfree(data->object_table);
1307err_free_mem:
1308 input_free_device(input_dev);
1309 kfree(data);
1310 return error;
1311}
1312
1313static 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
1327static 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
1342static 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
1367static const struct i2c_device_id qt602240_id[] = {
1368 { "qt602240_ts", 0 },
1369 { }
1370};
1371MODULE_DEVICE_TABLE(i2c, qt602240_id);
1372
1373static 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
1385static int __init qt602240_init(void)
1386{
1387 return i2c_add_driver(&qt602240_driver);
1388}
1389
1390static void __exit qt602240_exit(void)
1391{
1392 i2c_del_driver(&qt602240_driver);
1393}
1394
1395module_init(qt602240_init);
1396module_exit(qt602240_exit);
1397
1398/* Module information */
1399MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
1400MODULE_DESCRIPTION("AT42QT602240/ATMXT224 Touchscreen driver");
1401MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c
index 5b70a1419b4..a644d18c04d 100644
--- a/drivers/input/touchscreen/tps6507x-ts.c
+++ b/drivers/input/touchscreen/tps6507x-ts.c
@@ -355,9 +355,6 @@ static int __devexit tps6507x_ts_remove(struct platform_device *pdev)
355 struct tps6507x_ts *tsc = tps6507x_dev->ts; 355 struct tps6507x_ts *tsc = tps6507x_dev->ts;
356 struct input_dev *input_dev = tsc->input_dev; 356 struct input_dev *input_dev = tsc->input_dev;
357 357
358 if (!tsc)
359 return 0;
360
361 cancel_delayed_work_sync(&tsc->work); 358 cancel_delayed_work_sync(&tsc->work);
362 destroy_workqueue(tsc->wq); 359 destroy_workqueue(tsc->wq);
363 360
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 567d57215c2..f45f80f6d33 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -95,6 +95,7 @@ struct usbtouch_device_info {
95 int (*get_pkt_len) (unsigned char *pkt, int len); 95 int (*get_pkt_len) (unsigned char *pkt, int len);
96 96
97 int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); 97 int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt);
98 int (*alloc) (struct usbtouch_usb *usbtouch);
98 int (*init) (struct usbtouch_usb *usbtouch); 99 int (*init) (struct usbtouch_usb *usbtouch);
99 void (*exit) (struct usbtouch_usb *usbtouch); 100 void (*exit) (struct usbtouch_usb *usbtouch);
100}; 101};
@@ -135,7 +136,7 @@ enum {
135 DEVTYPE_JASTEC, 136 DEVTYPE_JASTEC,
136 DEVTYPE_E2I, 137 DEVTYPE_E2I,
137 DEVTYPE_ZYTRONIC, 138 DEVTYPE_ZYTRONIC,
138 DEVTYPE_TC5UH, 139 DEVTYPE_TC45USB,
139 DEVTYPE_NEXIO, 140 DEVTYPE_NEXIO,
140}; 141};
141 142
@@ -222,8 +223,11 @@ static const struct usb_device_id usbtouch_devices[] = {
222 {USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC}, 223 {USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC},
223#endif 224#endif
224 225
225#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH 226#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC45USB
226 {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH}, 227 /* TC5UH */
228 {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC45USB},
229 /* TC4UM */
230 {USB_DEVICE(0x0664, 0x0306), .driver_info = DEVTYPE_TC45USB},
227#endif 231#endif
228 232
229#ifdef CONFIG_TOUCHSCREEN_USB_NEXIO 233#ifdef CONFIG_TOUCHSCREEN_USB_NEXIO
@@ -507,7 +511,7 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
507 int ret = -ENOMEM; 511 int ret = -ENOMEM;
508 unsigned char *buf; 512 unsigned char *buf;
509 513
510 buf = kmalloc(2, GFP_KERNEL); 514 buf = kmalloc(2, GFP_NOIO);
511 if (!buf) 515 if (!buf)
512 goto err_nobuf; 516 goto err_nobuf;
513 /* reset */ 517 /* reset */
@@ -574,10 +578,10 @@ static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
574#endif 578#endif
575 579
576/***************************************************************************** 580/*****************************************************************************
577 * ET&T TC5UH part 581 * ET&T TC5UH/TC4UM part
578 */ 582 */
579#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH 583#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC45USB
580static int tc5uh_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 584static int tc45usb_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
581{ 585{
582 dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1]; 586 dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1];
583 dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3]; 587 dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3];
@@ -732,11 +736,43 @@ static void nexio_ack_complete(struct urb *urb)
732{ 736{
733} 737}
734 738
739static int nexio_alloc(struct usbtouch_usb *usbtouch)
740{
741 struct nexio_priv *priv;
742 int ret = -ENOMEM;
743
744 usbtouch->priv = kmalloc(sizeof(struct nexio_priv), GFP_KERNEL);
745 if (!usbtouch->priv)
746 goto out_buf;
747
748 priv = usbtouch->priv;
749
750 priv->ack_buf = kmemdup(nexio_ack_pkt, sizeof(nexio_ack_pkt),
751 GFP_KERNEL);
752 if (!priv->ack_buf)
753 goto err_priv;
754
755 priv->ack = usb_alloc_urb(0, GFP_KERNEL);
756 if (!priv->ack) {
757 dbg("%s - usb_alloc_urb failed: usbtouch->ack", __func__);
758 goto err_ack_buf;
759 }
760
761 return 0;
762
763err_ack_buf:
764 kfree(priv->ack_buf);
765err_priv:
766 kfree(priv);
767out_buf:
768 return ret;
769}
770
735static int nexio_init(struct usbtouch_usb *usbtouch) 771static int nexio_init(struct usbtouch_usb *usbtouch)
736{ 772{
737 struct usb_device *dev = interface_to_usbdev(usbtouch->interface); 773 struct usb_device *dev = interface_to_usbdev(usbtouch->interface);
738 struct usb_host_interface *interface = usbtouch->interface->cur_altsetting; 774 struct usb_host_interface *interface = usbtouch->interface->cur_altsetting;
739 struct nexio_priv *priv; 775 struct nexio_priv *priv = usbtouch->priv;
740 int ret = -ENOMEM; 776 int ret = -ENOMEM;
741 int actual_len, i; 777 int actual_len, i;
742 unsigned char *buf; 778 unsigned char *buf;
@@ -755,7 +791,7 @@ static int nexio_init(struct usbtouch_usb *usbtouch)
755 if (!input_ep || !output_ep) 791 if (!input_ep || !output_ep)
756 return -ENXIO; 792 return -ENXIO;
757 793
758 buf = kmalloc(NEXIO_BUFSIZE, GFP_KERNEL); 794 buf = kmalloc(NEXIO_BUFSIZE, GFP_NOIO);
759 if (!buf) 795 if (!buf)
760 goto out_buf; 796 goto out_buf;
761 797
@@ -787,11 +823,11 @@ static int nexio_init(struct usbtouch_usb *usbtouch)
787 switch (buf[0]) { 823 switch (buf[0]) {
788 case 0x83: /* firmware version */ 824 case 0x83: /* firmware version */
789 if (!firmware_ver) 825 if (!firmware_ver)
790 firmware_ver = kstrdup(&buf[2], GFP_KERNEL); 826 firmware_ver = kstrdup(&buf[2], GFP_NOIO);
791 break; 827 break;
792 case 0x84: /* device name */ 828 case 0x84: /* device name */
793 if (!device_name) 829 if (!device_name)
794 device_name = kstrdup(&buf[2], GFP_KERNEL); 830 device_name = kstrdup(&buf[2], GFP_NOIO);
795 break; 831 break;
796 } 832 }
797 } 833 }
@@ -802,36 +838,11 @@ static int nexio_init(struct usbtouch_usb *usbtouch)
802 kfree(firmware_ver); 838 kfree(firmware_ver);
803 kfree(device_name); 839 kfree(device_name);
804 840
805 /* prepare ACK URB */
806 ret = -ENOMEM;
807
808 usbtouch->priv = kmalloc(sizeof(struct nexio_priv), GFP_KERNEL);
809 if (!usbtouch->priv)
810 goto out_buf;
811
812 priv = usbtouch->priv;
813
814 priv->ack_buf = kmemdup(nexio_ack_pkt, sizeof(nexio_ack_pkt),
815 GFP_KERNEL);
816 if (!priv->ack_buf)
817 goto err_priv;
818
819 priv->ack = usb_alloc_urb(0, GFP_KERNEL);
820 if (!priv->ack) {
821 dbg("%s - usb_alloc_urb failed: usbtouch->ack", __func__);
822 goto err_ack_buf;
823 }
824
825 usb_fill_bulk_urb(priv->ack, dev, usb_sndbulkpipe(dev, output_ep), 841 usb_fill_bulk_urb(priv->ack, dev, usb_sndbulkpipe(dev, output_ep),
826 priv->ack_buf, sizeof(nexio_ack_pkt), 842 priv->ack_buf, sizeof(nexio_ack_pkt),
827 nexio_ack_complete, usbtouch); 843 nexio_ack_complete, usbtouch);
828 ret = 0; 844 ret = 0;
829 goto out_buf;
830 845
831err_ack_buf:
832 kfree(priv->ack_buf);
833err_priv:
834 kfree(priv);
835out_buf: 846out_buf:
836 kfree(buf); 847 kfree(buf);
837 return ret; 848 return ret;
@@ -849,29 +860,32 @@ static void nexio_exit(struct usbtouch_usb *usbtouch)
849 860
850static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt) 861static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt)
851{ 862{
852 int x, y, begin_x, begin_y, end_x, end_y, w, h, ret;
853 struct nexio_touch_packet *packet = (void *) pkt; 863 struct nexio_touch_packet *packet = (void *) pkt;
854 struct nexio_priv *priv = usbtouch->priv; 864 struct nexio_priv *priv = usbtouch->priv;
865 unsigned int data_len = be16_to_cpu(packet->data_len);
866 unsigned int x_len = be16_to_cpu(packet->x_len);
867 unsigned int y_len = be16_to_cpu(packet->y_len);
868 int x, y, begin_x, begin_y, end_x, end_y, w, h, ret;
855 869
856 /* got touch data? */ 870 /* got touch data? */
857 if ((pkt[0] & 0xe0) != 0xe0) 871 if ((pkt[0] & 0xe0) != 0xe0)
858 return 0; 872 return 0;
859 873
860 if (be16_to_cpu(packet->data_len) > 0xff) 874 if (data_len > 0xff)
861 packet->data_len = cpu_to_be16(be16_to_cpu(packet->data_len) - 0x100); 875 data_len -= 0x100;
862 if (be16_to_cpu(packet->x_len) > 0xff) 876 if (x_len > 0xff)
863 packet->x_len = cpu_to_be16(be16_to_cpu(packet->x_len) - 0x80); 877 x_len -= 0x80;
864 878
865 /* send ACK */ 879 /* send ACK */
866 ret = usb_submit_urb(priv->ack, GFP_ATOMIC); 880 ret = usb_submit_urb(priv->ack, GFP_ATOMIC);
867 881
868 if (!usbtouch->type->max_xc) { 882 if (!usbtouch->type->max_xc) {
869 usbtouch->type->max_xc = 2 * be16_to_cpu(packet->x_len); 883 usbtouch->type->max_xc = 2 * x_len;
870 input_set_abs_params(usbtouch->input, ABS_X, 0, 884 input_set_abs_params(usbtouch->input, ABS_X,
871 2 * be16_to_cpu(packet->x_len), 0, 0); 885 0, usbtouch->type->max_xc, 0, 0);
872 usbtouch->type->max_yc = 2 * be16_to_cpu(packet->y_len); 886 usbtouch->type->max_yc = 2 * y_len;
873 input_set_abs_params(usbtouch->input, ABS_Y, 0, 887 input_set_abs_params(usbtouch->input, ABS_Y,
874 2 * be16_to_cpu(packet->y_len), 0, 0); 888 0, usbtouch->type->max_yc, 0, 0);
875 } 889 }
876 /* 890 /*
877 * The device reports state of IR sensors on X and Y axes. 891 * The device reports state of IR sensors on X and Y axes.
@@ -881,22 +895,21 @@ static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt)
881 * it's disabled (and untested) here as there's no X driver for that. 895 * it's disabled (and untested) here as there's no X driver for that.
882 */ 896 */
883 begin_x = end_x = begin_y = end_y = -1; 897 begin_x = end_x = begin_y = end_y = -1;
884 for (x = 0; x < be16_to_cpu(packet->x_len); x++) { 898 for (x = 0; x < x_len; x++) {
885 if (begin_x == -1 && packet->data[x] > NEXIO_THRESHOLD) { 899 if (begin_x == -1 && packet->data[x] > NEXIO_THRESHOLD) {
886 begin_x = x; 900 begin_x = x;
887 continue; 901 continue;
888 } 902 }
889 if (end_x == -1 && begin_x != -1 && packet->data[x] < NEXIO_THRESHOLD) { 903 if (end_x == -1 && begin_x != -1 && packet->data[x] < NEXIO_THRESHOLD) {
890 end_x = x - 1; 904 end_x = x - 1;
891 for (y = be16_to_cpu(packet->x_len); 905 for (y = x_len; y < data_len; y++) {
892 y < be16_to_cpu(packet->data_len); y++) {
893 if (begin_y == -1 && packet->data[y] > NEXIO_THRESHOLD) { 906 if (begin_y == -1 && packet->data[y] > NEXIO_THRESHOLD) {
894 begin_y = y - be16_to_cpu(packet->x_len); 907 begin_y = y - x_len;
895 continue; 908 continue;
896 } 909 }
897 if (end_y == -1 && 910 if (end_y == -1 &&
898 begin_y != -1 && packet->data[y] < NEXIO_THRESHOLD) { 911 begin_y != -1 && packet->data[y] < NEXIO_THRESHOLD) {
899 end_y = y - 1 - be16_to_cpu(packet->x_len); 912 end_y = y - 1 - x_len;
900 w = end_x - begin_x; 913 w = end_x - begin_x;
901 h = end_y - begin_y; 914 h = end_y - begin_y;
902#if 0 915#if 0
@@ -1104,14 +1117,14 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
1104 }, 1117 },
1105#endif 1118#endif
1106 1119
1107#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC5UH 1120#ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC45USB
1108 [DEVTYPE_TC5UH] = { 1121 [DEVTYPE_TC45USB] = {
1109 .min_xc = 0x0, 1122 .min_xc = 0x0,
1110 .max_xc = 0x0fff, 1123 .max_xc = 0x0fff,
1111 .min_yc = 0x0, 1124 .min_yc = 0x0,
1112 .max_yc = 0x0fff, 1125 .max_yc = 0x0fff,
1113 .rept_size = 5, 1126 .rept_size = 5,
1114 .read_data = tc5uh_read_data, 1127 .read_data = tc45usb_read_data,
1115 }, 1128 },
1116#endif 1129#endif
1117 1130
@@ -1120,6 +1133,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
1120 .rept_size = 1024, 1133 .rept_size = 1024,
1121 .irq_always = true, 1134 .irq_always = true,
1122 .read_data = nexio_read_data, 1135 .read_data = nexio_read_data,
1136 .alloc = nexio_alloc,
1123 .init = nexio_init, 1137 .init = nexio_init,
1124 .exit = nexio_exit, 1138 .exit = nexio_exit,
1125 }, 1139 },
@@ -1263,6 +1277,7 @@ static void usbtouch_irq(struct urb *urb)
1263 usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length); 1277 usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length);
1264 1278
1265exit: 1279exit:
1280 usb_mark_last_busy(interface_to_usbdev(usbtouch->interface));
1266 retval = usb_submit_urb(urb, GFP_ATOMIC); 1281 retval = usb_submit_urb(urb, GFP_ATOMIC);
1267 if (retval) 1282 if (retval)
1268 err("%s - usb_submit_urb failed with result: %d", 1283 err("%s - usb_submit_urb failed with result: %d",
@@ -1272,25 +1287,89 @@ exit:
1272static int usbtouch_open(struct input_dev *input) 1287static int usbtouch_open(struct input_dev *input)
1273{ 1288{
1274 struct usbtouch_usb *usbtouch = input_get_drvdata(input); 1289 struct usbtouch_usb *usbtouch = input_get_drvdata(input);
1290 int r;
1275 1291
1276 usbtouch->irq->dev = interface_to_usbdev(usbtouch->interface); 1292 usbtouch->irq->dev = interface_to_usbdev(usbtouch->interface);
1277 1293
1294 r = usb_autopm_get_interface(usbtouch->interface) ? -EIO : 0;
1295 if (r < 0)
1296 goto out;
1297
1278 if (!usbtouch->type->irq_always) { 1298 if (!usbtouch->type->irq_always) {
1279 if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) 1299 if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) {
1280 return -EIO; 1300 r = -EIO;
1301 goto out_put;
1302 }
1281 } 1303 }
1282 1304
1283 return 0; 1305 usbtouch->interface->needs_remote_wakeup = 1;
1306out_put:
1307 usb_autopm_put_interface(usbtouch->interface);
1308out:
1309 return r;
1284} 1310}
1285 1311
1286static void usbtouch_close(struct input_dev *input) 1312static void usbtouch_close(struct input_dev *input)
1287{ 1313{
1288 struct usbtouch_usb *usbtouch = input_get_drvdata(input); 1314 struct usbtouch_usb *usbtouch = input_get_drvdata(input);
1315 int r;
1289 1316
1290 if (!usbtouch->type->irq_always) 1317 if (!usbtouch->type->irq_always)
1291 usb_kill_urb(usbtouch->irq); 1318 usb_kill_urb(usbtouch->irq);
1319 r = usb_autopm_get_interface(usbtouch->interface);
1320 usbtouch->interface->needs_remote_wakeup = 0;
1321 if (!r)
1322 usb_autopm_put_interface(usbtouch->interface);
1292} 1323}
1293 1324
1325static int usbtouch_suspend
1326(struct usb_interface *intf, pm_message_t message)
1327{
1328 struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
1329
1330 usb_kill_urb(usbtouch->irq);
1331
1332 return 0;
1333}
1334
1335static int usbtouch_resume(struct usb_interface *intf)
1336{
1337 struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
1338 struct input_dev *input = usbtouch->input;
1339 int result = 0;
1340
1341 mutex_lock(&input->mutex);
1342 if (input->users || usbtouch->type->irq_always)
1343 result = usb_submit_urb(usbtouch->irq, GFP_NOIO);
1344 mutex_unlock(&input->mutex);
1345
1346 return result;
1347}
1348
1349static int usbtouch_reset_resume(struct usb_interface *intf)
1350{
1351 struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
1352 struct input_dev *input = usbtouch->input;
1353 int err = 0;
1354
1355 /* reinit the device */
1356 if (usbtouch->type->init) {
1357 err = usbtouch->type->init(usbtouch);
1358 if (err) {
1359 dbg("%s - type->init() failed, err: %d",
1360 __func__, err);
1361 return err;
1362 }
1363 }
1364
1365 /* restart IO if needed */
1366 mutex_lock(&input->mutex);
1367 if (input->users)
1368 err = usb_submit_urb(usbtouch->irq, GFP_NOIO);
1369 mutex_unlock(&input->mutex);
1370
1371 return err;
1372}
1294 1373
1295static void usbtouch_free_buffers(struct usb_device *udev, 1374static void usbtouch_free_buffers(struct usb_device *udev,
1296 struct usbtouch_usb *usbtouch) 1375 struct usbtouch_usb *usbtouch)
@@ -1411,12 +1490,21 @@ static int usbtouch_probe(struct usb_interface *intf,
1411 usbtouch->irq->transfer_dma = usbtouch->data_dma; 1490 usbtouch->irq->transfer_dma = usbtouch->data_dma;
1412 usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 1491 usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1413 1492
1414 /* device specific init */ 1493 /* device specific allocations */
1494 if (type->alloc) {
1495 err = type->alloc(usbtouch);
1496 if (err) {
1497 dbg("%s - type->alloc() failed, err: %d", __func__, err);
1498 goto out_free_urb;
1499 }
1500 }
1501
1502 /* device specific initialisation*/
1415 if (type->init) { 1503 if (type->init) {
1416 err = type->init(usbtouch); 1504 err = type->init(usbtouch);
1417 if (err) { 1505 if (err) {
1418 dbg("%s - type->init() failed, err: %d", __func__, err); 1506 dbg("%s - type->init() failed, err: %d", __func__, err);
1419 goto out_free_urb; 1507 goto out_do_exit;
1420 } 1508 }
1421 } 1509 }
1422 1510
@@ -1429,8 +1517,11 @@ static int usbtouch_probe(struct usb_interface *intf,
1429 usb_set_intfdata(intf, usbtouch); 1517 usb_set_intfdata(intf, usbtouch);
1430 1518
1431 if (usbtouch->type->irq_always) { 1519 if (usbtouch->type->irq_always) {
1520 /* this can't fail */
1521 usb_autopm_get_interface(intf);
1432 err = usb_submit_urb(usbtouch->irq, GFP_KERNEL); 1522 err = usb_submit_urb(usbtouch->irq, GFP_KERNEL);
1433 if (err) { 1523 if (err) {
1524 usb_autopm_put_interface(intf);
1434 err("%s - usb_submit_urb failed with result: %d", 1525 err("%s - usb_submit_urb failed with result: %d",
1435 __func__, err); 1526 __func__, err);
1436 goto out_unregister_input; 1527 goto out_unregister_input;
@@ -1481,7 +1572,11 @@ static struct usb_driver usbtouch_driver = {
1481 .name = "usbtouchscreen", 1572 .name = "usbtouchscreen",
1482 .probe = usbtouch_probe, 1573 .probe = usbtouch_probe,
1483 .disconnect = usbtouch_disconnect, 1574 .disconnect = usbtouch_disconnect,
1575 .suspend = usbtouch_suspend,
1576 .resume = usbtouch_resume,
1577 .reset_resume = usbtouch_reset_resume,
1484 .id_table = usbtouch_devices, 1578 .id_table = usbtouch_devices,
1579 .supports_autosuspend = 1,
1485}; 1580};
1486 1581
1487static int __init usbtouch_init(void) 1582static int __init usbtouch_init(void)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 10ba12c8c5e..c43732ff180 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -645,9 +645,16 @@ config RTC_DRV_OMAP
645 DA8xx/OMAP-L13x chips. This driver can also be built as a 645 DA8xx/OMAP-L13x chips. This driver can also be built as a
646 module called rtc-omap. 646 module called rtc-omap.
647 647
648config HAVE_S3C_RTC
649 bool
650 help
651 This will include RTC support for Samsung SoCs. If
652 you want to include RTC support for any machine, kindly
653 select this in the respective mach-XXXX/Kconfig file.
654
648config RTC_DRV_S3C 655config RTC_DRV_S3C
649 tristate "Samsung S3C series SoC RTC" 656 tristate "Samsung S3C series SoC RTC"
650 depends on ARCH_S3C2410 || ARCH_S3C64XX 657 depends on ARCH_S3C2410 || ARCH_S3C64XX || HAVE_S3C_RTC
651 help 658 help
652 RTC (Realtime Clock) driver for the clock inbuilt into the 659 RTC (Realtime Clock) driver for the clock inbuilt into the
653 Samsung S3C24XX series of SoCs. This can provide periodic 660 Samsung S3C24XX series of SoCs. This can provide periodic
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 70b68d35f96..a0d3ec89d41 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -1,5 +1,8 @@
1/* drivers/rtc/rtc-s3c.c 1/* drivers/rtc/rtc-s3c.c
2 * 2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
3 * Copyright (c) 2004,2006 Simtec Electronics 6 * Copyright (c) 2004,2006 Simtec Electronics
4 * Ben Dooks, <ben@simtec.co.uk> 7 * Ben Dooks, <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/ 8 * http://armlinux.simtec.co.uk/
@@ -39,6 +42,7 @@ enum s3c_cpu_type {
39 42
40static struct resource *s3c_rtc_mem; 43static struct resource *s3c_rtc_mem;
41 44
45static struct clk *rtc_clk;
42static void __iomem *s3c_rtc_base; 46static void __iomem *s3c_rtc_base;
43static int s3c_rtc_alarmno = NO_IRQ; 47static int s3c_rtc_alarmno = NO_IRQ;
44static int s3c_rtc_tickno = NO_IRQ; 48static int s3c_rtc_tickno = NO_IRQ;
@@ -53,6 +57,10 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
53 struct rtc_device *rdev = id; 57 struct rtc_device *rdev = id;
54 58
55 rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF); 59 rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
60
61 if (s3c_rtc_cpu_type == TYPE_S3C64XX)
62 writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP);
63
56 return IRQ_HANDLED; 64 return IRQ_HANDLED;
57} 65}
58 66
@@ -61,6 +69,10 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
61 struct rtc_device *rdev = id; 69 struct rtc_device *rdev = id;
62 70
63 rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF); 71 rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF);
72
73 if (s3c_rtc_cpu_type == TYPE_S3C64XX)
74 writeb(S3C2410_INTP_TIC, s3c_rtc_base + S3C2410_INTP);
75
64 return IRQ_HANDLED; 76 return IRQ_HANDLED;
65} 77}
66 78
@@ -94,7 +106,7 @@ static int s3c_rtc_setpie(struct device *dev, int enabled)
94 if (enabled) 106 if (enabled)
95 tmp |= S3C64XX_RTCCON_TICEN; 107 tmp |= S3C64XX_RTCCON_TICEN;
96 108
97 writeb(tmp, s3c_rtc_base + S3C2410_RTCCON); 109 writew(tmp, s3c_rtc_base + S3C2410_RTCCON);
98 } else { 110 } else {
99 tmp = readb(s3c_rtc_base + S3C2410_TICNT); 111 tmp = readb(s3c_rtc_base + S3C2410_TICNT);
100 tmp &= ~S3C2410_TICNT_ENABLE; 112 tmp &= ~S3C2410_TICNT_ENABLE;
@@ -128,7 +140,7 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
128 140
129 tmp |= (rtc_dev->max_user_freq / freq)-1; 141 tmp |= (rtc_dev->max_user_freq / freq)-1;
130 142
131 writeb(tmp, s3c_rtc_base + S3C2410_TICNT); 143 writel(tmp, s3c_rtc_base + S3C2410_TICNT);
132 spin_unlock_irq(&s3c_rtc_pie_lock); 144 spin_unlock_irq(&s3c_rtc_pie_lock);
133 145
134 return 0; 146 return 0;
@@ -431,6 +443,10 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev)
431 s3c_rtc_setpie(&dev->dev, 0); 443 s3c_rtc_setpie(&dev->dev, 0);
432 s3c_rtc_setaie(0); 444 s3c_rtc_setaie(0);
433 445
446 clk_disable(rtc_clk);
447 clk_put(rtc_clk);
448 rtc_clk = NULL;
449
434 iounmap(s3c_rtc_base); 450 iounmap(s3c_rtc_base);
435 release_resource(s3c_rtc_mem); 451 release_resource(s3c_rtc_mem);
436 kfree(s3c_rtc_mem); 452 kfree(s3c_rtc_mem);
@@ -442,6 +458,7 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
442{ 458{
443 struct rtc_device *rtc; 459 struct rtc_device *rtc;
444 struct resource *res; 460 struct resource *res;
461 unsigned int tmp, i;
445 int ret; 462 int ret;
446 463
447 pr_debug("%s: probe=%p\n", __func__, pdev); 464 pr_debug("%s: probe=%p\n", __func__, pdev);
@@ -488,6 +505,16 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
488 goto err_nomap; 505 goto err_nomap;
489 } 506 }
490 507
508 rtc_clk = clk_get(&pdev->dev, "rtc");
509 if (IS_ERR(rtc_clk)) {
510 dev_err(&pdev->dev, "failed to find rtc clock source\n");
511 ret = PTR_ERR(rtc_clk);
512 rtc_clk = NULL;
513 goto err_clk;
514 }
515
516 clk_enable(rtc_clk);
517
491 /* check to see if everything is setup correctly */ 518 /* check to see if everything is setup correctly */
492 519
493 s3c_rtc_enable(pdev, 1); 520 s3c_rtc_enable(pdev, 1);
@@ -510,6 +537,15 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
510 537
511 s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; 538 s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
512 539
540 /* Check RTC Time */
541
542 for (i = S3C2410_RTCSEC; i <= S3C2410_RTCYEAR; i += 0x4) {
543 tmp = readb(s3c_rtc_base + i);
544
545 if ((tmp & 0xf) > 0x9 || ((tmp >> 4) & 0xf) > 0x9)
546 writeb(0, s3c_rtc_base + i);
547 }
548
513 if (s3c_rtc_cpu_type == TYPE_S3C64XX) 549 if (s3c_rtc_cpu_type == TYPE_S3C64XX)
514 rtc->max_user_freq = 32768; 550 rtc->max_user_freq = 32768;
515 else 551 else
@@ -523,6 +559,10 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
523 559
524 err_nortc: 560 err_nortc:
525 s3c_rtc_enable(pdev, 0); 561 s3c_rtc_enable(pdev, 0);
562 clk_disable(rtc_clk);
563 clk_put(rtc_clk);
564
565 err_clk:
526 iounmap(s3c_rtc_base); 566 iounmap(s3c_rtc_base);
527 567
528 err_nomap: 568 err_nomap:
diff --git a/include/linux/i2c/adp5588.h b/include/linux/i2c/adp5588.h
index 02c9af37474..269181b8f62 100644
--- a/include/linux/i2c/adp5588.h
+++ b/include/linux/i2c/adp5588.h
@@ -78,6 +78,40 @@
78 78
79#define ADP5588_KEYMAPSIZE 80 79#define ADP5588_KEYMAPSIZE 80
80 80
81#define GPI_PIN_ROW0 97
82#define GPI_PIN_ROW1 98
83#define GPI_PIN_ROW2 99
84#define GPI_PIN_ROW3 100
85#define GPI_PIN_ROW4 101
86#define GPI_PIN_ROW5 102
87#define GPI_PIN_ROW6 103
88#define GPI_PIN_ROW7 104
89#define GPI_PIN_COL0 105
90#define GPI_PIN_COL1 106
91#define GPI_PIN_COL2 107
92#define GPI_PIN_COL3 108
93#define GPI_PIN_COL4 109
94#define GPI_PIN_COL5 110
95#define GPI_PIN_COL6 111
96#define GPI_PIN_COL7 112
97#define GPI_PIN_COL8 113
98#define GPI_PIN_COL9 114
99
100#define GPI_PIN_ROW_BASE GPI_PIN_ROW0
101#define GPI_PIN_ROW_END GPI_PIN_ROW7
102#define GPI_PIN_COL_BASE GPI_PIN_COL0
103#define GPI_PIN_COL_END GPI_PIN_COL9
104
105#define GPI_PIN_BASE GPI_PIN_ROW_BASE
106#define GPI_PIN_END GPI_PIN_COL_END
107
108#define ADP5588_GPIMAPSIZE_MAX (GPI_PIN_END - GPI_PIN_BASE + 1)
109
110struct adp5588_gpi_map {
111 unsigned short pin;
112 unsigned short sw_evt;
113};
114
81struct adp5588_kpad_platform_data { 115struct adp5588_kpad_platform_data {
82 int rows; /* Number of rows */ 116 int rows; /* Number of rows */
83 int cols; /* Number of columns */ 117 int cols; /* Number of columns */
@@ -87,6 +121,9 @@ struct adp5588_kpad_platform_data {
87 unsigned en_keylock:1; /* Enable Key Lock feature */ 121 unsigned en_keylock:1; /* Enable Key Lock feature */
88 unsigned short unlock_key1; /* Unlock Key 1 */ 122 unsigned short unlock_key1; /* Unlock Key 1 */
89 unsigned short unlock_key2; /* Unlock Key 2 */ 123 unsigned short unlock_key2; /* Unlock Key 2 */
124 const struct adp5588_gpi_map *gpimap;
125 unsigned short gpimapsize;
126 const struct adp5588_gpio_platform_data *gpio_data;
90}; 127};
91 128
92struct adp5588_gpio_platform_data { 129struct adp5588_gpio_platform_data {
diff --git a/include/linux/i2c/mcs.h b/include/linux/i2c/mcs.h
new file mode 100644
index 00000000000..725ae7c313f
--- /dev/null
+++ b/include/linux/i2c/mcs.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2009 - 2010 Samsung Electronics Co.Ltd
3 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
4 * Author: HeungJun Kim <riverful.kim@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#ifndef __LINUX_MCS_H
14#define __LINUX_MCS_H
15
16#define MCS_KEY_MAP(v, c) ((((v) & 0xff) << 16) | ((c) & 0xffff))
17#define MCS_KEY_VAL(v) (((v) >> 16) & 0xff)
18#define MCS_KEY_CODE(v) ((v) & 0xffff)
19
20struct mcs_platform_data {
21 void (*cfg_pin)(void);
22
23 /* touchscreen */
24 unsigned int x_size;
25 unsigned int y_size;
26
27 /* touchkey */
28 const u32 *keymap;
29 unsigned int keymap_size;
30 unsigned int key_maxval;
31 bool no_autorepeat;
32};
33
34#endif /* __LINUX_MCS_H */
diff --git a/include/linux/i2c/mcs5000_ts.h b/include/linux/i2c/mcs5000_ts.h
deleted file mode 100644
index 5a117b5ca15..00000000000
--- a/include/linux/i2c/mcs5000_ts.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * mcs5000_ts.h
3 *
4 * Copyright (C) 2009 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#ifndef __LINUX_MCS5000_TS_H
15#define __LINUX_MCS5000_TS_H
16
17/* platform data for the MELFAS MCS-5000 touchscreen driver */
18struct mcs5000_ts_platform_data {
19 void (*cfg_pin)(void);
20 int x_size;
21 int y_size;
22};
23
24#endif /* __LINUX_MCS5000_TS_H */
diff --git a/include/linux/i2c/qt602240_ts.h b/include/linux/i2c/qt602240_ts.h
new file mode 100644
index 00000000000..c5033e10109
--- /dev/null
+++ b/include/linux/i2c/qt602240_ts.h
@@ -0,0 +1,38 @@
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#ifndef __LINUX_QT602240_TS_H
14#define __LINUX_QT602240_TS_H
15
16/* Orient */
17#define QT602240_NORMAL 0x0
18#define QT602240_DIAGONAL 0x1
19#define QT602240_HORIZONTAL_FLIP 0x2
20#define QT602240_ROTATED_90_COUNTER 0x3
21#define QT602240_VERTICAL_FLIP 0x4
22#define QT602240_ROTATED_90 0x5
23#define QT602240_ROTATED_180 0x6
24#define QT602240_DIAGONAL_COUNTER 0x7
25
26/* The platform data for the AT42QT602240/ATMXT224 touchscreen driver */
27struct qt602240_platform_data {
28 unsigned int x_line;
29 unsigned int y_line;
30 unsigned int x_size;
31 unsigned int y_size;
32 unsigned int blen;
33 unsigned int threshold;
34 unsigned int voltage;
35 unsigned char orient;
36};
37
38#endif /* __LINUX_QT602240_TS_H */
diff --git a/include/linux/input.h b/include/linux/input.h
index 6fcc9101bee..339d043ccb5 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -691,9 +691,12 @@ struct input_absinfo {
691#define ABS_TILT_X 0x1a 691#define ABS_TILT_X 0x1a
692#define ABS_TILT_Y 0x1b 692#define ABS_TILT_Y 0x1b
693#define ABS_TOOL_WIDTH 0x1c 693#define ABS_TOOL_WIDTH 0x1c
694
694#define ABS_VOLUME 0x20 695#define ABS_VOLUME 0x20
696
695#define ABS_MISC 0x28 697#define ABS_MISC 0x28
696 698
699#define ABS_MT_SLOT 0x2f /* MT slot being modified */
697#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ 700#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
698#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */ 701#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
699#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */ 702#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
@@ -706,6 +709,12 @@ struct input_absinfo {
706#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */ 709#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
707#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */ 710#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
708 711
712#ifdef __KERNEL__
713/* Implementation details, userspace should not care about these */
714#define ABS_MT_FIRST ABS_MT_TOUCH_MAJOR
715#define ABS_MT_LAST ABS_MT_PRESSURE
716#endif
717
709#define ABS_MAX 0x3f 718#define ABS_MAX 0x3f
710#define ABS_CNT (ABS_MAX+1) 719#define ABS_CNT (ABS_MAX+1)
711 720
@@ -1048,6 +1057,14 @@ struct ff_effect {
1048#include <linux/mod_devicetable.h> 1057#include <linux/mod_devicetable.h>
1049 1058
1050/** 1059/**
1060 * struct input_mt_slot - represents the state of an input MT slot
1061 * @abs: holds current values of ABS_MT axes for this slot
1062 */
1063struct input_mt_slot {
1064 int abs[ABS_MT_LAST - ABS_MT_FIRST + 1];
1065};
1066
1067/**
1051 * struct input_dev - represents an input device 1068 * struct input_dev - represents an input device
1052 * @name: name of the device 1069 * @name: name of the device
1053 * @phys: physical path to the device in the system hierarchy 1070 * @phys: physical path to the device in the system hierarchy
@@ -1063,6 +1080,10 @@ struct ff_effect {
1063 * @sndbit: bitmap of sound effects supported by the device 1080 * @sndbit: bitmap of sound effects supported by the device
1064 * @ffbit: bitmap of force feedback effects supported by the device 1081 * @ffbit: bitmap of force feedback effects supported by the device
1065 * @swbit: bitmap of switches present on the device 1082 * @swbit: bitmap of switches present on the device
1083 * @hint_events_per_packet: average number of events generated by the
1084 * device in a packet (between EV_SYN/SYN_REPORT events). Used by
1085 * event handlers to estimate size of the buffer needed to hold
1086 * events.
1066 * @keycodemax: size of keycode table 1087 * @keycodemax: size of keycode table
1067 * @keycodesize: size of elements in keycode table 1088 * @keycodesize: size of elements in keycode table
1068 * @keycode: map of scancodes to keycodes for this device 1089 * @keycode: map of scancodes to keycodes for this device
@@ -1078,9 +1099,12 @@ struct ff_effect {
1078 * @repeat_key: stores key code of the last key pressed; used to implement 1099 * @repeat_key: stores key code of the last key pressed; used to implement
1079 * software autorepeat 1100 * software autorepeat
1080 * @timer: timer for software autorepeat 1101 * @timer: timer for software autorepeat
1081 * @sync: set to 1 when there were no new events since last EV_SYNC
1082 * @abs: current values for reports from absolute axes 1102 * @abs: current values for reports from absolute axes
1083 * @rep: current values for autorepeat parameters (delay, rate) 1103 * @rep: current values for autorepeat parameters (delay, rate)
1104 * @mt: pointer to array of struct input_mt_slot holding current values
1105 * of tracked contacts
1106 * @mtsize: number of MT slots the device uses
1107 * @slot: MT slot currently being transmitted
1084 * @key: reflects current state of device's keys/buttons 1108 * @key: reflects current state of device's keys/buttons
1085 * @led: reflects current state of device's LEDs 1109 * @led: reflects current state of device's LEDs
1086 * @snd: reflects current state of sound effects 1110 * @snd: reflects current state of sound effects
@@ -1119,6 +1143,7 @@ struct ff_effect {
1119 * last user closes the device 1143 * last user closes the device
1120 * @going_away: marks devices that are in a middle of unregistering and 1144 * @going_away: marks devices that are in a middle of unregistering and
1121 * causes input_open_device*() fail with -ENODEV. 1145 * causes input_open_device*() fail with -ENODEV.
1146 * @sync: set to %true when there were no new events since last EV_SYN
1122 * @dev: driver model's view of this device 1147 * @dev: driver model's view of this device
1123 * @h_list: list of input handles associated with the device. When 1148 * @h_list: list of input handles associated with the device. When
1124 * accessing the list dev->mutex must be held 1149 * accessing the list dev->mutex must be held
@@ -1140,6 +1165,8 @@ struct input_dev {
1140 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; 1165 unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
1141 unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; 1166 unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
1142 1167
1168 unsigned int hint_events_per_packet;
1169
1143 unsigned int keycodemax; 1170 unsigned int keycodemax;
1144 unsigned int keycodesize; 1171 unsigned int keycodesize;
1145 void *keycode; 1172 void *keycode;
@@ -1153,11 +1180,13 @@ struct input_dev {
1153 unsigned int repeat_key; 1180 unsigned int repeat_key;
1154 struct timer_list timer; 1181 struct timer_list timer;
1155 1182
1156 int sync;
1157
1158 int abs[ABS_CNT]; 1183 int abs[ABS_CNT];
1159 int rep[REP_MAX + 1]; 1184 int rep[REP_MAX + 1];
1160 1185
1186 struct input_mt_slot *mt;
1187 int mtsize;
1188 int slot;
1189
1161 unsigned long key[BITS_TO_LONGS(KEY_CNT)]; 1190 unsigned long key[BITS_TO_LONGS(KEY_CNT)];
1162 unsigned long led[BITS_TO_LONGS(LED_CNT)]; 1191 unsigned long led[BITS_TO_LONGS(LED_CNT)];
1163 unsigned long snd[BITS_TO_LONGS(SND_CNT)]; 1192 unsigned long snd[BITS_TO_LONGS(SND_CNT)];
@@ -1182,6 +1211,8 @@ struct input_dev {
1182 unsigned int users; 1211 unsigned int users;
1183 bool going_away; 1212 bool going_away;
1184 1213
1214 bool sync;
1215
1185 struct device dev; 1216 struct device dev;
1186 1217
1187 struct list_head h_list; 1218 struct list_head h_list;
@@ -1406,8 +1437,28 @@ static inline void input_mt_sync(struct input_dev *dev)
1406 input_event(dev, EV_SYN, SYN_MT_REPORT, 0); 1437 input_event(dev, EV_SYN, SYN_MT_REPORT, 0);
1407} 1438}
1408 1439
1440static inline void input_mt_slot(struct input_dev *dev, int slot)
1441{
1442 input_event(dev, EV_ABS, ABS_MT_SLOT, slot);
1443}
1444
1409void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code); 1445void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code);
1410 1446
1447/**
1448 * input_set_events_per_packet - tell handlers about the driver event rate
1449 * @dev: the input device used by the driver
1450 * @n_events: the average number of events between calls to input_sync()
1451 *
1452 * If the event rate sent from a device is unusually large, use this
1453 * function to set the expected event rate. This will allow handlers
1454 * to set up an appropriate buffer size for the event stream, in order
1455 * to minimize information loss.
1456 */
1457static inline void input_set_events_per_packet(struct input_dev *dev, int n_events)
1458{
1459 dev->hint_events_per_packet = n_events;
1460}
1461
1411static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat) 1462static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
1412{ 1463{
1413 dev->absmin[axis] = min; 1464 dev->absmin[axis] = min;
@@ -1485,5 +1536,8 @@ int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file);
1485int input_ff_create_memless(struct input_dev *dev, void *data, 1536int input_ff_create_memless(struct input_dev *dev, void *data,
1486 int (*play_effect)(struct input_dev *, void *, struct ff_effect *)); 1537 int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
1487 1538
1539int input_mt_create_slots(struct input_dev *dev, unsigned int num_slots);
1540void input_mt_destroy_slots(struct input_dev *dev);
1541
1488#endif 1542#endif
1489#endif 1543#endif
diff --git a/include/linux/input/adxl34x.h b/include/linux/input/adxl34x.h
new file mode 100644
index 00000000000..df00d998a44
--- /dev/null
+++ b/include/linux/input/adxl34x.h
@@ -0,0 +1,349 @@
1/*
2 * include/linux/input/adxl34x.h
3 *
4 * Digital Accelerometer characteristics are highly application specific
5 * and may vary between boards and models. The platform_data for the
6 * device's "struct device" holds this information.
7 *
8 * Copyright 2009 Analog Devices Inc.
9 *
10 * Licensed under the GPL-2 or later.
11 */
12
13#ifndef __LINUX_INPUT_ADXL34X_H__
14#define __LINUX_INPUT_ADXL34X_H__
15
16struct adxl34x_platform_data {
17
18 /*
19 * X,Y,Z Axis Offset:
20 * offer user offset adjustments in twoscompliment
21 * form with a scale factor of 15.6 mg/LSB (i.e. 0x7F = +2 g)
22 */
23
24 s8 x_axis_offset;
25 s8 y_axis_offset;
26 s8 z_axis_offset;
27
28 /*
29 * TAP_X/Y/Z Enable: Setting TAP_X, Y, or Z Enable enables X,
30 * Y, or Z participation in Tap detection. A '0' excludes the
31 * selected axis from participation in Tap detection.
32 * Setting the SUPPRESS bit suppresses Double Tap detection if
33 * acceleration greater than tap_threshold is present between
34 * taps.
35 */
36
37#define ADXL_SUPPRESS (1 << 3)
38#define ADXL_TAP_X_EN (1 << 2)
39#define ADXL_TAP_Y_EN (1 << 1)
40#define ADXL_TAP_Z_EN (1 << 0)
41
42 u8 tap_axis_control;
43
44 /*
45 * tap_threshold:
46 * holds the threshold value for tap detection/interrupts.
47 * The data format is unsigned. The scale factor is 62.5 mg/LSB
48 * (i.e. 0xFF = +16 g). A zero value may result in undesirable
49 * behavior if Tap/Double Tap is enabled.
50 */
51
52 u8 tap_threshold;
53
54 /*
55 * tap_duration:
56 * is an unsigned time value representing the maximum
57 * time that an event must be above the tap_threshold threshold
58 * to qualify as a tap event. The scale factor is 625 us/LSB. A zero
59 * value will prevent Tap/Double Tap functions from working.
60 */
61
62 u8 tap_duration;
63
64 /*
65 * tap_latency:
66 * is an unsigned time value representing the wait time
67 * from the detection of a tap event to the opening of the time
68 * window tap_window for a possible second tap event. The scale
69 * factor is 1.25 ms/LSB. A zero value will disable the Double Tap
70 * function.
71 */
72
73 u8 tap_latency;
74
75 /*
76 * tap_window:
77 * is an unsigned time value representing the amount
78 * of time after the expiration of tap_latency during which a second
79 * tap can begin. The scale factor is 1.25 ms/LSB. A zero value will
80 * disable the Double Tap function.
81 */
82
83 u8 tap_window;
84
85 /*
86 * act_axis_control:
87 * X/Y/Z Enable: A '1' enables X, Y, or Z participation in activity
88 * or inactivity detection. A '0' excludes the selected axis from
89 * participation. If all of the axes are excluded, the function is
90 * disabled.
91 * AC/DC: A '0' = DC coupled operation and a '1' = AC coupled
92 * operation. In DC coupled operation, the current acceleration is
93 * compared with activity_threshold and inactivity_threshold directly
94 * to determine whether activity or inactivity is detected. In AC
95 * coupled operation for activity detection, the acceleration value
96 * at the start of activity detection is taken as a reference value.
97 * New samples of acceleration are then compared to this
98 * reference value and if the magnitude of the difference exceeds
99 * activity_threshold the device will trigger an activity interrupt. In
100 * AC coupled operation for inactivity detection, a reference value
101 * is used again for comparison and is updated whenever the
102 * device exceeds the inactivity threshold. Once the reference
103 * value is selected, the device compares the magnitude of the
104 * difference between the reference value and the current
105 * acceleration with inactivity_threshold. If the difference is below
106 * inactivity_threshold for a total of inactivity_time, the device is
107 * considered inactive and the inactivity interrupt is triggered.
108 */
109
110#define ADXL_ACT_ACDC (1 << 7)
111#define ADXL_ACT_X_EN (1 << 6)
112#define ADXL_ACT_Y_EN (1 << 5)
113#define ADXL_ACT_Z_EN (1 << 4)
114#define ADXL_INACT_ACDC (1 << 3)
115#define ADXL_INACT_X_EN (1 << 2)
116#define ADXL_INACT_Y_EN (1 << 1)
117#define ADXL_INACT_Z_EN (1 << 0)
118
119 u8 act_axis_control;
120
121 /*
122 * activity_threshold:
123 * holds the threshold value for activity detection.
124 * The data format is unsigned. The scale factor is
125 * 62.5 mg/LSB. A zero value may result in undesirable behavior if
126 * Activity interrupt is enabled.
127 */
128
129 u8 activity_threshold;
130
131 /*
132 * inactivity_threshold:
133 * holds the threshold value for inactivity
134 * detection. The data format is unsigned. The scale
135 * factor is 62.5 mg/LSB. A zero value may result in undesirable
136 * behavior if Inactivity interrupt is enabled.
137 */
138
139 u8 inactivity_threshold;
140
141 /*
142 * inactivity_time:
143 * is an unsigned time value representing the
144 * amount of time that acceleration must be below the value in
145 * inactivity_threshold for inactivity to be declared. The scale factor
146 * is 1 second/LSB. Unlike the other interrupt functions, which
147 * operate on unfiltered data, the inactivity function operates on the
148 * filtered output data. At least one output sample must be
149 * generated for the inactivity interrupt to be triggered. This will
150 * result in the function appearing un-responsive if the
151 * inactivity_time register is set with a value less than the time
152 * constant of the Output Data Rate. A zero value will result in an
153 * interrupt when the output data is below inactivity_threshold.
154 */
155
156 u8 inactivity_time;
157
158 /*
159 * free_fall_threshold:
160 * holds the threshold value for Free-Fall detection.
161 * The data format is unsigned. The root-sum-square(RSS) value
162 * of all axes is calculated and compared to the value in
163 * free_fall_threshold to determine if a free fall event may be
164 * occurring. The scale factor is 62.5 mg/LSB. A zero value may
165 * result in undesirable behavior if Free-Fall interrupt is
166 * enabled. Values between 300 and 600 mg (0x05 to 0x09) are
167 * recommended.
168 */
169
170 u8 free_fall_threshold;
171
172 /*
173 * free_fall_time:
174 * is an unsigned time value representing the minimum
175 * time that the RSS value of all axes must be less than
176 * free_fall_threshold to generate a Free-Fall interrupt. The
177 * scale factor is 5 ms/LSB. A zero value may result in
178 * undesirable behavior if Free-Fall interrupt is enabled.
179 * Values between 100 to 350 ms (0x14 to 0x46) are recommended.
180 */
181
182 u8 free_fall_time;
183
184 /*
185 * data_rate:
186 * Selects device bandwidth and output data rate.
187 * RATE = 3200 Hz / (2^(15 - x)). Default value is 0x0A, or 100 Hz
188 * Output Data Rate. An Output Data Rate should be selected that
189 * is appropriate for the communication protocol and frequency
190 * selected. Selecting too high of an Output Data Rate with a low
191 * communication speed will result in samples being discarded.
192 */
193
194 u8 data_rate;
195
196 /*
197 * data_range:
198 * FULL_RES: When this bit is set with the device is
199 * in Full-Resolution Mode, where the output resolution increases
200 * with RANGE to maintain a 4 mg/LSB scale factor. When this
201 * bit is cleared the device is in 10-bit Mode and RANGE determine the
202 * maximum g-Range and scale factor.
203 */
204
205#define ADXL_FULL_RES (1 << 3)
206#define ADXL_RANGE_PM_2g 0
207#define ADXL_RANGE_PM_4g 1
208#define ADXL_RANGE_PM_8g 2
209#define ADXL_RANGE_PM_16g 3
210
211 u8 data_range;
212
213 /*
214 * low_power_mode:
215 * A '0' = Normal operation and a '1' = Reduced
216 * power operation with somewhat higher noise.
217 */
218
219 u8 low_power_mode;
220
221 /*
222 * power_mode:
223 * LINK: A '1' with both the activity and inactivity functions
224 * enabled will delay the start of the activity function until
225 * inactivity is detected. Once activity is detected, inactivity
226 * detection will begin and prevent the detection of activity. This
227 * bit serially links the activity and inactivity functions. When '0'
228 * the inactivity and activity functions are concurrent. Additional
229 * information can be found in the Application section under Link
230 * Mode.
231 * AUTO_SLEEP: A '1' sets the ADXL34x to switch to Sleep Mode
232 * when inactivity (acceleration has been below inactivity_threshold
233 * for at least inactivity_time) is detected and the LINK bit is set.
234 * A '0' disables automatic switching to Sleep Mode. See SLEEP
235 * for further description.
236 */
237
238#define ADXL_LINK (1 << 5)
239#define ADXL_AUTO_SLEEP (1 << 4)
240
241 u8 power_mode;
242
243 /*
244 * fifo_mode:
245 * BYPASS The FIFO is bypassed
246 * FIFO FIFO collects up to 32 values then stops collecting data
247 * STREAM FIFO holds the last 32 data values. Once full, the FIFO's
248 * oldest data is lost as it is replaced with newer data
249 *
250 * DEFAULT should be ADXL_FIFO_STREAM
251 */
252
253#define ADXL_FIFO_BYPASS 0
254#define ADXL_FIFO_FIFO 1
255#define ADXL_FIFO_STREAM 2
256
257 u8 fifo_mode;
258
259 /*
260 * watermark:
261 * The Watermark feature can be used to reduce the interrupt load
262 * of the system. The FIFO fills up to the value stored in watermark
263 * [1..32] and then generates an interrupt.
264 * A '0' disables the watermark feature.
265 */
266
267 u8 watermark;
268
269 u32 ev_type; /* EV_ABS or EV_REL */
270
271 u32 ev_code_x; /* ABS_X,Y,Z or REL_X,Y,Z */
272 u32 ev_code_y; /* ABS_X,Y,Z or REL_X,Y,Z */
273 u32 ev_code_z; /* ABS_X,Y,Z or REL_X,Y,Z */
274
275 /*
276 * A valid BTN or KEY Code; use tap_axis_control to disable
277 * event reporting
278 */
279
280 u32 ev_code_tap[3]; /* EV_KEY {X-Axis, Y-Axis, Z-Axis} */
281
282 /*
283 * A valid BTN or KEY Code for Free-Fall or Activity enables
284 * input event reporting. A '0' disables the Free-Fall or
285 * Activity reporting.
286 */
287
288 u32 ev_code_ff; /* EV_KEY */
289 u32 ev_code_act_inactivity; /* EV_KEY */
290
291 /*
292 * Use ADXL34x INT2 instead of INT1
293 */
294 u8 use_int2;
295
296 /*
297 * ADXL346 only ORIENTATION SENSING feature
298 * The orientation function of the ADXL346 reports both 2-D and
299 * 3-D orientation concurrently.
300 */
301
302#define ADXL_EN_ORIENTATION_2D 1
303#define ADXL_EN_ORIENTATION_3D 2
304#define ADXL_EN_ORIENTATION_2D_3D 3
305
306 u8 orientation_enable;
307
308 /*
309 * The width of the deadzone region between two or more
310 * orientation positions is determined by setting the Deadzone
311 * value. The deadzone region size can be specified with a
312 * resolution of 3.6deg. The deadzone angle represents the total
313 * angle where the orientation is considered invalid.
314 */
315
316#define ADXL_DEADZONE_ANGLE_0p0 0 /* !!!0.0 [deg] */
317#define ADXL_DEADZONE_ANGLE_3p6 1 /* 3.6 [deg] */
318#define ADXL_DEADZONE_ANGLE_7p2 2 /* 7.2 [deg] */
319#define ADXL_DEADZONE_ANGLE_10p8 3 /* 10.8 [deg] */
320#define ADXL_DEADZONE_ANGLE_14p4 4 /* 14.4 [deg] */
321#define ADXL_DEADZONE_ANGLE_18p0 5 /* 18.0 [deg] */
322#define ADXL_DEADZONE_ANGLE_21p6 6 /* 21.6 [deg] */
323#define ADXL_DEADZONE_ANGLE_25p2 7 /* 25.2 [deg] */
324
325 u8 deadzone_angle;
326
327 /*
328 * To eliminate most human motion such as walking or shaking,
329 * a Divisor value should be selected to effectively limit the
330 * orientation bandwidth. Set the depth of the filter used to
331 * low-pass filter the measured acceleration for stable
332 * orientation sensing
333 */
334
335#define ADXL_LP_FILTER_DIVISOR_2 0
336#define ADXL_LP_FILTER_DIVISOR_4 1
337#define ADXL_LP_FILTER_DIVISOR_8 2
338#define ADXL_LP_FILTER_DIVISOR_16 3
339#define ADXL_LP_FILTER_DIVISOR_32 4
340#define ADXL_LP_FILTER_DIVISOR_64 5
341#define ADXL_LP_FILTER_DIVISOR_128 6
342#define ADXL_LP_FILTER_DIVISOR_256 7
343
344 u8 divisor_length;
345
346 u32 ev_codes_orient_2d[4]; /* EV_KEY {+X, -X, +Y, -Y} */
347 u32 ev_codes_orient_3d[6]; /* EV_KEY {+Z, +Y, +X, -X, -Y, -Z} */
348};
349#endif
diff --git a/include/linux/input/cy8ctmg110_pdata.h b/include/linux/input/cy8ctmg110_pdata.h
new file mode 100644
index 00000000000..09522cb5991
--- /dev/null
+++ b/include/linux/input/cy8ctmg110_pdata.h
@@ -0,0 +1,10 @@
1#ifndef _LINUX_CY8CTMG110_PDATA_H
2#define _LINUX_CY8CTMG110_PDATA_H
3
4struct cy8ctmg110_pdata
5{
6 int reset_pin; /* Reset pin is wired to this GPIO (optional) */
7 int irq_pin; /* IRQ pin is wired to this GPIO */
8};
9
10#endif
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
index c964cd7f436..80352ad6581 100644
--- a/include/linux/input/matrix_keypad.h
+++ b/include/linux/input/matrix_keypad.h
@@ -41,6 +41,9 @@ struct matrix_keymap_data {
41 * @col_scan_delay_us: delay, measured in microseconds, that is 41 * @col_scan_delay_us: delay, measured in microseconds, that is
42 * needed before we can keypad after activating column gpio 42 * needed before we can keypad after activating column gpio
43 * @debounce_ms: debounce interval in milliseconds 43 * @debounce_ms: debounce interval in milliseconds
44 * @clustered_irq: may be specified if interrupts of all row/column GPIOs
45 * are bundled to one single irq
46 * @clustered_irq_flags: flags that are needed for the clustered irq
44 * @active_low: gpio polarity 47 * @active_low: gpio polarity
45 * @wakeup: controls whether the device should be set up as wakeup 48 * @wakeup: controls whether the device should be set up as wakeup
46 * source 49 * source
@@ -63,6 +66,9 @@ struct matrix_keypad_platform_data {
63 /* key debounce interval in milli-second */ 66 /* key debounce interval in milli-second */
64 unsigned int debounce_ms; 67 unsigned int debounce_ms;
65 68
69 unsigned int clustered_irq;
70 unsigned int clustered_irq_flags;
71
66 bool active_low; 72 bool active_low;
67 bool wakeup; 73 bool wakeup;
68 bool no_autorepeat; 74 bool no_autorepeat;
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h
index b4ae570d3c9..92bd0839d5b 100644
--- a/include/linux/spi/ads7846.h
+++ b/include/linux/spi/ads7846.h
@@ -48,11 +48,12 @@ struct ads7846_platform_data {
48 * state if get_pendown_state == NULL 48 * state if get_pendown_state == NULL
49 */ 49 */
50 int (*get_pendown_state)(void); 50 int (*get_pendown_state)(void);
51 int (*filter_init) (struct ads7846_platform_data *pdata, 51 int (*filter_init) (const struct ads7846_platform_data *pdata,
52 void **filter_data); 52 void **filter_data);
53 int (*filter) (void *filter_data, int data_idx, int *val); 53 int (*filter) (void *filter_data, int data_idx, int *val);
54 void (*filter_cleanup)(void *filter_data); 54 void (*filter_cleanup)(void *filter_data);
55 void (*wait_for_sync)(void); 55 void (*wait_for_sync)(void);
56 bool wakeup; 56 bool wakeup;
57 unsigned long irq_flags;
57}; 58};
58 59