Merge branch 'next' into for-linus
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 6 Jul 2017 20:51:43 +0000 (13:51 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 6 Jul 2017 20:51:43 +0000 (13:51 -0700)
Prepare input updates for 4.13 merge window.

38 files changed:
Documentation/devicetree/bindings/input/dlink,dir685-touchkeys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/input/touchscreen/st,stmfts.txt [new file with mode: 0644]
MAINTAINERS
arch/sh/boards/mach-ecovec24/setup.c
drivers/input/input.c
drivers/input/joystick/xpad.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/dlink-dir685-touchkeys.c [new file with mode: 0644]
drivers/input/keyboard/lm8323.c
drivers/input/keyboard/mcs_touchkey.c
drivers/input/misc/axp20x-pek.c
drivers/input/misc/xen-kbdfront.c
drivers/input/mouse/elan_i2c.h
drivers/input/mouse/elan_i2c_core.c
drivers/input/mouse/elan_i2c_i2c.c
drivers/input/mouse/elan_i2c_smbus.c
drivers/input/mouse/elantech.c
drivers/input/rmi4/rmi_f34v7.c
drivers/input/sparse-keymap.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/mcs5000_ts.c
drivers/input/touchscreen/mms114.c
drivers/input/touchscreen/s3c2410_ts.c
drivers/input/touchscreen/stmfts.c [new file with mode: 0644]
drivers/input/touchscreen/tsc2007_core.c
drivers/mfd/timberdale.c
include/linux/i2c/lm8323.h [deleted file]
include/linux/i2c/mcs.h [deleted file]
include/linux/i2c/mms114.h [deleted file]
include/linux/i2c/tsc2007.h [deleted file]
include/linux/input/sparse-keymap.h
include/linux/platform_data/lm8323.h [new file with mode: 0644]
include/linux/platform_data/mcs.h [new file with mode: 0644]
include/linux/platform_data/mms114.h [new file with mode: 0644]
include/linux/platform_data/tsc2007.h [new file with mode: 0644]
include/uapi/linux/input-event-codes.h

diff --git a/Documentation/devicetree/bindings/input/dlink,dir685-touchkeys.txt b/Documentation/devicetree/bindings/input/dlink,dir685-touchkeys.txt
new file mode 100644 (file)
index 0000000..10dec1c
--- /dev/null
@@ -0,0 +1,21 @@
+* D-Link DIR-685 Touchkeys
+
+This is a I2C one-off touchkey controller based on the Cypress Semiconductor
+CY8C214 MCU with some firmware in its internal 8KB flash. The circuit
+board inside the router is named E119921.
+
+The touchkey device node should be placed inside an I2C bus node.
+
+Required properties:
+- compatible: must be "dlink,dir685-touchkeys"
+- reg: the I2C address of the touchkeys
+- interrupts: reference to the interrupt number
+
+Example:
+
+touchkeys@26 {
+       compatible = "dlink,dir685-touchkeys";
+       reg = <0x26>;
+       interrupt-parent = <&gpio0>;
+       interrupts = <17 IRQ_TYPE_EDGE_FALLING>;
+};
diff --git a/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.txt b/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.txt
new file mode 100644 (file)
index 0000000..9683595
--- /dev/null
@@ -0,0 +1,43 @@
+* ST-Microelectronics FingerTip touchscreen controller
+
+The ST-Microelectronics FingerTip device provides a basic touchscreen
+functionality. Along with it the user can enable the touchkey which can work as
+a basic HOME and BACK key for phones.
+
+The driver supports also hovering as an absolute single touch event with x, y, z
+coordinates.
+
+Required properties:
+- compatible           : must be "st,stmfts"
+- reg                  : I2C slave address, (e.g. 0x49)
+- interrupt-parent     : the phandle to the interrupt controller which provides
+                         the interrupt
+- interrupts           : interrupt specification
+- avdd-supply          : analogic power supply
+- vdd-supply           : power supply
+- touchscreen-size-x   : see touchscreen.txt
+- touchscreen-size-y   : see touchscreen.txt
+
+Optional properties:
+- touch-key-connected  : specifies whether the touchkey feature is connected
+- ledvdd-supply                : power supply to the touch key leds
+
+Example:
+
+i2c@00000000 {
+
+       /* ... */
+
+       touchscreen@49 {
+               compatible = "st,stmfts";
+               reg = <0x49>;
+               interrupt-parent = <&gpa1>;
+               interrupts = <1 IRQ_TYPE_NONE>;
+               touchscreen-size-x = <1599>;
+               touchscreen-size-y = <2559>;
+               touch-key-connected;
+               avdd-supply = <&ldo30_reg>;
+               vdd-supply = <&ldo31_reg>;
+               ledvdd-supply = <&ldo33_reg>;
+       };
+};
index 053c3bdd1fe51c1e48983cfa2e3b4b00349035f2..e14c5aa501ef080369a16545729e976cb2a93fb2 100644 (file)
@@ -3786,6 +3786,12 @@ S:       Supported
 F:     drivers/input/touchscreen/cyttsp*
 F:     include/linux/input/cyttsp.h
 
+D-LINK DIR-685 TOUCHKEYS DRIVER
+M:     Linus Walleij <linus.walleij@linaro.org>
+L:     linux-input@vger.kernel.org
+S:     Supported
+F:     drivers/input/dlink-dir685-touchkeys.c
+
 DALLAS/MAXIM DS1685-FAMILY REAL TIME CLOCK
 M:     Joshua Kinard <kumba@gentoo.org>
 S:     Maintained
@@ -6598,8 +6604,10 @@ S:       Maintained
 F:     drivers/input/
 F:     include/linux/input.h
 F:     include/uapi/linux/input.h
+F:     include/uapi/linux/input-event-codes.h
 F:     include/linux/input/
 F:     Documentation/devicetree/bindings/input/
+F:     Documentation/input/
 
 INPUT MULTITOUCH (MT) PROTOCOL
 M:     Henrik Rydberg <rydberg@bitmath.org>
index 6d612792f6b8ec6f41fd720cec952d173e4f5ca2..1faf6cb93dcb5659f1765c4072b93fe8297c0efc 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/usb/r8a66597.h>
 #include <linux/usb/renesas_usbhs.h>
 #include <linux/i2c.h>
-#include <linux/i2c/tsc2007.h>
+#include <linux/platform_data/tsc2007.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/sh_msiof.h>
 #include <linux/spi/mmc_spi.h>
index 067d648028a22ff8963ed12c3a59ae1a0b5e3dfd..7e6842bd525c679a808c0e39bab7c5c4711f72ba 100644 (file)
@@ -481,7 +481,7 @@ EXPORT_SYMBOL(input_inject_event);
 void input_alloc_absinfo(struct input_dev *dev)
 {
        if (!dev->absinfo)
-               dev->absinfo = kcalloc(ABS_CNT, sizeof(struct input_absinfo),
+               dev->absinfo = kcalloc(ABS_CNT, sizeof(*dev->absinfo),
                                        GFP_KERNEL);
 
        WARN(!dev->absinfo, "%s(): kcalloc() failed?\n", __func__);
@@ -1126,7 +1126,7 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
         * If no output was produced print a single 0.
         */
        if (skip_empty)
-               seq_puts(seq, "0");
+               seq_putc(seq, '0');
 
        seq_putc(seq, '\n');
 }
@@ -1144,7 +1144,7 @@ static int input_devices_seq_show(struct seq_file *seq, void *v)
        seq_printf(seq, "P: Phys=%s\n", dev->phys ? dev->phys : "");
        seq_printf(seq, "S: Sysfs=%s\n", path ? path : "");
        seq_printf(seq, "U: Uniq=%s\n", dev->uniq ? dev->uniq : "");
-       seq_printf(seq, "H: Handlers=");
+       seq_puts(seq, "H: Handlers=");
 
        list_for_each_entry(handle, &dev->h_list, d_node)
                seq_printf(seq, "%s ", handle->name);
@@ -1783,7 +1783,7 @@ struct input_dev *input_allocate_device(void)
        static atomic_t input_no = ATOMIC_INIT(-1);
        struct input_dev *dev;
 
-       dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (dev) {
                dev->dev.type = &input_dev_type;
                dev->dev.class = &input_class;
@@ -1849,7 +1849,7 @@ struct input_dev *devm_input_allocate_device(struct device *dev)
        struct input_devres *devres;
 
        devres = devres_alloc(devm_input_device_release,
-                             sizeof(struct input_devres), GFP_KERNEL);
+                             sizeof(*devres), GFP_KERNEL);
        if (!devres)
                return NULL;
 
@@ -2099,7 +2099,7 @@ int input_register_device(struct input_dev *dev)
 
        if (dev->devres_managed) {
                devres = devres_alloc(devm_input_device_unregister,
-                                     sizeof(struct input_devres), GFP_KERNEL);
+                                     sizeof(*devres), GFP_KERNEL);
                if (!devres)
                        return -ENOMEM;
 
index def96cd2479bafa04da2e15557d2bd83ebd123d3..298a6ba51411a2d68795f34b41c380df85fdfbc6 100644 (file)
@@ -126,13 +126,18 @@ static const struct xpad_device {
        u8 mapping;
        u8 xtype;
 } xpad_device[] = {
+       { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX },
+       { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX },
        { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
+       { 0x044f, 0x0f10, "Thrustmaster Modena GT Wheel", 0, XTYPE_XBOX },
        { 0x044f, 0xb326, "Thrustmaster Gamepad GP XID", 0, XTYPE_XBOX360 },
        { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX },
        { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX },
        { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX },
+       { 0x045e, 0x0288, "Microsoft Xbox Controller S v2", 0, XTYPE_XBOX },
        { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX },
        { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
+       { 0x045e, 0x028f, "Microsoft X-Box 360 pad v2", 0, XTYPE_XBOX360 },
        { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
        { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
        { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
@@ -145,28 +150,52 @@ static const struct xpad_device {
        { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 },
        { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX },
        { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX },
+       { 0x046d, 0xca8a, "Logitech Precision Vibration Feedback Wheel", 0, XTYPE_XBOX },
+       { 0x046d, 0xcaa3, "Logitech DriveFx Racing Wheel", 0, XTYPE_XBOX360 },
        { 0x056e, 0x2004, "Elecom JC-U3613M", 0, XTYPE_XBOX360 },
        { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX },
        { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX },
+       { 0x05fe, 0x3030, "Chic Controller", 0, XTYPE_XBOX },
+       { 0x05fe, 0x3031, "Chic Controller", 0, XTYPE_XBOX },
+       { 0x062a, 0x0020, "Logic3 Xbox GamePad", 0, XTYPE_XBOX },
+       { 0x062a, 0x0033, "Competition Pro Steering Wheel", 0, XTYPE_XBOX },
+       { 0x06a3, 0x0200, "Saitek Racing Wheel", 0, XTYPE_XBOX },
+       { 0x06a3, 0x0201, "Saitek Adrenalin", 0, XTYPE_XBOX },
+       { 0x06a3, 0xf51a, "Saitek P3600", 0, XTYPE_XBOX360 },
+       { 0x0738, 0x4506, "Mad Catz 4506 Wireless Controller", 0, XTYPE_XBOX },
        { 0x0738, 0x4516, "Mad Catz Control Pad", 0, XTYPE_XBOX },
+       { 0x0738, 0x4520, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX },
        { 0x0738, 0x4522, "Mad Catz LumiCON", 0, XTYPE_XBOX },
        { 0x0738, 0x4526, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX },
+       { 0x0738, 0x4530, "Mad Catz Universal MC2 Racing Wheel and Pedals", 0, XTYPE_XBOX },
        { 0x0738, 0x4536, "Mad Catz MicroCON", 0, XTYPE_XBOX },
        { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
        { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX },
+       { 0x0738, 0x4586, "Mad Catz MicroCon Wireless Controller", 0, XTYPE_XBOX },
+       { 0x0738, 0x4588, "Mad Catz Blaster", 0, XTYPE_XBOX },
+       { 0x0738, 0x45ff, "Mad Catz Beat Pad (w/ Handle)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
        { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
        { 0x0738, 0x4718, "Mad Catz Street Fighter IV FightStick SE", 0, XTYPE_XBOX360 },
        { 0x0738, 0x4726, "Mad Catz Xbox 360 Controller", 0, XTYPE_XBOX360 },
        { 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x0738, 0x4736, "Mad Catz MicroCon Gamepad", 0, XTYPE_XBOX360 },
        { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x0738, 0x4740, "Mad Catz Beat Pad", 0, XTYPE_XBOX360 },
+       { 0x0738, 0x4743, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+       { 0x0738, 0x4758, "Mad Catz Arcade Game Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x0738, 0x4a01, "Mad Catz FightStick TE 2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
        { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+       { 0x0738, 0x9871, "Mad Catz Portable Drum", 0, XTYPE_XBOX360 },
        { 0x0738, 0xb726, "Mad Catz Xbox controller - MW2", 0, XTYPE_XBOX360 },
+       { 0x0738, 0xb738, "Mad Catz MVC2TE Stick 2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", XTYPE_XBOX360 },
        { 0x0738, 0xcb02, "Saitek Cyborg Rumble Pad - PC/Xbox 360", 0, XTYPE_XBOX360 },
        { 0x0738, 0xcb03, "Saitek P3200 Rumble Pad - PC/Xbox 360", 0, XTYPE_XBOX360 },
+       { 0x0738, 0xcb29, "Saitek Aviator Stick AV8R02", 0, XTYPE_XBOX360 },
        { 0x0738, 0xf738, "Super SFIV FightStick TE S", 0, XTYPE_XBOX360 },
+       { 0x07ff, 0xffff, "Mad Catz GamePad", 0, XTYPE_XBOX360 },
+       { 0x0c12, 0x0005, "Intec wireless", 0, XTYPE_XBOX },
+       { 0x0c12, 0x8801, "Nyko Xbox Controller", 0, XTYPE_XBOX },
        { 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
        { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", DANCEPAD_MAP_CONFIG, XTYPE_XBOX },
        { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX },
@@ -174,37 +203,63 @@ static const struct xpad_device {
        { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX },
        { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
        { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX },
+       { 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX },
        { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX },
+       { 0x0e4c, 0x3510, "Radica Gamester", 0, XTYPE_XBOX },
        { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX },
        { 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX },
        { 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX },
+       { 0x0e6f, 0x0008, "After Glow Pro Controller", 0, XTYPE_XBOX },
        { 0x0e6f, 0x0105, "HSM3 Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x0e6f, 0x0113, "Afterglow AX.1 Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
        { 0x0e6f, 0x011f, "Rock Candy Gamepad Wired Controller", 0, XTYPE_XBOX360 },
+       { 0x0e6f, 0x0131, "PDP EA Sports Controller", 0, XTYPE_XBOX360 },
+       { 0x0e6f, 0x0133, "Xbox 360 Wired Controller", 0, XTYPE_XBOX360 },
        { 0x0e6f, 0x0139, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x013a, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
        { 0x0e6f, 0x0146, "Rock Candy Wired Controller for Xbox One", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x0147, "PDP Marvel Xbox One Controller", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x015c, "PDP Xbox One Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
+       { 0x0e6f, 0x0161, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x0162, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x0163, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x0164, "PDP Battlefield One", 0, XTYPE_XBOXONE },
+       { 0x0e6f, 0x0165, "PDP Titanfall 2", 0, XTYPE_XBOXONE },
        { 0x0e6f, 0x0201, "Pelican PL-3601 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
        { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
        { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
+       { 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE },
        { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 },
+       { 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE },
        { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 },
        { 0x0e6f, 0x0413, "Afterglow AX.1 Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
+       { 0x0e6f, 0x0501, "PDP Xbox 360 Controller", 0, XTYPE_XBOX360 },
+       { 0x0e6f, 0xf900, "PDP Afterglow AX.1", 0, XTYPE_XBOX360 },
        { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX },
        { 0x0e8f, 0x3008, "Generic xbox control (dealextreme)", 0, XTYPE_XBOX },
        { 0x0f0d, 0x000a, "Hori Co. DOA4 FightStick", 0, XTYPE_XBOX360 },
+       { 0x0f0d, 0x000c, "Hori PadEX Turbo", 0, XTYPE_XBOX360 },
        { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x0f0d, 0x001b, "Hori Real Arcade Pro VX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x0f0d, 0x0063, "Hori Real Arcade Pro Hayabusa (USA) Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
        { 0x0f0d, 0x0067, "HORIPAD ONE", 0, XTYPE_XBOXONE },
+       { 0x0f0d, 0x0078, "Hori Real Arcade Pro V Kai Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
+       { 0x0f30, 0x010b, "Philips Recoil", 0, XTYPE_XBOX },
        { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
        { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
        { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX },
+       { 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 },
        { 0x12ab, 0x0004, "Honey Bee Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x12ab, 0x0301, "PDP AFTERGLOW AX.1", 0, XTYPE_XBOX360 },
+       { 0x12ab, 0x0303, "Mortal Kombat Klassic FightStick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
        { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 },
        { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+       { 0x1430, 0xf801, "RedOctane Controller", 0, XTYPE_XBOX360 },
        { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
        { 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+       { 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
        { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE },
        { 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 },
        { 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
@@ -215,22 +270,44 @@ static const struct xpad_device {
        { 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 },
        { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 },
        { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0x0130, "Ion Drum Rocker", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x1bad, 0xf016, "Mad Catz Xbox 360 Controller", 0, XTYPE_XBOX360 },
        { 0x1bad, 0xf018, "Mad Catz Street Fighter IV SE Fighting Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x1bad, 0xf019, "Mad Catz Brawlstick for Xbox 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x1bad, 0xf021, "Mad Cats Ghost Recon FS GamePad", 0, XTYPE_XBOX360 },
        { 0x1bad, 0xf023, "MLG Pro Circuit Controller (Xbox)", 0, XTYPE_XBOX360 },
+       { 0x1bad, 0xf025, "Mad Catz Call Of Duty", 0, XTYPE_XBOX360 },
+       { 0x1bad, 0xf027, "Mad Catz FPS Pro", 0, XTYPE_XBOX360 },
        { 0x1bad, 0xf028, "Street Fighter IV FightPad", 0, XTYPE_XBOX360 },
        { 0x1bad, 0xf02e, "Mad Catz Fightpad", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0xf030, "Mad Catz Xbox 360 MC2 MicroCon Racing Wheel", 0, XTYPE_XBOX360 },
+       { 0x1bad, 0xf036, "Mad Catz MicroCon GamePad Pro", 0, XTYPE_XBOX360 },
        { 0x1bad, 0xf038, "Street Fighter IV FightStick TE", 0, XTYPE_XBOX360 },
+       { 0x1bad, 0xf039, "Mad Catz MvC2 TE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x1bad, 0xf03a, "Mad Catz SFxT Fightstick Pro", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0xf03d, "Street Fighter IV Arcade Stick TE - Chun Li", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0xf03e, "Mad Catz MLG FightStick TE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0xf03f, "Mad Catz FightStick SoulCaliber", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0xf042, "Mad Catz FightStick TES+", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0xf080, "Mad Catz FightStick TE2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0xf501, "HoriPad EX2 Turbo", 0, XTYPE_XBOX360 },
+       { 0x1bad, 0xf502, "Hori Real Arcade Pro.VX SA", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0xf503, "Hori Fighting Stick VX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0xf504, "Hori Real Arcade Pro. EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0xf505, "Hori Fighting Stick EX2B", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x1bad, 0xf506, "Hori Real Arcade Pro.EX Premium VLX", 0, XTYPE_XBOX360 },
        { 0x1bad, 0xf900, "Harmonix Xbox 360 Controller", 0, XTYPE_XBOX360 },
        { 0x1bad, 0xf901, "Gamestop Xbox 360 Controller", 0, XTYPE_XBOX360 },
        { 0x1bad, 0xf903, "Tron Xbox 360 controller", 0, XTYPE_XBOX360 },
+       { 0x1bad, 0xf904, "PDP Versus Fighting Pad", 0, XTYPE_XBOX360 },
+       { 0x1bad, 0xf906, "MortalKombat FightStick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x1bad, 0xfa01, "MadCatz GamePad", 0, XTYPE_XBOX360 },
+       { 0x1bad, 0xfd00, "Razer Onza TE", 0, XTYPE_XBOX360 },
+       { 0x1bad, 0xfd01, "Razer Onza", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
+       { 0x24c6, 0x530a, "Xbox 360 Pro EX Controller", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x531a, "PowerA Pro Ex", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x5397, "FUS1ON Tournament Controller", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x541a, "PowerA Xbox One Mini Wired Controller", 0, XTYPE_XBOXONE },
@@ -238,12 +315,19 @@ static const struct xpad_device {
        { 0x24c6, 0x543a, "PowerA Xbox One wired controller", 0, XTYPE_XBOXONE },
        { 0x24c6, 0x5500, "Hori XBOX 360 EX 2 with Turbo", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x5501, "Hori Real Arcade Pro VX-SA", 0, XTYPE_XBOX360 },
+       { 0x24c6, 0x5502, "Hori Fighting Stick VX Alt", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x24c6, 0x5503, "Hori Fighting Edge", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
        { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x550d, "Hori GEM Xbox controller", 0, XTYPE_XBOX360 },
+       { 0x24c6, 0x550e, "Hori Real Arcade Pro V Kai 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+       { 0x24c6, 0x551a, "PowerA FUSION Pro Controller", 0, XTYPE_XBOXONE },
+       { 0x24c6, 0x561a, "PowerA FUSION Controller", 0, XTYPE_XBOXONE },
+       { 0x24c6, 0x5b00, "ThrustMaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x5b02, "Thrustmaster, Inc. GPX Controller", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x5b03, "Thrustmaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+       { 0x24c6, 0xfafe, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
+       { 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX },
        { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
        { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
 };
@@ -331,13 +415,16 @@ static struct usb_device_id xpad_table[] = {
        XPAD_XBOXONE_VENDOR(0x045e),            /* Microsoft X-Box One controllers */
        XPAD_XBOX360_VENDOR(0x046d),            /* Logitech X-Box 360 style controllers */
        XPAD_XBOX360_VENDOR(0x056e),            /* Elecom JC-U3613M */
+       XPAD_XBOX360_VENDOR(0x06a3),            /* Saitek P3600 */
        XPAD_XBOX360_VENDOR(0x0738),            /* Mad Catz X-Box 360 controllers */
        { USB_DEVICE(0x0738, 0x4540) },         /* Mad Catz Beat Pad */
        XPAD_XBOXONE_VENDOR(0x0738),            /* Mad Catz FightStick TE 2 */
+       XPAD_XBOX360_VENDOR(0x07ff),            /* Mad Catz GamePad */
        XPAD_XBOX360_VENDOR(0x0e6f),            /* 0x0e6f X-Box 360 controllers */
        XPAD_XBOXONE_VENDOR(0x0e6f),            /* 0x0e6f X-Box One controllers */
        XPAD_XBOX360_VENDOR(0x0f0d),            /* Hori Controllers */
        XPAD_XBOXONE_VENDOR(0x0f0d),            /* Hori Controllers */
+       XPAD_XBOX360_VENDOR(0x11c9),            /* Nacon GC100XF */
        XPAD_XBOX360_VENDOR(0x12ab),            /* X-Box 360 dance pads */
        XPAD_XBOX360_VENDOR(0x1430),            /* RedOctane X-Box 360 controllers */
        XPAD_XBOX360_VENDOR(0x146b),            /* BigBen Interactive Controllers */
index 97acd6524ad7c37bc93cb3acc070fb171f76520c..4c4ab1ced2354853c3fb3187a1c175db4cc0cccb 100644 (file)
@@ -178,6 +178,17 @@ config KEYBOARD_CLPS711X
          To compile this driver as a module, choose M here: the
          module will be called clps711x-keypad.
 
+config KEYBOARD_DLINK_DIR685
+       tristate "D-Link DIR-685 touchkeys support"
+       depends on I2C
+       default ARCH_GEMINI
+       help
+         If you say yes here you get support for the D-Link DIR-685
+         touchkeys.
+
+         To compile this driver as a module, choose M here: the
+         module will be called dlink-dir685-touchkeys.
+
 config KEYBOARD_LKKBD
        tristate "DECstation/VAXstation LK201/LK401 keyboard"
        select SERIO
index 7d9acff819a7899c0b8031554a073136cc8a1377..d2338bacdad18b7086dc0e3f77e85f357c221df3 100644 (file)
@@ -17,6 +17,7 @@ obj-$(CONFIG_KEYBOARD_CAP11XX)                += cap11xx.o
 obj-$(CONFIG_KEYBOARD_CLPS711X)                += clps711x-keypad.o
 obj-$(CONFIG_KEYBOARD_CROS_EC)         += cros_ec_keyb.o
 obj-$(CONFIG_KEYBOARD_DAVINCI)         += davinci_keyscan.o
+obj-$(CONFIG_KEYBOARD_DLINK_DIR685)    += dlink-dir685-touchkeys.o
 obj-$(CONFIG_KEYBOARD_EP93XX)          += ep93xx_keypad.o
 obj-$(CONFIG_KEYBOARD_GOLDFISH_EVENTS) += goldfish_events.o
 obj-$(CONFIG_KEYBOARD_GPIO)            += gpio_keys.o
diff --git a/drivers/input/keyboard/dlink-dir685-touchkeys.c b/drivers/input/keyboard/dlink-dir685-touchkeys.c
new file mode 100644 (file)
index 0000000..88e321b
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * D-Link DIR-685 router I2C-based Touchkeys input driver
+ * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
+ *
+ * This is a one-off touchkey controller based on the Cypress Semiconductor
+ * CY8C214 MCU with some firmware in its internal 8KB flash. The circuit
+ * board inside the router is named E119921
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+
+struct dir685_touchkeys {
+       struct device           *dev;
+       struct i2c_client       *client;
+       struct input_dev        *input;
+       unsigned long           cur_key;
+       u16                     codes[7];
+};
+
+static irqreturn_t dir685_tk_irq_thread(int irq, void *data)
+{
+       struct dir685_touchkeys *tk = data;
+       const int num_bits = min_t(int, ARRAY_SIZE(tk->codes), 16);
+       unsigned long changed;
+       u8 buf[6];
+       unsigned long key;
+       int i;
+       int err;
+
+       memset(buf, 0, sizeof(buf));
+       err = i2c_master_recv(tk->client, buf, sizeof(buf));
+       if (err != sizeof(buf)) {
+               dev_err(tk->dev, "short read %d\n", err);
+               return IRQ_HANDLED;
+       }
+
+       dev_dbg(tk->dev, "IN: %*ph\n", (int)sizeof(buf), buf);
+       key = be16_to_cpup((__be16 *) &buf[4]);
+
+       /* Figure out if any bits went high or low since last message */
+       changed = tk->cur_key ^ key;
+       for_each_set_bit(i, &changed, num_bits) {
+               dev_dbg(tk->dev, "key %d is %s\n", i,
+                       test_bit(i, &key) ? "down" : "up");
+               input_report_key(tk->input, tk->codes[i], test_bit(i, &key));
+       }
+
+       /* Store currently down keys */
+       tk->cur_key = key;
+       input_sync(tk->input);
+
+       return IRQ_HANDLED;
+}
+
+static int dir685_tk_probe(struct i2c_client *client,
+                          const struct i2c_device_id *id)
+{
+       struct dir685_touchkeys *tk;
+       struct device *dev = &client->dev;
+       u8 bl_data[] = { 0xa7, 0x40 };
+       int err;
+       int i;
+
+       tk = devm_kzalloc(&client->dev, sizeof(*tk), GFP_KERNEL);
+       if (!tk)
+               return -ENOMEM;
+
+       tk->input = devm_input_allocate_device(dev);
+       if (!tk->input)
+               return -ENOMEM;
+
+       tk->client = client;
+       tk->dev = dev;
+
+       tk->input->keycodesize = sizeof(u16);
+       tk->input->keycodemax = ARRAY_SIZE(tk->codes);
+       tk->input->keycode = tk->codes;
+       tk->codes[0] = KEY_UP;
+       tk->codes[1] = KEY_DOWN;
+       tk->codes[2] = KEY_LEFT;
+       tk->codes[3] = KEY_RIGHT;
+       tk->codes[4] = KEY_ENTER;
+       tk->codes[5] = KEY_WPS_BUTTON;
+       /*
+        * This key appears in the vendor driver, but I have
+        * not been able to activate it.
+        */
+       tk->codes[6] = KEY_RESERVED;
+
+       __set_bit(EV_KEY, tk->input->evbit);
+       for (i = 0; i < ARRAY_SIZE(tk->codes); i++)
+               __set_bit(tk->codes[i], tk->input->keybit);
+       __clear_bit(KEY_RESERVED, tk->input->keybit);
+
+       tk->input->name = "D-Link DIR-685 touchkeys";
+       tk->input->id.bustype = BUS_I2C;
+
+       err = input_register_device(tk->input);
+       if (err)
+               return err;
+
+       /* Set the brightness to max level */
+       err = i2c_master_send(client, bl_data, sizeof(bl_data));
+       if (err != sizeof(bl_data))
+               dev_warn(tk->dev, "error setting brightness level\n");
+
+       if (!client->irq) {
+               dev_err(dev, "no IRQ on the I2C device\n");
+               return -ENODEV;
+       }
+       err = devm_request_threaded_irq(dev, client->irq,
+                                       NULL, dir685_tk_irq_thread,
+                                       IRQF_ONESHOT,
+                                       "dir685-tk", tk);
+       if (err) {
+               dev_err(dev, "can't request IRQ\n");
+               return err;
+       }
+
+       return 0;
+}
+
+static const struct i2c_device_id dir685_tk_id[] = {
+       { "dir685tk", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, dir685_tk_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id dir685_tk_of_match[] = {
+       { .compatible = "dlink,dir685-touchkeys" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, dir685_tk_of_match);
+#endif
+
+static struct i2c_driver dir685_tk_i2c_driver = {
+       .driver = {
+               .name   = "dlin-dir685-touchkeys",
+               .of_match_table = of_match_ptr(dir685_tk_of_match),
+       },
+       .probe          = dir685_tk_probe,
+       .id_table       = dir685_tk_id,
+};
+module_i2c_driver(dir685_tk_i2c_driver);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
+MODULE_DESCRIPTION("D-Link DIR-685 touchkeys driver");
+MODULE_LICENSE("GPL");
index 21bea52d4365797a602f27e2f2f7c514540c0120..04a5d7e134d72490bb8511754930f612db1978a1 100644 (file)
@@ -30,8 +30,8 @@
 #include <linux/delay.h>
 #include <linux/input.h>
 #include <linux/leds.h>
+#include <linux/platform_data/lm8323.h>
 #include <linux/pm.h>
-#include <linux/i2c/lm8323.h>
 #include <linux/slab.h>
 
 /* Commands to send to the chip. */
index 31090d71a685d18fe7bc0093b1927f304e3de7eb..be56d4f262a7e8ac0169b97698db2d6897acb2d4 100644 (file)
 
 #include <linux/module.h>
 #include <linux/i2c.h>
-#include <linux/i2c/mcs.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
+#include <linux/platform_data/mcs.h>
 #include <linux/pm.h>
 
 /* MCS5000 Touchkey */
index 400869e61a0663be592e723f8f9de4f3596aaf3d..38c79ebff0333f131923d96edec89d7771c7a7c7 100644 (file)
@@ -253,6 +253,9 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
                return error;
        }
 
+       if (axp20x_pek->axp20x->variant == AXP288_ID)
+               enable_irq_wake(axp20x_pek->irq_dbr);
+
        return 0;
 }
 
@@ -331,10 +334,35 @@ static int axp20x_pek_probe(struct platform_device *pdev)
        return 0;
 }
 
+static int __maybe_unused axp20x_pek_resume_noirq(struct device *dev)
+{
+       struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
+
+       if (axp20x_pek->axp20x->variant != AXP288_ID)
+               return 0;
+
+       /*
+        * Clear interrupts from button presses during suspend, to avoid
+        * a wakeup power-button press getting reported to userspace.
+        */
+       regmap_write(axp20x_pek->axp20x->regmap,
+                    AXP20X_IRQ1_STATE + AXP288_IRQ_POKN / 8,
+                    BIT(AXP288_IRQ_POKN % 8));
+
+       return 0;
+}
+
+static const struct dev_pm_ops axp20x_pek_pm_ops = {
+#ifdef CONFIG_PM_SLEEP
+       .resume_noirq = axp20x_pek_resume_noirq,
+#endif
+};
+
 static struct platform_driver axp20x_pek_driver = {
        .probe          = axp20x_pek_probe,
        .driver         = {
                .name           = "axp20x-pek",
+               .pm             = &axp20x_pek_pm_ops,
        },
 };
 module_platform_driver(axp20x_pek_driver);
index 690148f9940ed009c671aca3c37ac51b175bd7d9..eb770613a9bd847930cf295aff81e25a6673d3f1 100644 (file)
@@ -135,14 +135,17 @@ static int xenkbd_probe(struct xenbus_device *dev,
                goto error_nomem;
 
        /* Set input abs params to match backend screen res */
-       abs = xenbus_read_unsigned(dev->otherend, "feature-abs-pointer", 0);
-       ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend, "width",
+       abs = xenbus_read_unsigned(dev->otherend,
+                                  XENKBD_FIELD_FEAT_ABS_POINTER, 0);
+       ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend,
+                                                 XENKBD_FIELD_WIDTH,
                                                  ptr_size[KPARAM_X]);
-       ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend, "height",
+       ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend,
+                                                 XENKBD_FIELD_HEIGHT,
                                                  ptr_size[KPARAM_Y]);
        if (abs) {
                ret = xenbus_write(XBT_NIL, dev->nodename,
-                                  "request-abs-pointer", "1");
+                                  XENKBD_FIELD_REQ_ABS_POINTER, "1");
                if (ret) {
                        pr_warn("xenkbd: can't request abs-pointer\n");
                        abs = 0;
@@ -271,14 +274,15 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
                xenbus_dev_fatal(dev, ret, "starting transaction");
                goto error_irqh;
        }
-       ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
+       ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_REF, "%lu",
                            virt_to_gfn(info->page));
        if (ret)
                goto error_xenbus;
-       ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", info->gref);
+       ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_GREF,
+                           "%u", info->gref);
        if (ret)
                goto error_xenbus;
-       ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
+       ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_EVT_CHANNEL, "%u",
                            evtchn);
        if (ret)
                goto error_xenbus;
@@ -353,7 +357,7 @@ static void xenkbd_backend_changed(struct xenbus_device *dev,
 }
 
 static const struct xenbus_device_id xenkbd_ids[] = {
-       { "vkbd" },
+       { XENKBD_DRIVER_NAME },
        { "" }
 };
 
@@ -390,4 +394,4 @@ module_exit(xenkbd_cleanup);
 
 MODULE_DESCRIPTION("Xen virtual keyboard/pointer device frontend");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("xen:vkbd");
+MODULE_ALIAS("xen:" XENKBD_DRIVER_NAME);
index c0ec26118732879f7674f68bd0458b3d27602f61..61c2024362508548a076dcc1dd9a1d22e3bbf27a 100644 (file)
@@ -58,7 +58,7 @@ struct elan_transport_ops {
 
        int (*get_version)(struct i2c_client *client, bool iap, u8 *version);
        int (*get_sm_version)(struct i2c_client *client,
-                             u8* ic_type, u8 *version);
+                             u16 *ic_type, u8 *version);
        int (*get_checksum)(struct i2c_client *client, bool iap, u16 *csum);
        int (*get_product_id)(struct i2c_client *client, u16 *id);
 
@@ -82,6 +82,7 @@ struct elan_transport_ops {
        int (*get_report)(struct i2c_client *client, u8 *report);
        int (*get_pressure_adjustment)(struct i2c_client *client,
                                       int *adjustment);
+       int (*get_pattern)(struct i2c_client *client, u8 *pattern);
 };
 
 extern const struct elan_transport_ops elan_smbus_ops, elan_i2c_ops;
index d5ab9ddef3e37eeb553307c7406adc1f2c011057..3b616cb7c67f88512e82dbc8ba5f61e565cbd2a5 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
  * Author: KT Liao <kt.liao@emc.com.tw>
- * Version: 1.6.2
+ * Version: 1.6.3
  *
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -41,7 +41,7 @@
 #include "elan_i2c.h"
 
 #define DRIVER_NAME            "elan_i2c"
-#define ELAN_DRIVER_VERSION    "1.6.2"
+#define ELAN_DRIVER_VERSION    "1.6.3"
 #define ELAN_VENDOR_ID         0x04f3
 #define ETP_MAX_PRESSURE       255
 #define ETP_FWIDTH_REDUCE      90
@@ -78,6 +78,7 @@ struct elan_tp_data {
        unsigned int            x_res;
        unsigned int            y_res;
 
+       u8                      pattern;
        u16                     product_id;
        u8                      fw_version;
        u8                      sm_version;
@@ -85,7 +86,7 @@ struct elan_tp_data {
        u16                     fw_checksum;
        int                     pressure_adjustment;
        u8                      mode;
-       u                     ic_type;
+       u16                     ic_type;
        u16                     fw_validpage_count;
        u16                     fw_signature_address;
 
@@ -96,10 +97,10 @@ struct elan_tp_data {
        bool                    baseline_ready;
 };
 
-static int elan_get_fwinfo(u8 iap_version, u16 *validpage_count,
+static int elan_get_fwinfo(u16 ic_type, u16 *validpage_count,
                           u16 *signature_address)
 {
-       switch (iap_version) {
+       switch (ic_type) {
        case 0x00:
        case 0x06:
        case 0x08:
@@ -119,6 +120,9 @@ static int elan_get_fwinfo(u8 iap_version, u16 *validpage_count,
        case 0x0E:
                *validpage_count = 640;
                break;
+       case 0x10:
+               *validpage_count = 1024;
+               break;
        default:
                /* unknown ic type clear value */
                *validpage_count = 0;
@@ -305,6 +309,7 @@ static int elan_initialize(struct elan_tp_data *data)
 static int elan_query_device_info(struct elan_tp_data *data)
 {
        int error;
+       u16 ic_type;
 
        error = data->ops->get_version(data->client, false, &data->fw_version);
        if (error)
@@ -324,7 +329,16 @@ static int elan_query_device_info(struct elan_tp_data *data)
        if (error)
                return error;
 
-       error = elan_get_fwinfo(data->iap_version, &data->fw_validpage_count,
+       error = data->ops->get_pattern(data->client, &data->pattern);
+       if (error)
+               return error;
+
+       if (data->pattern == 0x01)
+               ic_type = data->ic_type;
+       else
+               ic_type = data->iap_version;
+
+       error = elan_get_fwinfo(ic_type, &data->fw_validpage_count,
                                &data->fw_signature_address);
        if (error)
                dev_warn(&data->client->dev,
@@ -1077,6 +1091,13 @@ static int elan_probe(struct i2c_client *client,
                return error;
        }
 
+       /* Make sure there is something at this address */
+       error = i2c_smbus_read_byte(client);
+       if (error < 0) {
+               dev_dbg(&client->dev, "nothing at this address: %d\n", error);
+               return -ENXIO;
+       }
+
        /* Initialize the touchpad. */
        error = elan_initialize(data);
        if (error)
@@ -1101,10 +1122,13 @@ static int elan_probe(struct i2c_client *client,
                "Elan Touchpad Extra Information:\n"
                "    Max ABS X,Y:   %d,%d\n"
                "    Width X,Y:   %d,%d\n"
-               "    Resolution X,Y:   %d,%d (dots/mm)\n",
+               "    Resolution X,Y:   %d,%d (dots/mm)\n"
+               "    ic type: 0x%x\n"
+               "    info pattern: 0x%x\n",
                data->max_x, data->max_y,
                data->width_x, data->width_y,
-               data->x_res, data->y_res);
+               data->x_res, data->y_res,
+               data->ic_type, data->pattern);
 
        /* Set up input device properties based on queried parameters. */
        error = elan_setup_input_device(data);
index f431da07f861e50fa86574954f7e4b0c2c1e57c3..80172f25974db01e1c39e9db3688b4b48b723dad 100644 (file)
 #define ETP_I2C_DESC_CMD               0x0001
 #define ETP_I2C_REPORT_DESC_CMD                0x0002
 #define ETP_I2C_STAND_CMD              0x0005
+#define ETP_I2C_PATTERN_CMD            0x0100
 #define ETP_I2C_UNIQUEID_CMD           0x0101
 #define ETP_I2C_FW_VERSION_CMD         0x0102
-#define ETP_I2C_SM_VERSION_CMD         0x0103
+#define ETP_I2C_IC_TYPE_CMD            0x0103
+#define ETP_I2C_OSM_VERSION_CMD                0x0103
+#define ETP_I2C_NSM_VERSION_CMD                0x0104
 #define ETP_I2C_XY_TRACENUM_CMD                0x0105
 #define ETP_I2C_MAX_X_AXIS_CMD         0x0106
 #define ETP_I2C_MAX_Y_AXIS_CMD         0x0107
@@ -239,12 +242,34 @@ static int elan_i2c_get_baseline_data(struct i2c_client *client,
        return 0;
 }
 
+static int elan_i2c_get_pattern(struct i2c_client *client, u8 *pattern)
+{
+       int error;
+       u8 val[3];
+
+       error = elan_i2c_read_cmd(client, ETP_I2C_PATTERN_CMD, val);
+       if (error) {
+               dev_err(&client->dev, "failed to get pattern: %d\n", error);
+               return error;
+       }
+       *pattern = val[1];
+
+       return 0;
+}
+
 static int elan_i2c_get_version(struct i2c_client *client,
                                bool iap, u8 *version)
 {
        int error;
+       u8 pattern_ver;
        u8 val[3];
 
+       error = elan_i2c_get_pattern(client, &pattern_ver);
+       if (error) {
+               dev_err(&client->dev, "failed to get pattern version\n");
+               return error;
+       }
+
        error = elan_i2c_read_cmd(client,
                                  iap ? ETP_I2C_IAP_VERSION_CMD :
                                        ETP_I2C_FW_VERSION_CMD,
@@ -255,24 +280,54 @@ static int elan_i2c_get_version(struct i2c_client *client,
                return error;
        }
 
-       *version = val[0];
+       if (pattern_ver == 0x01)
+               *version = iap ? val[1] : val[0];
+       else
+               *version = val[0];
        return 0;
 }
 
 static int elan_i2c_get_sm_version(struct i2c_client *client,
-                                  u8 *ic_type, u8 *version)
+                                  u16 *ic_type, u8 *version)
 {
        int error;
+       u8 pattern_ver;
        u8 val[3];
 
-       error = elan_i2c_read_cmd(client, ETP_I2C_SM_VERSION_CMD, val);
+       error = elan_i2c_get_pattern(client, &pattern_ver);
        if (error) {
-               dev_err(&client->dev, "failed to get SM version: %d\n", error);
+               dev_err(&client->dev, "failed to get pattern version\n");
                return error;
        }
 
-       *version = val[0];
-       *ic_type = val[1];
+       if (pattern_ver == 0x01) {
+               error = elan_i2c_read_cmd(client, ETP_I2C_IC_TYPE_CMD, val);
+               if (error) {
+                       dev_err(&client->dev, "failed to get ic type: %d\n",
+                               error);
+                       return error;
+               }
+               *ic_type = be16_to_cpup((__be16 *)val);
+
+               error = elan_i2c_read_cmd(client, ETP_I2C_NSM_VERSION_CMD,
+                                         val);
+               if (error) {
+                       dev_err(&client->dev, "failed to get SM version: %d\n",
+                               error);
+                       return error;
+               }
+               *version = val[1];
+       } else {
+               error = elan_i2c_read_cmd(client, ETP_I2C_OSM_VERSION_CMD, val);
+               if (error) {
+                       dev_err(&client->dev, "failed to get SM version: %d\n",
+                               error);
+                       return error;
+               }
+               *version = val[0];
+               *ic_type = val[1];
+       }
+
        return 0;
 }
 
@@ -641,5 +696,7 @@ const struct elan_transport_ops elan_i2c_ops = {
        .write_fw_block         = elan_i2c_write_fw_block,
        .finish_fw_update       = elan_i2c_finish_fw_update,
 
+       .get_pattern            = elan_i2c_get_pattern,
+
        .get_report             = elan_i2c_get_report,
 };
index e23b2495d52e1558f2b6dc8ff7128550f0e9dae0..df7a57ca73318849d6519f661802ea933ff007d3 100644 (file)
@@ -166,7 +166,7 @@ static int elan_smbus_get_version(struct i2c_client *client,
 }
 
 static int elan_smbus_get_sm_version(struct i2c_client *client,
-                                    u8 *ic_type, u8 *version)
+                                    u16 *ic_type, u8 *version)
 {
        int error;
        u8 val[3];
@@ -495,6 +495,12 @@ static int elan_smbus_finish_fw_update(struct i2c_client *client,
        return 0;
 }
 
+static int elan_smbus_get_pattern(struct i2c_client *client, u8 *pattern)
+{
+       *pattern = 0;
+       return 0;
+}
+
 const struct elan_transport_ops elan_smbus_ops = {
        .initialize             = elan_smbus_initialize,
        .sleep_control          = elan_smbus_sleep_control,
@@ -524,4 +530,5 @@ const struct elan_transport_ops elan_smbus_ops = {
        .finish_fw_update       = elan_smbus_finish_fw_update,
 
        .get_report             = elan_smbus_get_report,
+       .get_pattern            = elan_smbus_get_pattern,
 };
index f1fa1f172107722ef13d8c98e0c2d539d096c2aa..791993215ea34c8f88242ea94719746db240742d 100644 (file)
@@ -1711,6 +1711,17 @@ int elantech_init(struct psmouse *psmouse)
                             etd->samples[0], etd->samples[1], etd->samples[2]);
        }
 
+       if (etd->samples[1] == 0x74 && etd->hw_version == 0x03) {
+               /*
+                * This module has a bug which makes absolute mode
+                * unusable, so let's abort so we'll be using standard
+                * PS/2 protocol.
+                */
+               psmouse_info(psmouse,
+                            "absolute mode broken, forcing standard PS/2 protocol\n");
+               goto init_fail;
+       }
+
        if (elantech_set_absolute_mode(psmouse)) {
                psmouse_err(psmouse,
                            "failed to put touchpad into absolute mode.\n");
index 10c0d11b72c992e248f84418dd6d1e98cf1b10fe..3991d2943660c56d189fba623efbe014ee0d586b 100644 (file)
@@ -9,13 +9,14 @@
  * the Free Software Foundation.
  */
 
+#include <linux/bitops.h>
 #include <linux/kernel.h>
 #include <linux/rmi.h>
 #include <linux/firmware.h>
-#include <asm/unaligned.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
+#include <asm/unaligned.h>
 
 #include "rmi_driver.h"
 #include "rmi_f34.h"
@@ -464,7 +465,7 @@ static int rmi_f34v7_read_queries_bl_version(struct f34_data *f34)
 static int rmi_f34v7_read_queries(struct f34_data *f34)
 {
        int ret;
-       int i, j;
+       int i;
        u8 base;
        int offset;
        u8 *ptable;
@@ -518,10 +519,7 @@ static int rmi_f34v7_read_queries(struct f34_data *f34)
                        query_1_7.partition_support[1] & HAS_GUEST_CODE;
 
        if (query_0 & HAS_CONFIG_ID) {
-               char f34_ctrl[CONFIG_ID_SIZE];
-               int i = 0;
-               u8 *p = f34->configuration_id;
-               *p = '\0';
+               u8 f34_ctrl[CONFIG_ID_SIZE];
 
                ret = rmi_read_block(f34->fn->rmi_dev,
                                f34->fn->fd.control_base_addr,
@@ -531,13 +529,11 @@ static int rmi_f34v7_read_queries(struct f34_data *f34)
                        return ret;
 
                /* Eat leading zeros */
-               while (i < sizeof(f34_ctrl) && !f34_ctrl[i])
-                       i++;
+               for (i = 0; i < sizeof(f34_ctrl) - 1 && !f34_ctrl[i]; i++)
+                       /* Empty */;
 
-               for (; i < sizeof(f34_ctrl); i++)
-                       p += snprintf(p, f34->configuration_id
-                                     + sizeof(f34->configuration_id) - p,
-                                     "%02X", f34_ctrl[i]);
+               snprintf(f34->configuration_id, sizeof(f34->configuration_id),
+                        "%*phN", (int)sizeof(f34_ctrl) - i, f34_ctrl + i);
 
                rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "Configuration ID: %s\n",
                        f34->configuration_id);
@@ -545,9 +541,7 @@ static int rmi_f34v7_read_queries(struct f34_data *f34)
 
        f34->v7.partitions = 0;
        for (i = 0; i < sizeof(query_1_7.partition_support); i++)
-               for (j = 0; j < 8; j++)
-                       if (query_1_7.partition_support[i] & (1 << j))
-                               f34->v7.partitions++;
+               f34->v7.partitions += hweight8(query_1_7.partition_support[i]);
 
        rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: Supported partitions: %*ph\n",
                __func__, sizeof(query_1_7.partition_support),
index 12a3ad83296da259306a3bd6c2d934c0e862695d..bb0349fa64bc349c130d4f77a96fd7f3a1d525ca 100644 (file)
@@ -223,20 +223,6 @@ int sparse_keymap_setup(struct input_dev *dev,
 }
 EXPORT_SYMBOL(sparse_keymap_setup);
 
-/**
- * sparse_keymap_free - free memory allocated for sparse keymap
- * @dev: Input device using sparse keymap
- *
- * This function used to free memory allocated by sparse keymap
- * in an input device that was set up by sparse_keymap_setup().
- * Since sparse_keymap_setup() now uses a managed allocation for the
- * keymap copy, use of this function is deprecated.
- */
-void sparse_keymap_free(struct input_dev *dev)
-{
-}
-EXPORT_SYMBOL(sparse_keymap_free);
-
 /**
  * sparse_keymap_report_entry - report event corresponding to given key entry
  * @dev: Input device for which event should be reported
index cf26ca49ae6d623d44d68e654c20082e7cf09d9e..64b30fe273fd7ba17312402c0efc9e81b77e94bb 100644 (file)
@@ -1114,6 +1114,17 @@ config TOUCHSCREEN_ST1232
          To compile this driver as a module, choose M here: the
          module will be called st1232_ts.
 
+config TOUCHSCREEN_STMFTS
+       tristate "STMicroelectronics STMFTS touchscreen"
+       depends on I2C
+       depends on LEDS_CLASS
+       help
+         Say Y here if you want support for STMicroelectronics
+         STMFTS touchscreen.
+
+         To compile this driver as a module, choose M here: the
+         module will be called stmfts.
+
 config TOUCHSCREEN_STMPE
        tristate "STMicroelectronics STMPE touchscreens"
        depends on MFD_STMPE
index 18e476948e44e4a44b16acb9e96887ee4a88b606..6badce87037b54bcea7c91f5ddbaebca4c93db58 100644 (file)
@@ -67,6 +67,7 @@ obj-$(CONFIG_TOUCHSCREEN_S3C2410)     += s3c2410_ts.o
 obj-$(CONFIG_TOUCHSCREEN_SILEAD)       += silead.o
 obj-$(CONFIG_TOUCHSCREEN_SIS_I2C)      += sis_i2c.o
 obj-$(CONFIG_TOUCHSCREEN_ST1232)       += st1232.o
+obj-$(CONFIG_TOUCHSCREEN_STMFTS)       += stmfts.o
 obj-$(CONFIG_TOUCHSCREEN_STMPE)                += stmpe-ts.o
 obj-$(CONFIG_TOUCHSCREEN_SUN4I)                += sun4i-ts.o
 obj-$(CONFIG_TOUCHSCREEN_SUR40)                += sur40.o
index 90fc07dc98a6bbf86d000da1fc2834190b77c30e..8868573133ab24da5f9347f196ba7cded92ff97b 100644 (file)
 
 #include <linux/module.h>
 #include <linux/i2c.h>
-#include <linux/i2c/mcs.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/irq.h>
+#include <linux/platform_data/mcs.h>
 #include <linux/slab.h>
 
 /* Registers */
index 1fafc9f57af6c75a7a8a9e9d6b90e016f4e90272..e5eeb6311f7de782ef9bfc03fa290498e76e2c7d 100644 (file)
@@ -11,9 +11,9 @@
 #include <linux/delay.h>
 #include <linux/of.h>
 #include <linux/i2c.h>
-#include <linux/i2c/mms114.h>
 #include <linux/input/mt.h>
 #include <linux/interrupt.h>
+#include <linux/platform_data/mms114.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
index 41d58e88cc8a0de6c1e42eec64801e8838ff0447..3b3db8c868e01f81878563a1ae8a74cda41cf372 100644 (file)
@@ -264,7 +264,11 @@ static int s3c2410ts_probe(struct platform_device *pdev)
                return -ENOENT;
        }
 
-       clk_prepare_enable(ts.clock);
+       ret = clk_prepare_enable(ts.clock);
+       if (ret) {
+               dev_err(dev, "Failed! to enabled clocks\n");
+               goto err_clk_get;
+       }
        dev_dbg(dev, "got and enabled clocks\n");
 
        ts.irq_tc = ret = platform_get_irq(pdev, 0);
@@ -353,7 +357,9 @@ static int s3c2410ts_probe(struct platform_device *pdev)
  err_iomap:
        iounmap(ts.io);
  err_clk:
+       clk_disable_unprepare(ts.clock);
        del_timer_sync(&touch_timer);
+ err_clk_get:
        clk_put(ts.clock);
        return ret;
 }
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
new file mode 100644 (file)
index 0000000..157fdb4
--- /dev/null
@@ -0,0 +1,822 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Author: Andi Shyti <andi.shyti@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * STMicroelectronics FTS Touchscreen device driver
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+
+/* I2C commands */
+#define STMFTS_READ_INFO                       0x80
+#define STMFTS_READ_STATUS                     0x84
+#define STMFTS_READ_ONE_EVENT                  0x85
+#define STMFTS_READ_ALL_EVENT                  0x86
+#define STMFTS_LATEST_EVENT                    0x87
+#define STMFTS_SLEEP_IN                                0x90
+#define STMFTS_SLEEP_OUT                       0x91
+#define STMFTS_MS_MT_SENSE_OFF                 0x92
+#define STMFTS_MS_MT_SENSE_ON                  0x93
+#define STMFTS_SS_HOVER_SENSE_OFF              0x94
+#define STMFTS_SS_HOVER_SENSE_ON               0x95
+#define STMFTS_MS_KEY_SENSE_OFF                        0x9a
+#define STMFTS_MS_KEY_SENSE_ON                 0x9b
+#define STMFTS_SYSTEM_RESET                    0xa0
+#define STMFTS_CLEAR_EVENT_STACK               0xa1
+#define STMFTS_FULL_FORCE_CALIBRATION          0xa2
+#define STMFTS_MS_CX_TUNING                    0xa3
+#define STMFTS_SS_CX_TUNING                    0xa4
+
+/* events */
+#define STMFTS_EV_NO_EVENT                     0x00
+#define STMFTS_EV_MULTI_TOUCH_DETECTED         0x02
+#define STMFTS_EV_MULTI_TOUCH_ENTER            0x03
+#define STMFTS_EV_MULTI_TOUCH_LEAVE            0x04
+#define STMFTS_EV_MULTI_TOUCH_MOTION           0x05
+#define STMFTS_EV_HOVER_ENTER                  0x07
+#define STMFTS_EV_HOVER_LEAVE                  0x08
+#define STMFTS_EV_HOVER_MOTION                 0x09
+#define STMFTS_EV_KEY_STATUS                   0x0e
+#define STMFTS_EV_ERROR                                0x0f
+#define STMFTS_EV_CONTROLLER_READY             0x10
+#define STMFTS_EV_SLEEP_OUT_CONTROLLER_READY   0x11
+#define STMFTS_EV_STATUS                       0x16
+#define STMFTS_EV_DEBUG                                0xdb
+
+/* multi touch related event masks */
+#define STMFTS_MASK_EVENT_ID                   0x0f
+#define STMFTS_MASK_TOUCH_ID                   0xf0
+#define STMFTS_MASK_LEFT_EVENT                 0x0f
+#define STMFTS_MASK_X_MSB                      0x0f
+#define STMFTS_MASK_Y_LSB                      0xf0
+
+/* key related event masks */
+#define STMFTS_MASK_KEY_NO_TOUCH               0x00
+#define STMFTS_MASK_KEY_MENU                   0x01
+#define STMFTS_MASK_KEY_BACK                   0x02
+
+#define STMFTS_EVENT_SIZE      8
+#define STMFTS_STACK_DEPTH     32
+#define STMFTS_DATA_MAX_SIZE   (STMFTS_EVENT_SIZE * STMFTS_STACK_DEPTH)
+#define STMFTS_MAX_FINGERS     10
+#define STMFTS_DEV_NAME                "stmfts"
+
+enum stmfts_regulators {
+       STMFTS_REGULATOR_VDD,
+       STMFTS_REGULATOR_AVDD,
+};
+
+struct stmfts_data {
+       struct i2c_client *client;
+       struct input_dev *input;
+       struct led_classdev led_cdev;
+       struct mutex mutex;
+
+       struct touchscreen_properties prop;
+
+       struct regulator_bulk_data regulators[2];
+
+       /*
+        * Presence of ledvdd will be used also to check
+        * whether the LED is supported.
+        */
+       struct regulator *ledvdd;
+
+       u16 chip_id;
+       u8 chip_ver;
+       u16 fw_ver;
+       u8 config_id;
+       u8 config_ver;
+
+       u8 data[STMFTS_DATA_MAX_SIZE];
+
+       struct completion cmd_done;
+
+       bool use_key;
+       bool led_status;
+       bool hover_enabled;
+       bool running;
+};
+
+static void stmfts_brightness_set(struct led_classdev *led_cdev,
+                                       enum led_brightness value)
+{
+       struct stmfts_data *sdata = container_of(led_cdev,
+                                       struct stmfts_data, led_cdev);
+       int err;
+
+       if (value == sdata->led_status || !sdata->ledvdd)
+               return;
+
+       if (!value) {
+               regulator_disable(sdata->ledvdd);
+       } else {
+               err = regulator_enable(sdata->ledvdd);
+               if (err)
+                       dev_warn(&sdata->client->dev,
+                                "failed to disable ledvdd regulator: %d\n",
+                                err);
+       }
+
+       sdata->led_status = value;
+}
+
+static enum led_brightness stmfts_brightness_get(struct led_classdev *led_cdev)
+{
+       struct stmfts_data *sdata = container_of(led_cdev,
+                                               struct stmfts_data, led_cdev);
+
+       return !!regulator_is_enabled(sdata->ledvdd);
+}
+
+/*
+ * We can't simply use i2c_smbus_read_i2c_block_data because we
+ * need to read more than 255 bytes (
+ */
+static int stmfts_read_events(struct stmfts_data *sdata)
+{
+       u8 cmd = STMFTS_READ_ALL_EVENT;
+       struct i2c_msg msgs[2] = {
+               {
+                       .addr   = sdata->client->addr,
+                       .len    = 1,
+                       .buf    = &cmd,
+               },
+               {
+                       .addr   = sdata->client->addr,
+                       .flags  = I2C_M_RD,
+                       .len    = STMFTS_DATA_MAX_SIZE,
+                       .buf    = sdata->data,
+               },
+       };
+       int ret;
+
+       ret = i2c_transfer(sdata->client->adapter, msgs, ARRAY_SIZE(msgs));
+       if (ret < 0)
+               return ret;
+
+       return ret == ARRAY_SIZE(msgs) ? 0 : -EIO;
+}
+
+static void stmfts_report_contact_event(struct stmfts_data *sdata,
+                                       const u8 event[])
+{
+       u8 slot_id = (event[0] & STMFTS_MASK_TOUCH_ID) >> 4;
+       u16 x = event[1] | ((event[2] & STMFTS_MASK_X_MSB) << 8);
+       u16 y = (event[2] >> 4) | (event[3] << 4);
+       u8 maj = event[4];
+       u8 min = event[5];
+       u8 orientation = event[6];
+       u8 area = event[7];
+
+       input_mt_slot(sdata->input, slot_id);
+
+       input_mt_report_slot_state(sdata->input, MT_TOOL_FINGER, true);
+       input_report_abs(sdata->input, ABS_MT_POSITION_X, x);
+       input_report_abs(sdata->input, ABS_MT_POSITION_Y, y);
+       input_report_abs(sdata->input, ABS_MT_TOUCH_MAJOR, maj);
+       input_report_abs(sdata->input, ABS_MT_TOUCH_MINOR, min);
+       input_report_abs(sdata->input, ABS_MT_PRESSURE, area);
+       input_report_abs(sdata->input, ABS_MT_ORIENTATION, orientation);
+
+       input_sync(sdata->input);
+}
+
+static void stmfts_report_contact_release(struct stmfts_data *sdata,
+                                         const u8 event[])
+{
+       u8 slot_id = (event[0] & STMFTS_MASK_TOUCH_ID) >> 4;
+
+       input_mt_slot(sdata->input, slot_id);
+       input_mt_report_slot_state(sdata->input, MT_TOOL_FINGER, false);
+
+       input_sync(sdata->input);
+}
+
+static void stmfts_report_hover_event(struct stmfts_data *sdata,
+                                     const u8 event[])
+{
+       u16 x = (event[2] << 4) | (event[4] >> 4);
+       u16 y = (event[3] << 4) | (event[4] & STMFTS_MASK_Y_LSB);
+       u8 z = event[5];
+
+       input_report_abs(sdata->input, ABS_X, x);
+       input_report_abs(sdata->input, ABS_Y, y);
+       input_report_abs(sdata->input, ABS_DISTANCE, z);
+
+       input_sync(sdata->input);
+}
+
+static void stmfts_report_key_event(struct stmfts_data *sdata, const u8 event[])
+{
+       switch (event[2]) {
+       case 0:
+               input_report_key(sdata->input, KEY_BACK, 0);
+               input_report_key(sdata->input, KEY_MENU, 0);
+               break;
+
+       case STMFTS_MASK_KEY_BACK:
+               input_report_key(sdata->input, KEY_BACK, 1);
+               break;
+
+       case STMFTS_MASK_KEY_MENU:
+               input_report_key(sdata->input, KEY_MENU, 1);
+               break;
+
+       default:
+               dev_warn(&sdata->client->dev,
+                        "unknown key event: %#02x\n", event[2]);
+               break;
+       }
+
+       input_sync(sdata->input);
+}
+
+static void stmfts_parse_events(struct stmfts_data *sdata)
+{
+       int i;
+
+       for (i = 0; i < STMFTS_STACK_DEPTH; i++) {
+               u8 *event = &sdata->data[i * STMFTS_EVENT_SIZE];
+
+               switch (event[0]) {
+
+               case STMFTS_EV_CONTROLLER_READY:
+               case STMFTS_EV_SLEEP_OUT_CONTROLLER_READY:
+               case STMFTS_EV_STATUS:
+                       complete(&sdata->cmd_done);
+                       /* fall through */
+
+               case STMFTS_EV_NO_EVENT:
+               case STMFTS_EV_DEBUG:
+                       return;
+               }
+
+               switch (event[0] & STMFTS_MASK_EVENT_ID) {
+
+               case STMFTS_EV_MULTI_TOUCH_ENTER:
+               case STMFTS_EV_MULTI_TOUCH_MOTION:
+                       stmfts_report_contact_event(sdata, event);
+                       break;
+
+               case STMFTS_EV_MULTI_TOUCH_LEAVE:
+                       stmfts_report_contact_release(sdata, event);
+                       break;
+
+               case STMFTS_EV_HOVER_ENTER:
+               case STMFTS_EV_HOVER_LEAVE:
+               case STMFTS_EV_HOVER_MOTION:
+                       stmfts_report_hover_event(sdata, event);
+                       break;
+
+               case STMFTS_EV_KEY_STATUS:
+                       stmfts_report_key_event(sdata, event);
+                       break;
+
+               case STMFTS_EV_ERROR:
+                       dev_warn(&sdata->client->dev,
+                                       "error code: 0x%x%x%x%x%x%x",
+                                       event[6], event[5], event[4],
+                                       event[3], event[2], event[1]);
+                       break;
+
+               default:
+                       dev_err(&sdata->client->dev,
+                               "unknown event %#02x\n", event[0]);
+               }
+       }
+}
+
+static irqreturn_t stmfts_irq_handler(int irq, void *dev)
+{
+       struct stmfts_data *sdata = dev;
+       int err;
+
+       mutex_lock(&sdata->mutex);
+
+       err = stmfts_read_events(sdata);
+       if (unlikely(err))
+               dev_err(&sdata->client->dev,
+                       "failed to read events: %d\n", err);
+       else
+               stmfts_parse_events(sdata);
+
+       mutex_unlock(&sdata->mutex);
+       return IRQ_HANDLED;
+}
+
+static int stmfts_command(struct stmfts_data *sdata, const u8 cmd)
+{
+       int err;
+
+       reinit_completion(&sdata->cmd_done);
+
+       err = i2c_smbus_write_byte(sdata->client, cmd);
+       if (err)
+               return err;
+
+       if (!wait_for_completion_timeout(&sdata->cmd_done,
+                                        msecs_to_jiffies(1000)))
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+static int stmfts_input_open(struct input_dev *dev)
+{
+       struct stmfts_data *sdata = input_get_drvdata(dev);
+       int err;
+
+       err = pm_runtime_get_sync(&sdata->client->dev);
+       if (err < 0)
+               return err;
+
+       err = i2c_smbus_write_byte(sdata->client, STMFTS_MS_MT_SENSE_ON);
+       if (err)
+               return err;
+
+       mutex_lock(&sdata->mutex);
+       sdata->running = true;
+
+       if (sdata->hover_enabled) {
+               err = i2c_smbus_write_byte(sdata->client,
+                                          STMFTS_SS_HOVER_SENSE_ON);
+               if (err)
+                       dev_warn(&sdata->client->dev,
+                                "failed to enable hover\n");
+       }
+       mutex_unlock(&sdata->mutex);
+
+       if (sdata->use_key) {
+               err = i2c_smbus_write_byte(sdata->client,
+                                          STMFTS_MS_KEY_SENSE_ON);
+               if (err)
+                       /* I can still use only the touch screen */
+                       dev_warn(&sdata->client->dev,
+                                "failed to enable touchkey\n");
+       }
+
+       return 0;
+}
+
+static void stmfts_input_close(struct input_dev *dev)
+{
+       struct stmfts_data *sdata = input_get_drvdata(dev);
+       int err;
+
+       err = i2c_smbus_write_byte(sdata->client, STMFTS_MS_MT_SENSE_OFF);
+       if (err)
+               dev_warn(&sdata->client->dev,
+                        "failed to disable touchscreen: %d\n", err);
+
+       mutex_lock(&sdata->mutex);
+
+       sdata->running = false;
+
+       if (sdata->hover_enabled) {
+               err = i2c_smbus_write_byte(sdata->client,
+                                          STMFTS_SS_HOVER_SENSE_OFF);
+               if (err)
+                       dev_warn(&sdata->client->dev,
+                                "failed to disable hover: %d\n", err);
+       }
+       mutex_unlock(&sdata->mutex);
+
+       if (sdata->use_key) {
+               err = i2c_smbus_write_byte(sdata->client,
+                                          STMFTS_MS_KEY_SENSE_OFF);
+               if (err)
+                       dev_warn(&sdata->client->dev,
+                                "failed to disable touchkey: %d\n", err);
+       }
+
+       pm_runtime_put_sync(&sdata->client->dev);
+}
+
+static ssize_t stmfts_sysfs_chip_id(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%#x\n", sdata->chip_id);
+}
+
+static ssize_t stmfts_sysfs_chip_version(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%u\n", sdata->chip_ver);
+}
+
+static ssize_t stmfts_sysfs_fw_ver(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%u\n", sdata->fw_ver);
+}
+
+static ssize_t stmfts_sysfs_config_id(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%#x\n", sdata->config_id);
+}
+
+static ssize_t stmfts_sysfs_config_version(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%u\n", sdata->config_ver);
+}
+
+static ssize_t stmfts_sysfs_read_status(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+       u8 status[4];
+       int err;
+
+       err = i2c_smbus_read_i2c_block_data(sdata->client, STMFTS_READ_STATUS,
+                                           sizeof(status), status);
+       if (err)
+               return err;
+
+       return sprintf(buf, "%#02x\n", status[0]);
+}
+
+static ssize_t stmfts_sysfs_hover_enable_read(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%u\n", sdata->hover_enabled);
+}
+
+static ssize_t stmfts_sysfs_hover_enable_write(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t len)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+       unsigned long value;
+       int err = 0;
+
+       if (kstrtoul(buf, 0, &value))
+               return -EINVAL;
+
+       mutex_lock(&sdata->mutex);
+
+       if (value & sdata->hover_enabled)
+               goto out;
+
+       if (sdata->running)
+               err = i2c_smbus_write_byte(sdata->client,
+                                          value ? STMFTS_SS_HOVER_SENSE_ON :
+                                                  STMFTS_SS_HOVER_SENSE_OFF);
+
+       if (!err)
+               sdata->hover_enabled = !!value;
+
+out:
+       mutex_unlock(&sdata->mutex);
+
+       return len;
+}
+
+static DEVICE_ATTR(chip_id, 0444, stmfts_sysfs_chip_id, NULL);
+static DEVICE_ATTR(chip_version, 0444, stmfts_sysfs_chip_version, NULL);
+static DEVICE_ATTR(fw_ver, 0444, stmfts_sysfs_fw_ver, NULL);
+static DEVICE_ATTR(config_id, 0444, stmfts_sysfs_config_id, NULL);
+static DEVICE_ATTR(config_version, 0444, stmfts_sysfs_config_version, NULL);
+static DEVICE_ATTR(status, 0444, stmfts_sysfs_read_status, NULL);
+static DEVICE_ATTR(hover_enable, 0644, stmfts_sysfs_hover_enable_read,
+                                       stmfts_sysfs_hover_enable_write);
+
+static struct attribute *stmfts_sysfs_attrs[] = {
+       &dev_attr_chip_id.attr,
+       &dev_attr_chip_version.attr,
+       &dev_attr_fw_ver.attr,
+       &dev_attr_config_id.attr,
+       &dev_attr_config_version.attr,
+       &dev_attr_status.attr,
+       &dev_attr_hover_enable.attr,
+       NULL
+};
+
+static struct attribute_group stmfts_attribute_group = {
+       .attrs = stmfts_sysfs_attrs
+};
+
+static int stmfts_power_on(struct stmfts_data *sdata)
+{
+       int err;
+       u8 reg[8];
+
+       err = regulator_bulk_enable(ARRAY_SIZE(sdata->regulators),
+                                   sdata->regulators);
+       if (err)
+               return err;
+
+       /*
+        * The datasheet does not specify the power on time, but considering
+        * that the reset time is < 10ms, I sleep 20ms to be sure
+        */
+       msleep(20);
+
+       err = i2c_smbus_read_i2c_block_data(sdata->client, STMFTS_READ_INFO,
+                                           sizeof(reg), reg);
+       if (err < 0)
+               return err;
+       if (err != sizeof(reg))
+               return -EIO;
+
+       sdata->chip_id = be16_to_cpup((__be16 *)&reg[6]);
+       sdata->chip_ver = reg[0];
+       sdata->fw_ver = be16_to_cpup((__be16 *)&reg[2]);
+       sdata->config_id = reg[4];
+       sdata->config_ver = reg[5];
+
+       enable_irq(sdata->client->irq);
+
+       msleep(50);
+
+       err = stmfts_command(sdata, STMFTS_SYSTEM_RESET);
+       if (err)
+               return err;
+
+       err = stmfts_command(sdata, STMFTS_SLEEP_OUT);
+       if (err)
+               return err;
+
+       /* optional tuning */
+       err = stmfts_command(sdata, STMFTS_MS_CX_TUNING);
+       if (err)
+               dev_warn(&sdata->client->dev,
+                        "failed to perform mutual auto tune: %d\n", err);
+
+       /* optional tuning */
+       err = stmfts_command(sdata, STMFTS_SS_CX_TUNING);
+       if (err)
+               dev_warn(&sdata->client->dev,
+                        "failed to perform self auto tune: %d\n", err);
+
+       err = stmfts_command(sdata, STMFTS_FULL_FORCE_CALIBRATION);
+       if (err)
+               return err;
+
+       /*
+        * At this point no one is using the touchscreen
+        * and I don't really care about the return value
+        */
+       (void) i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
+
+       return 0;
+}
+
+static void stmfts_power_off(void *data)
+{
+       struct stmfts_data *sdata = data;
+
+       disable_irq(sdata->client->irq);
+       regulator_bulk_disable(ARRAY_SIZE(sdata->regulators),
+                                               sdata->regulators);
+}
+
+/* This function is void because I don't want to prevent using the touch key
+ * only because the LEDs don't get registered
+ */
+static int stmfts_enable_led(struct stmfts_data *sdata)
+{
+       int err;
+
+       /* get the regulator for powering the leds on */
+       sdata->ledvdd = devm_regulator_get(&sdata->client->dev, "ledvdd");
+       if (IS_ERR(sdata->ledvdd))
+               return PTR_ERR(sdata->ledvdd);
+
+       sdata->led_cdev.name = STMFTS_DEV_NAME;
+       sdata->led_cdev.max_brightness = LED_ON;
+       sdata->led_cdev.brightness = LED_OFF;
+       sdata->led_cdev.brightness_set = stmfts_brightness_set;
+       sdata->led_cdev.brightness_get = stmfts_brightness_get;
+
+       err = devm_led_classdev_register(&sdata->client->dev, &sdata->led_cdev);
+       if (err) {
+               devm_regulator_put(sdata->ledvdd);
+               return err;
+       }
+
+       return 0;
+}
+
+static int stmfts_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+{
+       int err;
+       struct stmfts_data *sdata;
+
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
+                                               I2C_FUNC_SMBUS_BYTE_DATA |
+                                               I2C_FUNC_SMBUS_I2C_BLOCK))
+               return -ENODEV;
+
+       sdata = devm_kzalloc(&client->dev, sizeof(*sdata), GFP_KERNEL);
+       if (!sdata)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, sdata);
+
+       sdata->client = client;
+       mutex_init(&sdata->mutex);
+       init_completion(&sdata->cmd_done);
+
+       sdata->regulators[STMFTS_REGULATOR_VDD].supply = "vdd";
+       sdata->regulators[STMFTS_REGULATOR_AVDD].supply = "avdd";
+       err = devm_regulator_bulk_get(&client->dev,
+                                     ARRAY_SIZE(sdata->regulators),
+                                     sdata->regulators);
+       if (err)
+               return err;
+
+       sdata->input = devm_input_allocate_device(&client->dev);
+       if (!sdata->input)
+               return -ENOMEM;
+
+       sdata->input->name = STMFTS_DEV_NAME;
+       sdata->input->id.bustype = BUS_I2C;
+       sdata->input->open = stmfts_input_open;
+       sdata->input->close = stmfts_input_close;
+
+       touchscreen_parse_properties(sdata->input, true, &sdata->prop);
+
+       input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0,
+                                               sdata->prop.max_x, 0, 0);
+       input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0,
+                                               sdata->prop.max_y, 0, 0);
+       input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+       input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
+       input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);
+       input_set_abs_params(sdata->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
+       input_set_abs_params(sdata->input, ABS_DISTANCE, 0, 255, 0, 0);
+
+       sdata->use_key = device_property_read_bool(&client->dev,
+                                                  "touch-key-connected");
+       if (sdata->use_key) {
+               input_set_capability(sdata->input, EV_KEY, KEY_MENU);
+               input_set_capability(sdata->input, EV_KEY, KEY_BACK);
+       }
+
+       err = input_mt_init_slots(sdata->input,
+                                 STMFTS_MAX_FINGERS, INPUT_MT_DIRECT);
+       if (err)
+               return err;
+
+       input_set_drvdata(sdata->input, sdata);
+
+       err = devm_request_threaded_irq(&client->dev, client->irq,
+                                       NULL, stmfts_irq_handler,
+                                       IRQF_ONESHOT,
+                                       "stmfts_irq", sdata);
+       if (err)
+               return err;
+
+       /* stmfts_power_on expects interrupt to be disabled */
+       disable_irq(client->irq);
+
+       dev_dbg(&client->dev, "initializing ST-Microelectronics FTS...\n");
+
+       err = stmfts_power_on(sdata);
+       if (err)
+               return err;
+
+       err = devm_add_action_or_reset(&client->dev, stmfts_power_off, sdata);
+       if (err)
+               return err;
+
+       err = input_register_device(sdata->input);
+       if (err)
+               return err;
+
+       if (sdata->use_key) {
+               err = stmfts_enable_led(sdata);
+               if (err) {
+                       /*
+                        * Even if the LEDs have failed to be initialized and
+                        * used in the driver, I can still use the device even
+                        * without LEDs. The ledvdd regulator pointer will be
+                        * used as a flag.
+                        */
+                       dev_warn(&client->dev, "unable to use touchkey leds\n");
+                       sdata->ledvdd = NULL;
+               }
+       }
+
+       err = sysfs_create_group(&sdata->client->dev.kobj,
+                                &stmfts_attribute_group);
+       if (err)
+               return err;
+
+       pm_runtime_enable(&client->dev);
+
+       return 0;
+}
+
+static int stmfts_remove(struct i2c_client *client)
+{
+       pm_runtime_disable(&client->dev);
+       sysfs_remove_group(&client->dev.kobj, &stmfts_attribute_group);
+
+       return 0;
+}
+
+static int __maybe_unused stmfts_runtime_suspend(struct device *dev)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+       int ret;
+
+       ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
+       if (ret)
+               dev_warn(dev, "failed to suspend device: %d\n", ret);
+
+       return ret;
+}
+
+static int __maybe_unused stmfts_runtime_resume(struct device *dev)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+       int ret;
+
+       ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_OUT);
+       if (ret)
+               dev_err(dev, "failed to resume device: %d\n", ret);
+
+       return ret;
+}
+
+static int __maybe_unused stmfts_suspend(struct device *dev)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+
+       stmfts_power_off(sdata);
+
+       return 0;
+}
+
+static int __maybe_unused stmfts_resume(struct device *dev)
+{
+       struct stmfts_data *sdata = dev_get_drvdata(dev);
+
+       return stmfts_power_on(sdata);
+}
+
+static const struct dev_pm_ops stmfts_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(stmfts_suspend, stmfts_resume)
+       SET_RUNTIME_PM_OPS(stmfts_runtime_suspend, stmfts_runtime_resume, NULL)
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id stmfts_of_match[] = {
+       { .compatible = "st,stmfts", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, stmfts_of_match);
+#endif
+
+static const struct i2c_device_id stmfts_id[] = {
+       { "stmfts", 0 },
+       { },
+};
+MODULE_DEVICE_TABLE(i2c, stmfts_id);
+
+static struct i2c_driver stmfts_driver = {
+       .driver = {
+               .name = STMFTS_DEV_NAME,
+               .of_match_table = of_match_ptr(stmfts_of_match),
+               .pm = &stmfts_pm_ops,
+       },
+       .probe = stmfts_probe,
+       .remove = stmfts_remove,
+       .id_table = stmfts_id,
+};
+
+module_i2c_driver(stmfts_driver);
+
+MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>");
+MODULE_DESCRIPTION("STMicroelectronics FTS Touch Screen");
+MODULE_LICENSE("GPL v2");
index fc7384936011dce48ba6d7c96d83bcc358409df8..8342e0c48a534d5554522a136cb46550e1a06461 100644 (file)
@@ -25,9 +25,9 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
-#include <linux/i2c/tsc2007.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
+#include <linux/platform_data/tsc2007.h>
 #include "tsc2007.h"
 
 int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
index c9339f85359b74482358f1d15328e0d03c4f732c..cd4a6d7d6750e8dabcb48518afc20518f471bb8c 100644 (file)
 #include <linux/i2c.h>
 #include <linux/i2c-ocores.h>
 #include <linux/i2c-xiic.h>
-#include <linux/i2c/tsc2007.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/xilinx_spi.h>
 #include <linux/spi/max7301.h>
 #include <linux/spi/mc33880.h>
 
+#include <linux/platform_data/tsc2007.h>
 #include <linux/platform_data/media/timb_radio.h>
 #include <linux/platform_data/media/timb_video.h>
 
diff --git a/include/linux/i2c/lm8323.h b/include/linux/i2c/lm8323.h
deleted file mode 100644 (file)
index 478d668..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * lm8323.h - Configuration for LM8323 keypad driver.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation (version 2 of the License only).
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __LINUX_LM8323_H
-#define __LINUX_LM8323_H
-
-#include <linux/types.h>
-
-/*
- * Largest keycode that the chip can send, plus one,
- * so keys can be mapped directly at the index of the
- * LM8323 keycode instead of subtracting one.
- */
-#define LM8323_KEYMAP_SIZE     (0x7f + 1)
-
-#define LM8323_NUM_PWMS                3
-
-struct lm8323_platform_data {
-       int debounce_time; /* Time to watch for key bouncing, in ms. */
-       int active_time; /* Idle time until sleep, in ms. */
-
-       int size_x;
-       int size_y;
-       bool repeat;
-       const unsigned short *keymap;
-
-       const char *pwm_names[LM8323_NUM_PWMS];
-
-       const char *name; /* Device name. */
-};
-
-#endif /* __LINUX_LM8323_H */
diff --git a/include/linux/i2c/mcs.h b/include/linux/i2c/mcs.h
deleted file mode 100644 (file)
index 61bb18a..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2009 - 2010 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- * Author: HeungJun Kim <riverful.kim@samsung.com>
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- */
-
-#ifndef __LINUX_MCS_H
-#define __LINUX_MCS_H
-
-#define MCS_KEY_MAP(v, c)      ((((v) & 0xff) << 16) | ((c) & 0xffff))
-#define MCS_KEY_VAL(v)         (((v) >> 16) & 0xff)
-#define MCS_KEY_CODE(v)                ((v) & 0xffff)
-
-struct mcs_platform_data {
-       void (*poweron)(bool);
-       void (*cfg_pin)(void);
-
-       /* touchscreen */
-       unsigned int x_size;
-       unsigned int y_size;
-
-       /* touchkey */
-       const u32 *keymap;
-       unsigned int keymap_size;
-       unsigned int key_maxval;
-       bool no_autorepeat;
-};
-
-#endif /* __LINUX_MCS_H */
diff --git a/include/linux/i2c/mms114.h b/include/linux/i2c/mms114.h
deleted file mode 100644 (file)
index 5722ebf..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2012 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundationr
- */
-
-#ifndef __LINUX_MMS114_H
-#define __LINUX_MMS114_H
-
-struct mms114_platform_data {
-       unsigned int x_size;
-       unsigned int y_size;
-       unsigned int contact_threshold;
-       unsigned int moving_threshold;
-       bool x_invert;
-       bool y_invert;
-
-       void (*cfg_pin)(bool);
-};
-
-#endif /* __LINUX_MMS114_H */
diff --git a/include/linux/i2c/tsc2007.h b/include/linux/i2c/tsc2007.h
deleted file mode 100644 (file)
index 4f35b6a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __LINUX_I2C_TSC2007_H
-#define __LINUX_I2C_TSC2007_H
-
-/* linux/i2c/tsc2007.h */
-
-struct tsc2007_platform_data {
-       u16     model;                          /* 2007. */
-       u16     x_plate_ohms;   /* must be non-zero value */
-       u16     max_rt; /* max. resistance above which samples are ignored */
-       unsigned long poll_period; /* time (in ms) between samples */
-       int     fuzzx; /* fuzz factor for X, Y and pressure axes */
-       int     fuzzy;
-       int     fuzzz;
-
-       int     (*get_pendown_state)(struct device *);
-       /* If needed, clear 2nd level interrupt source */
-       void    (*clear_penirq)(void);
-       int     (*init_platform_hw)(void);
-       void    (*exit_platform_hw)(void);
-};
-
-#endif
index 52db62064c6e378d87cb21a3b1501a0fb9a00e82..c7346e33d9582e4ac39742a8e76d66e8677ca040 100644 (file)
@@ -51,7 +51,6 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
 int sparse_keymap_setup(struct input_dev *dev,
                        const struct key_entry *keymap,
                        int (*setup)(struct input_dev *, struct key_entry *));
-void sparse_keymap_free(struct input_dev *dev);
 
 void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke,
                                unsigned int value, bool autorelease);
diff --git a/include/linux/platform_data/lm8323.h b/include/linux/platform_data/lm8323.h
new file mode 100644 (file)
index 0000000..478d668
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * lm8323.h - Configuration for LM8323 keypad driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation (version 2 of the License only).
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __LINUX_LM8323_H
+#define __LINUX_LM8323_H
+
+#include <linux/types.h>
+
+/*
+ * Largest keycode that the chip can send, plus one,
+ * so keys can be mapped directly at the index of the
+ * LM8323 keycode instead of subtracting one.
+ */
+#define LM8323_KEYMAP_SIZE     (0x7f + 1)
+
+#define LM8323_NUM_PWMS                3
+
+struct lm8323_platform_data {
+       int debounce_time; /* Time to watch for key bouncing, in ms. */
+       int active_time; /* Idle time until sleep, in ms. */
+
+       int size_x;
+       int size_y;
+       bool repeat;
+       const unsigned short *keymap;
+
+       const char *pwm_names[LM8323_NUM_PWMS];
+
+       const char *name; /* Device name. */
+};
+
+#endif /* __LINUX_LM8323_H */
diff --git a/include/linux/platform_data/mcs.h b/include/linux/platform_data/mcs.h
new file mode 100644 (file)
index 0000000..61bb18a
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009 - 2010 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MCS_H
+#define __LINUX_MCS_H
+
+#define MCS_KEY_MAP(v, c)      ((((v) & 0xff) << 16) | ((c) & 0xffff))
+#define MCS_KEY_VAL(v)         (((v) >> 16) & 0xff)
+#define MCS_KEY_CODE(v)                ((v) & 0xffff)
+
+struct mcs_platform_data {
+       void (*poweron)(bool);
+       void (*cfg_pin)(void);
+
+       /* touchscreen */
+       unsigned int x_size;
+       unsigned int y_size;
+
+       /* touchkey */
+       const u32 *keymap;
+       unsigned int keymap_size;
+       unsigned int key_maxval;
+       bool no_autorepeat;
+};
+
+#endif /* __LINUX_MCS_H */
diff --git a/include/linux/platform_data/mms114.h b/include/linux/platform_data/mms114.h
new file mode 100644 (file)
index 0000000..5722ebf
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundationr
+ */
+
+#ifndef __LINUX_MMS114_H
+#define __LINUX_MMS114_H
+
+struct mms114_platform_data {
+       unsigned int x_size;
+       unsigned int y_size;
+       unsigned int contact_threshold;
+       unsigned int moving_threshold;
+       bool x_invert;
+       bool y_invert;
+
+       void (*cfg_pin)(bool);
+};
+
+#endif /* __LINUX_MMS114_H */
diff --git a/include/linux/platform_data/tsc2007.h b/include/linux/platform_data/tsc2007.h
new file mode 100644 (file)
index 0000000..c2d3aa1
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __LINUX_I2C_TSC2007_H
+#define __LINUX_I2C_TSC2007_H
+
+/* linux/platform_data/tsc2007.h */
+
+struct tsc2007_platform_data {
+       u16     model;                          /* 2007. */
+       u16     x_plate_ohms;   /* must be non-zero value */
+       u16     max_rt; /* max. resistance above which samples are ignored */
+       unsigned long poll_period; /* time (in ms) between samples */
+       int     fuzzx; /* fuzz factor for X, Y and pressure axes */
+       int     fuzzy;
+       int     fuzzz;
+
+       int     (*get_pendown_state)(struct device *);
+       /* If needed, clear 2nd level interrupt source */
+       void    (*clear_penirq)(void);
+       int     (*init_platform_hw)(void);
+       void    (*exit_platform_hw)(void);
+};
+
+#endif
index f5a8d96e1e098543d7cad6af1d7a77b117701f40..179891074b3c24780bb10e5a9a4f8d2183d2c684 100644 (file)
 #define KEY_APPSELECT          0x244   /* AL Select Task/Application */
 #define KEY_SCREENSAVER                0x245   /* AL Screen Saver */
 #define KEY_VOICECOMMAND               0x246   /* Listening Voice Command */
+#define KEY_ASSISTANT          0x247   /* AL Context-aware desktop assistant */
 
 #define KEY_BRIGHTNESS_MIN             0x250   /* Set Brightness to Minimum */
 #define KEY_BRIGHTNESS_MAX             0x251   /* Set Brightness to Maximum */