]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Feb 2017 16:39:40 +0000 (08:39 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 23 Feb 2017 16:39:40 +0000 (08:39 -0800)
Pull input updates from Dmitry:

 - a new driver for Zeitech touchscreen controller

 - a new driver for Samsung "touchkeys"

 - touchscreen driver for Moorestown platform has been removed because
   platform support is gone

 - MPU3050 accelerometer driver was removed in favor of IIO driver

 - miscellaneous driver cleanup and fixes

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (88 commits)
  Input: zet6223 - export OF device ID as module aliases
  Input: tsc2004/5 - switch to using generic device properties
  Input: tsc2004/5 - fix regulator handling
  Input: tsc2005 - add OF device table
  Input: add driver for Zeitec ZET6223
  Input: joydev - do not report stale values on first open
  Input: synaptics-rmi4 - forward upper mechanical buttons to PS/2 guest
  Input: synaptics-rmi4 - clean up F30 implementation
  Input: synaptics - use SERIO_OOB_DATA to handle trackstick buttons
  Input: psmouse - add a custom serio protocol to send extra information
  Input: synaptics-rmi4 - fix error return code in rmi_probe_interrupts()
  Input: xpad - restore LED state after device resume
  Input: synaptics-rmi4 - add rmi_find_function()
  Input: xpad - fix stuck mode button on Xbox One S pad
  Input: joydev - use clamp() macro
  Input: refuse to register absolute devices without absinfo
  Input: synaptics-rmi4 - add sysfs interfaces for hardware IDs
  Input: synaptics-rmi4 - add sysfs attribute update_fw_status
  Input: mousedev - stop offering PS/2 to userspace by default
  Input: tca8418 - switch to using generic device properties
  ...

132 files changed:
Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt [new file with mode: 0644]
Documentation/devicetree/bindings/input/mpr121-touchkey.txt [new file with mode: 0644]
Documentation/devicetree/bindings/input/pwm-beeper.txt
Documentation/devicetree/bindings/input/touchscreen/zet6223.txt [new file with mode: 0644]
Documentation/devicetree/bindings/vendor-prefixes.txt
drivers/input/Kconfig
drivers/input/input.c
drivers/input/joydev.c
drivers/input/joystick/maplecontrol.c
drivers/input/joystick/xpad.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/adc-keys.c
drivers/input/keyboard/adp5520-keys.c
drivers/input/keyboard/bcm-keypad.c
drivers/input/keyboard/bf54x-keys.c
drivers/input/keyboard/cap11xx.c
drivers/input/keyboard/cros_ec_keyb.c
drivers/input/keyboard/davinci_keyscan.c
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/gpio_keys_polled.c
drivers/input/keyboard/jornada680_kbd.c
drivers/input/keyboard/lpc32xx-keys.c
drivers/input/keyboard/maple_keyb.c
drivers/input/keyboard/matrix_keypad.c
drivers/input/keyboard/max7359_keypad.c
drivers/input/keyboard/mpr121_touchkey.c
drivers/input/keyboard/nspire-keypad.c
drivers/input/keyboard/omap4-keypad.c
drivers/input/keyboard/opencores-kbd.c
drivers/input/keyboard/pmic8xxx-keypad.c
drivers/input/keyboard/pxa27x_keypad.c
drivers/input/keyboard/samsung-keypad.c
drivers/input/keyboard/spear-keyboard.c
drivers/input/keyboard/st-keyscan.c
drivers/input/keyboard/stmpe-keypad.c
drivers/input/keyboard/sun4i-lradc-keys.c
drivers/input/keyboard/tca8418_keypad.c
drivers/input/keyboard/tm2-touchkey.c [new file with mode: 0644]
drivers/input/keyboard/twl4030_keypad.c
drivers/input/matrix-keymap.c
drivers/input/misc/88pm80x_onkey.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/ab8500-ponkey.c
drivers/input/misc/arizona-haptics.c
drivers/input/misc/atmel_captouch.c
drivers/input/misc/bfin_rotary.c
drivers/input/misc/bma150.c
drivers/input/misc/da9063_onkey.c
drivers/input/misc/dm355evm_keys.c
drivers/input/misc/drv260x.c
drivers/input/misc/e3x0-button.c
drivers/input/misc/gp2ap002a00f.c
drivers/input/misc/gpio_decoder.c
drivers/input/misc/gpio_tilt_polled.c
drivers/input/misc/hisi_powerkey.c
drivers/input/misc/mma8450.c
drivers/input/misc/mpu3050.c [deleted file]
drivers/input/misc/pm8941-pwrkey.c
drivers/input/misc/pmic8xxx-pwrkey.c
drivers/input/misc/pwm-beeper.c
drivers/input/misc/retu-pwrbutton.c
drivers/input/misc/sirfsoc-onkey.c
drivers/input/misc/soc_button_array.c
drivers/input/misc/tps65218-pwrbutton.c
drivers/input/misc/twl4030-pwrbutton.c
drivers/input/mouse/alps.c
drivers/input/mouse/bcm5974.c
drivers/input/mouse/cyapa.c
drivers/input/mouse/cyapa_gen3.c
drivers/input/mouse/cypress_ps2.c
drivers/input/mouse/elan_i2c_core.c
drivers/input/mouse/elantech.c
drivers/input/mouse/hgpk.c
drivers/input/mouse/logips2pp.c
drivers/input/mouse/maplemouse.c
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse.h
drivers/input/mouse/synaptics.c
drivers/input/mouse/synaptics.h
drivers/input/mouse/trackpoint.c
drivers/input/rmi4/Kconfig
drivers/input/rmi4/rmi_2d_sensor.c
drivers/input/rmi4/rmi_bus.c
drivers/input/rmi4/rmi_driver.c
drivers/input/rmi4/rmi_driver.h
drivers/input/rmi4/rmi_f01.c
drivers/input/rmi4/rmi_f03.c
drivers/input/rmi4/rmi_f30.c
drivers/input/rmi4/rmi_f34.c
drivers/input/rmi4/rmi_f34.h
drivers/input/rmi4/rmi_f34v7.c
drivers/input/serio/at32psif.c
drivers/input/serio/hyperv-keyboard.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/i8042.c
drivers/input/serio/xilinx_ps2.c
drivers/input/touchscreen/88pm860x-ts.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/ar1021_i2c.c
drivers/input/touchscreen/atmel-wm97xx.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/bu21013_ts.c
drivers/input/touchscreen/colibri-vf50-ts.c
drivers/input/touchscreen/edt-ft5x06.c
drivers/input/touchscreen/eeti_ts.c
drivers/input/touchscreen/egalax_ts.c
drivers/input/touchscreen/elants_i2c.c
drivers/input/touchscreen/fsl-imx25-tcq.c
drivers/input/touchscreen/ili210x.c
drivers/input/touchscreen/intel-mid-touch.c [deleted file]
drivers/input/touchscreen/lpc32xx_ts.c
drivers/input/touchscreen/max11801_ts.c
drivers/input/touchscreen/mcs5000_ts.c
drivers/input/touchscreen/pixcir_i2c_ts.c
drivers/input/touchscreen/raydium_i2c_ts.c
drivers/input/touchscreen/rohm_bu21023.c
drivers/input/touchscreen/s3c2410_ts.c
drivers/input/touchscreen/sis_i2c.c
drivers/input/touchscreen/st1232.c
drivers/input/touchscreen/sx8654.c
drivers/input/touchscreen/tsc2005.c
drivers/input/touchscreen/tsc200x-core.c
drivers/input/touchscreen/zet6223.c [new file with mode: 0644]
include/linux/i2c/mpr121_touchkey.h [deleted file]
include/linux/input/matrix_keypad.h
include/linux/input/tca8418_keypad.h [deleted file]
include/linux/spi/tsc2005.h [deleted file]
include/uapi/linux/serio.h

diff --git a/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt b/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt
new file mode 100644 (file)
index 0000000..635f62c
--- /dev/null
@@ -0,0 +1,27 @@
+Samsung tm2-touchkey
+
+Required properties:
+- compatible: must be "cypress,tm2-touchkey"
+- reg: I2C address of the chip.
+- interrupt-parent: a phandle for the interrupt controller (see interrupt
+       binding[0]).
+- interrupts: interrupt to which the chip is connected (see interrupt
+       binding[0]).
+- vcc-supply : internal regulator output. 1.8V
+- vdd-supply : power supply for IC 3.3V
+
+[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example:
+       &i2c0 {
+               /* ... */
+
+               touchkey@20 {
+                       compatible = "cypress,tm2-touchkey";
+                       reg = <0x20>;
+                       interrupt-parent = <&gpa3>;
+                       interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+                       vcc-supply=<&ldo32_reg>;
+                       vdd-supply=<&ldo33_reg>;
+               };
+       };
diff --git a/Documentation/devicetree/bindings/input/mpr121-touchkey.txt b/Documentation/devicetree/bindings/input/mpr121-touchkey.txt
new file mode 100644 (file)
index 0000000..b7c61ee
--- /dev/null
@@ -0,0 +1,30 @@
+* Freescale MPR121 Controllor
+
+Required Properties:
+- compatible:          Should be "fsl,mpr121-touchkey"
+- reg:                 The I2C slave address of the device.
+- interrupts:          The interrupt number to the cpu.
+- vdd-supply:          Phandle to the Vdd power supply.
+- linux,keycodes:      Specifies an array of numeric keycode values to
+                       be used for reporting button presses. The array can
+                       contain up to 12 entries.
+
+Optional Properties:
+- wakeup-source:       Use any event on keypad as wakeup event.
+- autorepeat:          Enable autorepeat feature.
+
+Example:
+
+#include "dt-bindings/input/input.h"
+
+       touchkey: mpr121@5a {
+               compatible = "fsl,mpr121-touchkey";
+               reg = <0x5a>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <28 2>;
+               autorepeat;
+               vdd-supply = <&ldo4_reg>;
+               linux,keycodes = <KEY_0>, <KEY_1>, <KEY_2>, <KEY_3>,
+                               <KEY_4> <KEY_5>, <KEY_6>, <KEY_7>,
+                               <KEY_8>, <KEY_9>, <KEY_A>, <KEY_B>;
+       };
index be332ae4f2d6fc305947187e5ed77de0f7a7cb0f..529408b4431a62e44ddfb4ee0bd6795182c2d792 100644 (file)
@@ -5,3 +5,19 @@ Registers a PWM device as beeper.
 Required properties:
 - compatible: should be "pwm-beeper"
 - pwms: phandle to the physical PWM device
+
+Optional properties:
+- amp-supply: phandle to a regulator that acts as an amplifier for the beeper
+
+Example:
+
+beeper_amp: amplifier {
+       compatible = "fixed-regulator";
+       gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+};
+
+beeper {
+       compatible = "pwm-beeper";
+       pwms = <&pwm0>;
+       amp-supply = <&beeper_amp>;
+};
diff --git a/Documentation/devicetree/bindings/input/touchscreen/zet6223.txt b/Documentation/devicetree/bindings/input/touchscreen/zet6223.txt
new file mode 100644 (file)
index 0000000..fe6a1fe
--- /dev/null
@@ -0,0 +1,32 @@
+Zeitec ZET6223 I2C touchscreen controller
+
+Required properties:
+- compatible             : "zeitec,zet6223"
+- reg                    : I2C slave address of the chip (0x76)
+- interrupt-parent       : a phandle pointing to the interrupt controller
+                           serving the interrupt for this chip
+- interrupts             : interrupt specification for the zet6223 interrupt
+
+Optional properties:
+
+- vio-supply             : Specification for VIO supply (1.8V or 3.3V,
+                           depending on system interface needs).
+- vcc-supply             : Specification for 3.3V VCC supply.
+- touchscreen-size-x     : See touchscreen.txt
+- touchscreen-size-y     : See touchscreen.txt
+- touchscreen-inverted-x  : See touchscreen.txt
+- touchscreen-inverted-y  : See touchscreen.txt
+- touchscreen-swapped-x-y : See touchscreen.txt
+
+Example:
+
+i2c@00000000 {
+
+       zet6223: touchscreen@76 {
+               compatible = "zeitec,zet6223";
+               reg = <0x76>;
+               interrupt-parent = <&pio>;
+               interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>
+       };
+
+};
index 1d0bb2c9def4416b0cf32ff6137f6fb86754ca41..ebd46f2eef24fe43fa4f8d14e4a84a1006fd8f84 100644 (file)
@@ -334,6 +334,7 @@ xes Extreme Engineering Solutions (X-ES)
 xillybus       Xillybus Ltd.
 xlnx   Xilinx
 zarlink        Zarlink Semiconductor
+zeitec ZEITEC Semiconductor Co., LTD.
 zii    Zodiac Inflight Innovations
 zte    ZTE Corp.
 zyxel  ZyXEL Communications Corp.
index 6261874c07c9a76783227b28fd2020df32d6389a..ff80377987795df3bdd3755e55806499ea54d6d2 100644 (file)
@@ -94,7 +94,6 @@ comment "Userland interfaces"
 
 config INPUT_MOUSEDEV
        tristate "Mouse interface"
-       default y
        help
          Say Y here if you want your mouse to be accessible as char devices
          13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an
@@ -109,7 +108,6 @@ config INPUT_MOUSEDEV
 
 config INPUT_MOUSEDEV_PSAUX
        bool "Provide legacy /dev/psaux device"
-       default y
        depends on INPUT_MOUSEDEV
        help
          Say Y here if you want your mouse also be accessible as char device
@@ -118,7 +116,6 @@ config INPUT_MOUSEDEV_PSAUX
 
          If unsure, say Y.
 
-
 config INPUT_MOUSEDEV_SCREEN_X
        int "Horizontal screen resolution"
        depends on INPUT_MOUSEDEV
index d95c34ee5dc1430f5664e8b50d449f01c802ae4a..067d648028a22ff8963ed12c3a59ae1a0b5e3dfd 100644 (file)
@@ -1749,7 +1749,7 @@ static const struct dev_pm_ops input_dev_pm_ops = {
 };
 #endif /* CONFIG_PM */
 
-static struct device_type input_dev_type = {
+static const struct device_type input_dev_type = {
        .groups         = input_dev_attr_groups,
        .release        = input_dev_release,
        .uevent         = input_dev_uevent,
@@ -2091,6 +2091,12 @@ int input_register_device(struct input_dev *dev)
        const char *path;
        int error;
 
+       if (test_bit(EV_ABS, dev->evbit) && !dev->absinfo) {
+               dev_err(&dev->dev,
+                       "Absolute device without dev->absinfo, refusing to register\n");
+               return -EINVAL;
+       }
+
        if (dev->devres_managed) {
                devres = devres_alloc(devm_input_device_unregister,
                                      sizeof(struct input_devres), GFP_KERNEL);
index abd18f31b24f68e27c28f1120e52aa96b9347887..065e67bf56dd99e603e692b6ce9b2590205cb3ef 100644 (file)
@@ -87,7 +87,7 @@ static int joydev_correct(int value, struct js_corr *corr)
                return 0;
        }
 
-       return value < -32767 ? -32767 : (value > 32767 ? 32767 : value);
+       return clamp(value, -32767, 32767);
 }
 
 static void joydev_pass_event(struct joydev_client *client,
@@ -187,6 +187,17 @@ static void joydev_detach_client(struct joydev *joydev,
        synchronize_rcu();
 }
 
+static void joydev_refresh_state(struct joydev *joydev)
+{
+       struct input_dev *dev = joydev->handle.dev;
+       int i, val;
+
+       for (i = 0; i < joydev->nabs; i++) {
+               val = input_abs_get_val(dev, joydev->abspam[i]);
+               joydev->abs[i] = joydev_correct(val, &joydev->corr[i]);
+       }
+}
+
 static int joydev_open_device(struct joydev *joydev)
 {
        int retval;
@@ -201,6 +212,8 @@ static int joydev_open_device(struct joydev *joydev)
                retval = input_open_device(&joydev->handle);
                if (retval)
                        joydev->open--;
+               else
+                       joydev_refresh_state(joydev);
        }
 
        mutex_unlock(&joydev->mutex);
@@ -872,7 +885,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
                j = joydev->abspam[i];
                if (input_abs_get_max(dev, j) == input_abs_get_min(dev, j)) {
                        joydev->corr[i].type = JS_CORR_NONE;
-                       joydev->abs[i] = input_abs_get_val(dev, j);
                        continue;
                }
                joydev->corr[i].type = JS_CORR_BROKEN;
@@ -887,10 +899,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
                if (t) {
                        joydev->corr[i].coef[2] = (1 << 29) / t;
                        joydev->corr[i].coef[3] = (1 << 29) / t;
-
-                       joydev->abs[i] =
-                               joydev_correct(input_abs_get_val(dev, j),
-                                              joydev->corr + i);
                }
        }
 
index 8aa6e4c497da77c70df1827934b696c2bc4c0159..ff54e195d42c34fea48342460ae83f668bfe4752 100644 (file)
@@ -139,7 +139,6 @@ static int probe_maple_controller(struct device *dev)
        idev->dev.parent = &mdev->dev;
        idev->name = mdev->product_name;
        idev->id.bustype = BUS_HOST;
-       input_set_drvdata(idev, pad);
 
        error = input_register_device(idev);
        if (error)
index c7d5b2b643d10798eb7da917f16888a2cff2bc3b..155fcb3b6230a01da6d1de3ab772e508b56fef78 100644 (file)
@@ -320,18 +320,18 @@ static struct usb_device_id xpad_table[] = {
        XPAD_XBOXONE_VENDOR(0x0738),            /* Mad Catz FightStick TE 2 */
        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(0x12ab),            /* X-Box 360 dance pads */
        XPAD_XBOX360_VENDOR(0x1430),            /* RedOctane X-Box 360 controllers */
        XPAD_XBOX360_VENDOR(0x146b),            /* BigBen Interactive Controllers */
-       XPAD_XBOX360_VENDOR(0x1bad),            /* Harminix Rock Band Guitar and Drums */
-       XPAD_XBOX360_VENDOR(0x0f0d),            /* Hori Controllers */
-       XPAD_XBOXONE_VENDOR(0x0f0d),            /* Hori Controllers */
-       XPAD_XBOX360_VENDOR(0x1689),            /* Razer Onza */
-       XPAD_XBOX360_VENDOR(0x24c6),            /* PowerA Controllers */
-       XPAD_XBOXONE_VENDOR(0x24c6),            /* PowerA Controllers */
        XPAD_XBOX360_VENDOR(0x1532),            /* Razer Sabertooth */
        XPAD_XBOX360_VENDOR(0x15e4),            /* Numark X-Box 360 controllers */
        XPAD_XBOX360_VENDOR(0x162e),            /* Joytech X-Box 360 controllers */
+       XPAD_XBOX360_VENDOR(0x1689),            /* Razer Onza */
+       XPAD_XBOX360_VENDOR(0x1bad),            /* Harminix Rock Band Guitar and Drums */
+       XPAD_XBOX360_VENDOR(0x24c6),            /* PowerA Controllers */
+       XPAD_XBOXONE_VENDOR(0x24c6),            /* PowerA Controllers */
        { }
 };
 
@@ -389,6 +389,7 @@ struct usb_xpad {
 
 static int xpad_init_input(struct usb_xpad *xpad);
 static void xpad_deinit_input(struct usb_xpad *xpad);
+static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num);
 
 /*
  *     xpad_process_packet
@@ -608,14 +609,36 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
 }
 
 /*
- *     xpadone_process_buttons
+ *     xpadone_process_packet
+ *
+ *     Completes a request by converting the data into events for the
+ *     input subsystem. This version is for the Xbox One controller.
  *
- *     Process a button update packet from an Xbox one controller.
+ *     The report format was gleaned from
+ *     https://github.com/kylelemons/xbox/blob/master/xbox.go
  */
-static void xpadone_process_buttons(struct usb_xpad *xpad,
-                               struct input_dev *dev,
-                               unsigned char *data)
+static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
 {
+       struct input_dev *dev = xpad->dev;
+
+       /* the xbox button has its own special report */
+       if (data[0] == 0X07) {
+               /*
+                * The Xbox One S controller requires these reports to be
+                * acked otherwise it continues sending them forever and
+                * won't report further mode button events.
+                */
+               if (data[1] == 0x30)
+                       xpadone_ack_mode_report(xpad, data[2]);
+
+               input_report_key(dev, BTN_MODE, data[4] & 0x01);
+               input_sync(dev);
+               return;
+       }
+       /* check invalid packet */
+       else if (data[0] != 0X20)
+               return;
+
        /* menu/view buttons */
        input_report_key(dev, BTN_START,  data[4] & 0x04);
        input_report_key(dev, BTN_SELECT, data[4] & 0x08);
@@ -678,34 +701,6 @@ static void xpadone_process_buttons(struct usb_xpad *xpad,
        input_sync(dev);
 }
 
-/*
- *     xpadone_process_packet
- *
- *     Completes a request by converting the data into events for the
- *     input subsystem. This version is for the Xbox One controller.
- *
- *     The report format was gleaned from
- *     https://github.com/kylelemons/xbox/blob/master/xbox.go
- */
-
-static void xpadone_process_packet(struct usb_xpad *xpad,
-                               u16 cmd, unsigned char *data)
-{
-       struct input_dev *dev = xpad->dev;
-
-       switch (data[0]) {
-       case 0x20:
-               xpadone_process_buttons(xpad, dev, data);
-               break;
-
-       case 0x07:
-               /* the xbox button has its own special report */
-               input_report_key(dev, BTN_MODE, data[4] & 0x01);
-               input_sync(dev);
-               break;
-       }
-}
-
 static void xpad_irq_in(struct urb *urb)
 {
        struct usb_xpad *xpad = urb->context;
@@ -850,10 +845,9 @@ static void xpad_irq_out(struct urb *urb)
        spin_unlock_irqrestore(&xpad->odata_lock, flags);
 }
 
-static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
+static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad,
+                       struct usb_endpoint_descriptor *ep_irq_out)
 {
-       struct usb_endpoint_descriptor *ep_irq_out;
-       int ep_irq_out_idx;
        int error;
 
        if (xpad->xtype == XTYPE_UNKNOWN)
@@ -863,23 +857,17 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
 
        xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
                                         GFP_KERNEL, &xpad->odata_dma);
-       if (!xpad->odata) {
-               error = -ENOMEM;
-               goto fail1;
-       }
+       if (!xpad->odata)
+               return -ENOMEM;
 
        spin_lock_init(&xpad->odata_lock);
 
        xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
        if (!xpad->irq_out) {
                error = -ENOMEM;
-               goto fail2;
+               goto err_free_coherent;
        }
 
-       /* Xbox One controller has in/out endpoints swapped. */
-       ep_irq_out_idx = xpad->xtype == XTYPE_XBOXONE ? 0 : 1;
-       ep_irq_out = &intf->cur_altsetting->endpoint[ep_irq_out_idx].desc;
-
        usb_fill_int_urb(xpad->irq_out, xpad->udev,
                         usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
                         xpad->odata, XPAD_PKT_LEN,
@@ -889,8 +877,9 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
 
        return 0;
 
- fail2:        usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
- fail1:        return error;
+err_free_coherent:
+       usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
+       return error;
 }
 
 static void xpad_stop_output(struct usb_xpad *xpad)
@@ -974,6 +963,30 @@ static int xpad_start_xbox_one(struct usb_xpad *xpad)
        return retval;
 }
 
+static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num)
+{
+       unsigned long flags;
+       struct xpad_output_packet *packet =
+                       &xpad->out_packets[XPAD_OUT_CMD_IDX];
+       static const u8 mode_report_ack[] = {
+               0x01, 0x20, 0x00, 0x09, 0x00, 0x07, 0x20, 0x02,
+               0x00, 0x00, 0x00, 0x00, 0x00
+       };
+
+       spin_lock_irqsave(&xpad->odata_lock, flags);
+
+       packet->len = sizeof(mode_report_ack);
+       memcpy(packet->data, mode_report_ack, packet->len);
+       packet->data[2] = seq_num;
+       packet->pending = true;
+
+       /* Reset the sequence so we send out the ack now */
+       xpad->last_out_packet = -1;
+       xpad_try_sending_next_out_packet(xpad);
+
+       spin_unlock_irqrestore(&xpad->odata_lock, flags);
+}
+
 #ifdef CONFIG_JOYSTICK_XPAD_FF
 static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
 {
@@ -1198,6 +1211,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
        led_cdev = &led->led_cdev;
        led_cdev->name = led->name;
        led_cdev->brightness_set = xpad_led_set;
+       led_cdev->flags = LED_CORE_SUSPENDRESUME;
 
        error = led_classdev_register(&xpad->udev->dev, led_cdev);
        if (error)
@@ -1468,8 +1482,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 {
        struct usb_device *udev = interface_to_usbdev(intf);
        struct usb_xpad *xpad;
-       struct usb_endpoint_descriptor *ep_irq_in;
-       int ep_irq_in_idx;
+       struct usb_endpoint_descriptor *ep_irq_in, *ep_irq_out;
        int i, error;
 
        if (intf->cur_altsetting->desc.bNumEndpoints != 2)
@@ -1539,13 +1552,26 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
                goto err_free_in_urb;
        }
 
-       error = xpad_init_output(intf, xpad);
-       if (error)
+       ep_irq_in = ep_irq_out = NULL;
+
+       for (i = 0; i < 2; i++) {
+               struct usb_endpoint_descriptor *ep =
+                               &intf->cur_altsetting->endpoint[i].desc;
+
+               if (usb_endpoint_dir_in(ep))
+                       ep_irq_in = ep;
+               else
+                       ep_irq_out = ep;
+       }
+
+       if (!ep_irq_in || !ep_irq_out) {
+               error = -ENODEV;
                goto err_free_in_urb;
+       }
 
-       /* Xbox One controller has in/out endpoints swapped. */
-       ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0;
-       ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc;
+       error = xpad_init_output(intf, xpad, ep_irq_out);
+       if (error)
+               goto err_free_in_urb;
 
        usb_fill_int_urb(xpad->irq_in, udev,
                         usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
@@ -1662,8 +1688,16 @@ static int xpad_resume(struct usb_interface *intf)
                retval = xpad360w_start_input(xpad);
        } else {
                mutex_lock(&input->mutex);
-               if (input->users)
+               if (input->users) {
                        retval = xpad_start_input(xpad);
+               } else if (xpad->xtype == XTYPE_XBOXONE) {
+                       /*
+                        * Even if there are no users, we'll send Xbox One pads
+                        * the startup sequence so they don't sit there and
+                        * blink until somebody opens the input device again.
+                        */
+                       retval = xpad_start_xbox_one(xpad);
+               }
                mutex_unlock(&input->mutex);
        }
 
index cbd75cf44739b19354decf0b0ebf3602cb2113c3..97acd6524ad7c37bc93cb3acc070fb171f76520c 100644 (file)
@@ -666,6 +666,17 @@ config KEYBOARD_TC3589X
          To compile this driver as a module, choose M here: the
          module will be called tc3589x-keypad.
 
+config KEYBOARD_TM2_TOUCHKEY
+       tristate "TM2 touchkey support"
+       depends on I2C
+       depends on LEDS_CLASS
+       help
+         Say Y here to enable device driver for tm2-touchkey with
+         LED control for the Exynos5433 TM2 board.
+
+         To compile this driver as a module, choose M here.
+         module will be called tm2-touchkey.
+
 config KEYBOARD_TWL4030
        tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
        depends on TWL4030_CORE
index d9f4cfcf34104dc1c579e14969c2249e81a66df7..7d9acff819a7899c0b8031554a073136cc8a1377 100644 (file)
@@ -61,6 +61,7 @@ obj-$(CONFIG_KEYBOARD_SUN4I_LRADC)    += sun4i-lradc-keys.o
 obj-$(CONFIG_KEYBOARD_SUNKBD)          += sunkbd.o
 obj-$(CONFIG_KEYBOARD_TC3589X)         += tc3589x-keypad.o
 obj-$(CONFIG_KEYBOARD_TEGRA)           += tegra-kbc.o
+obj-$(CONFIG_KEYBOARD_TM2_TOUCHKEY)    += tm2-touchkey.o
 obj-$(CONFIG_KEYBOARD_TWL4030)         += twl4030_keypad.o
 obj-$(CONFIG_KEYBOARD_XTKBD)           += xtkbd.o
 obj-$(CONFIG_KEYBOARD_W90P910)         += w90p910_keypad.o
index f8cf2ccacefd3655b9a6751ed0c63dd63f94621b..c255af21e71ab58b6e9b6ef8c905ca7b02f8b14a 100644 (file)
@@ -148,8 +148,6 @@ static int adc_keys_probe(struct platform_device *pdev)
        if (error)
                return error;
 
-       platform_set_drvdata(pdev, st);
-
        poll_dev = devm_input_allocate_polled_device(dev);
        if (!poll_dev) {
                dev_err(dev, "failed to allocate input device\n");
index db1004dad10819d55689e4293d93328e08eac3b5..f0b9b37bde5854275f045bbe71f38b89f4afcd6c 100644 (file)
@@ -107,8 +107,6 @@ static int adp5520_keys_probe(struct platform_device *pdev)
        input->phys = "adp5520-keys/input0";
        input->dev.parent = &pdev->dev;
 
-       input_set_drvdata(input, dev);
-
        input->id.bustype = BUS_I2C;
        input->id.vendor = 0x0001;
        input->id.product = 0x5520;
index 86a8b723ae1533db37f87ae400ad3f30638973e1..e1cf63ee148f5e67ddd45fde5c9fa41200faf6c6 100644 (file)
@@ -213,7 +213,7 @@ static int bcm_kp_matrix_key_parse_dt(struct bcm_kp *kp)
        /* Initialize the KPCR Keypad Configuration Register */
        kp->kpcr = KPCR_STATUSFILTERENABLE | KPCR_COLFILTERENABLE;
 
-       error = matrix_keypad_parse_of_params(dev, &kp->n_rows, &kp->n_cols);
+       error = matrix_keypad_parse_properties(dev, &kp->n_rows, &kp->n_cols);
        if (error) {
                dev_err(dev, "failed to parse kp params\n");
                return error;
@@ -352,8 +352,6 @@ static int bcm_kp_probe(struct platform_device *pdev)
 
        kp->input_dev = input_dev;
 
-       platform_set_drvdata(pdev, kp);
-
        error = bcm_kp_matrix_key_parse_dt(kp);
        if (error)
                return error;
index 81b07dddae86e93dbbf46a7c6af9c05ad66a1c94..39bcbc38997fcd193a5f2bbfc51f1494b5b39c1e 100644 (file)
@@ -268,8 +268,6 @@ static int bfin_kpad_probe(struct platform_device *pdev)
        input->phys = "bf54x-keys/input0";
        input->dev.parent = &pdev->dev;
 
-       input_set_drvdata(input, bf54x_kpad);
-
        input->id.bustype = BUS_HOST;
        input->id.vendor = 0x0001;
        input->id.product = 0x0001;
index 4401be225d64b28b8ffa798ba71cce07c8a81282..1a1eacae3ea14295f7b1284d83dd9b0f68ef7a29 100644 (file)
@@ -392,7 +392,6 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
                return error;
 
        dev_info(dev, "CAP11XX detected, revision 0x%02x\n", rev);
-       i2c_set_clientdata(i2c_client, priv);
        node = dev->of_node;
 
        if (!of_property_read_u32(node, "microchip,sensor-gain", &gain32)) {
index 604c7ade8df2c697a484c85600a0453209a21e20..6a250d65f8fe200b29608c1ff56281705e325904 100644 (file)
@@ -535,7 +535,7 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
        const char *phys;
        int err;
 
-       err = matrix_keypad_parse_of_params(dev, &ckdev->rows, &ckdev->cols);
+       err = matrix_keypad_parse_properties(dev, &ckdev->rows, &ckdev->cols);
        if (err)
                return err;
 
index f363d1d2907afbec9b2df607bfa6d1301a714c61..b20a5d044caa096f1fd05ef90a781b0cde0de00f 100644 (file)
@@ -172,7 +172,7 @@ static int __init davinci_ks_probe(struct platform_device *pdev)
        struct input_dev *key_dev;
        struct resource *res, *mem;
        struct device *dev = &pdev->dev;
-       struct davinci_ks_platform_data *pdata = dev_get_platdata(&pdev->dev);
+       struct davinci_ks_platform_data *pdata = dev_get_platdata(dev);
        int error, i;
 
        if (pdata->device_enable) {
@@ -255,7 +255,7 @@ static int __init davinci_ks_probe(struct platform_device *pdev)
 
        key_dev->name = "davinci_keyscan";
        key_dev->phys = "davinci_keyscan/input0";
-       key_dev->dev.parent = &pdev->dev;
+       key_dev->dev.parent = dev;
        key_dev->id.bustype = BUS_HOST;
        key_dev->id.vendor = 0x0001;
        key_dev->id.product = 0x0001;
index 582462d0af758566a3611b3b7bac7328b6d491a0..9c92cdf196e34125a9bc9cdb634daec0497a8575 100644 (file)
@@ -36,6 +36,8 @@ struct gpio_button_data {
        struct input_dev *input;
        struct gpio_desc *gpiod;
 
+       unsigned short *code;
+
        struct timer_list release_timer;
        unsigned int release_delay;     /* in msecs, for IRQ-only buttons */
 
@@ -52,6 +54,7 @@ struct gpio_keys_drvdata {
        const struct gpio_keys_platform_data *pdata;
        struct input_dev *input;
        struct mutex disable_lock;
+       unsigned short *keymap;
        struct gpio_button_data data[0];
 };
 
@@ -203,7 +206,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata,
                if (only_disabled && !bdata->disabled)
                        continue;
 
-               __set_bit(bdata->button->code, bits);
+               __set_bit(*bdata->code, bits);
        }
 
        ret = scnprintf(buf, PAGE_SIZE - 1, "%*pbl", n_events, bits);
@@ -254,7 +257,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
                if (bdata->button->type != type)
                        continue;
 
-               if (test_bit(bdata->button->code, bits) &&
+               if (test_bit(*bdata->code, bits) &&
                    !bdata->button->can_disable) {
                        error = -EINVAL;
                        goto out;
@@ -269,7 +272,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
                if (bdata->button->type != type)
                        continue;
 
-               if (test_bit(bdata->button->code, bits))
+               if (test_bit(*bdata->code, bits))
                        gpio_keys_disable_button(bdata);
                else
                        gpio_keys_enable_button(bdata);
@@ -371,7 +374,7 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
                if (state)
                        input_event(input, type, button->code, button->value);
        } else {
-               input_event(input, type, button->code, state);
+               input_event(input, type, *bdata->code, state);
        }
        input_sync(input);
 }
@@ -411,7 +414,7 @@ static void gpio_keys_irq_timer(unsigned long _data)
 
        spin_lock_irqsave(&bdata->lock, flags);
        if (bdata->key_pressed) {
-               input_event(input, EV_KEY, bdata->button->code, 0);
+               input_event(input, EV_KEY, *bdata->code, 0);
                input_sync(input);
                bdata->key_pressed = false;
        }
@@ -421,7 +424,6 @@ static void gpio_keys_irq_timer(unsigned long _data)
 static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
 {
        struct gpio_button_data *bdata = dev_id;
-       const struct gpio_keys_button *button = bdata->button;
        struct input_dev *input = bdata->input;
        unsigned long flags;
 
@@ -433,11 +435,11 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
                if (bdata->button->wakeup)
                        pm_wakeup_event(bdata->input->dev.parent, 0);
 
-               input_event(input, EV_KEY, button->code, 1);
+               input_event(input, EV_KEY, *bdata->code, 1);
                input_sync(input);
 
                if (!bdata->release_delay) {
-                       input_event(input, EV_KEY, button->code, 0);
+                       input_event(input, EV_KEY, *bdata->code, 0);
                        input_sync(input);
                        goto out;
                }
@@ -465,12 +467,14 @@ static void gpio_keys_quiesce_key(void *data)
 
 static int gpio_keys_setup_key(struct platform_device *pdev,
                                struct input_dev *input,
-                               struct gpio_button_data *bdata,
+                               struct gpio_keys_drvdata *ddata,
                                const struct gpio_keys_button *button,
+                               int idx,
                                struct fwnode_handle *child)
 {
        const char *desc = button->desc ? button->desc : "gpio_keys";
        struct device *dev = &pdev->dev;
+       struct gpio_button_data *bdata = &ddata->data[idx];
        irq_handler_t isr;
        unsigned long irqflags;
        int irq;
@@ -514,8 +518,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
                if (button->active_low)
                        flags |= GPIOF_ACTIVE_LOW;
 
-               error = devm_gpio_request_one(&pdev->dev, button->gpio, flags,
-                                             desc);
+               error = devm_gpio_request_one(dev, button->gpio, flags, desc);
                if (error < 0) {
                        dev_err(dev, "Failed to request GPIO %d, error %d\n",
                                button->gpio, error);
@@ -577,16 +580,17 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
                irqflags = 0;
        }
 
-       input_set_capability(input, button->type ?: EV_KEY, button->code);
+       bdata->code = &ddata->keymap[idx];
+       *bdata->code = button->code;
+       input_set_capability(input, button->type ?: EV_KEY, *bdata->code);
 
        /*
         * Install custom action to cancel release timer and
         * workqueue item.
         */
-       error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata);
+       error = devm_add_action(dev, gpio_keys_quiesce_key, bdata);
        if (error) {
-               dev_err(&pdev->dev,
-                       "failed to register quiesce action, error: %d\n",
+               dev_err(dev, "failed to register quiesce action, error: %d\n",
                        error);
                return error;
        }
@@ -598,8 +602,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
        if (!button->can_disable)
                irqflags |= IRQF_SHARED;
 
-       error = devm_request_any_context_irq(&pdev->dev, bdata->irq,
-                                            isr, irqflags, desc, bdata);
+       error = devm_request_any_context_irq(dev, bdata->irq, isr, irqflags,
+                                            desc, bdata);
        if (error < 0) {
                dev_err(dev, "Unable to claim irq %d; error %d\n",
                        bdata->irq, error);
@@ -750,6 +754,12 @@ static int gpio_keys_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
+       ddata->keymap = devm_kcalloc(dev,
+                                    pdata->nbuttons, sizeof(ddata->keymap[0]),
+                                    GFP_KERNEL);
+       if (!ddata->keymap)
+               return -ENOMEM;
+
        input = devm_input_allocate_device(dev);
        if (!input) {
                dev_err(dev, "failed to allocate input device\n");
@@ -765,7 +775,7 @@ static int gpio_keys_probe(struct platform_device *pdev)
 
        input->name = pdata->name ? : pdev->name;
        input->phys = "gpio-keys/input0";
-       input->dev.parent = &pdev->dev;
+       input->dev.parent = dev;
        input->open = gpio_keys_open;
        input->close = gpio_keys_close;
 
@@ -774,25 +784,29 @@ static int gpio_keys_probe(struct platform_device *pdev)
        input->id.product = 0x0001;
        input->id.version = 0x0100;
 
+       input->keycode = ddata->keymap;
+       input->keycodesize = sizeof(ddata->keymap[0]);
+       input->keycodemax = pdata->nbuttons;
+
        /* Enable auto repeat feature of Linux input subsystem */
        if (pdata->rep)
                __set_bit(EV_REP, input->evbit);
 
        for (i = 0; i < pdata->nbuttons; i++) {
                const struct gpio_keys_button *button = &pdata->buttons[i];
-               struct gpio_button_data *bdata = &ddata->data[i];
 
                if (!dev_get_platdata(dev)) {
-                       child = device_get_next_child_node(&pdev->dev, child);
+                       child = device_get_next_child_node(dev, child);
                        if (!child) {
-                               dev_err(&pdev->dev,
+                               dev_err(dev,
                                        "missing child device node for entry %d\n",
                                        i);
                                return -EINVAL;
                        }
                }
 
-               error = gpio_keys_setup_key(pdev, input, bdata, button, child);
+               error = gpio_keys_setup_key(pdev, input, ddata,
+                                           button, i, child);
                if (error) {
                        fwnode_handle_put(child);
                        return error;
@@ -804,7 +818,7 @@ static int gpio_keys_probe(struct platform_device *pdev)
 
        fwnode_handle_put(child);
 
-       error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group);
+       error = sysfs_create_group(&dev->kobj, &gpio_keys_attr_group);
        if (error) {
                dev_err(dev, "Unable to export keys/switches, error: %d\n",
                        error);
@@ -818,12 +832,12 @@ static int gpio_keys_probe(struct platform_device *pdev)
                goto err_remove_group;
        }
 
-       device_init_wakeup(&pdev->dev, wakeup);
+       device_init_wakeup(dev, wakeup);
 
        return 0;
 
 err_remove_group:
-       sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group);
+       sysfs_remove_group(&dev->kobj, &gpio_keys_attr_group);
        return error;
 }
 
@@ -831,8 +845,6 @@ static int gpio_keys_remove(struct platform_device *pdev)
 {
        sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group);
 
-       device_init_wakeup(&pdev->dev, 0);
-
        return 0;
 }
 
index bed4f2086158e3073b325dcc75fbcac3c51df4da..4fce43a6a0e0c12f851944cbe175de74e1cb53f1 100644 (file)
@@ -252,13 +252,13 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
 
        size = sizeof(struct gpio_keys_polled_dev) +
                        pdata->nbuttons * sizeof(struct gpio_keys_button_data);
-       bdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
+       bdev = devm_kzalloc(dev, size, GFP_KERNEL);
        if (!bdev) {
                dev_err(dev, "no memory for private data\n");
                return -ENOMEM;
        }
 
-       poll_dev = devm_input_allocate_polled_device(&pdev->dev);
+       poll_dev = devm_input_allocate_polled_device(dev);
        if (!poll_dev) {
                dev_err(dev, "no memory for polled device\n");
                return -ENOMEM;
@@ -332,7 +332,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
                        if (button->active_low)
                                flags |= GPIOF_ACTIVE_LOW;
 
-                       error = devm_gpio_request_one(&pdev->dev, button->gpio,
+                       error = devm_gpio_request_one(dev, button->gpio,
                                        flags, button->desc ? : DRV_NAME);
                        if (error) {
                                dev_err(dev,
@@ -365,7 +365,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
        bdev->poll_dev = poll_dev;
        bdev->dev = dev;
        bdev->pdata = pdata;
-       platform_set_drvdata(pdev, bdev);
 
        error = input_register_polled_device(poll_dev);
        if (error) {
index 80c81278ad2c39b6cbddd1b80452c4798a4014d7..0116ac99f44ce110ea060b1e52f8bdbd291f5378 100644 (file)
@@ -197,8 +197,6 @@ static int jornada680kbd_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       platform_set_drvdata(pdev, jornadakbd);
-
        jornadakbd->poll_dev = poll_dev;
 
        memcpy(jornadakbd->keymap, jornada_scancodes,
index 632523d4f5dc11b21e1591ccd79f841dbb640194..1dd57ac0e7a27158cf996b5e4b0a9e4027ae4a1e 100644 (file)
@@ -145,7 +145,7 @@ static int lpc32xx_parse_dt(struct device *dev,
        u32 rows = 0, columns = 0;
        int err;
 
-       err = matrix_keypad_parse_of_params(dev, &rows, &columns);
+       err = matrix_keypad_parse_properties(dev, &rows, &columns);
        if (err)
                return err;
        if (rows != columns) {
index 5aa2361aef95be73080e1392185ac57a2275a220..78e3567ec18c39e14e51d62d6a2c673caa116431 100644 (file)
@@ -196,7 +196,6 @@ static int probe_maple_kbd(struct device *dev)
        __clear_bit(KEY_RESERVED, idev->keybit);
 
        input_set_capability(idev, EV_MSC, MSC_SCAN);
-       input_set_drvdata(idev, kbd);
 
        error = input_register_device(idev);
        if (error)
index 7f12b6579f822d48add2f6f42ab7f8a1ad068d11..18839cd5f76e089dc3da912cad7b7f04f6a302e9 100644 (file)
@@ -545,8 +545,6 @@ static int matrix_keypad_remove(struct platform_device *pdev)
 {
        struct matrix_keypad *keypad = platform_get_drvdata(pdev);
 
-       device_init_wakeup(&pdev->dev, 0);
-
        matrix_keypad_free_gpio(keypad);
        input_unregister_device(keypad->input_dev);
        kfree(keypad);
index 5091133b7b8eac7d2c89da972dbefc6ce8164787..cd44d22d8770388e19a56f5fc01f8c9c380042ca 100644 (file)
@@ -241,7 +241,6 @@ static int max7359_probe(struct i2c_client *client,
        /* Initialize MAX7359 */
        max7359_initialize(client);
 
-       i2c_set_clientdata(client, keypad);
        device_init_wakeup(&client->dev, 1);
 
        return 0;
index 0fd612dd76edec57f8cf18d5ea6df87f06de56cb..884a74d8a7edf50b26f9e62a4ce731d77d9f2c8e 100644 (file)
  *
  */
 
-#include <linux/module.h>
-#include <linux/input.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
 #include <linux/interrupt.h>
-#include <linux/i2c/mpr121_touchkey.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 
 /* Register definitions */
 #define ELE_TOUCH_STATUS_0_ADDR        0x0
 struct mpr121_touchkey {
        struct i2c_client       *client;
        struct input_dev        *input_dev;
-       unsigned int            key_val;
        unsigned int            statusbits;
        unsigned int            keycount;
-       u16                     keycodes[MPR121_MAX_KEY_COUNT];
+       u32                     keycodes[MPR121_MAX_KEY_COUNT];
 };
 
 struct mpr121_init_register {
@@ -82,12 +83,49 @@ static const struct mpr121_init_register init_reg_table[] = {
        { AUTO_CONFIG_CTRL_ADDR, 0x0b },
 };
 
+static void mpr121_vdd_supply_disable(void *data)
+{
+       struct regulator *vdd_supply = data;
+
+       regulator_disable(vdd_supply);
+}
+
+static struct regulator *mpr121_vdd_supply_init(struct device *dev)
+{
+       struct regulator *vdd_supply;
+       int err;
+
+       vdd_supply = devm_regulator_get(dev, "vdd");
+       if (IS_ERR(vdd_supply)) {
+               dev_err(dev, "failed to get vdd regulator: %ld\n",
+                       PTR_ERR(vdd_supply));
+               return vdd_supply;
+       }
+
+       err = regulator_enable(vdd_supply);
+       if (err) {
+               dev_err(dev, "failed to enable vdd regulator: %d\n", err);
+               return ERR_PTR(err);
+       }
+
+       err = devm_add_action(dev, mpr121_vdd_supply_disable, vdd_supply);
+       if (err) {
+               regulator_disable(vdd_supply);
+               dev_err(dev, "failed to add disable regulator action: %d\n",
+                       err);
+               return ERR_PTR(err);
+       }
+
+       return vdd_supply;
+}
+
 static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
 {
        struct mpr121_touchkey *mpr121 = dev_id;
        struct i2c_client *client = mpr121->client;
        struct input_dev *input = mpr121->input_dev;
-       unsigned int key_num, key_val, pressed;
+       unsigned long bit_changed;
+       unsigned int key_num;
        int reg;
 
        reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR);
@@ -105,26 +143,29 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
 
        reg &= TOUCH_STATUS_MASK;
        /* use old press bit to figure out which bit changed */
-       key_num = ffs(reg ^ mpr121->statusbits) - 1;
-       pressed = reg & (1 << key_num);
+       bit_changed = reg ^ mpr121->statusbits;
        mpr121->statusbits = reg;
+       for_each_set_bit(key_num, &bit_changed, mpr121->keycount) {
+               unsigned int key_val, pressed;
 
-       key_val = mpr121->keycodes[key_num];
+               pressed = reg & BIT(key_num);
+               key_val = mpr121->keycodes[key_num];
 
-       input_event(input, EV_MSC, MSC_SCAN, key_num);
-       input_report_key(input, key_val, pressed);
-       input_sync(input);
+               input_event(input, EV_MSC, MSC_SCAN, key_num);
+               input_report_key(input, key_val, pressed);
 
-       dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val,
-               pressed ? "pressed" : "released");
+               dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val,
+                       pressed ? "pressed" : "released");
+
+       }
+       input_sync(input);
 
 out:
        return IRQ_HANDLED;
 }
 
-static int mpr121_phys_init(const struct mpr121_platform_data *pdata,
-                                     struct mpr121_touchkey *mpr121,
-                                     struct i2c_client *client)
+static int mpr121_phys_init(struct mpr121_touchkey *mpr121,
+                           struct i2c_client *client, int vdd_uv)
 {
        const struct mpr121_init_register *reg;
        unsigned char usl, lsl, tl, eleconf;
@@ -154,9 +195,9 @@ static int mpr121_phys_init(const struct mpr121_platform_data *pdata,
        /*
         * Capacitance on sensing input varies and needs to be compensated.
         * The internal MPR121-auto-configuration can do this if it's
-        * registers are set properly (based on pdata->vdd_uv).
+        * registers are set properly (based on vdd_uv).
         */
-       vdd = pdata->vdd_uv / 1000;
+       vdd = vdd_uv / 1000;
        usl = ((vdd - 700) * 256) / vdd;
        lsl = (usl * 65) / 100;
        tl = (usl * 90) / 100;
@@ -187,72 +228,77 @@ err_i2c_write:
 static int mpr_touchkey_probe(struct i2c_client *client,
                              const struct i2c_device_id *id)
 {
-       const struct mpr121_platform_data *pdata =
-                       dev_get_platdata(&client->dev);
+       struct device *dev = &client->dev;
+       struct regulator *vdd_supply;
+       int vdd_uv;
        struct mpr121_touchkey *mpr121;
        struct input_dev *input_dev;
        int error;
        int i;
 
-       if (!pdata) {
-               dev_err(&client->dev, "no platform data defined\n");
-               return -EINVAL;
-       }
-
-       if (!pdata->keymap || !pdata->keymap_size) {
-               dev_err(&client->dev, "missing keymap data\n");
+       if (!client->irq) {
+               dev_err(dev, "irq number should not be zero\n");
                return -EINVAL;
        }
 
-       if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) {
-               dev_err(&client->dev, "too many keys defined\n");
-               return -EINVAL;
-       }
+       vdd_supply = mpr121_vdd_supply_init(dev);
+       if (IS_ERR(vdd_supply))
+               return PTR_ERR(vdd_supply);
 
-       if (!client->irq) {
-               dev_err(&client->dev, "irq number should not be zero\n");
-               return -EINVAL;
-       }
+       vdd_uv = regulator_get_voltage(vdd_supply);
 
-       mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121),
-                             GFP_KERNEL);
+       mpr121 = devm_kzalloc(dev, sizeof(*mpr121), GFP_KERNEL);
        if (!mpr121)
                return -ENOMEM;
 
-       input_dev = devm_input_allocate_device(&client->dev);
+       input_dev = devm_input_allocate_device(dev);
        if (!input_dev)
                return -ENOMEM;
 
        mpr121->client = client;
        mpr121->input_dev = input_dev;
-       mpr121->keycount = pdata->keymap_size;
+       mpr121->keycount = device_property_read_u32_array(dev, "linux,keycodes",
+                                                         NULL, 0);
+       if (mpr121->keycount > MPR121_MAX_KEY_COUNT) {
+               dev_err(dev, "too many keys defined (%d)\n", mpr121->keycount);
+               return -EINVAL;
+       }
+
+       error = device_property_read_u32_array(dev, "linux,keycodes",
+                                              mpr121->keycodes,
+                                              mpr121->keycount);
+       if (error) {
+               dev_err(dev,
+                       "failed to read linux,keycode property: %d\n", error);
+               return error;
+       }
 
        input_dev->name = "Freescale MPR121 Touchkey";
        input_dev->id.bustype = BUS_I2C;
-       input_dev->dev.parent = &client->dev;
-       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+       input_dev->dev.parent = dev;
+       if (device_property_read_bool(dev, "autorepeat"))
+               __set_bit(EV_REP, input_dev->evbit);
+       input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 
        input_dev->keycode = mpr121->keycodes;
        input_dev->keycodesize = sizeof(mpr121->keycodes[0]);
        input_dev->keycodemax = mpr121->keycount;
 
-       for (i = 0; i < pdata->keymap_size; i++) {
-               input_set_capability(input_dev, EV_KEY, pdata->keymap[i]);
-               mpr121->keycodes[i] = pdata->keymap[i];
-       }
+       for (i = 0; i < mpr121->keycount; i++)
+               input_set_capability(input_dev, EV_KEY, mpr121->keycodes[i]);
 
-       error = mpr121_phys_init(pdata, mpr121, client);
+       error = mpr121_phys_init(mpr121, client, vdd_uv);
        if (error) {
-               dev_err(&client->dev, "Failed to init register\n");
+               dev_err(dev, "Failed to init register\n");
                return error;
        }
 
-       error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
-                                    mpr_touchkey_interrupt,
-                                    IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                                    client->dev.driver->name, mpr121);
+       error = devm_request_threaded_irq(dev, client->irq, NULL,
+                                         mpr_touchkey_interrupt,
+                                         IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                         dev->driver->name, mpr121);
        if (error) {
-               dev_err(&client->dev, "Failed to register interrupt\n");
+               dev_err(dev, "Failed to register interrupt\n");
                return error;
        }
 
@@ -261,13 +307,13 @@ static int mpr_touchkey_probe(struct i2c_client *client,
                return error;
 
        i2c_set_clientdata(client, mpr121);
-       device_init_wakeup(&client->dev, pdata->wakeup);
+       device_init_wakeup(dev,
+                       device_property_read_bool(dev, "wakeup-source"));
 
        return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int mpr_suspend(struct device *dev)
+static int __maybe_unused mpr_suspend(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
 
@@ -279,7 +325,7 @@ static int mpr_suspend(struct device *dev)
        return 0;
 }
 
-static int mpr_resume(struct device *dev)
+static int __maybe_unused mpr_resume(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client);
@@ -292,7 +338,6 @@ static int mpr_resume(struct device *dev)
 
        return 0;
 }
-#endif
 
 static SIMPLE_DEV_PM_OPS(mpr121_touchkey_pm_ops, mpr_suspend, mpr_resume);
 
@@ -302,10 +347,19 @@ static const struct i2c_device_id mpr121_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, mpr121_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id mpr121_touchkey_dt_match_table[] = {
+       { .compatible = "fsl,mpr121-touchkey" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, mpr121_touchkey_dt_match_table);
+#endif
+
 static struct i2c_driver mpr_touchkey_driver = {
        .driver = {
                .name   = "mpr121",
                .pm     = &mpr121_touchkey_pm_ops,
+               .of_match_table = of_match_ptr(mpr121_touchkey_dt_match_table),
        },
        .id_table       = mpr121_id,
        .probe          = mpr_touchkey_probe,
index 7abfd34eb87ec5f7f1df56fbb307058c0cee3cdf..c7f26fa3034cac33b9e098a1a1a806648f7637ae 100644 (file)
@@ -249,8 +249,6 @@ static int nspire_keypad_probe(struct platform_device *pdev)
                return error;
        }
 
-       platform_set_drvdata(pdev, keypad);
-
        dev_dbg(&pdev->dev,
                "TI-NSPIRE keypad at %pR (scan_interval=%uus, row_delay=%uus%s)\n",
                res, keypad->row_delay, keypad->scan_interval,
index 6639b2b8528aa6da9a518d3bd3dc0da3010f4a09..ebc67ba41fe24a0bbadb952916c07b8df917cc66 100644 (file)
@@ -223,8 +223,8 @@ static int omap4_keypad_parse_dt(struct device *dev,
        struct device_node *np = dev->of_node;
        int err;
 
-       err = matrix_keypad_parse_of_params(dev, &keypad_data->rows,
-                                           &keypad_data->cols);
+       err = matrix_keypad_parse_properties(dev, &keypad_data->rows,
+                                            &keypad_data->cols);
        if (err)
                return err;
 
@@ -375,7 +375,6 @@ static int omap4_keypad_probe(struct platform_device *pdev)
 
 err_pm_disable:
        pm_runtime_disable(&pdev->dev);
-       device_init_wakeup(&pdev->dev, false);
        free_irq(keypad_data->irq, keypad_data);
 err_free_keymap:
        kfree(keypad_data->keymap);
@@ -401,8 +400,6 @@ static int omap4_keypad_remove(struct platform_device *pdev)
 
        pm_runtime_disable(&pdev->dev);
 
-       device_init_wakeup(&pdev->dev, false);
-
        input_unregister_device(keypad_data->input);
 
        iounmap(keypad_data->base);
index f8502bb291767c539d1a204ed34bc09d3e90c4b0..d62b4068c077993fb1cd1c7de3551062a40d4421 100644 (file)
@@ -75,8 +75,6 @@ static int opencores_kbd_probe(struct platform_device *pdev)
        input->name = pdev->name;
        input->phys = "opencores-kbd/input0";
 
-       input_set_drvdata(input, opencores_kbd);
-
        input->id.bustype = BUS_HOST;
        input->id.vendor = 0x0001;
        input->id.product = 0x0001;
@@ -112,8 +110,6 @@ static int opencores_kbd_probe(struct platform_device *pdev)
                return error;
        }
 
-       platform_set_drvdata(pdev, opencores_kbd);
-
        return 0;
 }
 
index 5c68e3f096bc83fce073f6ff7dfafe65fe7e8f56..97c5424f49b95df566a2fd84a5ad3ffdeb4cc75f 100644 (file)
@@ -515,7 +515,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
        int rc;
        unsigned int ctrl_val;
 
-       rc = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols);
+       rc = matrix_keypad_parse_properties(&pdev->dev, &rows, &cols);
        if (rc)
                return rc;
 
index e24443376e756fe6290cfba7e5dbb0aa5f336b9f..3841fa30db3343c2a7a4d464ea4d5ad77335830a 100644 (file)
@@ -126,7 +126,7 @@ static int pxa27x_keypad_matrix_key_parse_dt(struct pxa27x_keypad *keypad,
        u32 rows, cols;
        int error;
 
-       error = matrix_keypad_parse_of_params(dev, &rows, &cols);
+       error = matrix_keypad_parse_properties(dev, &rows, &cols);
        if (error)
                return error;
 
index 4e319eb9e19d9f75a67d7c2123cc3bf5550c86ad..316414465c779b23d8ec4a03b42d634013dca9a8 100644 (file)
@@ -445,7 +445,6 @@ static int samsung_keypad_probe(struct platform_device *pdev)
 
 err_disable_runtime_pm:
        pm_runtime_disable(&pdev->dev);
-       device_init_wakeup(&pdev->dev, 0);
 err_unprepare_clk:
        clk_unprepare(keypad->clk);
        return error;
@@ -456,7 +455,6 @@ static int samsung_keypad_remove(struct platform_device *pdev)
        struct samsung_keypad *keypad = platform_get_drvdata(pdev);
 
        pm_runtime_disable(&pdev->dev);
-       device_init_wakeup(&pdev->dev, 0);
 
        input_unregister_device(keypad->input_dev);
 
index 8083eaa0524ad8914d0fbc3eb240188741f6b44d..7d25fa338ab4c01408b3014b3f047702bd079717 100644 (file)
@@ -283,8 +283,6 @@ static int spear_kbd_remove(struct platform_device *pdev)
        input_unregister_device(kbd->input);
        clk_unprepare(kbd->clk);
 
-       device_init_wakeup(&pdev->dev, 0);
-
        return 0;
 }
 
index de7be4f03d9193884d248d506b6f75a306dbc17a..babcfb165e4f0060c854ee524582b3ec436e8978 100644 (file)
@@ -106,8 +106,8 @@ static int keypad_matrix_key_parse_dt(struct st_keyscan *keypad_data)
        struct device_node *np = dev->of_node;
        int error;
 
-       error = matrix_keypad_parse_of_params(dev, &keypad_data->n_rows,
-                                             &keypad_data->n_cols);
+       error = matrix_keypad_parse_properties(dev, &keypad_data->n_rows,
+                                              &keypad_data->n_cols);
        if (error) {
                dev_err(dev, "failed to parse keypad params\n");
                return error;
index fe6e3f22eed76157c42a1d9b873b01e34f38b5f2..8c6c0b9109c75e22bfdc290d4ecfacb88d911ca9 100644 (file)
@@ -354,7 +354,7 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
        input->id.bustype = BUS_I2C;
        input->dev.parent = &pdev->dev;
 
-       error = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols);
+       error = matrix_keypad_parse_properties(&pdev->dev, &rows, &cols);
        if (error)
                return error;
 
index cc8f7ddcee53f1d94ff741ad6de03c3dea3f6910..a37c172452e6349780b66dc2c1c5075d4e4a246f 100644 (file)
@@ -261,7 +261,6 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
        if (error)
                return error;
 
-       platform_set_drvdata(pdev, lradc);
        return 0;
 }
 
index 3048ef3e3e1639e2f7d24b9e60c6cf45cfe01c8a..44dd7689c5711c281f4e9df93428c24aeff9e4ed 100644 (file)
  * alternative licensing inquiries.
  */
 
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/gpio.h>
 #include <linux/i2c.h>
+#include <linux/init.h>
 #include <linux/input.h>
-#include <linux/input/tca8418_keypad.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
 #include <linux/of.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+#include <linux/types.h>
 
 /* TCA8418 hardware limits */
 #define TCA8418_MAX_ROWS       8
@@ -264,41 +263,25 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data,
 }
 
 static int tca8418_keypad_probe(struct i2c_client *client,
-                                         const struct i2c_device_id *id)
+                               const struct i2c_device_id *id)
 {
        struct device *dev = &client->dev;
-       const struct tca8418_keypad_platform_data *pdata =
-                                               dev_get_platdata(dev);
        struct tca8418_keypad *keypad_data;
        struct input_dev *input;
-       const struct matrix_keymap_data *keymap_data = NULL;
        u32 rows = 0, cols = 0;
-       bool rep = false;
-       bool irq_is_gpio = false;
-       int irq;
        int error, row_shift, max_keys;
 
-       /* Copy the platform data */
-       if (pdata) {
-               if (!pdata->keymap_data) {
-                       dev_err(dev, "no keymap data defined\n");
-                       return -EINVAL;
-               }
-               keymap_data = pdata->keymap_data;
-               rows = pdata->rows;
-               cols = pdata->cols;
-               rep  = pdata->rep;
-               irq_is_gpio = pdata->irq_is_gpio;
-       } else {
-               struct device_node *np = dev->of_node;
-               int err;
-
-               err = matrix_keypad_parse_of_params(dev, &rows, &cols);
-               if (err)
-                       return err;
-               rep = of_property_read_bool(np, "keypad,autorepeat");
+       /* Check i2c driver capabilities */
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
+               dev_err(dev, "%s adapter not supported\n",
+                       dev_driver_string(&client->adapter->dev));
+               return -ENODEV;
        }
 
+       error = matrix_keypad_parse_properties(dev, &rows, &cols);
+       if (error)
+               return error;
+
        if (!rows || rows > TCA8418_MAX_ROWS) {
                dev_err(dev, "invalid rows\n");
                return -EINVAL;
@@ -309,13 +292,6 @@ static int tca8418_keypad_probe(struct i2c_client *client,
                return -EINVAL;
        }
 
-       /* Check i2c driver capabilities */
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
-               dev_err(dev, "%s adapter not supported\n",
-                       dev_driver_string(&client->adapter->dev));
-               return -ENODEV;
-       }
-
        row_shift = get_count_order(cols);
        max_keys = rows << row_shift;
 
@@ -345,27 +321,20 @@ static int tca8418_keypad_probe(struct i2c_client *client,
        input->id.product = 0x001;
        input->id.version = 0x0001;
 
-       error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols,
-                                          NULL, input);
+       error = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL, input);
        if (error) {
                dev_err(dev, "Failed to build keymap\n");
                return error;
        }
 
-       if (rep)
+       if (device_property_read_bool(dev, "keypad,autorepeat"))
                __set_bit(EV_REP, input->evbit);
-       input_set_capability(input, EV_MSC, MSC_SCAN);
-
-       input_set_drvdata(input, keypad_data);
 
-       irq = client->irq;
-       if (irq_is_gpio)
-               irq = gpio_to_irq(irq);
+       input_set_capability(input, EV_MSC, MSC_SCAN);
 
-       error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler,
-                                         IRQF_TRIGGER_FALLING |
-                                               IRQF_SHARED |
-                                               IRQF_ONESHOT,
+       error = devm_request_threaded_irq(dev, client->irq,
+                                         NULL, tca8418_irq_handler,
+                                         IRQF_SHARED | IRQF_ONESHOT,
                                          client->name, keypad_data);
        if (error) {
                dev_err(dev, "Unable to claim irq %d; error %d\n",
@@ -384,30 +353,21 @@ static int tca8418_keypad_probe(struct i2c_client *client,
 }
 
 static const struct i2c_device_id tca8418_id[] = {
-       { TCA8418_NAME, 8418, },
+       { "tca8418", 8418, },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, tca8418_id);
 
-#ifdef CONFIG_OF
 static const struct of_device_id tca8418_dt_ids[] = {
        { .compatible = "ti,tca8418", },
        { }
 };
 MODULE_DEVICE_TABLE(of, tca8418_dt_ids);
 
-/*
- * The device tree based i2c loader looks for
- * "i2c:" + second_component_of(property("compatible"))
- * and therefore we need an alias to be found.
- */
-MODULE_ALIAS("i2c:tca8418");
-#endif
-
 static struct i2c_driver tca8418_keypad_driver = {
        .driver = {
-               .name   = TCA8418_NAME,
-               .of_match_table = of_match_ptr(tca8418_dt_ids),
+               .name   = "tca8418_keypad",
+               .of_match_table = tca8418_dt_ids,
        },
        .probe          = tca8418_keypad_probe,
        .id_table       = tca8418_id,
diff --git a/drivers/input/keyboard/tm2-touchkey.c b/drivers/input/keyboard/tm2-touchkey.c
new file mode 100644 (file)
index 0000000..485900f
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * TM2 touchkey device driver
+ *
+ * Copyright 2005 Phil Blundell
+ * Copyright 2016 Samsung Electronics Co., Ltd.
+ *
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ * Author: Jaechul Lee <jcsing.lee@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.
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm.h>
+#include <linux/regulator/consumer.h>
+
+#define TM2_TOUCHKEY_DEV_NAME          "tm2-touchkey"
+#define TM2_TOUCHKEY_KEYCODE_REG       0x03
+#define TM2_TOUCHKEY_BASE_REG          0x00
+#define TM2_TOUCHKEY_CMD_LED_ON                0x10
+#define TM2_TOUCHKEY_CMD_LED_OFF       0x20
+#define TM2_TOUCHKEY_BIT_PRESS_EV      BIT(3)
+#define TM2_TOUCHKEY_BIT_KEYCODE       GENMASK(2, 0)
+#define TM2_TOUCHKEY_LED_VOLTAGE_MIN   2500000
+#define TM2_TOUCHKEY_LED_VOLTAGE_MAX   3300000
+
+enum {
+       TM2_TOUCHKEY_KEY_MENU = 0x1,
+       TM2_TOUCHKEY_KEY_BACK,
+};
+
+struct tm2_touchkey_data {
+       struct i2c_client *client;
+       struct input_dev *input_dev;
+       struct led_classdev led_dev;
+       struct regulator *vdd;
+       struct regulator_bulk_data regulators[2];
+};
+
+static void tm2_touchkey_led_brightness_set(struct led_classdev *led_dev,
+                                           enum led_brightness brightness)
+{
+       struct tm2_touchkey_data *touchkey =
+               container_of(led_dev, struct tm2_touchkey_data, led_dev);
+       u32 volt;
+       u8 data;
+
+       if (brightness == LED_OFF) {
+               volt = TM2_TOUCHKEY_LED_VOLTAGE_MIN;
+               data = TM2_TOUCHKEY_CMD_LED_OFF;
+       } else {
+               volt = TM2_TOUCHKEY_LED_VOLTAGE_MAX;
+               data = TM2_TOUCHKEY_CMD_LED_ON;
+       }
+
+       regulator_set_voltage(touchkey->vdd, volt, volt);
+       i2c_smbus_write_byte_data(touchkey->client,
+                                 TM2_TOUCHKEY_BASE_REG, data);
+}
+
+static int tm2_touchkey_power_enable(struct tm2_touchkey_data *touchkey)
+{
+       int error;
+
+       error = regulator_bulk_enable(ARRAY_SIZE(touchkey->regulators),
+                                     touchkey->regulators);
+       if (error)
+               return error;
+
+       /* waiting for device initialization, at least 150ms */
+       msleep(150);
+
+       return 0;
+}
+
+static void tm2_touchkey_power_disable(void *data)
+{
+       struct tm2_touchkey_data *touchkey = data;
+
+       regulator_bulk_disable(ARRAY_SIZE(touchkey->regulators),
+                              touchkey->regulators);
+}
+
+static irqreturn_t tm2_touchkey_irq_handler(int irq, void *devid)
+{
+       struct tm2_touchkey_data *touchkey = devid;
+       int data;
+       int key;
+
+       data = i2c_smbus_read_byte_data(touchkey->client,
+                                       TM2_TOUCHKEY_KEYCODE_REG);
+       if (data < 0) {
+               dev_err(&touchkey->client->dev,
+                       "failed to read i2c data: %d\n", data);
+               goto out;
+       }
+
+       switch (data & TM2_TOUCHKEY_BIT_KEYCODE) {
+       case TM2_TOUCHKEY_KEY_MENU:
+               key = KEY_PHONE;
+               break;
+
+       case TM2_TOUCHKEY_KEY_BACK:
+               key = KEY_BACK;
+               break;
+
+       default:
+               dev_warn(&touchkey->client->dev,
+                        "unhandled keycode, data %#02x\n", data);
+               goto out;
+       }
+
+       if (data & TM2_TOUCHKEY_BIT_PRESS_EV) {
+               input_report_key(touchkey->input_dev, KEY_PHONE, 0);
+               input_report_key(touchkey->input_dev, KEY_BACK, 0);
+       } else {
+               input_report_key(touchkey->input_dev, key, 1);
+       }
+
+       input_sync(touchkey->input_dev);
+
+out:
+       return IRQ_HANDLED;
+}
+
+static int tm2_touchkey_probe(struct i2c_client *client,
+                             const struct i2c_device_id *id)
+{
+       struct tm2_touchkey_data *touchkey;
+       int error;
+
+       if (!i2c_check_functionality(client->adapter,
+                       I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA)) {
+               dev_err(&client->dev, "incompatible I2C adapter\n");
+               return -EIO;
+       }
+
+       touchkey = devm_kzalloc(&client->dev, sizeof(*touchkey), GFP_KERNEL);
+       if (!touchkey)
+               return -ENOMEM;
+
+       touchkey->client = client;
+       i2c_set_clientdata(client, touchkey);
+
+       touchkey->regulators[0].supply = "vcc";
+       touchkey->regulators[1].supply = "vdd";
+       error = devm_regulator_bulk_get(&client->dev,
+                                       ARRAY_SIZE(touchkey->regulators),
+                                       touchkey->regulators);
+       if (error) {
+               dev_err(&client->dev, "failed to get regulators: %d\n", error);
+               return error;
+       }
+
+       /* Save VDD for easy access */
+       touchkey->vdd = touchkey->regulators[1].consumer;
+
+       error = tm2_touchkey_power_enable(touchkey);
+       if (error) {
+               dev_err(&client->dev, "failed to power up device: %d\n", error);
+               return error;
+       }
+
+       error = devm_add_action_or_reset(&client->dev,
+                                        tm2_touchkey_power_disable, touchkey);
+       if (error) {
+               dev_err(&client->dev,
+                       "failed to install poweroff handler: %d\n", error);
+               return error;
+       }
+
+       /* input device */
+       touchkey->input_dev = devm_input_allocate_device(&client->dev);
+       if (!touchkey->input_dev) {
+               dev_err(&client->dev, "failed to allocate input device\n");
+               return -ENOMEM;
+       }
+
+       touchkey->input_dev->name = TM2_TOUCHKEY_DEV_NAME;
+       touchkey->input_dev->id.bustype = BUS_I2C;
+
+       input_set_capability(touchkey->input_dev, EV_KEY, KEY_PHONE);
+       input_set_capability(touchkey->input_dev, EV_KEY, KEY_BACK);
+
+       error = input_register_device(touchkey->input_dev);
+       if (error) {
+               dev_err(&client->dev,
+                       "failed to register input device: %d\n", error);
+               return error;
+       }
+
+       error = devm_request_threaded_irq(&client->dev, client->irq,
+                                         NULL, tm2_touchkey_irq_handler,
+                                         IRQF_ONESHOT,
+                                         TM2_TOUCHKEY_DEV_NAME, touchkey);
+       if (error) {
+               dev_err(&client->dev,
+                       "failed to request threaded irq: %d\n", error);
+               return error;
+       }
+
+       /* led device */
+       touchkey->led_dev.name = TM2_TOUCHKEY_DEV_NAME;
+       touchkey->led_dev.brightness = LED_FULL;
+       touchkey->led_dev.max_brightness = LED_FULL;
+       touchkey->led_dev.brightness_set = tm2_touchkey_led_brightness_set;
+
+       error = devm_led_classdev_register(&client->dev, &touchkey->led_dev);
+       if (error) {
+               dev_err(&client->dev,
+                       "failed to register touchkey led: %d\n", error);
+               return error;
+       }
+
+       return 0;
+}
+
+static int __maybe_unused tm2_touchkey_suspend(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct tm2_touchkey_data *touchkey = i2c_get_clientdata(client);
+
+       disable_irq(client->irq);
+       tm2_touchkey_power_disable(touchkey);
+
+       return 0;
+}
+
+static int __maybe_unused tm2_touchkey_resume(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct tm2_touchkey_data *touchkey = i2c_get_clientdata(client);
+       int ret;
+
+       enable_irq(client->irq);
+
+       ret = tm2_touchkey_power_enable(touchkey);
+       if (ret)
+               dev_err(dev, "failed to enable power: %d\n", ret);
+
+       return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(tm2_touchkey_pm_ops,
+                        tm2_touchkey_suspend, tm2_touchkey_resume);
+
+static const struct i2c_device_id tm2_touchkey_id_table[] = {
+       { TM2_TOUCHKEY_DEV_NAME, 0 },
+       { },
+};
+MODULE_DEVICE_TABLE(i2c, tm2_touchkey_id_table);
+
+static const struct of_device_id tm2_touchkey_of_match[] = {
+       { .compatible = "cypress,tm2-touchkey", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, tm2_touchkey_of_match);
+
+static struct i2c_driver tm2_touchkey_driver = {
+       .driver = {
+               .name = TM2_TOUCHKEY_DEV_NAME,
+               .pm = &tm2_touchkey_pm_ops,
+               .of_match_table = of_match_ptr(tm2_touchkey_of_match),
+       },
+       .probe = tm2_touchkey_probe,
+       .id_table = tm2_touchkey_id_table,
+};
+module_i2c_driver(tm2_touchkey_driver);
+
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_AUTHOR("Jaechul Lee <jcsing.lee@samsung.com>");
+MODULE_DESCRIPTION("Samsung touchkey driver");
+MODULE_LICENSE("GPL v2");
index 323a0fb575a442d7c3b50837c0a1a235693fe8d2..39e72b3219d8a4ddb0ed358d561a2e2f0abf4285 100644 (file)
@@ -374,8 +374,8 @@ static int twl4030_kp_probe(struct platform_device *pdev)
                kp->autorepeat = pdata->rep;
                keymap_data = pdata->keymap_data;
        } else {
-               error = matrix_keypad_parse_of_params(&pdev->dev, &kp->n_rows,
-                                                     &kp->n_cols);
+               error = matrix_keypad_parse_properties(&pdev->dev, &kp->n_rows,
+                                                      &kp->n_cols);
                if (error)
                        return error;
 
@@ -441,7 +441,6 @@ static int twl4030_kp_probe(struct platform_device *pdev)
                return -EIO;
        }
 
-       platform_set_drvdata(pdev, kp);
        return 0;
 }
 
index 08b61f506db616d6a463ae96347dad62bc26517f..8ccefc15c7a4dfcfb03295a681f52620ebf47d4c 100644 (file)
  * 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.
- *
  */
 
 #include <linux/device.h>
+#include <linux/export.h>
 #include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
 #include <linux/input.h>
-#include <linux/of.h>
-#include <linux/export.h>
-#include <linux/module.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+#include <linux/types.h>
 
 static bool matrix_keypad_map_key(struct input_dev *input_dev,
                                  unsigned int rows, unsigned int cols,
@@ -49,18 +49,22 @@ static bool matrix_keypad_map_key(struct input_dev *input_dev,
        return true;
 }
 
-#ifdef CONFIG_OF
-int matrix_keypad_parse_of_params(struct device *dev,
-                                 unsigned int *rows, unsigned int *cols)
+/**
+ * matrix_keypad_parse_properties() - Read properties of matrix keypad
+ *
+ * @dev: Device containing properties
+ * @rows: Returns number of matrix rows
+ * @cols: Returns number of matrix columns
+ * @return 0 if OK, <0 on error
+ */
+int matrix_keypad_parse_properties(struct device *dev,
+                                  unsigned int *rows, unsigned int *cols)
 {
-       struct device_node *np = dev->of_node;
+       *rows = *cols = 0;
+
+       device_property_read_u32(dev, "keypad,num-rows", rows);
+       device_property_read_u32(dev, "keypad,num-columns", cols);
 
-       if (!np) {
-               dev_err(dev, "missing DT data");
-               return -EINVAL;
-       }
-       of_property_read_u32(np, "keypad,num-rows", rows);
-       of_property_read_u32(np, "keypad,num-columns", cols);
        if (!*rows || !*cols) {
                dev_err(dev, "number of keypad rows/columns not specified\n");
                return -EINVAL;
@@ -68,62 +72,61 @@ int matrix_keypad_parse_of_params(struct device *dev,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(matrix_keypad_parse_of_params);
+EXPORT_SYMBOL_GPL(matrix_keypad_parse_properties);
 
-static int matrix_keypad_parse_of_keymap(const char *propname,
-                                        unsigned int rows, unsigned int cols,
-                                        struct input_dev *input_dev)
+static int matrix_keypad_parse_keymap(const char *propname,
+                                     unsigned int rows, unsigned int cols,
+                                     struct input_dev *input_dev)
 {
        struct device *dev = input_dev->dev.parent;
-       struct device_node *np = dev->of_node;
        unsigned int row_shift = get_count_order(cols);
        unsigned int max_keys = rows << row_shift;
-       unsigned int proplen, i, size;
-       const __be32 *prop;
-
-       if (!np)
-               return -ENOENT;
+       u32 *keys;
+       int i;
+       int size;
+       int retval;
 
        if (!propname)
                propname = "linux,keymap";
 
-       prop = of_get_property(np, propname, &proplen);
-       if (!prop) {
-               dev_err(dev, "OF: %s property not defined in %s\n",
-                       propname, np->full_name);
-               return -ENOENT;
+       size = device_property_read_u32_array(dev, propname, NULL, 0);
+       if (size <= 0) {
+               dev_err(dev, "missing or malformed property %s: %d\n",
+                       propname, size);
+               return size < 0 ? size : -EINVAL;
        }
 
-       if (proplen % sizeof(u32)) {
-               dev_err(dev, "OF: Malformed keycode property %s in %s\n",
-                       propname, np->full_name);
+       if (size > max_keys) {
+               dev_err(dev, "%s size overflow (%d vs max %u)\n",
+                       propname, size, max_keys);
                return -EINVAL;
        }
 
-       size = proplen / sizeof(u32);
-       if (size > max_keys) {
-               dev_err(dev, "OF: %s size overflow\n", propname);
-               return -EINVAL;
+       keys = kmalloc_array(size, sizeof(u32), GFP_KERNEL);
+       if (!keys)
+               return -ENOMEM;
+
+       retval = device_property_read_u32_array(dev, propname, keys, size);
+       if (retval) {
+               dev_err(dev, "failed to read %s property: %d\n",
+                       propname, retval);
+               goto out;
        }
 
        for (i = 0; i < size; i++) {
-               unsigned int key = be32_to_cpup(prop + i);
-
                if (!matrix_keypad_map_key(input_dev, rows, cols,
-                                          row_shift, key))
-                       return -EINVAL;
+                                          row_shift, keys[i])) {
+                       retval = -EINVAL;
+                       goto out;
+               }
        }
 
-       return 0;
-}
-#else
-static int matrix_keypad_parse_of_keymap(const char *propname,
-                                        unsigned int rows, unsigned int cols,
-                                        struct input_dev *input_dev)
-{
-       return -ENOSYS;
+       retval = 0;
+
+out:
+       kfree(keys);
+       return retval;
 }
-#endif
 
 /**
  * matrix_keypad_build_keymap - convert platform keymap into matrix keymap
@@ -192,8 +195,8 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
                                return -EINVAL;
                }
        } else {
-               error = matrix_keypad_parse_of_keymap(keymap_name, rows, cols,
-                                                     input_dev);
+               error = matrix_keypad_parse_keymap(keymap_name, rows, cols,
+                                                  input_dev);
                if (error)
                        return error;
        }
index cf9908f1e5d5be758fa65d31dbe5577acdf6e295..45a09497f68098cb8179e4cc1bcb38e21c274df8 100644 (file)
@@ -143,7 +143,6 @@ static int pm80x_onkey_remove(struct platform_device *pdev)
 {
        struct pm80x_onkey_info *info = platform_get_drvdata(pdev);
 
-       device_init_wakeup(&pdev->dev, 0);
        pm80x_free_irq(info->pm80x, info->irq, info);
        input_unregister_device(info->idev);
        kfree(info);
index 1ae4d9617ff807c71ac011f79413d6faeed2d202..5b6c52210d20c3310a84c3d006363515a716d6ca 100644 (file)
@@ -234,16 +234,6 @@ config INPUT_MMA8450
          To compile this driver as a module, choose M here: the
          module will be called mma8450.
 
-config INPUT_MPU3050
-       tristate "MPU3050 Triaxial gyroscope sensor"
-       depends on I2C
-       help
-         Say Y here if you want to support InvenSense MPU3050
-         connected via an I2C bus.
-
-         To compile this driver as a module, choose M here: the
-         module will be called mpu3050.
-
 config INPUT_APANEL
        tristate "Fujitsu Lifebook Application Panel buttons"
        depends on X86 && I2C && LEDS_CLASS
index 0b6d025f0487a58d412388ea16fc293b3de7690b..b10523f2878e2fb7564bad3240294ea0644ecab6 100644 (file)
@@ -48,7 +48,6 @@ obj-$(CONFIG_INPUT_MAX8925_ONKEY)     += max8925_onkey.o
 obj-$(CONFIG_INPUT_MAX8997_HAPTIC)     += max8997_haptic.o
 obj-$(CONFIG_INPUT_MC13783_PWRBUTTON)  += mc13783-pwrbutton.o
 obj-$(CONFIG_INPUT_MMA8450)            += mma8450.o
-obj-$(CONFIG_INPUT_MPU3050)            += mpu3050.o
 obj-$(CONFIG_INPUT_PALMAS_PWRBUTTON)   += palmas-pwrbutton.o
 obj-$(CONFIG_INPUT_PCAP)               += pcap_keys.o
 obj-$(CONFIG_INPUT_PCF50633_PMU)       += pcf50633-input.o
index 4f5ef5bb535b86dcd0d16a198dca65de731f746f..a33ed5710b15a5c8d6079b837b24dc24a9aa1697 100644 (file)
@@ -109,7 +109,6 @@ static int ab8500_ponkey_probe(struct platform_device *pdev)
                return error;
        }
 
-       platform_set_drvdata(pdev, ponkey);
        return 0;
 }
 
index 07ec465f109587e48b946c9513f7b1fbc98a5619..21dc1b8b2a4a9362c4a49fbb998cd401a4037e99 100644 (file)
@@ -201,8 +201,6 @@ static int arizona_haptics_probe(struct platform_device *pdev)
                return ret;
        }
 
-       platform_set_drvdata(pdev, haptics);
-
        return 0;
 }
 
index 941265415a893d24438c19b120fef3c868f97c50..c4c0f4bb7627a001b360ba9e90b155e827e4017a 100644 (file)
@@ -191,7 +191,6 @@ static int atmel_captouch_probe(struct i2c_client *client,
                return -ENOMEM;
 
        capdev->client = client;
-       i2c_set_clientdata(client, capdev);
 
        err = atmel_read(capdev, REG_KEY_STATE,
                            &capdev->prev_btn, sizeof(capdev->prev_btn));
index a0fc18fdfc0c62263c21537a2f8105a3820846e3..799ce3d2820e45111222262ba8110d34d287adc4 100644 (file)
@@ -147,19 +147,18 @@ static int bfin_rotary_probe(struct platform_device *pdev)
 
        if (pdata->pin_list) {
                error = peripheral_request_list(pdata->pin_list,
-                                               dev_name(&pdev->dev));
+                                               dev_name(dev));
                if (error) {
                        dev_err(dev, "requesting peripherals failed: %d\n",
                                error);
                        return error;
                }
 
-               error = devm_add_action(dev, bfin_rotary_free_action,
-                                       pdata->pin_list);
+               error = devm_add_action_or_reset(dev, bfin_rotary_free_action,
+                                                pdata->pin_list);
                if (error) {
                        dev_err(dev, "setting cleanup action failed: %d\n",
                                error);
-                       peripheral_free_list(pdata->pin_list);
                        return error;
                }
        }
@@ -189,7 +188,7 @@ static int bfin_rotary_probe(struct platform_device *pdev)
 
        input->name = pdev->name;
        input->phys = "bfin-rotary/input0";
-       input->dev.parent = &pdev->dev;
+       input->dev.parent = dev;
 
        input_set_drvdata(input, rotary);
 
@@ -239,7 +238,7 @@ static int bfin_rotary_probe(struct platform_device *pdev)
        }
 
        platform_set_drvdata(pdev, rotary);
-       device_init_wakeup(&pdev->dev, 1);
+       device_init_wakeup(dev, 1);
 
        return 0;
 }
index 2124390ec38c606bf55ba0d953f681862d9c962f..1fa85379f86c15d43bc03acd1bb3c37207cac05c 100644 (file)
@@ -207,7 +207,7 @@ static int bma150_set_mode(struct bma150_data *bma150, u8 mode)
                return error;
 
        if (mode == BMA150_MODE_NORMAL)
-               msleep(2);
+               usleep_range(2000, 2100);
 
        bma150->mode = mode;
        return 0;
@@ -222,7 +222,7 @@ static int bma150_soft_reset(struct bma150_data *bma150)
        if (error)
                return error;
 
-       msleep(2);
+       usleep_range(2000, 2100);
        return 0;
 }
 
index b4ff1e86d3d30fee8a4e3ff4e33dd066c6a869b0..3e9c353d82effcd4a6e29396470bde27e5f19000 100644 (file)
@@ -287,7 +287,6 @@ static int da9063_onkey_probe(struct platform_device *pdev)
                return error;
        }
 
-       platform_set_drvdata(pdev, onkey);
        return 0;
 }
 
index b6b7bd4e54625d80e1112640c0226d6c4df68e6e..82e272ebc0ed0b968f5b1a131c8efede9e5b0591 100644 (file)
@@ -195,8 +195,6 @@ static int dm355evm_keys_probe(struct platform_device *pdev)
                goto fail1;
        keys->irq = status;
 
-       input_set_drvdata(input, keys);
-
        input->name = "DM355 EVM Controls";
        input->phys = "dm355evm/input0";
        input->dev.parent = &pdev->dev;
index 0a2b865b100040d99731abe52c1261c5f390f1b3..fb089d36c0d65e2b0edbf7ec16f05773f286e552 100644 (file)
@@ -538,7 +538,7 @@ static int drv260x_probe(struct i2c_client *client,
 
        haptics->input_dev = devm_input_allocate_device(dev);
        if (!haptics->input_dev) {
-               dev_err(&client->dev, "Failed to allocate input device\n");
+               dev_err(dev, "Failed to allocate input device\n");
                return -ENOMEM;
        }
 
index 13bfca8a7b166b75c4ecd0e19b3ac9c3892231d4..e956cf1d273fe6dd65775b6b18356c73e4531a49 100644 (file)
@@ -120,17 +120,10 @@ static int e3x0_button_probe(struct platform_device *pdev)
                return error;
        }
 
-       platform_set_drvdata(pdev, input);
        device_init_wakeup(&pdev->dev, 1);
        return 0;
 }
 
-static int e3x0_button_remove(struct platform_device *pdev)
-{
-       device_init_wakeup(&pdev->dev, 0);
-       return 0;
-}
-
 #ifdef CONFIG_OF
 static const struct of_device_id e3x0_button_match[] = {
        { .compatible = "ettus,e3x0-button", },
@@ -146,7 +139,6 @@ static struct platform_driver e3x0_button_driver = {
                .pm     = &e3x0_button_pm_ops,
        },
        .probe          = e3x0_button_probe,
-       .remove         = e3x0_button_remove,
 };
 
 module_platform_driver(e3x0_button_driver);
index 3bfdfcc2048519bb18822908a696ef8838ef6360..c6a29e57b5e493807d93dfe161ea78e362cca7da 100644 (file)
@@ -210,8 +210,6 @@ static int gp2a_remove(struct i2c_client *client)
        struct gp2a_data *dt = i2c_get_clientdata(client);
        const struct gp2a_platform_data *pdata = dt->pdata;
 
-       device_init_wakeup(&client->dev, false);
-
        free_irq(client->irq, dt);
 
        input_unregister_device(dt->input);
index ca7e0bacb2d8c4718884907262bd0ea8bec74005..1dca526e6f1a5c32966932ee4f4bfe070157c2ca 100644 (file)
@@ -110,7 +110,6 @@ static int gpio_decoder_probe(struct platform_device *pdev)
                dev_err(dev, "failed to register polled  device\n");
                return err;
        }
-       platform_set_drvdata(pdev, decoder);
 
        return 0;
 }
index f103b99d18529a80e2945c04df4fb95d35d4bfd3..6e217a45e39a804e917a822fd4aee502daca7c96 100644 (file)
@@ -138,7 +138,7 @@ static int gpio_tilt_polled_probe(struct platform_device *pdev)
 
        input->name = pdev->name;
        input->phys = DRV_NAME"/input0";
-       input->dev.parent = &pdev->dev;
+       input->dev.parent = dev;
 
        input->id.bustype = BUS_HOST;
        input->id.vendor = 0x0001;
index 675539c529ce75e06b2a70325347044ea7799eb3..dee6245f38d777b30cdb323f895a8e7be0bf8398 100644 (file)
@@ -75,9 +75,9 @@ static int hi65xx_powerkey_probe(struct platform_device *pdev)
        struct input_dev *input;
        int irq, i, error;
 
-       input = devm_input_allocate_device(&pdev->dev);
+       input = devm_input_allocate_device(dev);
        if (!input) {
-               dev_err(&pdev->dev, "failed to allocate input device\n");
+               dev_err(dev, "failed to allocate input device\n");
                return -ENOMEM;
        }
 
@@ -111,19 +111,11 @@ static int hi65xx_powerkey_probe(struct platform_device *pdev)
 
        error = input_register_device(input);
        if (error) {
-               dev_err(&pdev->dev, "failed to register input device: %d\n",
-                       error);
+               dev_err(dev, "failed to register input device: %d\n", error);
                return error;
        }
 
-       device_init_wakeup(&pdev->dev, 1);
-
-       return 0;
-}
-
-static int hi65xx_powerkey_remove(struct platform_device *pdev)
-{
-       device_init_wakeup(&pdev->dev, 0);
+       device_init_wakeup(dev, 1);
 
        return 0;
 }
@@ -133,7 +125,6 @@ static struct platform_driver hi65xx_powerkey_driver = {
                .name = "hi65xx-powerkey",
        },
        .probe = hi65xx_powerkey_probe,
-       .remove  = hi65xx_powerkey_remove,
 };
 module_platform_driver(hi65xx_powerkey_driver);
 
index 19c73574458e8201bc8c36d3b083e241cf1fc841..b60cdea738263073ff300f22ba1f70d787e716ab 100644 (file)
@@ -205,8 +205,6 @@ static int mma8450_probe(struct i2c_client *c,
                return err;
        }
 
-       i2c_set_clientdata(c, m);
-
        return 0;
 }
 
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c
deleted file mode 100644 (file)
index f088db3..0000000
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * MPU3050 Tri-axis gyroscope driver
- *
- * Copyright (C) 2011 Wistron Co.Ltd
- * Joseph Lai <joseph_lai@wistron.com>
- *
- * Trimmed down by Alan Cox <alan@linux.intel.com> to produce this version
- *
- * This is a 'lite' version of the driver, while we consider the right way
- * to present the other features to user space. In particular it requires the
- * device has an IRQ, and it only provides an input interface, so is not much
- * use for device orientation. A fuller version is available from the Meego
- * tree.
- *
- * This program is based on bma023.c.
- *
- * 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.
- *
- * 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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/input.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/pm_runtime.h>
-
-#define MPU3050_CHIP_ID                0x69
-
-#define MPU3050_AUTO_DELAY     1000
-
-#define MPU3050_MIN_VALUE      -32768
-#define MPU3050_MAX_VALUE      32767
-
-#define MPU3050_DEFAULT_POLL_INTERVAL  200
-#define MPU3050_DEFAULT_FS_RANGE       3
-
-/* Register map */
-#define MPU3050_CHIP_ID_REG    0x00
-#define MPU3050_SMPLRT_DIV     0x15
-#define MPU3050_DLPF_FS_SYNC   0x16
-#define MPU3050_INT_CFG                0x17
-#define MPU3050_XOUT_H         0x1D
-#define MPU3050_PWR_MGM                0x3E
-#define MPU3050_PWR_MGM_POS    6
-
-/* Register bits */
-
-/* DLPF_FS_SYNC */
-#define MPU3050_EXT_SYNC_NONE          0x00
-#define MPU3050_EXT_SYNC_TEMP          0x20
-#define MPU3050_EXT_SYNC_GYROX         0x40
-#define MPU3050_EXT_SYNC_GYROY         0x60
-#define MPU3050_EXT_SYNC_GYROZ         0x80
-#define MPU3050_EXT_SYNC_ACCELX        0xA0
-#define MPU3050_EXT_SYNC_ACCELY        0xC0
-#define MPU3050_EXT_SYNC_ACCELZ        0xE0
-#define MPU3050_EXT_SYNC_MASK          0xE0
-#define MPU3050_FS_250DPS              0x00
-#define MPU3050_FS_500DPS              0x08
-#define MPU3050_FS_1000DPS             0x10
-#define MPU3050_FS_2000DPS             0x18
-#define MPU3050_FS_MASK                0x18
-#define MPU3050_DLPF_CFG_256HZ_NOLPF2  0x00
-#define MPU3050_DLPF_CFG_188HZ         0x01
-#define MPU3050_DLPF_CFG_98HZ          0x02
-#define MPU3050_DLPF_CFG_42HZ          0x03
-#define MPU3050_DLPF_CFG_20HZ          0x04
-#define MPU3050_DLPF_CFG_10HZ          0x05
-#define MPU3050_DLPF_CFG_5HZ           0x06
-#define MPU3050_DLPF_CFG_2100HZ_NOLPF  0x07
-#define MPU3050_DLPF_CFG_MASK          0x07
-/* INT_CFG */
-#define MPU3050_RAW_RDY_EN             0x01
-#define MPU3050_MPU_RDY_EN             0x02
-#define MPU3050_LATCH_INT_EN           0x04
-/* PWR_MGM */
-#define MPU3050_PWR_MGM_PLL_X          0x01
-#define MPU3050_PWR_MGM_PLL_Y          0x02
-#define MPU3050_PWR_MGM_PLL_Z          0x03
-#define MPU3050_PWR_MGM_CLKSEL         0x07
-#define MPU3050_PWR_MGM_STBY_ZG        0x08
-#define MPU3050_PWR_MGM_STBY_YG        0x10
-#define MPU3050_PWR_MGM_STBY_XG        0x20
-#define MPU3050_PWR_MGM_SLEEP          0x40
-#define MPU3050_PWR_MGM_RESET          0x80
-#define MPU3050_PWR_MGM_MASK           0x40
-
-struct axis_data {
-       s16 x;
-       s16 y;
-       s16 z;
-};
-
-struct mpu3050_sensor {
-       struct i2c_client *client;
-       struct device *dev;
-       struct input_dev *idev;
-};
-
-/**
- *     mpu3050_xyz_read_reg    -       read the axes values
- *     @buffer: provide register addr and get register
- *     @length: length of register
- *
- *     Reads the register values in one transaction or returns a negative
- *     error code on failure.
- */
-static int mpu3050_xyz_read_reg(struct i2c_client *client,
-                              u8 *buffer, int length)
-{
-       /*
-        * Annoying we can't make this const because the i2c layer doesn't
-        * declare input buffers const.
-        */
-       char cmd = MPU3050_XOUT_H;
-       struct i2c_msg msg[] = {
-               {
-                       .addr = client->addr,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = &cmd,
-               },
-               {
-                       .addr = client->addr,
-                       .flags = I2C_M_RD,
-                       .len = length,
-                       .buf = buffer,
-               },
-       };
-
-       return i2c_transfer(client->adapter, msg, 2);
-}
-
-/**
- *     mpu3050_read_xyz        -       get co-ordinates from device
- *     @client: i2c address of sensor
- *     @coords: co-ordinates to update
- *
- *     Return the converted X Y and Z co-ordinates from the sensor device
- */
-static void mpu3050_read_xyz(struct i2c_client *client,
-                            struct axis_data *coords)
-{
-       u16 buffer[3];
-
-       mpu3050_xyz_read_reg(client, (u8 *)buffer, 6);
-       coords->x = be16_to_cpu(buffer[0]);
-       coords->y = be16_to_cpu(buffer[1]);
-       coords->z = be16_to_cpu(buffer[2]);
-       dev_dbg(&client->dev, "%s: x %d, y %d, z %d\n", __func__,
-                                       coords->x, coords->y, coords->z);
-}
-
-/**
- *     mpu3050_set_power_mode  -       set the power mode
- *     @client: i2c client for the sensor
- *     @val: value to switch on/off of power, 1: normal power, 0: low power
- *
- *     Put device to normal-power mode or low-power mode.
- */
-static void mpu3050_set_power_mode(struct i2c_client *client, u8 val)
-{
-       u8 value;
-
-       value = i2c_smbus_read_byte_data(client, MPU3050_PWR_MGM);
-       value = (value & ~MPU3050_PWR_MGM_MASK) |
-               (((val << MPU3050_PWR_MGM_POS) & MPU3050_PWR_MGM_MASK) ^
-                MPU3050_PWR_MGM_MASK);
-       i2c_smbus_write_byte_data(client, MPU3050_PWR_MGM, value);
-}
-
-/**
- *     mpu3050_input_open      -       called on input event open
- *     @input: input dev of opened device
- *
- *     The input layer calls this function when input event is opened. The
- *     function will push the device to resume. Then, the device is ready
- *     to provide data.
- */
-static int mpu3050_input_open(struct input_dev *input)
-{
-       struct mpu3050_sensor *sensor = input_get_drvdata(input);
-       int error;
-
-       pm_runtime_get(sensor->dev);
-
-       /* Enable interrupts */
-       error = i2c_smbus_write_byte_data(sensor->client, MPU3050_INT_CFG,
-                                         MPU3050_LATCH_INT_EN |
-                                         MPU3050_RAW_RDY_EN |
-                                         MPU3050_MPU_RDY_EN);
-       if (error < 0) {
-               pm_runtime_put(sensor->dev);
-               return error;
-       }
-
-       return 0;
-}
-
-/**
- *     mpu3050_input_close     -       called on input event close
- *     @input: input dev of closed device
- *
- *     The input layer calls this function when input event is closed. The
- *     function will push the device to suspend.
- */
-static void mpu3050_input_close(struct input_dev *input)
-{
-       struct mpu3050_sensor *sensor = input_get_drvdata(input);
-
-       pm_runtime_put(sensor->dev);
-}
-
-/**
- *     mpu3050_interrupt_thread        -       handle an IRQ
- *     @irq: interrupt numner
- *     @data: the sensor
- *
- *     Called by the kernel single threaded after an interrupt occurs. Read
- *     the sensor data and generate an input event for it.
- */
-static irqreturn_t mpu3050_interrupt_thread(int irq, void *data)
-{
-       struct mpu3050_sensor *sensor = data;
-       struct axis_data axis;
-
-       mpu3050_read_xyz(sensor->client, &axis);
-
-       input_report_abs(sensor->idev, ABS_X, axis.x);
-       input_report_abs(sensor->idev, ABS_Y, axis.y);
-       input_report_abs(sensor->idev, ABS_Z, axis.z);
-       input_sync(sensor->idev);
-
-       return IRQ_HANDLED;
-}
-
-/**
- *     mpu3050_hw_init -       initialize hardware
- *     @sensor: the sensor
- *
- *     Called during device probe; configures the sampling method.
- */
-static int mpu3050_hw_init(struct mpu3050_sensor *sensor)
-{
-       struct i2c_client *client = sensor->client;
-       int ret;
-       u8 reg;
-
-       /* Reset */
-       ret = i2c_smbus_write_byte_data(client, MPU3050_PWR_MGM,
-                                       MPU3050_PWR_MGM_RESET);
-       if (ret < 0)
-               return ret;
-
-       ret = i2c_smbus_read_byte_data(client, MPU3050_PWR_MGM);
-       if (ret < 0)
-               return ret;
-
-       ret &= ~MPU3050_PWR_MGM_CLKSEL;
-       ret |= MPU3050_PWR_MGM_PLL_Z;
-       ret = i2c_smbus_write_byte_data(client, MPU3050_PWR_MGM, ret);
-       if (ret < 0)
-               return ret;
-
-       /* Output frequency divider. The poll interval */
-       ret = i2c_smbus_write_byte_data(client, MPU3050_SMPLRT_DIV,
-                                       MPU3050_DEFAULT_POLL_INTERVAL - 1);
-       if (ret < 0)
-               return ret;
-
-       /* Set low pass filter and full scale */
-       reg = MPU3050_DEFAULT_FS_RANGE;
-       reg |= MPU3050_DLPF_CFG_42HZ << 3;
-       reg |= MPU3050_EXT_SYNC_NONE << 5;
-       ret = i2c_smbus_write_byte_data(client, MPU3050_DLPF_FS_SYNC, reg);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-/**
- *     mpu3050_probe   -       device detection callback
- *     @client: i2c client of found device
- *     @id: id match information
- *
- *     The I2C layer calls us when it believes a sensor is present at this
- *     address. Probe to see if this is correct and to validate the device.
- *
- *     If present install the relevant sysfs interfaces and input device.
- */
-static int mpu3050_probe(struct i2c_client *client,
-                                  const struct i2c_device_id *id)
-{
-       struct mpu3050_sensor *sensor;
-       struct input_dev *idev;
-       int ret;
-       int error;
-
-       sensor = kzalloc(sizeof(struct mpu3050_sensor), GFP_KERNEL);
-       idev = input_allocate_device();
-       if (!sensor || !idev) {
-               dev_err(&client->dev, "failed to allocate driver data\n");
-               error = -ENOMEM;
-               goto err_free_mem;
-       }
-
-       sensor->client = client;
-       sensor->dev = &client->dev;
-       sensor->idev = idev;
-
-       mpu3050_set_power_mode(client, 1);
-       msleep(10);
-
-       ret = i2c_smbus_read_byte_data(client, MPU3050_CHIP_ID_REG);
-       if (ret < 0) {
-               dev_err(&client->dev, "failed to detect device\n");
-               error = -ENXIO;
-               goto err_free_mem;
-       }
-
-       if (ret != MPU3050_CHIP_ID) {
-               dev_err(&client->dev, "unsupported chip id\n");
-               error = -ENXIO;
-               goto err_free_mem;
-       }
-
-       idev->name = "MPU3050";
-       idev->id.bustype = BUS_I2C;
-       idev->dev.parent = &client->dev;
-
-       idev->open = mpu3050_input_open;
-       idev->close = mpu3050_input_close;
-
-       __set_bit(EV_ABS, idev->evbit);
-       input_set_abs_params(idev, ABS_X,
-                            MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0);
-       input_set_abs_params(idev, ABS_Y,
-                            MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0);
-       input_set_abs_params(idev, ABS_Z,
-                            MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0);
-
-       input_set_drvdata(idev, sensor);
-
-       pm_runtime_set_active(&client->dev);
-
-       error = mpu3050_hw_init(sensor);
-       if (error)
-               goto err_pm_set_suspended;
-
-       error = request_threaded_irq(client->irq,
-                                    NULL, mpu3050_interrupt_thread,
-                                    IRQF_TRIGGER_RISING | IRQF_ONESHOT,
-                                    "mpu3050", sensor);
-       if (error) {
-               dev_err(&client->dev,
-                       "can't get IRQ %d, error %d\n", client->irq, error);
-               goto err_pm_set_suspended;
-       }
-
-       error = input_register_device(idev);
-       if (error) {
-               dev_err(&client->dev, "failed to register input device\n");
-               goto err_free_irq;
-       }
-
-       pm_runtime_enable(&client->dev);
-       pm_runtime_set_autosuspend_delay(&client->dev, MPU3050_AUTO_DELAY);
-       i2c_set_clientdata(client, sensor);
-
-       return 0;
-
-err_free_irq:
-       free_irq(client->irq, sensor);
-err_pm_set_suspended:
-       pm_runtime_set_suspended(&client->dev);
-err_free_mem:
-       input_free_device(idev);
-       kfree(sensor);
-       return error;
-}
-
-/**
- *     mpu3050_remove  -       remove a sensor
- *     @client: i2c client of sensor being removed
- *
- *     Our sensor is going away, clean up the resources.
- */
-static int mpu3050_remove(struct i2c_client *client)
-{
-       struct mpu3050_sensor *sensor = i2c_get_clientdata(client);
-
-       pm_runtime_disable(&client->dev);
-       pm_runtime_set_suspended(&client->dev);
-
-       free_irq(client->irq, sensor);
-       input_unregister_device(sensor->idev);
-       kfree(sensor);
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-/**
- *     mpu3050_suspend         -       called on device suspend
- *     @dev: device being suspended
- *
- *     Put the device into sleep mode before we suspend the machine.
- */
-static int mpu3050_suspend(struct device *dev)
-{
-       struct i2c_client *client = to_i2c_client(dev);
-
-       mpu3050_set_power_mode(client, 0);
-
-       return 0;
-}
-
-/**
- *     mpu3050_resume          -       called on device resume
- *     @dev: device being resumed
- *
- *     Put the device into powered mode on resume.
- */
-static int mpu3050_resume(struct device *dev)
-{
-       struct i2c_client *client = to_i2c_client(dev);
-
-       mpu3050_set_power_mode(client, 1);
-       msleep(100);  /* wait for gyro chip resume */
-
-       return 0;
-}
-#endif
-
-static UNIVERSAL_DEV_PM_OPS(mpu3050_pm, mpu3050_suspend, mpu3050_resume, NULL);
-
-static const struct i2c_device_id mpu3050_ids[] = {
-       { "mpu3050", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, mpu3050_ids);
-
-static const struct of_device_id mpu3050_of_match[] = {
-       { .compatible = "invn,mpu3050", },
-       { },
-};
-MODULE_DEVICE_TABLE(of, mpu3050_of_match);
-
-static struct i2c_driver mpu3050_i2c_driver = {
-       .driver = {
-               .name   = "mpu3050",
-               .pm     = &mpu3050_pm,
-               .of_match_table = mpu3050_of_match,
-       },
-       .probe          = mpu3050_probe,
-       .remove         = mpu3050_remove,
-       .id_table       = mpu3050_ids,
-};
-
-module_i2c_driver(mpu3050_i2c_driver);
-
-MODULE_AUTHOR("Wistron Corp.");
-MODULE_DESCRIPTION("MPU3050 Tri-axis gyroscope driver");
-MODULE_LICENSE("GPL");
index e317b75357a0182d99ef3c04223596bd1de6fc80..18ad956454f1e4819d0c5aede7925012e51be22e 100644 (file)
@@ -266,7 +266,6 @@ static int pm8941_pwrkey_remove(struct platform_device *pdev)
 {
        struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev);
 
-       device_init_wakeup(&pdev->dev, 0);
        unregister_reboot_notifier(&pwrkey->reboot_notifier);
 
        return 0;
index 67aab86048ad73faa1f1af16c1ae1663cf4500f1..73323b0c72c145e453871df967f1187a337ded05 100644 (file)
@@ -438,13 +438,6 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int pmic8xxx_pwrkey_remove(struct platform_device *pdev)
-{
-       device_init_wakeup(&pdev->dev, 0);
-
-       return 0;
-}
-
 static const struct of_device_id pm8xxx_pwr_key_id_table[] = {
        { .compatible = "qcom,pm8058-pwrkey", .data = &pm8058_pwrkey_shutdown },
        { .compatible = "qcom,pm8921-pwrkey", .data = &pm8921_pwrkey_shutdown },
@@ -454,7 +447,6 @@ MODULE_DEVICE_TABLE(of, pm8xxx_pwr_key_id_table);
 
 static struct platform_driver pmic8xxx_pwrkey_driver = {
        .probe          = pmic8xxx_pwrkey_probe,
-       .remove         = pmic8xxx_pwrkey_remove,
        .shutdown       = pmic8xxx_pwrkey_shutdown,
        .driver         = {
                .name   = "pm8xxx-pwrkey",
index 5f9655d49a65475f4e64a6ac85de5b34f33ee321..e53801dbd5603f4fd1274cb608784383adfe9405 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/input.h>
+#include <linux/regulator/consumer.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 struct pwm_beeper {
        struct input_dev *input;
        struct pwm_device *pwm;
+       struct regulator *amplifier;
        struct work_struct work;
        unsigned long period;
+       bool suspended;
+       bool amplifier_on;
 };
 
 #define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
 
-static void __pwm_beeper_set(struct pwm_beeper *beeper)
+static int pwm_beeper_on(struct pwm_beeper *beeper, unsigned long period)
 {
-       unsigned long period = beeper->period;
+       struct pwm_state state;
+       int error;
+
+       pwm_get_state(beeper->pwm, &state);
+
+       state.enabled = true;
+       state.period = period;
+       pwm_set_relative_duty_cycle(&state, 50, 100);
+
+       error = pwm_apply_state(beeper->pwm, &state);
+       if (error)
+               return error;
+
+       if (!beeper->amplifier_on) {
+               error = regulator_enable(beeper->amplifier);
+               if (error) {
+                       pwm_disable(beeper->pwm);
+                       return error;
+               }
+
+               beeper->amplifier_on = true;
+       }
+
+       return 0;
+}
 
-       if (period) {
-               pwm_config(beeper->pwm, period / 2, period);
-               pwm_enable(beeper->pwm);
-       } else
-               pwm_disable(beeper->pwm);
+static void pwm_beeper_off(struct pwm_beeper *beeper)
+{
+       if (beeper->amplifier_on) {
+               regulator_disable(beeper->amplifier);
+               beeper->amplifier_on = false;
+       }
+
+       pwm_disable(beeper->pwm);
 }
 
 static void pwm_beeper_work(struct work_struct *work)
 {
-       struct pwm_beeper *beeper =
-               container_of(work, struct pwm_beeper, work);
+       struct pwm_beeper *beeper = container_of(work, struct pwm_beeper, work);
+       unsigned long period = READ_ONCE(beeper->period);
 
-       __pwm_beeper_set(beeper);
+       if (period)
+               pwm_beeper_on(beeper, period);
+       else
+               pwm_beeper_off(beeper);
 }
 
 static int pwm_beeper_event(struct input_dev *input,
@@ -73,7 +107,8 @@ static int pwm_beeper_event(struct input_dev *input,
        else
                beeper->period = HZ_TO_NANOSECONDS(value);
 
-       schedule_work(&beeper->work);
+       if (!beeper->suspended)
+               schedule_work(&beeper->work);
 
        return 0;
 }
@@ -81,9 +116,7 @@ static int pwm_beeper_event(struct input_dev *input,
 static void pwm_beeper_stop(struct pwm_beeper *beeper)
 {
        cancel_work_sync(&beeper->work);
-
-       if (beeper->period)
-               pwm_disable(beeper->pwm);
+       pwm_beeper_off(beeper);
 }
 
 static void pwm_beeper_close(struct input_dev *input)
@@ -95,41 +128,50 @@ static void pwm_beeper_close(struct input_dev *input)
 
 static int pwm_beeper_probe(struct platform_device *pdev)
 {
-       unsigned long pwm_id = (unsigned long)dev_get_platdata(&pdev->dev);
+       struct device *dev = &pdev->dev;
        struct pwm_beeper *beeper;
+       struct pwm_state state;
        int error;
 
-       beeper = kzalloc(sizeof(*beeper), GFP_KERNEL);
+       beeper = devm_kzalloc(dev, sizeof(*beeper), GFP_KERNEL);
        if (!beeper)
                return -ENOMEM;
 
-       beeper->pwm = pwm_get(&pdev->dev, NULL);
+       beeper->pwm = devm_pwm_get(dev, NULL);
        if (IS_ERR(beeper->pwm)) {
-               dev_dbg(&pdev->dev, "unable to request PWM, trying legacy API\n");
-               beeper->pwm = pwm_request(pwm_id, "pwm beeper");
+               error = PTR_ERR(beeper->pwm);
+               if (error != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to request PWM device: %d\n",
+                               error);
+               return error;
        }
 
-       if (IS_ERR(beeper->pwm)) {
-               error = PTR_ERR(beeper->pwm);
-               dev_err(&pdev->dev, "Failed to request pwm device: %d\n", error);
-               goto err_free;
+       /* Sync up PWM state and ensure it is off. */
+       pwm_init_state(beeper->pwm, &state);
+       state.enabled = false;
+       error = pwm_apply_state(beeper->pwm, &state);
+       if (error) {
+               dev_err(dev, "failed to apply initial PWM state: %d\n",
+                       error);
+               return error;
        }
 
-       /*
-        * FIXME: pwm_apply_args() should be removed when switching to
-        * the atomic PWM API.
-        */
-       pwm_apply_args(beeper->pwm);
+       beeper->amplifier = devm_regulator_get(dev, "amp");
+       if (IS_ERR(beeper->amplifier)) {
+               error = PTR_ERR(beeper->amplifier);
+               if (error != -EPROBE_DEFER)
+                       dev_err(dev, "Failed to get 'amp' regulator: %d\n",
+                               error);
+               return error;
+       }
 
        INIT_WORK(&beeper->work, pwm_beeper_work);
 
-       beeper->input = input_allocate_device();
+       beeper->input = devm_input_allocate_device(dev);
        if (!beeper->input) {
-               dev_err(&pdev->dev, "Failed to allocate input device\n");
-               error = -ENOMEM;
-               goto err_pwm_free;
+               dev_err(dev, "Failed to allocate input device\n");
+               return -ENOMEM;
        }
-       beeper->input->dev.parent = &pdev->dev;
 
        beeper->input->name = "pwm-beeper";
        beeper->input->phys = "pwm/input0";
@@ -138,8 +180,8 @@ static int pwm_beeper_probe(struct platform_device *pdev)
        beeper->input->id.product = 0x0001;
        beeper->input->id.version = 0x0100;
 
-       beeper->input->evbit[0] = BIT(EV_SND);
-       beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL);
+       input_set_capability(beeper->input, EV_SND, SND_TONE);
+       input_set_capability(beeper->input, EV_SND, SND_BELL);
 
        beeper->input->event = pwm_beeper_event;
        beeper->input->close = pwm_beeper_close;
@@ -148,34 +190,12 @@ static int pwm_beeper_probe(struct platform_device *pdev)
 
        error = input_register_device(beeper->input);
        if (error) {
-               dev_err(&pdev->dev, "Failed to register input device: %d\n", error);
-               goto err_input_free;
+               dev_err(dev, "Failed to register input device: %d\n", error);
+               return error;
        }
 
        platform_set_drvdata(pdev, beeper);
 
-       return 0;
-
-err_input_free:
-       input_free_device(beeper->input);
-err_pwm_free:
-       pwm_free(beeper->pwm);
-err_free:
-       kfree(beeper);
-
-       return error;
-}
-
-static int pwm_beeper_remove(struct platform_device *pdev)
-{
-       struct pwm_beeper *beeper = platform_get_drvdata(pdev);
-
-       input_unregister_device(beeper->input);
-
-       pwm_free(beeper->pwm);
-
-       kfree(beeper);
-
        return 0;
 }
 
@@ -183,6 +203,15 @@ static int __maybe_unused pwm_beeper_suspend(struct device *dev)
 {
        struct pwm_beeper *beeper = dev_get_drvdata(dev);
 
+       /*
+        * Spinlock is taken here is not to protect write to
+        * beeper->suspended, but to ensure that pwm_beeper_event
+        * does not re-submit work once flag is set.
+        */
+       spin_lock_irq(&beeper->input->event_lock);
+       beeper->suspended = true;
+       spin_unlock_irq(&beeper->input->event_lock);
+
        pwm_beeper_stop(beeper);
 
        return 0;
@@ -192,8 +221,12 @@ static int __maybe_unused pwm_beeper_resume(struct device *dev)
 {
        struct pwm_beeper *beeper = dev_get_drvdata(dev);
 
-       if (beeper->period)
-               __pwm_beeper_set(beeper);
+       spin_lock_irq(&beeper->input->event_lock);
+       beeper->suspended = false;
+       spin_unlock_irq(&beeper->input->event_lock);
+
+       /* Let worker figure out if we should resume beeping */
+       schedule_work(&beeper->work);
 
        return 0;
 }
@@ -211,7 +244,6 @@ MODULE_DEVICE_TABLE(of, pwm_beeper_match);
 
 static struct platform_driver pwm_beeper_driver = {
        .probe  = pwm_beeper_probe,
-       .remove = pwm_beeper_remove,
        .driver = {
                .name   = "pwm-beeper",
                .pm     = &pwm_beeper_pm_ops,
index 30b459b6b344c427cd4bef9501b4c592ef952a56..64023ac08e2b9c3bfa2d80c4a8d9cf1dd8ba2f24 100644 (file)
@@ -76,14 +76,8 @@ static int retu_pwrbutton_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int retu_pwrbutton_remove(struct platform_device *pdev)
-{
-       return 0;
-}
-
 static struct platform_driver retu_pwrbutton_driver = {
        .probe          = retu_pwrbutton_probe,
-       .remove         = retu_pwrbutton_remove,
        .driver         = {
                .name   = "retu-pwrbutton",
        },
index ed7237f1953966c378c3822faa9a40f7c6a044dd..4fd038d476a31f2e91899d8c2a08ca9195804942 100644 (file)
@@ -172,13 +172,6 @@ static int sirfsoc_pwrc_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int sirfsoc_pwrc_remove(struct platform_device *pdev)
-{
-       device_init_wakeup(&pdev->dev, 0);
-
-       return 0;
-}
-
 static int __maybe_unused sirfsoc_pwrc_resume(struct device *dev)
 {
        struct sirfsoc_pwrc_drvdata *pwrcdrv = dev_get_drvdata(dev);
@@ -200,7 +193,6 @@ static SIMPLE_DEV_PM_OPS(sirfsoc_pwrc_pm_ops, NULL, sirfsoc_pwrc_resume);
 
 static struct platform_driver sirfsoc_pwrc_driver = {
        .probe          = sirfsoc_pwrc_probe,
-       .remove         = sirfsoc_pwrc_remove,
        .driver         = {
                .name   = "sirfsoc-pwrc",
                .pm     = &sirfsoc_pwrc_pm_ops,
index 908b51089dee4b1cb128393cba441eecc477c994..ddb2f22fca7aff42ff7c3ae13b7b3f3e18eefafa 100644 (file)
@@ -102,6 +102,8 @@ soc_button_device_create(struct platform_device *pdev,
                gpio_keys[n_buttons].active_low = 1;
                gpio_keys[n_buttons].desc = info->name;
                gpio_keys[n_buttons].wakeup = info->wakeup;
+               /* These devices often use cheap buttons, use 50 ms debounce */
+               gpio_keys[n_buttons].debounce_interval = 50;
                n_buttons++;
        }
 
@@ -167,12 +169,12 @@ static int soc_button_probe(struct platform_device *pdev)
 
        button_info = (struct soc_button_info *)id->driver_data;
 
-       if (gpiod_count(&pdev->dev, KBUILD_MODNAME) <= 0) {
-               dev_dbg(&pdev->dev, "no GPIO attached, ignoring...\n");
+       if (gpiod_count(dev, KBUILD_MODNAME) <= 0) {
+               dev_dbg(dev, "no GPIO attached, ignoring...\n");
                return -ENODEV;
        }
 
-       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
index cc74a41bdb0d24d7e5eddd0f1e019ab01cea71c4..a4455bb12ae0c1896a08aaa9bd198b2aafed19d9 100644 (file)
@@ -95,7 +95,7 @@ static int tps6521x_pb_probe(struct platform_device *pdev)
        int error;
        int irq;
 
-       match = of_match_node(of_tps6521x_pb_match, pdev->dev.of_node);
+       match = of_match_node(of_tps6521x_pb_match, dev->of_node);
        if (!match)
                return -ENXIO;
 
@@ -118,10 +118,9 @@ static int tps6521x_pb_probe(struct platform_device *pdev)
 
        input_set_capability(idev, EV_KEY, KEY_POWER);
 
-       pwr->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+       pwr->regmap = dev_get_regmap(dev->parent, NULL);
        pwr->dev = dev;
        pwr->idev = idev;
-       platform_set_drvdata(pdev, pwr);
        device_init_wakeup(dev, true);
 
        irq = platform_get_irq(pdev, 0);
@@ -136,8 +135,7 @@ static int tps6521x_pb_probe(struct platform_device *pdev)
                                                IRQF_ONESHOT,
                                          pwr->data->name, pwr);
        if (error) {
-               dev_err(dev, "failed to request IRQ #%d: %d\n",
-                       irq, error);
+               dev_err(dev, "failed to request IRQ #%d: %d\n", irq, error);
                return error;
        }
 
index 603fc2fadf057d9bb08f9a373e0bf6b20440dc18..54162d2cbcfce2ef48aa55dc1bfaaddb531d20c0 100644 (file)
@@ -85,7 +85,6 @@ static int twl4030_pwrbutton_probe(struct platform_device *pdev)
                return err;
        }
 
-       platform_set_drvdata(pdev, pwr);
        device_init_wakeup(&pdev->dev, true);
 
        return 0;
index 328edc8c8786339d009abb99fe6e000d9edbb805..72b28ebfe360030cbeeadec8a52385a9de09a7f0 100644 (file)
@@ -1855,7 +1855,7 @@ static int alps_absolute_mode_v1_v2(struct psmouse *psmouse)
         * Switch mouse to poll (remote) mode so motion data will not
         * get in our way
         */
-       return ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
+       return ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
 }
 
 static int alps_monitor_mode_send_word(struct psmouse *psmouse, u16 word)
index 30e3442518f85cfe06732e0f331962458396008c..d0122134f320e82ee6c3db6afc3215de31239769 100644 (file)
@@ -665,7 +665,7 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
        char *data;
 
        /* Type 3 does not require a mode switch */
-       if (dev->cfg.tp_type == TYPE3)
+       if (c->tp_type == TYPE3)
                return 0;
 
        data = kmalloc(c->um_size, GFP_KERNEL);
index dc239429208892fab3ed1357ec3d636f821959e2..fd8865c65cafc8b22a5203047eeb40db2459b5a8 100644 (file)
@@ -832,8 +832,8 @@ static int cyapa_prepare_wakeup_controls(struct cyapa *cyapa)
        int error;
 
        if (device_can_wakeup(dev)) {
-               error = sysfs_merge_group(&client->dev.kobj,
-                                       &cyapa_power_wakeup_group);
+               error = sysfs_merge_group(&dev->kobj,
+                                         &cyapa_power_wakeup_group);
                if (error) {
                        dev_err(dev, "failed to add power wakeup group: %d\n",
                                error);
@@ -1312,7 +1312,7 @@ static int cyapa_probe(struct i2c_client *client,
                return error;
        }
 
-       error = sysfs_create_group(&client->dev.kobj, &cyapa_sysfs_group);
+       error = sysfs_create_group(&dev->kobj, &cyapa_sysfs_group);
        if (error) {
                dev_err(dev, "failed to create sysfs entries: %d\n", error);
                return error;
index f9600753eca54937648b95a4632932312d7e50c4..1cbfa4a6e83057dde0bb743fedb18f0fdd5f2df2 100644 (file)
@@ -562,7 +562,7 @@ static int cyapa_gen3_bl_exit(struct cyapa *cyapa)
         * Wait for bootloader to exit, and operation mode to start.
         * Normally, this takes at least 50 ms.
         */
-       usleep_range(50000, 100000);
+       msleep(50);
        /*
         * In addition, when a device boots for the first time after being
         * updated to new firmware, it must first calibrate its sensors, which
@@ -789,7 +789,7 @@ static ssize_t cyapa_gen3_do_calibrate(struct device *dev,
                                     const char *buf, size_t count)
 {
        struct cyapa *cyapa = dev_get_drvdata(dev);
-       int tries;
+       unsigned long timeout;
        int ret;
 
        ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS);
@@ -812,31 +812,28 @@ static ssize_t cyapa_gen3_do_calibrate(struct device *dev,
                goto out;
        }
 
-       tries = 20;  /* max recalibration timeout 2s. */
+       /* max recalibration timeout 2s. */
+       timeout = jiffies + 2 * HZ;
        do {
                /*
                 * For this recalibration, the max time will not exceed 2s.
                 * The average time is approximately 500 - 700 ms, and we
                 * will check the status every 100 - 200ms.
                 */
-               usleep_range(100000, 200000);
-
+               msleep(100);
                ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS);
                if (ret < 0) {
-                       dev_err(dev, "Error reading dev status: %d\n",
-                               ret);
+                       dev_err(dev, "Error reading dev status: %d\n", ret);
                        goto out;
                }
-               if ((ret & CYAPA_DEV_NORMAL) == CYAPA_DEV_NORMAL)
-                       break;
-       } while (--tries);
+               if ((ret & CYAPA_DEV_NORMAL) == CYAPA_DEV_NORMAL) {
+                       dev_dbg(dev, "Calibration successful.\n");
+                       goto out;
+               }
+       } while (time_is_after_jiffies(timeout));
 
-       if (tries == 0) {
-               dev_err(dev, "Failed to calibrate. Timeout.\n");
-               ret = -ETIMEDOUT;
-               goto out;
-       }
-       dev_dbg(dev, "Calibration successful.\n");
+       dev_err(dev, "Failed to calibrate. Timeout.\n");
+       ret = -ETIMEDOUT;
 
 out:
        return ret < 0 ? ret : count;
index 28dcfc822bf647f4386239d49487e111020a2272..21bad3e75feed25e3d4de34b6f2ae94697ceb894 100644 (file)
@@ -107,7 +107,7 @@ static int cypress_ps2_read_cmd_status(struct psmouse *psmouse,
        enum psmouse_state old_state;
        int pktsize;
 
-       ps2_begin_command(&psmouse->ps2dev);
+       ps2_begin_command(ps2dev);
 
        old_state = psmouse->state;
        psmouse->state = PSMOUSE_CMD_MODE;
@@ -133,7 +133,7 @@ out:
        psmouse->state = old_state;
        psmouse->pktcnt = 0;
 
-       ps2_end_command(&psmouse->ps2dev);
+       ps2_end_command(ps2dev);
 
        return rc;
 }
@@ -414,8 +414,6 @@ static int cypress_set_input_params(struct input_dev *input,
        __set_bit(BTN_RIGHT, input->keybit);
        __set_bit(BTN_MIDDLE, input->keybit);
 
-       input_set_drvdata(input, cytp);
-
        return 0;
 }
 
index 1e1d0ad406f2b7178bbb8cdcf1f320ade13ea0a1..352050e9031dc31ab87e7d3cdb2948b2ead7dee1 100644 (file)
@@ -1041,8 +1041,7 @@ static int elan_probe(struct i2c_client *client,
                return -EIO;
        }
 
-       data = devm_kzalloc(&client->dev, sizeof(struct elan_tp_data),
-                           GFP_KERNEL);
+       data = devm_kzalloc(dev, sizeof(struct elan_tp_data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -1053,29 +1052,25 @@ static int elan_probe(struct i2c_client *client,
        init_completion(&data->fw_completion);
        mutex_init(&data->sysfs_mutex);
 
-       data->vcc = devm_regulator_get(&client->dev, "vcc");
+       data->vcc = devm_regulator_get(dev, "vcc");
        if (IS_ERR(data->vcc)) {
                error = PTR_ERR(data->vcc);
                if (error != -EPROBE_DEFER)
-                       dev_err(&client->dev,
-                               "Failed to get 'vcc' regulator: %d\n",
+                       dev_err(dev, "Failed to get 'vcc' regulator: %d\n",
                                error);
                return error;
        }
 
        error = regulator_enable(data->vcc);
        if (error) {
-               dev_err(&client->dev,
-                       "Failed to enable regulator: %d\n", error);
+               dev_err(dev, "Failed to enable regulator: %d\n", error);
                return error;
        }
 
-       error = devm_add_action(&client->dev,
-                               elan_disable_regulator, data);
+       error = devm_add_action(dev, elan_disable_regulator, data);
        if (error) {
                regulator_disable(data->vcc);
-               dev_err(&client->dev,
-                       "Failed to add disable regulator action: %d\n",
+               dev_err(dev, "Failed to add disable regulator action: %d\n",
                        error);
                return error;
        }
@@ -1093,14 +1088,14 @@ static int elan_probe(struct i2c_client *client,
        if (error)
                return error;
 
-       dev_info(&client->dev,
+       dev_info(dev,
                 "Elan Touchpad: Module ID: 0x%04x, Firmware: 0x%04x, Sample: 0x%04x, IAP: 0x%04x\n",
                 data->product_id,
                 data->fw_version,
                 data->sm_version,
                 data->iap_version);
 
-       dev_dbg(&client->dev,
+       dev_dbg(dev,
                "Elan Touchpad Extra Information:\n"
                "    Max ABS X,Y:   %d,%d\n"
                "    Width X,Y:   %d,%d\n"
@@ -1118,38 +1113,33 @@ static int elan_probe(struct i2c_client *client,
         * Systems using device tree should set up interrupt via DTS,
         * the rest will use the default falling edge interrupts.
         */
-       irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING;
+       irqflags = dev->of_node ? 0 : IRQF_TRIGGER_FALLING;
 
-       error = devm_request_threaded_irq(&client->dev, client->irq,
-                                         NULL, elan_isr,
+       error = devm_request_threaded_irq(dev, client->irq, NULL, elan_isr,
                                          irqflags | IRQF_ONESHOT,
                                          client->name, data);
        if (error) {
-               dev_err(&client->dev, "cannot register irq=%d\n", client->irq);
+               dev_err(dev, "cannot register irq=%d\n", client->irq);
                return error;
        }
 
-       error = sysfs_create_groups(&client->dev.kobj, elan_sysfs_groups);
+       error = sysfs_create_groups(&dev->kobj, elan_sysfs_groups);
        if (error) {
-               dev_err(&client->dev, "failed to create sysfs attributes: %d\n",
-                       error);
+               dev_err(dev, "failed to create sysfs attributes: %d\n", error);
                return error;
        }
 
-       error = devm_add_action(&client->dev,
-                               elan_remove_sysfs_groups, data);
+       error = devm_add_action(dev, elan_remove_sysfs_groups, data);
        if (error) {
                elan_remove_sysfs_groups(data);
-               dev_err(&client->dev,
-                       "Failed to add sysfs cleanup action: %d\n",
+               dev_err(dev, "Failed to add sysfs cleanup action: %d\n",
                        error);
                return error;
        }
 
        error = input_register_device(data->input);
        if (error) {
-               dev_err(&client->dev, "failed to register input device: %d\n",
-                       error);
+               dev_err(dev, "failed to register input device: %d\n", error);
                return error;
        }
 
@@ -1157,8 +1147,8 @@ static int elan_probe(struct i2c_client *client,
         * Systems using device tree should set up wakeup via DTS,
         * the rest will configure device as wakeup source by default.
         */
-       if (!client->dev.of_node)
-               device_init_wakeup(&client->dev, true);
+       if (!dev->of_node)
+               device_init_wakeup(dev, true);
 
        return 0;
 }
index db7d1d666ac1092e23806793e3c3b4b8e292a766..efc8ec3423514ad33dd2ebaf0c861d41bb960140 100644 (file)
@@ -1412,7 +1412,7 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties)
        struct ps2dev *ps2dev = &psmouse->ps2dev;
        unsigned char param[3];
 
-       ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
+       ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
 
        if (ps2_command(ps2dev,  NULL, PSMOUSE_CMD_DISABLE) ||
            ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE11) ||
index 62be888e83d03df3aaf587a4a49f9024596b59be..015509e0b1408f66a2ff048d53be22365e453639 100644 (file)
@@ -713,8 +713,7 @@ static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable)
                 * the upper bound. (in practice, it takes about 3 loops.)
                 */
                for (timeo = 20; timeo > 0; timeo--) {
-                       if (!ps2_sendbyte(&psmouse->ps2dev,
-                                       PSMOUSE_CMD_DISABLE, 20))
+                       if (!ps2_sendbyte(ps2dev, PSMOUSE_CMD_DISABLE, 20))
                                break;
                        msleep(25);
                }
@@ -740,7 +739,7 @@ static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable)
                psmouse_set_state(psmouse, PSMOUSE_IGNORE);
 
                /* probably won't see an ACK, the touchpad will be off */
-               ps2_sendbyte(&psmouse->ps2dev, 0xec, 20);
+               ps2_sendbyte(ps2dev, 0xec, 20);
        }
 
        return 0;
index 422da1cd9e763839381267f0c3395100cf9df648..ef9c97f5e3d78b6e1f5ca728bbc1ebf3c352bc73 100644 (file)
@@ -402,7 +402,7 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties)
                                psmouse->set_resolution = ps2pp_set_resolution;
                                psmouse->disconnect = ps2pp_disconnect;
 
-                               error = device_create_file(&psmouse->ps2dev.serio->dev,
+                               error = device_create_file(&ps2dev->serio->dev,
                                                           &psmouse_attr_smartscroll.dattr);
                                if (error) {
                                        psmouse_err(psmouse,
index 0a60717b91c67803bcb417c9dec1ac7527584314..25f0ecb9012627b093099c376555f71969df2f09 100644 (file)
@@ -87,7 +87,6 @@ static int probe_maple_mouse(struct device *dev)
        mse->dev = input_dev;
        mse->mdev = mdev;
 
-       input_set_drvdata(input_dev, mse);
        input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
        input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
                BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
index bee2674249722fd4117a7d7de95d222749c6b86a..a598b7223cef2fc60f1df135856ac5dd669b86d6 100644 (file)
@@ -127,6 +127,13 @@ struct psmouse_protocol {
        int (*init)(struct psmouse *);
 };
 
+static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
+{
+       input_report_key(dev, BTN_LEFT,   buttons & BIT(0));
+       input_report_key(dev, BTN_MIDDLE, buttons & BIT(2));
+       input_report_key(dev, BTN_RIGHT,  buttons & BIT(1));
+}
+
 /*
  * psmouse_process_byte() analyzes the PS/2 data stream and reports
  * relevant events to the input module once full packet has arrived.
@@ -199,9 +206,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
        }
 
        /* Generic PS/2 Mouse */
-       input_report_key(dev, BTN_LEFT,    packet[0]       & 1);
-       input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
-       input_report_key(dev, BTN_RIGHT,  (packet[0] >> 1) & 1);
+       psmouse_report_standard_buttons(dev,
+                                       packet[0] | psmouse->extra_buttons);
 
        input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
        input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
@@ -282,6 +288,30 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
        return 0;
 }
 
+static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data)
+{
+       switch (psmouse->oob_data_type) {
+       case PSMOUSE_OOB_NONE:
+               psmouse->oob_data_type = data;
+               break;
+
+       case PSMOUSE_OOB_EXTRA_BTNS:
+               psmouse_report_standard_buttons(psmouse->dev, data);
+               input_sync(psmouse->dev);
+
+               psmouse->extra_buttons = data;
+               psmouse->oob_data_type = PSMOUSE_OOB_NONE;
+               break;
+
+       default:
+               psmouse_warn(psmouse,
+                            "unknown OOB_DATA type: 0x%02x\n",
+                            psmouse->oob_data_type);
+               psmouse->oob_data_type = PSMOUSE_OOB_NONE;
+               break;
+       }
+}
+
 /*
  * psmouse_interrupt() handles incoming characters, either passing them
  * for normal processing or gathering them as command response.
@@ -306,6 +336,11 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
                goto out;
        }
 
+       if (flags & SERIO_OOB_DATA) {
+               psmouse_handle_oob_data(psmouse, data);
+               goto out;
+       }
+
        if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK))
                if  (ps2_handle_ack(&psmouse->ps2dev, data))
                        goto out;
index e0ca6cda3d166ad2d5b0e14d63ccb5fb257727ce..8c83b8e2505cea4e9f77555f4050759432d6bf30 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef _PSMOUSE_H
 #define _PSMOUSE_H
 
+#define PSMOUSE_OOB_NONE       0x00
+#define PSMOUSE_OOB_EXTRA_BTNS 0x01
+
 #define PSMOUSE_CMD_SETSCALE11 0x00e6
 #define PSMOUSE_CMD_SETSCALE21 0x00e7
 #define PSMOUSE_CMD_SETRES     0x10e8
@@ -53,6 +56,8 @@ struct psmouse {
        unsigned char pktcnt;
        unsigned char pktsize;
        unsigned char type;
+       unsigned char oob_data_type;
+       unsigned char extra_buttons;
        bool ignore_parity;
        bool acks_disable_command;
        unsigned int model;
index a41d8328c0643ccd9f2c88885f47be262983df30..597ee4b01d9ff8939a716c2f0a2a5f008d0481f0 100644 (file)
@@ -597,15 +597,13 @@ static int synaptics_is_pt_packet(unsigned char *buf)
        return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
 }
 
-static void synaptics_pass_pt_packet(struct psmouse *psmouse,
-                                    struct serio *ptport,
+static void synaptics_pass_pt_packet(struct serio *ptport,
                                     unsigned char *packet)
 {
-       struct synaptics_data *priv = psmouse->private;
        struct psmouse *child = serio_get_drvdata(ptport);
 
        if (child && child->state == PSMOUSE_ACTIVATED) {
-               serio_interrupt(ptport, packet[1] | priv->pt_buttons, 0);
+               serio_interrupt(ptport, packet[1], 0);
                serio_interrupt(ptport, packet[4], 0);
                serio_interrupt(ptport, packet[5], 0);
                if (child->pktsize == 4)
@@ -856,7 +854,6 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse,
        struct input_dev *dev = psmouse->dev;
        struct synaptics_data *priv = psmouse->private;
        int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1;
-       char buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        int i;
 
        if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
@@ -883,15 +880,18 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse,
         * physically wired to the touchpad. Re-route them through
         * the pass-through interface.
         */
-       if (!priv->pt_port)
-               return;
+       if (priv->pt_port) {
+               u8 pt_buttons;
 
-       /* The trackstick expects at most 3 buttons */
-       priv->pt_buttons = SYN_CAP_EXT_BUTTON_STICK_L(hw->ext_buttons)      |
-                          SYN_CAP_EXT_BUTTON_STICK_R(hw->ext_buttons) << 1 |
-                          SYN_CAP_EXT_BUTTON_STICK_M(hw->ext_buttons) << 2;
+               /* The trackstick expects at most 3 buttons */
+               pt_buttons = SYN_CAP_EXT_BUTTON_STICK_L(hw->ext_buttons)      |
+                            SYN_CAP_EXT_BUTTON_STICK_R(hw->ext_buttons) << 1 |
+                            SYN_CAP_EXT_BUTTON_STICK_M(hw->ext_buttons) << 2;
 
-       synaptics_pass_pt_packet(psmouse, priv->pt_port, buf);
+               serio_interrupt(priv->pt_port,
+                               PSMOUSE_OOB_EXTRA_BTNS, SERIO_OOB_DATA);
+               serio_interrupt(priv->pt_port, pt_buttons, SERIO_OOB_DATA);
+       }
 }
 
 static void synaptics_report_buttons(struct psmouse *psmouse,
@@ -1132,7 +1132,7 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
                if (SYN_CAP_PASS_THROUGH(priv->capabilities) &&
                    synaptics_is_pt_packet(psmouse->packet)) {
                        if (priv->pt_port)
-                               synaptics_pass_pt_packet(psmouse, priv->pt_port,
+                               synaptics_pass_pt_packet(priv->pt_port,
                                                         psmouse->packet);
                } else
                        synaptics_process_packet(psmouse);
index 56faa7ec443480af63e66b56819be46fb44a6ee7..116ae2546ace9618430612274f39f6237c8ae8ad 100644 (file)
@@ -183,7 +183,6 @@ struct synaptics_data {
        bool disable_gesture;                   /* disable gestures */
 
        struct serio *pt_port;                  /* Pass-through serio port */
-       unsigned char pt_buttons;               /* Pass-through buttons */
 
        /*
         * Last received Advanced Gesture Mode (AGM) packet. An AGM packet
index 7331084973e12f75753159833fdf0d1e06126ae8..922ea02edcc3ef6c091b572275245e7d5fabd3f0 100644 (file)
@@ -379,7 +379,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
        if (!set_properties)
                return 0;
 
-       if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) {
+       if (trackpoint_read(ps2dev, TP_EXT_BTN, &button_info)) {
                psmouse_warn(psmouse, "failed to get extended button data\n");
                button_info = 0;
        }
@@ -402,7 +402,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
 
        trackpoint_defaults(psmouse->private);
 
-       error = trackpoint_power_on_reset(&psmouse->ps2dev);
+       error = trackpoint_power_on_reset(ps2dev);
 
        /* Write defaults to TP only if reset fails. */
        if (error)
index bb7762bf2879b3a7383b2d326a859833adbbf360..7172b88cd0649c8de16ac7373ec2a16c42c338d2 100644 (file)
@@ -9,9 +9,11 @@ config RMI4_CORE
 
          If unsure, say Y.
 
+if RMI4_CORE
+
 config RMI4_I2C
        tristate "RMI4 I2C Support"
-       depends on RMI4_CORE && I2C
+       depends on I2C
        help
          Say Y here if you want to support RMI4 devices connected to an I2C
          bus.
@@ -20,7 +22,7 @@ config RMI4_I2C
 
 config RMI4_SPI
        tristate "RMI4 SPI Support"
-       depends on RMI4_CORE && SPI
+       depends on SPI
        help
          Say Y here if you want to support RMI4 devices connected to a SPI
          bus.
@@ -29,7 +31,7 @@ config RMI4_SPI
 
 config RMI4_SMB
        tristate "RMI4 SMB Support"
-       depends on RMI4_CORE && I2C
+       depends on I2C
        help
          Say Y here if you want to support RMI4 devices connected to an SMB
          bus.
@@ -40,13 +42,13 @@ config RMI4_SMB
          called rmi_smbus.
 
 config RMI4_F03
-        bool "RMI4 Function 03 (PS2 Guest)"
+       bool "RMI4 Function 03 (PS2 Guest)"
        depends on RMI4_CORE
-        help
-          Say Y here if you want to add support for RMI4 function 03.
+       help
+         Say Y here if you want to add support for RMI4 function 03.
 
-          Function 03 provides PS2 guest support for RMI4 devices. This
-          includes support for TrackPoints on TouchPads.
+         Function 03 provides PS2 guest support for RMI4 devices. This
+         includes support for TrackPoints on TouchPads.
 
 config RMI4_F03_SERIO
        tristate
@@ -57,12 +59,10 @@ config RMI4_F03_SERIO
 
 config RMI4_2D_SENSOR
        bool
-       depends on RMI4_CORE
 
 config RMI4_F11
        bool "RMI4 Function 11 (2D pointing)"
        select RMI4_2D_SENSOR
-       depends on RMI4_CORE
        help
          Say Y here if you want to add support for RMI4 function 11.
 
@@ -73,7 +73,6 @@ config RMI4_F11
 config RMI4_F12
        bool "RMI4 Function 12 (2D pointing)"
        select RMI4_2D_SENSOR
-       depends on RMI4_CORE
        help
          Say Y here if you want to add support for RMI4 function 12.
 
@@ -83,7 +82,6 @@ config RMI4_F12
 
 config RMI4_F30
        bool "RMI4 Function 30 (GPIO LED)"
-       depends on RMI4_CORE
        help
          Say Y here if you want to add support for RMI4 function 30.
 
@@ -92,7 +90,6 @@ config RMI4_F30
 
 config RMI4_F34
        bool "RMI4 Function 34 (Device reflash)"
-       depends on RMI4_CORE
        select FW_LOADER
        help
          Say Y here if you want to add support for RMI4 function 34.
@@ -103,7 +100,6 @@ config RMI4_F34
 
 config RMI4_F54
        bool "RMI4 Function 54 (Analog diagnostics)"
-       depends on RMI4_CORE
        depends on VIDEO_V4L2=y || (RMI4_CORE=m && VIDEO_V4L2=m)
        select VIDEOBUF2_VMALLOC
        select RMI4_F55
@@ -115,9 +111,10 @@ config RMI4_F54
 
 config RMI4_F55
        bool "RMI4 Function 55 (Sensor tuning)"
-       depends on RMI4_CORE
        help
          Say Y here if you want to add support for RMI4 function 55
 
          Function 55 provides access to the RMI4 touch sensor tuning
          mechanism.
+
+endif # RMI_CORE
index 07007ff8e29fff7bf0d245a0174b17e8fcbccf29..8bb866c7b9855c5025d31b7be3f722d469f73da9 100644 (file)
@@ -144,8 +144,13 @@ static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
        int input_flags = 0;
 
        if (sensor->report_abs) {
-               if (sensor->axis_align.swap_axes)
+               if (sensor->axis_align.swap_axes) {
                        swap(sensor->max_x, sensor->max_y);
+                       swap(sensor->axis_align.clip_x_low,
+                            sensor->axis_align.clip_y_low);
+                       swap(sensor->axis_align.clip_x_high,
+                            sensor->axis_align.clip_y_high);
+               }
 
                sensor->min_x = sensor->axis_align.clip_x_low;
                if (sensor->axis_align.clip_x_high)
index 1c40d94ca506cceb776798cb8db1444e36824ffc..ae1bffe45c7511fdf065809b26267710dc5bfaac 100644 (file)
@@ -55,7 +55,7 @@ static void rmi_release_device(struct device *dev)
        kfree(rmi_dev);
 }
 
-static struct device_type rmi_device_type = {
+static const struct device_type rmi_device_type = {
        .name           = "rmi4_sensor",
        .release        = rmi_release_device,
 };
@@ -134,7 +134,7 @@ static void rmi_release_function(struct device *dev)
        kfree(fn);
 }
 
-static struct device_type rmi_function_type = {
+static const struct device_type rmi_function_type = {
        .name           = "rmi4_function",
        .release        = rmi_release_function,
 };
@@ -261,10 +261,10 @@ int __rmi_register_function_handler(struct rmi_function_handler *handler,
        driver->probe = rmi_function_probe;
        driver->remove = rmi_function_remove;
 
-       error = driver_register(&handler->driver);
+       error = driver_register(driver);
        if (error) {
                pr_err("driver_register() failed for %s, error: %d\n",
-                       handler->driver.name, error);
+                       driver->name, error);
                return error;
        }
 
index bf5c36e229bacd63dd7e77d028aa65fb4555ce89..d64fc92858f2038a9fd76a7b7e2a0e17d7380698 100644 (file)
@@ -265,6 +265,19 @@ static int rmi_irq_init(struct rmi_device *rmi_dev)
        return 0;
 }
 
+struct rmi_function *rmi_find_function(struct rmi_device *rmi_dev, u8 number)
+{
+       struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
+       struct rmi_function *entry;
+
+       list_for_each_entry(entry, &data->function_list, node) {
+               if (entry->fd.function_number == number)
+                       return entry;
+       }
+
+       return NULL;
+}
+
 static int suspend_one_function(struct rmi_function *fn)
 {
        struct rmi_function_handler *fh;
@@ -364,7 +377,7 @@ static void rmi_driver_set_input_name(struct rmi_device *rmi_dev,
                                struct input_dev *input)
 {
        struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
-       char *device_name = rmi_f01_get_product_ID(data->f01_container);
+       const char *device_name = rmi_f01_get_product_ID(data->f01_container);
        char *name;
 
        name = devm_kasprintf(&rmi_dev->dev, GFP_KERNEL,
@@ -836,7 +849,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
                               void *ctx, const struct pdt_entry *pdt)
 {
        struct device *dev = &rmi_dev->dev;
-       struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
+       struct rmi_driver_data *data = dev_get_drvdata(dev);
        int *current_irq_count = ctx;
        struct rmi_function *fn;
        int i;
@@ -1040,7 +1053,7 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
        }
 
        if (data->bootloader_mode)
-               dev_warn(&rmi_dev->dev, "Device in bootloader mode.\n");
+               dev_warn(dev, "Device in bootloader mode.\n");
 
        data->irq_count = irq_count;
        data->num_of_irq_regs = (data->irq_count + 7) / 8;
@@ -1049,7 +1062,7 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
        data->irq_memory = devm_kzalloc(dev, size * 4, GFP_KERNEL);
        if (!data->irq_memory) {
                dev_err(dev, "Failed to allocate memory for irq masks.\n");
-               return retval;
+               return -ENOMEM;
        }
 
        data->irq_status        = data->irq_memory + size * 0;
index 24f8f764d171cafb18fbc878b707006ecdfcc658..f1a2a2266022779e3d6266958c1314d9f508209d 100644 (file)
@@ -93,6 +93,7 @@ bool rmi_is_physical_driver(struct device_driver *);
 int rmi_register_physical_driver(void);
 void rmi_unregister_physical_driver(void);
 void rmi_free_function_list(struct rmi_device *rmi_dev);
+struct rmi_function *rmi_find_function(struct rmi_device *rmi_dev, u8 number);
 int rmi_enable_sensor(struct rmi_device *rmi_dev);
 int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx,
                 int (*callback)(struct rmi_device *rmi_dev, void *ctx,
@@ -104,7 +105,20 @@ int rmi_init_functions(struct rmi_driver_data *data);
 int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx,
                      const struct pdt_entry *pdt);
 
-char *rmi_f01_get_product_ID(struct rmi_function *fn);
+const char *rmi_f01_get_product_ID(struct rmi_function *fn);
+
+#ifdef CONFIG_RMI4_F03
+int rmi_f03_overwrite_button(struct rmi_function *fn, unsigned int button,
+                            int value);
+void rmi_f03_commit_buttons(struct rmi_function *fn);
+#else
+static inline int rmi_f03_overwrite_button(struct rmi_function *fn,
+                                          unsigned int button, int value)
+{
+       return 0;
+}
+static inline void rmi_f03_commit_buttons(struct rmi_function *fn) {}
+#endif
 
 #ifdef CONFIG_RMI4_F34
 int rmi_f34_create_sysfs(struct rmi_device *rmi_dev);
index 18baf4ceb9407e6cad636ec9d41f638b9aba2131..7f7e9176f7ea26b34b03a501722a30cec70241e0 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/of.h>
+#include <asm/unaligned.h>
 #include "rmi_driver.h"
 
 #define RMI_PRODUCT_ID_LENGTH    10
@@ -54,6 +55,7 @@ struct f01_basic_properties {
        u8 product_id[RMI_PRODUCT_ID_LENGTH + 1];
        u16 productinfo;
        u32 firmware_id;
+       u32 package_id;
 };
 
 /* F01 device status bits */
@@ -220,8 +222,19 @@ static int rmi_f01_read_properties(struct rmi_device *rmi_dev,
                        has_build_id_query = !!(queries[0] & BIT(1));
                }
 
-               if (has_package_id_query)
+               if (has_package_id_query) {
+                       ret = rmi_read_block(rmi_dev, prod_info_addr,
+                                            queries, sizeof(__le64));
+                       if (ret) {
+                               dev_err(&rmi_dev->dev,
+                                       "Failed to read package info: %d\n",
+                                       ret);
+                               return ret;
+                       }
+
+                       props->package_id = get_unaligned_le64(queries);
                        prod_info_addr++;
+               }
 
                if (has_build_id_query) {
                        ret = rmi_read_block(rmi_dev, prod_info_addr, queries,
@@ -241,13 +254,90 @@ static int rmi_f01_read_properties(struct rmi_device *rmi_dev,
        return 0;
 }
 
-char *rmi_f01_get_product_ID(struct rmi_function *fn)
+const char *rmi_f01_get_product_ID(struct rmi_function *fn)
 {
        struct f01_data *f01 = dev_get_drvdata(&fn->dev);
 
        return f01->properties.product_id;
 }
 
+static ssize_t rmi_driver_manufacturer_id_show(struct device *dev,
+                                              struct device_attribute *dattr,
+                                              char *buf)
+{
+       struct rmi_driver_data *data = dev_get_drvdata(dev);
+       struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%d\n",
+                        f01->properties.manufacturer_id);
+}
+
+static DEVICE_ATTR(manufacturer_id, 0444,
+                  rmi_driver_manufacturer_id_show, NULL);
+
+static ssize_t rmi_driver_dom_show(struct device *dev,
+                                  struct device_attribute *dattr, char *buf)
+{
+       struct rmi_driver_data *data = dev_get_drvdata(dev);
+       struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%s\n", f01->properties.dom);
+}
+
+static DEVICE_ATTR(date_of_manufacture, 0444, rmi_driver_dom_show, NULL);
+
+static ssize_t rmi_driver_product_id_show(struct device *dev,
+                                         struct device_attribute *dattr,
+                                         char *buf)
+{
+       struct rmi_driver_data *data = dev_get_drvdata(dev);
+       struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%s\n", f01->properties.product_id);
+}
+
+static DEVICE_ATTR(product_id, 0444, rmi_driver_product_id_show, NULL);
+
+static ssize_t rmi_driver_firmware_id_show(struct device *dev,
+                                          struct device_attribute *dattr,
+                                          char *buf)
+{
+       struct rmi_driver_data *data = dev_get_drvdata(dev);
+       struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
+
+       return scnprintf(buf, PAGE_SIZE, "%d\n", f01->properties.firmware_id);
+}
+
+static DEVICE_ATTR(firmware_id, 0444, rmi_driver_firmware_id_show, NULL);
+
+static ssize_t rmi_driver_package_id_show(struct device *dev,
+                                         struct device_attribute *dattr,
+                                         char *buf)
+{
+       struct rmi_driver_data *data = dev_get_drvdata(dev);
+       struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
+
+       u32 package_id = f01->properties.package_id;
+
+       return scnprintf(buf, PAGE_SIZE, "%04x.%04x\n",
+                        package_id & 0xffff, (package_id >> 16) & 0xffff);
+}
+
+static DEVICE_ATTR(package_id, 0444, rmi_driver_package_id_show, NULL);
+
+static struct attribute *rmi_f01_attrs[] = {
+       &dev_attr_manufacturer_id.attr,
+       &dev_attr_date_of_manufacture.attr,
+       &dev_attr_product_id.attr,
+       &dev_attr_firmware_id.attr,
+       &dev_attr_package_id.attr,
+       NULL
+};
+
+static struct attribute_group rmi_f01_attr_group = {
+       .attrs = rmi_f01_attrs,
+};
+
 #ifdef CONFIG_OF
 static int rmi_f01_of_probe(struct device *dev,
                                struct rmi_device_platform_data *pdata)
@@ -480,9 +570,18 @@ static int rmi_f01_probe(struct rmi_function *fn)
 
        dev_set_drvdata(&fn->dev, f01);
 
+       error = sysfs_create_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
+       if (error)
+               dev_warn(&fn->dev, "Failed to create sysfs group: %d\n", error);
+
        return 0;
 }
 
+static void rmi_f01_remove(struct rmi_function *fn)
+{
+       sysfs_remove_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
+}
+
 static int rmi_f01_config(struct rmi_function *fn)
 {
        struct f01_data *f01 = dev_get_drvdata(&fn->dev);
@@ -622,6 +721,7 @@ struct rmi_function_handler rmi_f01_handler = {
        },
        .func           = 0x01,
        .probe          = rmi_f01_probe,
+       .remove         = rmi_f01_remove,
        .config         = rmi_f01_config,
        .attention      = rmi_f01_attention,
        .suspend        = rmi_f01_suspend,
index 8a7ca3e2f95e62448cc2ecfcf910f767b9337bfa..77dad045a4683026460dca491419112d730897d7 100644 (file)
 #define RMI_F03_BYTES_PER_DEVICE_SHIFT 4
 #define RMI_F03_QUEUE_LENGTH           0x0F
 
+#define PSMOUSE_OOB_EXTRA_BTNS         0x01
+
 struct f03_data {
        struct rmi_function *fn;
 
        struct serio *serio;
 
+       unsigned int overwrite_buttons;
+
        u8 device_count;
        u8 rx_queue_length;
 };
 
+int rmi_f03_overwrite_button(struct rmi_function *fn, unsigned int button,
+                            int value)
+{
+       struct f03_data *f03 = dev_get_drvdata(&fn->dev);
+       unsigned int bit;
+
+       if (button < BTN_LEFT || button > BTN_MIDDLE)
+               return -EINVAL;
+
+       bit = BIT(button - BTN_LEFT);
+
+       if (value)
+               f03->overwrite_buttons |= bit;
+       else
+               f03->overwrite_buttons &= ~bit;
+
+       return 0;
+}
+
+void rmi_f03_commit_buttons(struct rmi_function *fn)
+{
+       struct f03_data *f03 = dev_get_drvdata(&fn->dev);
+       struct serio *serio = f03->serio;
+
+       serio_pause_rx(serio);
+       if (serio->drv) {
+               serio->drv->interrupt(serio, PSMOUSE_OOB_EXTRA_BTNS,
+                                     SERIO_OOB_DATA);
+               serio->drv->interrupt(serio, f03->overwrite_buttons,
+                                     SERIO_OOB_DATA);
+       }
+       serio_continue_rx(serio);
+}
+
 static int rmi_f03_pt_write(struct serio *id, unsigned char val)
 {
        struct f03_data *f03 = id->port_data;
@@ -175,9 +213,6 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
        int i;
        int error;
 
-       if (!rmi_dev)
-               return -ENODEV;
-
        if (drvdata->attn_data.data) {
                /* First grab the data passed by the transport device */
                if (drvdata->attn_data.size < ob_len) {
index f4b491e3e0fd4486c2680fab77515d91abaec4aa..3422464af229bc578d43726d266943558fe538bf 100644 (file)
 
 /* Defs for Query 0 */
 #define RMI_F30_EXTENDED_PATTERNS              0x01
-#define RMI_F30_HAS_MAPPABLE_BUTTONS           (1 << 1)
-#define RMI_F30_HAS_LED                        (1 << 2)
-#define RMI_F30_HAS_GPIO                       (1 << 3)
-#define RMI_F30_HAS_HAPTIC                     (1 << 4)
-#define RMI_F30_HAS_GPIO_DRV_CTL               (1 << 5)
-#define RMI_F30_HAS_MECH_MOUSE_BTNS            (1 << 6)
+#define RMI_F30_HAS_MAPPABLE_BUTTONS           BIT(1)
+#define RMI_F30_HAS_LED                                BIT(2)
+#define RMI_F30_HAS_GPIO                       BIT(3)
+#define RMI_F30_HAS_HAPTIC                     BIT(4)
+#define RMI_F30_HAS_GPIO_DRV_CTL               BIT(5)
+#define RMI_F30_HAS_MECH_MOUSE_BTNS            BIT(6)
 
 /* Defs for Query 1 */
 #define RMI_F30_GPIO_LED_COUNT                 0x1F
 
 /* Defs for Control Registers */
 #define RMI_F30_CTRL_1_GPIO_DEBOUNCE           0x01
-#define RMI_F30_CTRL_1_HALT                    (1 << 4)
-#define RMI_F30_CTRL_1_HALTED                  (1 << 5)
+#define RMI_F30_CTRL_1_HALT                    BIT(4)
+#define RMI_F30_CTRL_1_HALTED                  BIT(5)
 #define RMI_F30_CTRL_10_NUM_MECH_MOUSE_BTNS    0x03
 
-struct rmi_f30_ctrl_data {
-       int address;
-       int length;
-       u8 *regs;
-};
-
 #define RMI_F30_CTRL_MAX_REGS          32
-#define RMI_F30_CTRL_MAX_BYTES         ((RMI_F30_CTRL_MAX_REGS + 7) >> 3)
+#define RMI_F30_CTRL_MAX_BYTES         DIV_ROUND_UP(RMI_F30_CTRL_MAX_REGS, 8)
 #define RMI_F30_CTRL_MAX_REG_BLOCKS    11
 
 #define RMI_F30_CTRL_REGS_MAX_SIZE (RMI_F30_CTRL_MAX_BYTES             \
@@ -54,6 +48,15 @@ struct rmi_f30_ctrl_data {
                                        + 1                             \
                                        + 1)
 
+#define TRACKSTICK_RANGE_START         3
+#define TRACKSTICK_RANGE_END           6
+
+struct rmi_f30_ctrl_data {
+       int address;
+       int length;
+       u8 *regs;
+};
+
 struct f30_data {
        /* Query Data */
        bool has_extended_pattern;
@@ -76,18 +79,21 @@ struct f30_data {
        u16 *gpioled_key_map;
 
        struct input_dev *input;
+
+       struct rmi_function *f03;
+       bool trackstick_buttons;
 };
 
 static int rmi_f30_read_control_parameters(struct rmi_function *fn,
                                                struct f30_data *f30)
 {
-       struct rmi_device *rmi_dev = fn->rmi_dev;
-       int error = 0;
+       int error;
 
-       error = rmi_read_block(rmi_dev, fn->fd.control_base_addr,
-                               f30->ctrl_regs, f30->ctrl_regs_size);
+       error = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr,
+                              f30->ctrl_regs, f30->ctrl_regs_size);
        if (error) {
-               dev_err(&rmi_dev->dev, "%s : Could not read control registers at 0x%x error (%d)\n",
+               dev_err(&fn->dev,
+                       "%s: Could not read control registers at 0x%x: %d\n",
                        __func__, fn->fd.control_base_addr, error);
                return error;
        }
@@ -95,24 +101,39 @@ static int rmi_f30_read_control_parameters(struct rmi_function *fn,
        return 0;
 }
 
+static void rmi_f30_report_button(struct rmi_function *fn,
+                                 struct f30_data *f30, unsigned int button)
+{
+       unsigned int reg_num = button >> 3;
+       unsigned int bit_num = button & 0x07;
+       u16 key_code = f30->gpioled_key_map[button];
+       bool key_down = !(f30->data_regs[reg_num] & BIT(bit_num));
+
+       if (f30->trackstick_buttons &&
+           button >= TRACKSTICK_RANGE_START &&
+           button <= TRACKSTICK_RANGE_END) {
+               rmi_f03_overwrite_button(f30->f03, key_code, key_down);
+       } else {
+               rmi_dbg(RMI_DEBUG_FN, &fn->dev,
+                       "%s: call input report key (0x%04x) value (0x%02x)",
+                       __func__, key_code, key_down);
+
+               input_report_key(f30->input, key_code, key_down);
+       }
+}
+
 static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
 {
        struct f30_data *f30 = dev_get_drvdata(&fn->dev);
-       struct rmi_device *rmi_dev = fn->rmi_dev;
-       struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
-       int retval;
-       int gpiled = 0;
-       int value = 0;
+       struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
+       int error;
        int i;
-       int reg_num;
-
-       if (!f30->input)
-               return 0;
 
        /* Read the gpi led data. */
        if (drvdata->attn_data.data) {
                if (drvdata->attn_data.size < f30->register_count) {
-                       dev_warn(&fn->dev, "F30 interrupted, but data is missing\n");
+                       dev_warn(&fn->dev,
+                                "F30 interrupted, but data is missing\n");
                        return 0;
                }
                memcpy(f30->data_regs, drvdata->attn_data.data,
@@ -120,72 +141,24 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
                drvdata->attn_data.data += f30->register_count;
                drvdata->attn_data.size -= f30->register_count;
        } else {
-               retval = rmi_read_block(rmi_dev, fn->fd.data_base_addr,
-                       f30->data_regs, f30->register_count);
-
-               if (retval) {
-                       dev_err(&fn->dev, "%s: Failed to read F30 data registers.\n",
-                               __func__);
-                       return retval;
-               }
-       }
-
-       for (reg_num = 0; reg_num < f30->register_count; ++reg_num) {
-               for (i = 0; gpiled < f30->gpioled_count && i < 8; ++i,
-                       ++gpiled) {
-                       if (f30->gpioled_key_map[gpiled] != 0) {
-                               /* buttons have pull up resistors */
-                               value = (((f30->data_regs[reg_num] >> i) & 0x01)
-                                                                       == 0);
-
-                               rmi_dbg(RMI_DEBUG_FN, &fn->dev,
-                                       "%s: call input report key (0x%04x) value (0x%02x)",
-                                       __func__,
-                                       f30->gpioled_key_map[gpiled], value);
-                               input_report_key(f30->input,
-                                                f30->gpioled_key_map[gpiled],
-                                                value);
-                       }
-
+               error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr,
+                                      f30->data_regs, f30->register_count);
+               if (error) {
+                       dev_err(&fn->dev,
+                               "%s: Failed to read F30 data registers: %d\n",
+                               __func__, error);
+                       return error;
                }
        }
 
-       return 0;
-}
-
-static int rmi_f30_register_device(struct rmi_function *fn)
-{
-       int i;
-       struct rmi_device *rmi_dev = fn->rmi_dev;
-       struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
-       struct f30_data *f30 = dev_get_drvdata(&fn->dev);
-       struct input_dev *input_dev;
-       int button_count = 0;
-
-       input_dev = drv_data->input;
-       if (!input_dev) {
-               dev_info(&fn->dev, "F30: no input device found, ignoring.\n");
-               return -EINVAL;
-       }
-
-       f30->input = input_dev;
-
-       set_bit(EV_KEY, input_dev->evbit);
-
-       input_dev->keycode = f30->gpioled_key_map;
-       input_dev->keycodesize = sizeof(u16);
-       input_dev->keycodemax = f30->gpioled_count;
-
-       for (i = 0; i < f30->gpioled_count; i++) {
-               if (f30->gpioled_key_map[i] != 0) {
-                       input_set_capability(input_dev, EV_KEY,
-                                               f30->gpioled_key_map[i]);
-                       button_count++;
-               }
+       if (f30->has_gpio) {
+               for (i = 0; i < f30->gpioled_count; i++)
+                       if (f30->gpioled_key_map[i] != KEY_RESERVED)
+                               rmi_f30_report_button(fn, f30, i);
+               if (f30->trackstick_buttons)
+                       rmi_f03_commit_buttons(f30->f03);
        }
 
-       if (button_count == 1)
-               __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
        return 0;
 }
 
@@ -197,6 +170,12 @@ static int rmi_f30_config(struct rmi_function *fn)
                                rmi_get_platform_data(fn->rmi_dev);
        int error;
 
+       if (pdata->f30_data.trackstick_buttons) {
+               /* Try [re-]establish link to F03. */
+               f30->f03 = rmi_find_function(fn->rmi_dev, 0x03);
+               f30->trackstick_buttons = f30->f03 != NULL;
+       }
+
        if (pdata->f30_data.disable) {
                drv->clear_irq_bits(fn->rmi_dev, fn->irq_mask);
        } else {
@@ -204,19 +183,20 @@ static int rmi_f30_config(struct rmi_function *fn)
                error = rmi_write_block(fn->rmi_dev, fn->fd.control_base_addr,
                                        f30->ctrl_regs, f30->ctrl_regs_size);
                if (error) {
-                       dev_err(&fn->rmi_dev->dev,
-                               "%s : Could not write control registers at 0x%x error (%d)\n",
+                       dev_err(&fn->dev,
+                               "%s: Could not write control registers at 0x%x: %d\n",
                                __func__, fn->fd.control_base_addr, error);
                        return error;
                }
 
                drv->set_irq_bits(fn->rmi_dev, fn->irq_mask);
        }
+
        return 0;
 }
 
-static inline void rmi_f30_set_ctrl_data(struct rmi_f30_ctrl_data *ctrl,
-                                       int *ctrl_addr, int len, u8 **reg)
+static void rmi_f30_set_ctrl_data(struct rmi_f30_ctrl_data *ctrl,
+                                 int *ctrl_addr, int len, u8 **reg)
 {
        ctrl->address = *ctrl_addr;
        ctrl->length = len;
@@ -225,8 +205,7 @@ static inline void rmi_f30_set_ctrl_data(struct rmi_f30_ctrl_data *ctrl,
        *reg += len;
 }
 
-static inline bool rmi_f30_is_valid_button(int button,
-               struct rmi_f30_ctrl_data *ctrl)
+static bool rmi_f30_is_valid_button(int button, struct rmi_f30_ctrl_data *ctrl)
 {
        int byte_position = button >> 3;
        int bit_position = button & 0x07;
@@ -239,32 +218,66 @@ static inline bool rmi_f30_is_valid_button(int button,
                (ctrl[3].regs[byte_position] & BIT(bit_position));
 }
 
-static inline int rmi_f30_initialize(struct rmi_function *fn)
+static int rmi_f30_map_gpios(struct rmi_function *fn,
+                            struct f30_data *f30)
 {
-       struct f30_data *f30;
-       struct rmi_device *rmi_dev = fn->rmi_dev;
-       const struct rmi_device_platform_data *pdata;
-       int retval = 0;
-       int control_address;
+       const struct rmi_device_platform_data *pdata =
+                                       rmi_get_platform_data(fn->rmi_dev);
+       struct input_dev *input = f30->input;
+       unsigned int button = BTN_LEFT;
+       unsigned int trackstick_button = BTN_LEFT;
+       bool button_mapped = false;
        int i;
-       int button;
-       u8 buf[RMI_F30_QUERY_SIZE];
-       u8 *ctrl_reg;
-       u8 *map_memory;
 
-       f30 = devm_kzalloc(&fn->dev, sizeof(struct f30_data),
-                          GFP_KERNEL);
-       if (!f30)
+       f30->gpioled_key_map = devm_kcalloc(&fn->dev,
+                                           f30->gpioled_count,
+                                           sizeof(f30->gpioled_key_map[0]),
+                                           GFP_KERNEL);
+       if (!f30->gpioled_key_map) {
+               dev_err(&fn->dev, "Failed to allocate gpioled map memory.\n");
                return -ENOMEM;
+       }
 
-       dev_set_drvdata(&fn->dev, f30);
+       for (i = 0; i < f30->gpioled_count; i++) {
+               if (!rmi_f30_is_valid_button(i, f30->ctrl))
+                       continue;
+
+               if (pdata->f30_data.trackstick_buttons &&
+                   i >= TRACKSTICK_RANGE_START && i < TRACKSTICK_RANGE_END) {
+                       f30->gpioled_key_map[i] = trackstick_button++;
+               } else if (!pdata->f30_data.buttonpad || !button_mapped) {
+                       f30->gpioled_key_map[i] = button;
+                       input_set_capability(input, EV_KEY, button++);
+                       button_mapped = true;
+               }
+       }
+
+       input->keycode = f30->gpioled_key_map;
+       input->keycodesize = sizeof(f30->gpioled_key_map[0]);
+       input->keycodemax = f30->gpioled_count;
+
+       /*
+        * Buttonpad could be also inferred from f30->has_mech_mouse_btns,
+        * but I am not sure, so use only the pdata info.
+        */
+       if (pdata->f30_data.buttonpad)
+               __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
+
+       return 0;
+}
 
-       retval = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr, buf,
-                               RMI_F30_QUERY_SIZE);
+static int rmi_f30_initialize(struct rmi_function *fn, struct f30_data *f30)
+{
+       u8 *ctrl_reg = f30->ctrl_regs;
+       int control_address = fn->fd.control_base_addr;
+       u8 buf[RMI_F30_QUERY_SIZE];
+       int error;
 
-       if (retval) {
-               dev_err(&fn->dev, "Failed to read query register.\n");
-               return retval;
+       error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
+                              buf, RMI_F30_QUERY_SIZE);
+       if (error) {
+               dev_err(&fn->dev, "Failed to read query register\n");
+               return error;
        }
 
        f30->has_extended_pattern = buf[0] & RMI_F30_EXTENDED_PATTERNS;
@@ -276,101 +289,71 @@ static inline int rmi_f30_initialize(struct rmi_function *fn)
        f30->has_mech_mouse_btns = buf[0] & RMI_F30_HAS_MECH_MOUSE_BTNS;
        f30->gpioled_count = buf[1] & RMI_F30_GPIO_LED_COUNT;
 
-       f30->register_count = (f30->gpioled_count + 7) >> 3;
-
-       control_address = fn->fd.control_base_addr;
-       ctrl_reg = f30->ctrl_regs;
+       f30->register_count = DIV_ROUND_UP(f30->gpioled_count, 8);
 
        if (f30->has_gpio && f30->has_led)
                rmi_f30_set_ctrl_data(&f30->ctrl[0], &control_address,
-                                       f30->register_count, &ctrl_reg);
+                                     f30->register_count, &ctrl_reg);
 
-       rmi_f30_set_ctrl_data(&f30->ctrl[1], &control_address, sizeof(u8),
-                               &ctrl_reg);
+       rmi_f30_set_ctrl_data(&f30->ctrl[1], &control_address,
+                             sizeof(u8), &ctrl_reg);
 
        if (f30->has_gpio) {
                rmi_f30_set_ctrl_data(&f30->ctrl[2], &control_address,
-                                       f30->register_count, &ctrl_reg);
+                                     f30->register_count, &ctrl_reg);
 
                rmi_f30_set_ctrl_data(&f30->ctrl[3], &control_address,
-                                       f30->register_count, &ctrl_reg);
+                                     f30->register_count, &ctrl_reg);
        }
 
        if (f30->has_led) {
-               int ctrl5_len;
-
                rmi_f30_set_ctrl_data(&f30->ctrl[4], &control_address,
-                                       f30->register_count, &ctrl_reg);
-
-               if (f30->has_extended_pattern)
-                       ctrl5_len = 6;
-               else
-                       ctrl5_len = 2;
+                                     f30->register_count, &ctrl_reg);
 
                rmi_f30_set_ctrl_data(&f30->ctrl[5], &control_address,
-                                       ctrl5_len, &ctrl_reg);
+                                     f30->has_extended_pattern ? 6 : 2,
+                                     &ctrl_reg);
        }
 
        if (f30->has_led || f30->has_gpio_driver_control) {
                /* control 6 uses a byte per gpio/led */
                rmi_f30_set_ctrl_data(&f30->ctrl[6], &control_address,
-                                       f30->gpioled_count, &ctrl_reg);
+                                     f30->gpioled_count, &ctrl_reg);
        }
 
        if (f30->has_mappable_buttons) {
                /* control 7 uses a byte per gpio/led */
                rmi_f30_set_ctrl_data(&f30->ctrl[7], &control_address,
-                                       f30->gpioled_count, &ctrl_reg);
+                                     f30->gpioled_count, &ctrl_reg);
        }
 
        if (f30->has_haptic) {
                rmi_f30_set_ctrl_data(&f30->ctrl[8], &control_address,
-                                       f30->register_count, &ctrl_reg);
+                                     f30->register_count, &ctrl_reg);
 
                rmi_f30_set_ctrl_data(&f30->ctrl[9], &control_address,
-                                       sizeof(u8), &ctrl_reg);
+                                     sizeof(u8), &ctrl_reg);
        }
 
        if (f30->has_mech_mouse_btns)
                rmi_f30_set_ctrl_data(&f30->ctrl[10], &control_address,
-                                       sizeof(u8), &ctrl_reg);
+                                     sizeof(u8), &ctrl_reg);
 
-       f30->ctrl_regs_size = ctrl_reg - f30->ctrl_regs
-                               ?: RMI_F30_CTRL_REGS_MAX_SIZE;
+       f30->ctrl_regs_size = ctrl_reg -
+                               f30->ctrl_regs ?: RMI_F30_CTRL_REGS_MAX_SIZE;
 
-       retval = rmi_f30_read_control_parameters(fn, f30);
-       if (retval < 0) {
+       error = rmi_f30_read_control_parameters(fn, f30);
+       if (error) {
                dev_err(&fn->dev,
-                       "Failed to initialize F19 control params.\n");
-               return retval;
-       }
-
-       map_memory = devm_kzalloc(&fn->dev,
-                                 (f30->gpioled_count * (sizeof(u16))),
-                                 GFP_KERNEL);
-       if (!map_memory) {
-               dev_err(&fn->dev, "Failed to allocate gpioled map memory.\n");
-               return -ENOMEM;
+                       "Failed to initialize F30 control params: %d\n",
+                       error);
+               return error;
        }
 
-       f30->gpioled_key_map = (u16 *)map_memory;
-
-       pdata = rmi_get_platform_data(rmi_dev);
        if (f30->has_gpio) {
-               button = BTN_LEFT;
-               for (i = 0; i < f30->gpioled_count; i++) {
-                       if (rmi_f30_is_valid_button(i, f30->ctrl)) {
-                               f30->gpioled_key_map[i] = button++;
-
-                               /*
-                                * buttonpad might be given by
-                                * f30->has_mech_mouse_btns, but I am
-                                * not sure, so use only the pdata info
-                                */
-                               if (pdata->f30_data.buttonpad)
-                                       break;
-                       }
-               }
+               error = rmi_f30_map_gpios(fn, f30);
+               if (error)
+                       return error;
        }
 
        return 0;
@@ -378,26 +361,33 @@ static inline int rmi_f30_initialize(struct rmi_function *fn)
 
 static int rmi_f30_probe(struct rmi_function *fn)
 {
-       int rc;
+       struct rmi_device *rmi_dev = fn->rmi_dev;
        const struct rmi_device_platform_data *pdata =
-                               rmi_get_platform_data(fn->rmi_dev);
+                                       rmi_get_platform_data(rmi_dev);
+       struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
+       struct f30_data *f30;
+       int error;
 
        if (pdata->f30_data.disable)
                return 0;
 
-       rc = rmi_f30_initialize(fn);
-       if (rc < 0)
-               goto error_exit;
+       if (!drv_data->input) {
+               dev_info(&fn->dev, "F30: no input device found, ignoring\n");
+               return -ENXIO;
+       }
 
-       rc = rmi_f30_register_device(fn);
-       if (rc < 0)
-               goto error_exit;
+       f30 = devm_kzalloc(&fn->dev, sizeof(*f30), GFP_KERNEL);
+       if (!f30)
+               return -ENOMEM;
 
-       return 0;
+       f30->input = drv_data->input;
 
-error_exit:
-       return rc;
+       error = rmi_f30_initialize(fn, f30);
+       if (error)
+               return error;
 
+       dev_set_drvdata(&fn->dev, f30);
+       return 0;
 }
 
 struct rmi_function_handler rmi_f30_handler = {
index 9774dfbab9bb239886572c1a2b412d74a67ebccd..425fe140e9df3f4c15ecb091d1c08beb6dfb60d2 100644 (file)
@@ -157,6 +157,9 @@ static int rmi_f34_write_blocks(struct f34_data *f34, const void *data,
                        i + 1, block_count);
 
                data += f34->v5.block_size;
+               f34->update_progress += f34->v5.block_size;
+               f34->update_status = (f34->update_progress * 100) /
+                       f34->update_size;
        }
 
        return 0;
@@ -174,7 +177,7 @@ static int rmi_f34_write_config(struct f34_data *f34, const void *data)
                                    F34_WRITE_CONFIG_BLOCK);
 }
 
-int rmi_f34_enable_flash(struct f34_data *f34)
+static int rmi_f34_enable_flash(struct f34_data *f34)
 {
        return rmi_f34_command(f34, F34_ENABLE_FLASH_PROG,
                               F34_ENABLE_WAIT_MS, true);
@@ -184,9 +187,14 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
                                  const struct rmi_f34_firmware *syn_fw)
 {
        struct rmi_function *fn = f34->fn;
+       u32 image_size = le32_to_cpu(syn_fw->image_size);
+       u32 config_size = le32_to_cpu(syn_fw->config_size);
        int ret;
 
-       if (syn_fw->image_size) {
+       f34->update_progress = 0;
+       f34->update_size = image_size + config_size;
+
+       if (image_size) {
                dev_info(&fn->dev, "Erasing firmware...\n");
                ret = rmi_f34_command(f34, F34_ERASE_ALL,
                                      F34_ERASE_WAIT_MS, true);
@@ -194,18 +202,18 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
                        return ret;
 
                dev_info(&fn->dev, "Writing firmware (%d bytes)...\n",
-                        syn_fw->image_size);
+                        image_size);
                ret = rmi_f34_write_firmware(f34, syn_fw->data);
                if (ret)
                        return ret;
        }
 
-       if (syn_fw->config_size) {
+       if (config_size) {
                /*
                 * We only need to erase config if we haven't updated
                 * firmware.
                 */
-               if (!syn_fw->image_size) {
+               if (!image_size) {
                        dev_info(&fn->dev, "Erasing config...\n");
                        ret = rmi_f34_command(f34, F34_ERASE_CONFIG,
                                              F34_ERASE_WAIT_MS, true);
@@ -214,9 +222,8 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
                }
 
                dev_info(&fn->dev, "Writing config (%d bytes)...\n",
-                        syn_fw->config_size);
-               ret = rmi_f34_write_config(f34,
-                               &syn_fw->data[syn_fw->image_size]);
+                        config_size);
+               ret = rmi_f34_write_config(f34, &syn_fw->data[image_size]);
                if (ret)
                        return ret;
        }
@@ -224,21 +231,23 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
        return 0;
 }
 
-int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw)
+static int rmi_f34_update_firmware(struct f34_data *f34,
+                                  const struct firmware *fw)
 {
-       const struct rmi_f34_firmware *syn_fw;
+       const struct rmi_f34_firmware *syn_fw =
+                               (const struct rmi_f34_firmware *)fw->data;
+       u32 image_size = le32_to_cpu(syn_fw->image_size);
+       u32 config_size = le32_to_cpu(syn_fw->config_size);
        int ret;
 
-       syn_fw = (const struct rmi_f34_firmware *)fw->data;
        BUILD_BUG_ON(offsetof(struct rmi_f34_firmware, data) !=
                        F34_FW_IMAGE_OFFSET);
 
        rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
-               "FW size:%d, checksum:%08x, image_size:%d, config_size:%d\n",
-               (int)fw->size,
+               "FW size:%zd, checksum:%08x, image_size:%d, config_size:%d\n",
+               fw->size,
                le32_to_cpu(syn_fw->checksum),
-               le32_to_cpu(syn_fw->image_size),
-               le32_to_cpu(syn_fw->config_size));
+               image_size, config_size);
 
        rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
                "FW bootloader_id:%02x, product_id:%.*s, info: %02x%02x\n",
@@ -246,27 +255,25 @@ int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw)
                (int)sizeof(syn_fw->product_id), syn_fw->product_id,
                syn_fw->product_info[0], syn_fw->product_info[1]);
 
-       if (syn_fw->image_size &&
-           syn_fw->image_size != f34->v5.fw_blocks * f34->v5.block_size) {
+       if (image_size && image_size != f34->v5.fw_blocks * f34->v5.block_size) {
                dev_err(&f34->fn->dev,
                        "Bad firmware image: fw size %d, expected %d\n",
-                       syn_fw->image_size,
-                       f34->v5.fw_blocks * f34->v5.block_size);
+                       image_size, f34->v5.fw_blocks * f34->v5.block_size);
                ret = -EILSEQ;
                goto out;
        }
 
-       if (syn_fw->config_size &&
-           syn_fw->config_size != f34->v5.config_blocks * f34->v5.block_size) {
+       if (config_size &&
+           config_size != f34->v5.config_blocks * f34->v5.block_size) {
                dev_err(&f34->fn->dev,
                        "Bad firmware image: config size %d, expected %d\n",
-                       syn_fw->config_size,
+                       config_size,
                        f34->v5.config_blocks * f34->v5.block_size);
                ret = -EILSEQ;
                goto out;
        }
 
-       if (syn_fw->image_size && !syn_fw->config_size) {
+       if (image_size && !config_size) {
                dev_err(&f34->fn->dev, "Bad firmware image: no config data\n");
                ret = -EILSEQ;
                goto out;
@@ -283,6 +290,63 @@ out:
        return ret;
 }
 
+static int rmi_f34_status(struct rmi_function *fn)
+{
+       struct f34_data *f34 = dev_get_drvdata(&fn->dev);
+
+       /*
+        * The status is the percentage complete, or once complete,
+        * zero for success or a negative return code.
+        */
+       return f34->update_status;
+}
+
+static ssize_t rmi_driver_bootloader_id_show(struct device *dev,
+                                            struct device_attribute *dattr,
+                                            char *buf)
+{
+       struct rmi_driver_data *data = dev_get_drvdata(dev);
+       struct rmi_function *fn = data->f34_container;
+       struct f34_data *f34;
+
+       if (fn) {
+               f34 = dev_get_drvdata(&fn->dev);
+
+               if (f34->bl_version == 5)
+                       return scnprintf(buf, PAGE_SIZE, "%c%c\n",
+                                        f34->bootloader_id[0],
+                                        f34->bootloader_id[1]);
+               else
+                       return scnprintf(buf, PAGE_SIZE, "V%d.%d\n",
+                                        f34->bootloader_id[1],
+                                        f34->bootloader_id[0]);
+       }
+
+       return 0;
+}
+
+static DEVICE_ATTR(bootloader_id, 0444, rmi_driver_bootloader_id_show, NULL);
+
+static ssize_t rmi_driver_configuration_id_show(struct device *dev,
+                                               struct device_attribute *dattr,
+                                               char *buf)
+{
+       struct rmi_driver_data *data = dev_get_drvdata(dev);
+       struct rmi_function *fn = data->f34_container;
+       struct f34_data *f34;
+
+       if (fn) {
+               f34 = dev_get_drvdata(&fn->dev);
+
+               return scnprintf(buf, PAGE_SIZE, "%s\n", f34->configuration_id);
+       }
+
+       return 0;
+}
+
+static DEVICE_ATTR(configuration_id, 0444,
+                  rmi_driver_configuration_id_show, NULL);
+
 static int rmi_firmware_update(struct rmi_driver_data *data,
                               const struct firmware *fw)
 {
@@ -346,7 +410,13 @@ static int rmi_firmware_update(struct rmi_driver_data *data,
        else
                ret = rmi_f34_update_firmware(f34, fw);
 
-       dev_info(&f34->fn->dev, "Firmware update complete, status:%d\n", ret);
+       if (ret) {
+               f34->update_status = ret;
+               dev_err(&f34->fn->dev,
+                       "Firmware update failed, status: %d\n", ret);
+       } else {
+               dev_info(&f34->fn->dev, "Firmware update complete\n");
+       }
 
        rmi_disable_irq(rmi_dev, false);
 
@@ -377,9 +447,6 @@ static int rmi_firmware_update(struct rmi_driver_data *data,
        return ret;
 }
 
-static int rmi_firmware_update(struct rmi_driver_data *data,
-                              const struct firmware *fw);
-
 static ssize_t rmi_driver_update_fw_store(struct device *dev,
                                          struct device_attribute *dattr,
                                          const char *buf, size_t count)
@@ -414,8 +481,27 @@ static ssize_t rmi_driver_update_fw_store(struct device *dev,
 
 static DEVICE_ATTR(update_fw, 0200, NULL, rmi_driver_update_fw_store);
 
+static ssize_t rmi_driver_update_fw_status_show(struct device *dev,
+                                               struct device_attribute *dattr,
+                                               char *buf)
+{
+       struct rmi_driver_data *data = dev_get_drvdata(dev);
+       int update_status = 0;
+
+       if (data->f34_container)
+               update_status = rmi_f34_status(data->f34_container);
+
+       return scnprintf(buf, PAGE_SIZE, "%d\n", update_status);
+}
+
+static DEVICE_ATTR(update_fw_status, 0444,
+                  rmi_driver_update_fw_status_show, NULL);
+
 static struct attribute *rmi_firmware_attrs[] = {
+       &dev_attr_bootloader_id.attr,
+       &dev_attr_configuration_id.attr,
        &dev_attr_update_fw.attr,
+       &dev_attr_update_fw_status.attr,
        NULL
 };
 
@@ -441,8 +527,6 @@ static int rmi_f34_probe(struct rmi_function *fn)
        /* v5 code only supported version 0, try V7 probe */
        if (version > 0)
                return rmi_f34v7_probe(f34);
-       else if (version != 0)
-               return -ENODEV;
 
        f34->bl_version = 5;
 
index 2c21056dc37514f7336df0c8c4b8a3b9c1edf0f1..43a91349b28d3c87b39fb844082da8b7b00d80d1 100644 (file)
@@ -301,6 +301,10 @@ struct f34_data {
        unsigned char bootloader_id[5];
        unsigned char configuration_id[CONFIG_ID_SIZE*2 + 1];
 
+       int update_status;
+       int update_progress;
+       int update_size;
+
        union {
                struct f34v5_data v5;
                struct f34v7_data v7;
index ca31f9539d9bb42641646e643baedc2c0850a8a6..56c6c39ad31e3c947f3fd856088c2d031db5c56c 100644 (file)
@@ -588,6 +588,7 @@ static int rmi_f34v7_check_ui_firmware_size(struct f34_data *f34)
        u16 block_count;
 
        block_count = f34->v7.img.ui_firmware.size / f34->v7.block_size;
+       f34->update_size += block_count;
 
        if (block_count != f34->v7.blkcount.ui_firmware) {
                dev_err(&f34->fn->dev,
@@ -604,6 +605,7 @@ static int rmi_f34v7_check_ui_config_size(struct f34_data *f34)
        u16 block_count;
 
        block_count = f34->v7.img.ui_config.size / f34->v7.block_size;
+       f34->update_size += block_count;
 
        if (block_count != f34->v7.blkcount.ui_config) {
                dev_err(&f34->fn->dev, "UI config size mismatch\n");
@@ -618,6 +620,7 @@ static int rmi_f34v7_check_dp_config_size(struct f34_data *f34)
        u16 block_count;
 
        block_count = f34->v7.img.dp_config.size / f34->v7.block_size;
+       f34->update_size += block_count;
 
        if (block_count != f34->v7.blkcount.dp_config) {
                dev_err(&f34->fn->dev, "Display config size mismatch\n");
@@ -632,6 +635,8 @@ static int rmi_f34v7_check_guest_code_size(struct f34_data *f34)
        u16 block_count;
 
        block_count = f34->v7.img.guest_code.size / f34->v7.block_size;
+       f34->update_size += block_count;
+
        if (block_count != f34->v7.blkcount.guest_code) {
                dev_err(&f34->fn->dev, "Guest code size mismatch\n");
                return -EINVAL;
@@ -645,6 +650,7 @@ static int rmi_f34v7_check_bl_config_size(struct f34_data *f34)
        u16 block_count;
 
        block_count = f34->v7.img.bl_config.size / f34->v7.block_size;
+       f34->update_size += block_count;
 
        if (block_count != f34->v7.blkcount.bl_config) {
                dev_err(&f34->fn->dev, "Bootloader config size mismatch\n");
@@ -881,6 +887,9 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34,
 
                block_ptr += (transfer * f34->v7.block_size);
                remaining -= transfer;
+               f34->update_progress += transfer;
+               f34->update_status = (f34->update_progress * 100) /
+                                    f34->update_size;
        } while (remaining);
 
        return 0;
@@ -1191,6 +1200,8 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw)
        rmi_f34v7_read_queries_bl_version(f34);
 
        f34->v7.image = fw->data;
+       f34->update_progress = 0;
+       f34->update_size = 0;
 
        ret = rmi_f34v7_parse_image_info(f34);
        if (ret < 0)
index 2e4ff5bac754291d7550458085cf54127e132168..e420fd781d444ca34dea2f518ef8cb8ac27671ea 100644 (file)
@@ -159,13 +159,12 @@ static int psif_open(struct serio *io)
 
        retval = clk_enable(psif->pclk);
        if (retval)
-               goto out;
+               return retval;
 
        psif_writel(psif, CR, PSIF_BIT(CR_TXEN) | PSIF_BIT(CR_RXEN));
        psif_writel(psif, IER, PSIF_BIT(RXRDY));
 
        psif->open = true;
-out:
        return retval;
 }
 
@@ -210,16 +209,12 @@ static int __init psif_probe(struct platform_device *pdev)
        int ret;
 
        psif = kzalloc(sizeof(struct psif), GFP_KERNEL);
-       if (!psif) {
-               dev_dbg(&pdev->dev, "out of memory\n");
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!psif)
+               return -ENOMEM;
        psif->pdev = pdev;
 
        io = kzalloc(sizeof(struct serio), GFP_KERNEL);
        if (!io) {
-               dev_dbg(&pdev->dev, "out of memory\n");
                ret = -ENOMEM;
                goto out_free_psif;
        }
@@ -297,7 +292,6 @@ out_free_io:
        kfree(io);
 out_free_psif:
        kfree(psif);
-out:
        return ret;
 }
 
index c948866edf8705e6c538f52f140f8c0c01e9c336..25151d9214e05c8b6de3ee6bf146617d99740697 100644 (file)
@@ -402,7 +402,6 @@ static int hv_kbd_remove(struct hv_device *hv_dev)
 {
        struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev);
 
-       device_init_wakeup(&hv_dev->device, false);
        serio_unregister_port(kbd_dev->hv_serio);
        vmbus_close(hv_dev->channel);
        kfree(kbd_dev);
index a7618776705ab929e42d4c3e870b4911f1a30d9c..05afd16ea9c9efc0bb52efe49510444478e1e220 100644 (file)
@@ -923,6 +923,10 @@ static struct pnp_driver i8042_pnp_kbd_driver = {
        .name           = "i8042 kbd",
        .id_table       = pnp_kbd_devids,
        .probe          = i8042_pnp_kbd_probe,
+       .driver         = {
+               .probe_type = PROBE_FORCE_SYNCHRONOUS,
+               .suppress_bind_attrs = true,
+       },
 };
 
 static struct pnp_device_id pnp_aux_devids[] = {
@@ -945,6 +949,10 @@ static struct pnp_driver i8042_pnp_aux_driver = {
        .name           = "i8042 aux",
        .id_table       = pnp_aux_devids,
        .probe          = i8042_pnp_aux_probe,
+       .driver         = {
+               .probe_type = PROBE_FORCE_SYNCHRONOUS,
+               .suppress_bind_attrs = true,
+       },
 };
 
 static void i8042_pnp_exit(void)
index 62685a76891363b93d1d6a1d4db613fad814686b..c52da651269b094647aee0bfd63812940d06bc24 100644 (file)
@@ -312,8 +312,10 @@ static int __i8042_command(unsigned char *param, int command)
 
        for (i = 0; i < ((command >> 12) & 0xf); i++) {
                error = i8042_wait_write();
-               if (error)
+               if (error) {
+                       dbg("     -- i8042 (wait write timeout)\n");
                        return error;
+               }
                dbg("%02x -> i8042 (parameter)\n", param[i]);
                i8042_write_data(param[i]);
        }
@@ -321,7 +323,7 @@ static int __i8042_command(unsigned char *param, int command)
        for (i = 0; i < ((command >> 8) & 0xf); i++) {
                error = i8042_wait_read();
                if (error) {
-                       dbg("     -- i8042 (timeout)\n");
+                       dbg("     -- i8042 (wait read timeout)\n");
                        return error;
                }
 
index 5223cbf94262781412e93ab289cb4da5d6fa6f8a..14c40892ed82718246be6a60deed23e71e33e4d4 100644 (file)
@@ -243,18 +243,17 @@ static int xps2_of_probe(struct platform_device *ofdev)
        unsigned int irq;
        int error;
 
-       dev_info(dev, "Device Tree Probing \'%s\'\n",
-                       ofdev->dev.of_node->name);
+       dev_info(dev, "Device Tree Probing \'%s\'\n", dev->of_node->name);
 
        /* Get iospace for the device */
-       error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem);
+       error = of_address_to_resource(dev->of_node, 0, &r_mem);
        if (error) {
                dev_err(dev, "invalid address\n");
                return error;
        }
 
        /* Get IRQ for the device */
-       irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
+       irq = irq_of_parse_and_map(dev->of_node, 0);
        if (!irq) {
                dev_err(dev, "no IRQ found\n");
                return -ENODEV;
index 251ff2aa0633170a7c1bcf09c1ba194893a53cd9..7ed828a51f4c87883ca4258a5cc1ca9cad375dcc 100644 (file)
@@ -240,8 +240,6 @@ static int pm860x_touch_probe(struct platform_device *pdev)
        if (!touch)
                return -ENOMEM;
 
-       platform_set_drvdata(pdev, touch);
-
        touch->idev = devm_input_allocate_device(&pdev->dev);
        if (!touch->idev) {
                dev_err(&pdev->dev, "Failed to allocate input device!\n");
@@ -285,7 +283,6 @@ static int pm860x_touch_probe(struct platform_device *pdev)
                return ret;
        }
 
-       platform_set_drvdata(pdev, touch);
        return 0;
 }
 
index efca0133e266b84439bed072f86b6d4c3e147ece..03359977765156edb0f8d00c04d51e8921358ef9 100644 (file)
@@ -546,18 +546,6 @@ config TOUCHSCREEN_INEXIO
          To compile this driver as a module, choose M here: the
          module will be called inexio.
 
-config TOUCHSCREEN_INTEL_MID
-       tristate "Intel MID platform resistive touchscreen"
-       depends on INTEL_SCU_IPC
-       help
-         Say Y here if you have a Intel MID based touchscreen in
-         your system.
-
-         If unsure, say N.
-
-         To compile this driver as a module, choose M here: the
-         module will be called intel_mid_touch.
-
 config TOUCHSCREEN_MK712
        tristate "ICS MicroClock MK712 touchscreen"
        help
@@ -1177,6 +1165,17 @@ config TOUCHSCREEN_TPS6507X
          To compile this driver as a module, choose M here: the
          module will be called tps6507x_ts.
 
+config TOUCHSCREEN_ZET6223
+       tristate "Zeitec ZET6223 touchscreen driver"
+       depends on I2C
+       help
+         Say Y here if you have a touchscreen using Zeitec ZET6223
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called zet6223.
+
 config TOUCHSCREEN_ZFORCE
        tristate "Neonode zForce infrared touchscreens"
        depends on I2C
index 81b86451782d4479147fbb1a8c70cdc0f6f08eac..b622e53441376a7261fe42b1f82598b0aeb3126a 100644 (file)
@@ -42,7 +42,6 @@ obj-$(CONFIG_TOUCHSCREEN_GOODIX)      += goodix.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)      += ili210x.o
 obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC)   += imx6ul_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)       += inexio.o
-obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)    += intel-mid-touch.o
 obj-$(CONFIG_TOUCHSCREEN_IPROC)                += bcm_iproc_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_LPC32XX)      += lpc32xx_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MAX11801)     += max11801_ts.o
@@ -96,6 +95,7 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE)     += zylonite-wm97xx.o
 obj-$(CONFIG_TOUCHSCREEN_W90X900)      += w90p910_ts.o
 obj-$(CONFIG_TOUCHSCREEN_SX8654)       += sx8654.o
 obj-$(CONFIG_TOUCHSCREEN_TPS6507X)     += tps6507x-ts.o
+obj-$(CONFIG_TOUCHSCREEN_ZET6223)      += zet6223.o
 obj-$(CONFIG_TOUCHSCREEN_ZFORCE)       += zforce_ts.o
 obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o
 obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o
index 1ce3ecbe37f89153e7b863fab92b7d8f05f6ef14..f5793e3d945f76d2b5e27e829c6441cf352e2b56 100644 (file)
@@ -1462,8 +1462,6 @@ static int ads7846_remove(struct spi_device *spi)
 {
        struct ads7846 *ts = spi_get_drvdata(spi);
 
-       device_init_wakeup(&spi->dev, false);
-
        sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group);
 
        ads7846_disable(ts);
index 71b5a634cf6d56509f49563ed7454af9f8ae1b88..6562b17117f7fdd8e3bfc30cb8b926849fba9b13 100644 (file)
@@ -127,7 +127,6 @@ static int ar1021_i2c_probe(struct i2c_client *client,
                return error;
        }
 
-       i2c_set_clientdata(client, ar1021);
        return 0;
 }
 
index 7ec0421c0dd82b9e9f445581abef1fdc8df5155d..8cf0b2be2df4968653303aa45c719ce0c5086a2b 100644 (file)
@@ -339,10 +339,8 @@ static int __init atmel_wm97xx_probe(struct platform_device *pdev)
        int ret;
 
        atmel_wm97xx = kzalloc(sizeof(struct atmel_wm97xx), GFP_KERNEL);
-       if (!atmel_wm97xx) {
-               dev_dbg(&pdev->dev, "out of memory\n");
+       if (!atmel_wm97xx)
                return -ENOMEM;
-       }
 
        atmel_wm97xx->wm        = wm;
        atmel_wm97xx->regs      = (void *)ATMEL_WM97XX_AC97C_IOMEM;
index e5d185fe69b97d7a8c744487fcbbbe32027e398b..2302aef2b2d403d47f8384c0127ad91104788ef5 100644 (file)
@@ -2509,7 +2509,7 @@ static void mxt_debug_init(struct mxt_data *data)
                dbg->t37_pages = MXT1386_COLUMNS * MXT1386_PAGES_PER_COLUMN;
        else
                dbg->t37_pages = DIV_ROUND_UP(data->xsize *
-                                             data->info.matrix_ysize *
+                                             info->matrix_ysize *
                                              sizeof(u16),
                                              sizeof(dbg->t37_buf->data));
 
index 931417eb4f5a2351c21fbfa3a311e448fbc26478..4fa5da8d5fa899a330aca2f401b9a210201ee407 100644 (file)
@@ -637,8 +637,6 @@ static int bu21013_remove(struct i2c_client *client)
 
        kfree(bu21013_data);
 
-       device_init_wakeup(&client->dev, false);
-
        return 0;
 }
 
index 69828d015d45ffa4747368e79f6fa5f47108c0c9..69c08acae26485ad1ea0e6850fe339393532c041 100644 (file)
@@ -311,8 +311,6 @@ static int vf50_ts_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       platform_set_drvdata(pdev, touchdev);
-
        input->name = DRIVER_NAME;
        input->id.bustype = BUS_HOST;
        input->dev.parent = dev;
index 28466e358fee1dc6399ea8693dfd7e909fd29870..8cf8d8d5d4ef4f82b45cc5ecbb959c92be95b699 100644 (file)
@@ -67,7 +67,7 @@
 #define EDT_SWITCH_MODE_RETRIES                10
 #define EDT_SWITCH_MODE_DELAY          5 /* msec */
 #define EDT_RAW_DATA_RETRIES           100
-#define EDT_RAW_DATA_DELAY             1 /* msec */
+#define EDT_RAW_DATA_DELAY             1000 /* usec */
 
 enum edt_ver {
        M06,
@@ -664,7 +664,7 @@ static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file,
        }
 
        do {
-               msleep(EDT_RAW_DATA_DELAY);
+               usleep_range(EDT_RAW_DATA_DELAY, EDT_RAW_DATA_DELAY + 100);
                val = edt_ft5x06_register_read(tsdata, 0x08);
                if (val < 1)
                        break;
@@ -982,7 +982,6 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
                return error;
        }
 
-       input_set_drvdata(input, tsdata);
        i2c_set_clientdata(client, tsdata);
 
        irq_flags = irq_get_trigger_type(client->irq);
index 09be6ced71515031eae17db5b54c07108953cbd8..16023867b9da7bf2e2b348805c4d6b77a8f14699 100644 (file)
@@ -173,12 +173,11 @@ static int eeti_ts_probe(struct i2c_client *client,
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv) {
                dev_err(&client->dev, "failed to allocate driver data\n");
-               goto err0;
+               return -ENOMEM;
        }
 
        mutex_init(&priv->mutex);
        input = input_allocate_device();
-
        if (!input) {
                dev_err(&client->dev, "Failed to allocate input device.\n");
                goto err1;
@@ -232,7 +231,6 @@ static int eeti_ts_probe(struct i2c_client *client,
         */
        eeti_ts_stop(priv);
 
-       device_init_wakeup(&client->dev, 0);
        return 0;
 
 err3:
@@ -243,7 +241,6 @@ err2:
 err1:
        input_free_device(input);
        kfree(priv);
-err0:
        return err;
 }
 
index 1afc08b08155548236bbcbcf095cf3c82949d67a..752ae9cf451495c17400d97152f71bee78fee699 100644 (file)
@@ -214,8 +214,6 @@ static int egalax_ts_probe(struct i2c_client *client,
                             ABS_MT_POSITION_Y, 0, EGALAX_MAX_Y, 0, 0);
        input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS, 0);
 
-       input_set_drvdata(input_dev, ts);
-
        error = devm_request_threaded_irq(&client->dev, client->irq, NULL,
                                          egalax_ts_interrupt,
                                          IRQF_TRIGGER_LOW | IRQF_ONESHOT,
@@ -229,7 +227,6 @@ static int egalax_ts_probe(struct i2c_client *client,
        if (error)
                return error;
 
-       i2c_set_clientdata(client, ts);
        return 0;
 }
 
index 3e6003d32e565c748a43730574b9424eeb294d33..872750eeca9325cbb3a9140b0686da4a2f5cbdfa 100644 (file)
@@ -1260,8 +1260,6 @@ static int elants_i2c_probe(struct i2c_client *client,
        input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res);
        input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res);
 
-       input_set_drvdata(ts->input, ts);
-
        error = input_register_device(ts->input);
        if (error) {
                dev_err(&client->dev,
index d50ee490c9ccacf653a3b04dbecbc43b0f78ec2e..47fe1f184bbca342977d10057f4801364427818e 100644 (file)
@@ -507,7 +507,7 @@ static int mx25_tcq_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct input_dev *idev;
        struct mx25_tcq_priv *priv;
-       struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent);
+       struct mx25_tsadc *tsadc = dev_get_drvdata(dev->parent);
        struct resource *res;
        void __iomem *mem;
        int error;
index fe4848bd1f4c3ecc564a9eaa479f029f4e590c45..6f76eeedf4652eecdf2c6a24ec6440d504dafb82 100644 (file)
@@ -256,7 +256,6 @@ static int ili210x_i2c_probe(struct i2c_client *client,
        input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0);
        input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0);
 
-       input_set_drvdata(input, priv);
        i2c_set_clientdata(client, priv);
 
        error = request_irq(client->irq, ili210x_irq, pdata->irq_flags,
@@ -280,7 +279,7 @@ static int ili210x_i2c_probe(struct i2c_client *client,
                goto err_remove_sysfs;
        }
 
-       device_init_wakeup(&client->dev, 1);
+       device_init_wakeup(dev, 1);
 
        dev_dbg(dev,
                "ILI210x initialized (IRQ: %d), firmware version %d.%d.%d",
diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c
deleted file mode 100644 (file)
index b4f0725..0000000
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- * Intel MID Resistive Touch Screen Driver
- *
- * Copyright (C) 2008 Intel Corp
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * 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.
- *
- * 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.
- *
- * Questions/Comments/Bug fixes to Sreedhara (sreedhara.ds@intel.com)
- *                         Ramesh Agarwal (ramesh.agarwal@intel.com)
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * TODO:
- *     review conversion of r/m/w sequences
- */
-
-#include <linux/module.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/param.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <asm/intel_scu_ipc.h>
-#include <linux/device.h>
-
-/* PMIC Interrupt registers */
-#define PMIC_REG_ID1           0x00 /* PMIC ID1 register */
-
-/* PMIC Interrupt registers */
-#define PMIC_REG_INT           0x04 /* PMIC interrupt register */
-#define PMIC_REG_MINT          0x05 /* PMIC interrupt mask register */
-
-/* ADC Interrupt registers */
-#define PMIC_REG_ADCINT                0x5F /* ADC interrupt register */
-#define PMIC_REG_MADCINT       0x60 /* ADC interrupt mask register */
-
-/* ADC Control registers */
-#define PMIC_REG_ADCCNTL1      0x61 /* ADC control register */
-
-/* ADC Channel Selection registers */
-#define PMICADDR0              0xA4
-#define END_OF_CHANNEL         0x1F
-
-/* ADC Result register */
-#define PMIC_REG_ADCSNS0H      0x64
-
-/* ADC channels for touch screen */
-#define MRST_TS_CHAN10         0xA /* Touch screen X+ connection */
-#define MRST_TS_CHAN11         0xB /* Touch screen X- connection */
-#define MRST_TS_CHAN12         0xC /* Touch screen Y+ connection */
-#define MRST_TS_CHAN13         0xD /* Touch screen Y- connection */
-
-/* Touch screen channel BIAS constants */
-#define MRST_XBIAS             0x20
-#define MRST_YBIAS             0x40
-#define MRST_ZBIAS             0x80
-
-/* Touch screen coordinates */
-#define MRST_X_MIN             10
-#define MRST_X_MAX             1024
-#define MRST_X_FUZZ            5
-#define MRST_Y_MIN             10
-#define MRST_Y_MAX             1024
-#define MRST_Y_FUZZ            5
-#define MRST_PRESSURE_MIN      0
-#define MRST_PRESSURE_NOMINAL  50
-#define MRST_PRESSURE_MAX      100
-
-#define WAIT_ADC_COMPLETION    10 /* msec */
-
-/* PMIC ADC round robin delays */
-#define ADC_LOOP_DELAY0                0x0 /* Continuous loop */
-#define ADC_LOOP_DELAY1                0x1 /* 4.5  ms approximate */
-
-/* PMIC Vendor Identifiers */
-#define PMIC_VENDOR_FS         0 /* PMIC vendor FreeScale */
-#define PMIC_VENDOR_MAXIM      1 /* PMIC vendor MAXIM */
-#define PMIC_VENDOR_NEC                2 /* PMIC vendor NEC */
-#define MRSTOUCH_MAX_CHANNELS  32 /* Maximum ADC channels */
-
-/* Touch screen device structure */
-struct mrstouch_dev {
-       struct device *dev; /* device associated with touch screen */
-       struct input_dev *input;
-       char phys[32];
-       u16 asr;                /* Address selection register */
-       int irq;
-       unsigned int vendor;    /* PMIC vendor */
-       unsigned int rev;       /* PMIC revision */
-
-       int (*read_prepare)(struct mrstouch_dev *tsdev);
-       int (*read)(struct mrstouch_dev *tsdev, u16 *x, u16 *y, u16 *z);
-       int (*read_finish)(struct mrstouch_dev *tsdev);
-};
-
-
-/*************************** NEC and Maxim Interface ************************/
-
-static int mrstouch_nec_adc_read_prepare(struct mrstouch_dev *tsdev)
-{
-       return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0, 0x20);
-}
-
-/*
- * Enables PENDET interrupt.
- */
-static int mrstouch_nec_adc_read_finish(struct mrstouch_dev *tsdev)
-{
-       int err;
-
-       err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x20, 0x20);
-       if (!err)
-               err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, 0, 0x05);
-
-       return err;
-}
-
-/*
- * Reads PMIC ADC touch screen result
- * Reads ADC storage registers for higher 7 and lower 3 bits and
- * converts the two readings into a single value and turns off gain bit
- */
-static int mrstouch_ts_chan_read(u16 offset, u16 chan, u16 *vp, u16 *vm)
-{
-       int err;
-       u16 result;
-       u32 res;
-
-       result = PMIC_REG_ADCSNS0H + offset;
-
-       if (chan == MRST_TS_CHAN12)
-               result += 4;
-
-       err = intel_scu_ipc_ioread32(result, &res);
-       if (err)
-               return err;
-
-       /* Mash the bits up */
-
-       *vp = (res & 0xFF) << 3;        /* Highest 7 bits */
-       *vp |= (res >> 8) & 0x07;       /* Lower 3 bits */
-       *vp &= 0x3FF;
-
-       res >>= 16;
-
-       *vm = (res & 0xFF) << 3;        /* Highest 7 bits */
-       *vm |= (res >> 8) & 0x07;       /* Lower 3 bits */
-       *vm &= 0x3FF;
-
-       return 0;
-}
-
-/*
- * Enables X, Y and Z bias values
- * Enables YPYM for X channels and XPXM for Y channels
- */
-static int mrstouch_ts_bias_set(uint offset, uint bias)
-{
-       int count;
-       u16 chan, start;
-       u16 reg[4];
-       u8 data[4];
-
-       chan = PMICADDR0 + offset;
-       start = MRST_TS_CHAN10;
-
-       for (count = 0; count <= 3; count++) {
-               reg[count] = chan++;
-               data[count] = bias | (start + count);
-       }
-
-       return intel_scu_ipc_writev(reg, data, 4);
-}
-
-/* To read touch screen channel values */
-static int mrstouch_nec_adc_read(struct mrstouch_dev *tsdev,
-                                u16 *x, u16 *y, u16 *z)
-{
-       int err;
-       u16 xm, ym, zm;
-
-       /* configure Y bias for X channels */
-       err = mrstouch_ts_bias_set(tsdev->asr, MRST_YBIAS);
-       if (err)
-               goto ipc_error;
-
-       msleep(WAIT_ADC_COMPLETION);
-
-       /* read x+ and x- channels */
-       err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, x, &xm);
-       if (err)
-               goto ipc_error;
-
-       /* configure x bias for y channels */
-       err = mrstouch_ts_bias_set(tsdev->asr, MRST_XBIAS);
-       if (err)
-               goto ipc_error;
-
-       msleep(WAIT_ADC_COMPLETION);
-
-       /* read y+ and y- channels */
-       err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN12, y, &ym);
-       if (err)
-               goto ipc_error;
-
-       /* configure z bias for x and y channels */
-       err = mrstouch_ts_bias_set(tsdev->asr, MRST_ZBIAS);
-       if (err)
-               goto ipc_error;
-
-       msleep(WAIT_ADC_COMPLETION);
-
-       /* read z+ and z- channels */
-       err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, z, &zm);
-       if (err)
-               goto ipc_error;
-
-       return 0;
-
-ipc_error:
-       dev_err(tsdev->dev, "ipc error during adc read\n");
-       return err;
-}
-
-
-/*************************** Freescale Interface ************************/
-
-static int mrstouch_fs_adc_read_prepare(struct mrstouch_dev *tsdev)
-{
-       int err, count;
-       u16 chan;
-       u16 reg[5];
-       u8 data[5];
-
-       /* Stop the ADC */
-       err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x00, 0x02);
-       if (err)
-               goto ipc_error;
-
-       chan = PMICADDR0 + tsdev->asr;
-
-       /* Set X BIAS */
-       for (count = 0; count <= 3; count++) {
-               reg[count] = chan++;
-               data[count] = 0x2A;
-       }
-       reg[count] =  chan++; /* Dummy */
-       data[count] = 0;
-
-       err = intel_scu_ipc_writev(reg, data, 5);
-       if (err)
-               goto ipc_error;
-
-       msleep(WAIT_ADC_COMPLETION);
-
-       /* Set Y BIAS */
-       for (count = 0; count <= 3; count++) {
-               reg[count] = chan++;
-               data[count] = 0x4A;
-       }
-       reg[count] = chan++; /* Dummy */
-       data[count] = 0;
-
-       err = intel_scu_ipc_writev(reg, data, 5);
-       if (err)
-               goto ipc_error;
-
-       msleep(WAIT_ADC_COMPLETION);
-
-       /* Set Z BIAS */
-       err = intel_scu_ipc_iowrite32(chan + 2, 0x8A8A8A8A);
-       if (err)
-               goto ipc_error;
-
-       msleep(WAIT_ADC_COMPLETION);
-
-       return 0;
-
-ipc_error:
-       dev_err(tsdev->dev, "ipc error during %s\n", __func__);
-       return err;
-}
-
-static int mrstouch_fs_adc_read(struct mrstouch_dev *tsdev,
-                               u16 *x, u16 *y, u16 *z)
-{
-       int err;
-       u16 result;
-       u16 reg[4];
-       u8 data[4];
-
-       result = PMIC_REG_ADCSNS0H + tsdev->asr;
-
-       reg[0] = result + 4;
-       reg[1] = result + 5;
-       reg[2] = result + 16;
-       reg[3] = result + 17;
-
-       err = intel_scu_ipc_readv(reg, data, 4);
-       if (err)
-               goto ipc_error;
-
-       *x = data[0] << 3; /* Higher 7 bits */
-       *x |= data[1] & 0x7; /* Lower 3 bits */
-       *x &= 0x3FF;
-
-       *y = data[2] << 3; /* Higher 7 bits */
-       *y |= data[3] & 0x7; /* Lower 3 bits */
-       *y &= 0x3FF;
-
-       /* Read Z value */
-       reg[0] = result + 28;
-       reg[1] = result + 29;
-
-       err = intel_scu_ipc_readv(reg, data, 4);
-       if (err)
-               goto ipc_error;
-
-       *z = data[0] << 3; /* Higher 7 bits */
-       *z |= data[1] & 0x7; /* Lower 3 bits */
-       *z &= 0x3FF;
-
-       return 0;
-
-ipc_error:
-       dev_err(tsdev->dev, "ipc error during %s\n", __func__);
-       return err;
-}
-
-static int mrstouch_fs_adc_read_finish(struct mrstouch_dev *tsdev)
-{
-       int err, count;
-       u16 chan;
-       u16 reg[5];
-       u8 data[5];
-
-       /* Clear all TS channels */
-       chan = PMICADDR0 + tsdev->asr;
-       for (count = 0; count <= 4; count++) {
-               reg[count] = chan++;
-               data[count] = 0;
-       }
-       err = intel_scu_ipc_writev(reg, data, 5);
-       if (err)
-               goto ipc_error;
-
-       for (count = 0; count <= 4; count++) {
-               reg[count] = chan++;
-               data[count] = 0;
-       }
-       err = intel_scu_ipc_writev(reg, data, 5);
-       if (err)
-               goto ipc_error;
-
-       err = intel_scu_ipc_iowrite32(chan + 2, 0x00000000);
-       if (err)
-               goto ipc_error;
-
-       /* Start ADC */
-       err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x02, 0x02);
-       if (err)
-               goto ipc_error;
-
-       return 0;
-
-ipc_error:
-       dev_err(tsdev->dev, "ipc error during %s\n", __func__);
-       return err;
-}
-
-static void mrstouch_report_event(struct input_dev *input,
-                       unsigned int x, unsigned int y, unsigned int z)
-{
-       if (z > MRST_PRESSURE_NOMINAL) {
-               /* Pen touched, report button touch and coordinates */
-               input_report_key(input, BTN_TOUCH, 1);
-               input_report_abs(input, ABS_X, x);
-               input_report_abs(input, ABS_Y, y);
-       } else {
-               input_report_key(input, BTN_TOUCH, 0);
-       }
-
-       input_report_abs(input, ABS_PRESSURE, z);
-       input_sync(input);
-}
-
-/* PENDET interrupt handler */
-static irqreturn_t mrstouch_pendet_irq(int irq, void *dev_id)
-{
-       struct mrstouch_dev *tsdev = dev_id;
-       u16 x, y, z;
-
-       /*
-        * Should we lower thread priority? Probably not, since we are
-        * not spinning but sleeping...
-        */
-
-       if (tsdev->read_prepare(tsdev))
-               goto out;
-
-       do {
-               if (tsdev->read(tsdev, &x, &y, &z))
-                       break;
-
-               mrstouch_report_event(tsdev->input, x, y, z);
-       } while (z > MRST_PRESSURE_NOMINAL);
-
-       tsdev->read_finish(tsdev);
-
-out:
-       return IRQ_HANDLED;
-}
-
-/* Utility to read PMIC ID */
-static int mrstouch_read_pmic_id(uint *vendor, uint *rev)
-{
-       int err;
-       u8 r;
-
-       err = intel_scu_ipc_ioread8(PMIC_REG_ID1, &r);
-       if (err)
-               return err;
-
-       *vendor = r & 0x7;
-       *rev = (r >> 3) & 0x7;
-
-       return 0;
-}
-
-/*
- * Parse ADC channels to find end of the channel configured by other ADC user
- * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels
- */
-static int mrstouch_chan_parse(struct mrstouch_dev *tsdev)
-{
-       int found = 0;
-       int err, i;
-       u8 r8;
-
-       for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) {
-               err = intel_scu_ipc_ioread8(PMICADDR0 + i, &r8);
-               if (err)
-                       return err;
-
-               if (r8 == END_OF_CHANNEL) {
-                       found = i;
-                       break;
-               }
-       }
-
-       if (tsdev->vendor == PMIC_VENDOR_FS) {
-               if (found > MRSTOUCH_MAX_CHANNELS - 18)
-                       return -ENOSPC;
-       } else {
-               if (found > MRSTOUCH_MAX_CHANNELS - 4)
-                       return -ENOSPC;
-       }
-
-       return found;
-}
-
-
-/*
- * Writes touch screen channels to ADC address selection registers
- */
-static int mrstouch_ts_chan_set(uint offset)
-{
-       u16 chan;
-
-       int ret, count;
-
-       chan = PMICADDR0 + offset;
-       for (count = 0; count <= 3; count++) {
-               ret = intel_scu_ipc_iowrite8(chan++, MRST_TS_CHAN10 + count);
-               if (ret)
-                       return ret;
-       }
-       return intel_scu_ipc_iowrite8(chan++, END_OF_CHANNEL);
-}
-
-/* Initialize ADC */
-static int mrstouch_adc_init(struct mrstouch_dev *tsdev)
-{
-       int err, start;
-       u8 ra, rm;
-
-       err = mrstouch_read_pmic_id(&tsdev->vendor, &tsdev->rev);
-       if (err) {
-               dev_err(tsdev->dev, "Unable to read PMIC id\n");
-               return err;
-       }
-
-       switch (tsdev->vendor) {
-       case PMIC_VENDOR_NEC:
-       case PMIC_VENDOR_MAXIM:
-               tsdev->read_prepare = mrstouch_nec_adc_read_prepare;
-               tsdev->read = mrstouch_nec_adc_read;
-               tsdev->read_finish = mrstouch_nec_adc_read_finish;
-               break;
-
-       case PMIC_VENDOR_FS:
-               tsdev->read_prepare = mrstouch_fs_adc_read_prepare;
-               tsdev->read = mrstouch_fs_adc_read;
-               tsdev->read_finish = mrstouch_fs_adc_read_finish;
-               break;
-
-       default:
-               dev_err(tsdev->dev,
-                       "Unsupported touchscreen: %d\n", tsdev->vendor);
-               return -ENXIO;
-       }
-
-       start = mrstouch_chan_parse(tsdev);
-       if (start < 0) {
-               dev_err(tsdev->dev, "Unable to parse channels\n");
-               return start;
-       }
-
-       tsdev->asr = start;
-
-       /*
-        * ADC power on, start, enable PENDET and set loop delay
-        * ADC loop delay is set to 4.5 ms approximately
-        * Loop delay more than this results in jitter in adc readings
-        * Setting loop delay to 0 (continuous loop) in MAXIM stops PENDET
-        * interrupt generation sometimes.
-        */
-
-       if (tsdev->vendor == PMIC_VENDOR_FS) {
-               ra = 0xE0 | ADC_LOOP_DELAY0;
-               rm = 0x5;
-       } else {
-               /* NEC and MAXIm not consistent with loop delay 0 */
-               ra = 0xE0 | ADC_LOOP_DELAY1;
-               rm = 0x0;
-
-               /* configure touch screen channels */
-               err = mrstouch_ts_chan_set(tsdev->asr);
-               if (err)
-                       return err;
-       }
-
-       err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, ra, 0xE7);
-       if (err)
-               return err;
-
-       err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, rm, 0x03);
-       if (err)
-               return err;
-
-       return 0;
-}
-
-
-/* Probe function for touch screen driver */
-static int mrstouch_probe(struct platform_device *pdev)
-{
-       struct mrstouch_dev *tsdev;
-       struct input_dev *input;
-       int err;
-       int irq;
-
-       irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev, "no interrupt assigned\n");
-               return -EINVAL;
-       }
-
-       tsdev = devm_kzalloc(&pdev->dev, sizeof(struct mrstouch_dev),
-                            GFP_KERNEL);
-       if (!tsdev) {
-               dev_err(&pdev->dev, "unable to allocate memory\n");
-               return -ENOMEM;
-       }
-
-       input = devm_input_allocate_device(&pdev->dev);
-       if (!input) {
-               dev_err(&pdev->dev, "unable to allocate input device\n");
-               return -ENOMEM;
-       }
-
-       tsdev->dev = &pdev->dev;
-       tsdev->input = input;
-       tsdev->irq = irq;
-
-       snprintf(tsdev->phys, sizeof(tsdev->phys),
-                "%s/input0", dev_name(tsdev->dev));
-
-       err = mrstouch_adc_init(tsdev);
-       if (err) {
-               dev_err(&pdev->dev, "ADC initialization failed\n");
-               return err;
-       }
-
-       input->name = "mrst_touchscreen";
-       input->phys = tsdev->phys;
-       input->dev.parent = tsdev->dev;
-
-       input->id.vendor = tsdev->vendor;
-       input->id.version = tsdev->rev;
-
-       input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-       input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-
-       input_set_abs_params(tsdev->input, ABS_X,
-                            MRST_X_MIN, MRST_X_MAX, MRST_X_FUZZ, 0);
-       input_set_abs_params(tsdev->input, ABS_Y,
-                            MRST_Y_MIN, MRST_Y_MAX, MRST_Y_FUZZ, 0);
-       input_set_abs_params(tsdev->input, ABS_PRESSURE,
-                            MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0);
-
-       err = devm_request_threaded_irq(&pdev->dev, tsdev->irq, NULL,
-                                       mrstouch_pendet_irq, IRQF_ONESHOT,
-                                       "mrstouch", tsdev);
-       if (err) {
-               dev_err(tsdev->dev, "unable to allocate irq\n");
-               return err;
-       }
-
-       err = input_register_device(tsdev->input);
-       if (err) {
-               dev_err(tsdev->dev, "unable to register input device\n");
-               return err;
-       }
-
-       return 0;
-}
-
-static struct platform_driver mrstouch_driver = {
-       .driver = {
-               .name   = "pmic_touch",
-       },
-       .probe          = mrstouch_probe,
-};
-module_platform_driver(mrstouch_driver);
-
-MODULE_AUTHOR("Sreedhara Murthy. D.S, sreedhara.ds@intel.com");
-MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver");
-MODULE_LICENSE("GPL");
index 7fbb3b0c857150170a293981e1e7940d70478c3f..e0baa7de410215cf56c32f7235ec1fa045ed525b 100644 (file)
@@ -313,7 +313,6 @@ static int lpc32xx_ts_remove(struct platform_device *pdev)
        struct lpc32xx_tsc *tsc = platform_get_drvdata(pdev);
        struct resource *res;
 
-       device_init_wakeup(&pdev->dev, 0);
        free_irq(tsc->irq, tsc);
 
        input_unregister_device(tsc->dev);
index 82079cde849c802a058b7b3cb60a4e3295579394..a595ae5284e36887767ce5fda19ec68055daafa5 100644 (file)
@@ -199,7 +199,6 @@ static int max11801_ts_probe(struct i2c_client *client,
        __set_bit(BTN_TOUCH, input_dev->keybit);
        input_set_abs_params(input_dev, ABS_X, 0, MAX11801_MAX_X, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, 0, MAX11801_MAX_Y, 0, 0);
-       input_set_drvdata(input_dev, data);
 
        max11801_ts_phy_init(data);
 
@@ -216,7 +215,6 @@ static int max11801_ts_probe(struct i2c_client *client,
        if (error)
                return error;
 
-       i2c_set_clientdata(client, data);
        return 0;
 }
 
index 8b47e1fecb25287a48b60a4547deba7bbf90c9dd..90fc07dc98a6bbf86d000da1fc2834190b77c30e 100644 (file)
@@ -221,7 +221,6 @@ static int mcs5000_ts_probe(struct i2c_client *client,
        input_set_abs_params(input_dev, ABS_X, 0, MCS5000_MAX_XC, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, 0, MCS5000_MAX_YC, 0, 0);
 
-       input_set_drvdata(input_dev, data);
        data->input_dev = input_dev;
 
        if (pdata->cfg_pin)
index 3bb0637d832e412944d9f6511c99e32705785702..37ff672c780233a4f1423564288c104a6f32e5e0 100644 (file)
@@ -461,7 +461,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
                if (error)
                        return error;
        } else {
-               dev_err(&client->dev, "platform data not defined\n");
+               dev_err(dev, "platform data not defined\n");
                return -EINVAL;
        }
 
@@ -483,7 +483,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
        input->id.bustype = BUS_I2C;
        input->open = pixcir_input_open;
        input->close = pixcir_input_close;
-       input->dev.parent = &client->dev;
+       input->dev.parent = dev;
 
        if (pdata) {
                input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0);
index 2658afa016c94a88bc04489772a183e6e687c2e5..1252e49ccfa1c42455667e7b775343107853d5ba 100644 (file)
@@ -1087,8 +1087,6 @@ static int raydium_i2c_probe(struct i2c_client *client,
        ts->input->name = "Raydium Touchscreen";
        ts->input->id.bustype = BUS_I2C;
 
-       input_set_drvdata(ts->input, ts);
-
        input_set_abs_params(ts->input, ABS_MT_POSITION_X,
                             0, le16_to_cpu(ts->info.x_max), 0, 0);
        input_set_abs_params(ts->input, ABS_MT_POSITION_Y,
index 611156a2ef80d7a1381597d59444083807316bd9..eeaf6ff035974c836668a0aaec55fb4bd0f05965 100644 (file)
@@ -1189,8 +1189,7 @@ static int rohm_bu21023_i2c_probe(struct i2c_client *client,
        error = devm_add_action(dev, rohm_ts_remove_sysfs_group, dev);
        if (error) {
                rohm_ts_remove_sysfs_group(dev);
-               dev_err(&client->dev,
-                       "Failed to add sysfs cleanup action: %d\n",
+               dev_err(dev, "Failed to add sysfs cleanup action: %d\n",
                        error);
                return error;
        }
index a4a103e1d11b0ae6f65fe3ce496755b5618c898e..41d58e88cc8a0de6c1e42eec64801e8838ff0447 100644 (file)
@@ -250,7 +250,7 @@ static int s3c2410ts_probe(struct platform_device *pdev)
 
        ts.dev = dev;
 
-       info = dev_get_platdata(&pdev->dev);
+       info = dev_get_platdata(dev);
        if (!info) {
                dev_err(dev, "no platform data, cannot attach\n");
                return -EINVAL;
index 8d93f8c9a403b2c1088c1391a230a17ec4760a0d..67c2563031d6429b7ebc91742d2b0d3cc5a094c5 100644 (file)
@@ -316,7 +316,6 @@ static int sis_ts_probe(struct i2c_client *client,
                return -ENOMEM;
 
        ts->client = client;
-       i2c_set_clientdata(client, ts);
 
        ts->attn_gpio = devm_gpiod_get_optional(&client->dev,
                                                "attn", GPIOD_IN);
index e943678ce54cd48c64240d63e964408e670d4417..be5615c6bf8ff5e99b2d3d49350526b51a9223d8 100644 (file)
@@ -237,7 +237,6 @@ static int st1232_ts_remove(struct i2c_client *client)
 {
        struct st1232_ts_data *ts = i2c_get_clientdata(client);
 
-       device_init_wakeup(&client->dev, 0);
        st1232_ts_power(ts, false);
 
        return 0;
index 642f4a53de509f2f240f4cd5279ce2749d235455..ed29db3ec731e582a4fdd919e37c7be7e2af135e 100644 (file)
@@ -253,7 +253,6 @@ static int sx8654_probe(struct i2c_client *client,
        if (error)
                return error;
 
-       i2c_set_clientdata(client, sx8654);
        return 0;
 }
 
index f2c5f0e47f77dd6ab177adec2bb102ed0da5dd08..e02b69f40ad8ab103024071623d1165629b9b8b9 100644 (file)
@@ -18,8 +18,9 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/module.h>
 #include <linux/input.h>
+#include <linux/module.h>
+#include <linux/of.h>
 #include <linux/spi/spi.h>
 #include <linux/regmap.h>
 #include "tsc200x-core.h"
@@ -77,9 +78,18 @@ static int tsc2005_remove(struct spi_device *spi)
        return tsc200x_remove(&spi->dev);
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id tsc2005_of_match[] = {
+       { .compatible = "ti,tsc2005" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, tsc2005_of_match);
+#endif
+
 static struct spi_driver tsc2005_driver = {
        .driver = {
                .name   = "tsc2005",
+               .of_match_table = of_match_ptr(tsc2005_of_match),
                .pm     = &tsc200x_pm_ops,
        },
        .probe  = tsc2005_probe,
index b7059ed8872e40b77eed45e33808ba4b135485c4..88ea5e1b72aedd023c0fdf817cbeee906fdda292 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/of.h>
-#include <linux/spi/tsc2005.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regmap.h>
 #include <linux/gpio/consumer.h>
@@ -114,7 +113,6 @@ struct tsc200x {
        struct regulator        *vio;
 
        struct gpio_desc        *reset_gpio;
-       void                    (*set_reset)(bool enable);
        int                     (*tsc200x_cmd)(struct device *dev, u8 cmd);
        int                     irq;
 };
@@ -227,12 +225,13 @@ static void tsc200x_stop_scan(struct tsc200x *ts)
        ts->tsc200x_cmd(ts->dev, TSC200X_CMD_STOP);
 }
 
-static void tsc200x_set_reset(struct tsc200x *ts, bool enable)
+static void tsc200x_reset(struct tsc200x *ts)
 {
-       if (ts->reset_gpio)
-               gpiod_set_value_cansleep(ts->reset_gpio, enable);
-       else if (ts->set_reset)
-               ts->set_reset(enable);
+       if (ts->reset_gpio) {
+               gpiod_set_value_cansleep(ts->reset_gpio, 1);
+               usleep_range(100, 500); /* only 10us required */
+               gpiod_set_value_cansleep(ts->reset_gpio, 0);
+       }
 }
 
 /* must be called with ts->mutex held */
@@ -253,7 +252,7 @@ static void __tsc200x_enable(struct tsc200x *ts)
 {
        tsc200x_start_scan(ts);
 
-       if (ts->esd_timeout && (ts->set_reset || ts->reset_gpio)) {
+       if (ts->esd_timeout && ts->reset_gpio) {
                ts->last_valid_interrupt = jiffies;
                schedule_delayed_work(&ts->esd_work,
                                round_jiffies_relative(
@@ -310,9 +309,7 @@ static ssize_t tsc200x_selftest_show(struct device *dev,
        }
 
        /* hardware reset */
-       tsc200x_set_reset(ts, false);
-       usleep_range(100, 500); /* only 10us required */
-       tsc200x_set_reset(ts, true);
+       tsc200x_reset(ts);
 
        if (!success)
                goto out;
@@ -354,7 +351,7 @@ static umode_t tsc200x_attr_is_visible(struct kobject *kobj,
        umode_t mode = attr->mode;
 
        if (attr == &dev_attr_selftest.attr) {
-               if (!ts->set_reset && !ts->reset_gpio)
+               if (!ts->reset_gpio)
                        mode = 0;
        }
 
@@ -404,9 +401,7 @@ static void tsc200x_esd_work(struct work_struct *work)
 
        tsc200x_update_pen_state(ts, 0, 0, 0);
 
-       tsc200x_set_reset(ts, false);
-       usleep_range(100, 500); /* only 10us required */
-       tsc200x_set_reset(ts, true);
+       tsc200x_reset(ts);
 
        enable_irq(ts->irq);
        tsc200x_start_scan(ts);
@@ -454,26 +449,12 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
                  struct regmap *regmap,
                  int (*tsc200x_cmd)(struct device *dev, u8 cmd))
 {
-       const struct tsc2005_platform_data *pdata = dev_get_platdata(dev);
-       struct device_node *np = dev->of_node;
-
        struct tsc200x *ts;
        struct input_dev *input_dev;
-       unsigned int max_x = MAX_12BIT;
-       unsigned int max_y = MAX_12BIT;
-       unsigned int max_p = MAX_12BIT;
-       unsigned int fudge_x = TSC200X_DEF_X_FUZZ;
-       unsigned int fudge_y = TSC200X_DEF_Y_FUZZ;
-       unsigned int fudge_p = TSC200X_DEF_P_FUZZ;
-       unsigned int x_plate_ohm = TSC200X_DEF_RESISTOR;
-       unsigned int esd_timeout;
+       u32 x_plate_ohm;
+       u32 esd_timeout;
        int error;
 
-       if (!np && !pdata) {
-               dev_err(dev, "no platform data\n");
-               return -ENODEV;
-       }
-
        if (irq <= 0) {
                dev_err(dev, "no irq\n");
                return -ENODEV;
@@ -487,23 +468,6 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
                return -ENODEV;
        }
 
-       if (pdata) {
-               fudge_x = pdata->ts_x_fudge;
-               fudge_y = pdata->ts_y_fudge;
-               fudge_p = pdata->ts_pressure_fudge;
-               max_x   = pdata->ts_x_max;
-               max_y   = pdata->ts_y_max;
-               max_p   = pdata->ts_pressure_max;
-               x_plate_ohm = pdata->ts_x_plate_ohm;
-               esd_timeout = pdata->esd_timeout_ms;
-       } else {
-               x_plate_ohm = TSC200X_DEF_RESISTOR;
-               of_property_read_u32(np, "ti,x-plate-ohms", &x_plate_ohm);
-               esd_timeout = 0;
-               of_property_read_u32(np, "ti,esd-recovery-timeout-ms",
-                                                               &esd_timeout);
-       }
-
        ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
        if (!ts)
                return -ENOMEM;
@@ -517,8 +481,13 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
        ts->idev = input_dev;
        ts->regmap = regmap;
        ts->tsc200x_cmd = tsc200x_cmd;
-       ts->x_plate_ohm = x_plate_ohm;
-       ts->esd_timeout = esd_timeout;
+
+       error = device_property_read_u32(dev, "ti,x-plate-ohms", &x_plate_ohm);
+       ts->x_plate_ohm = error ? TSC200X_DEF_RESISTOR : x_plate_ohm;
+
+       error = device_property_read_u32(dev, "ti,esd-recovery-timeout-ms",
+                                        &esd_timeout);
+       ts->esd_timeout = error ? 0 : esd_timeout;
 
        ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
        if (IS_ERR(ts->reset_gpio)) {
@@ -527,16 +496,13 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
                return error;
        }
 
-       ts->vio = devm_regulator_get_optional(dev, "vio");
+       ts->vio = devm_regulator_get(dev, "vio");
        if (IS_ERR(ts->vio)) {
                error = PTR_ERR(ts->vio);
-               dev_err(dev, "vio regulator missing (%d)", error);
+               dev_err(dev, "error acquiring vio regulator: %d", error);
                return error;
        }
 
-       if (!ts->reset_gpio && pdata)
-               ts->set_reset = pdata->set_reset;
-
        mutex_init(&ts->mutex);
 
        spin_lock_init(&ts->lock);
@@ -559,22 +525,23 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
 
        input_dev->phys = ts->phys;
        input_dev->id = *tsc_id;
-       input_dev->dev.parent = dev;
-       input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
-       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-
-       input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0);
-       input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0);
-       input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0);
-
-       if (np)
-               touchscreen_parse_properties(input_dev, false, NULL);
 
        input_dev->open = tsc200x_open;
        input_dev->close = tsc200x_close;
 
        input_set_drvdata(input_dev, ts);
 
+       input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
+
+       input_set_abs_params(input_dev, ABS_X,
+                            0, MAX_12BIT, TSC200X_DEF_X_FUZZ, 0);
+       input_set_abs_params(input_dev, ABS_Y,
+                            0, MAX_12BIT, TSC200X_DEF_Y_FUZZ, 0);
+       input_set_abs_params(input_dev, ABS_PRESSURE,
+                            0, MAX_12BIT, TSC200X_DEF_P_FUZZ, 0);
+
+       touchscreen_parse_properties(input_dev, false, NULL);
+
        /* Ensure the touchscreen is off */
        tsc200x_stop_scan(ts);
 
@@ -587,12 +554,9 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
                return error;
        }
 
-       /* enable regulator for DT */
-       if (ts->vio) {
-               error = regulator_enable(ts->vio);
-               if (error)
-                       return error;
-       }
+       error = regulator_enable(ts->vio);
+       if (error)
+               return error;
 
        dev_set_drvdata(dev, ts);
        error = sysfs_create_group(&dev->kobj, &tsc200x_attr_group);
@@ -615,8 +579,7 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
 err_remove_sysfs:
        sysfs_remove_group(&dev->kobj, &tsc200x_attr_group);
 disable_regulator:
-       if (ts->vio)
-               regulator_disable(ts->vio);
+       regulator_disable(ts->vio);
        return error;
 }
 EXPORT_SYMBOL_GPL(tsc200x_probe);
@@ -627,8 +590,7 @@ int tsc200x_remove(struct device *dev)
 
        sysfs_remove_group(&dev->kobj, &tsc200x_attr_group);
 
-       if (ts->vio)
-               regulator_disable(ts->vio);
+       regulator_disable(ts->vio);
 
        return 0;
 }
diff --git a/drivers/input/touchscreen/zet6223.c b/drivers/input/touchscreen/zet6223.c
new file mode 100644 (file)
index 0000000..19ffcc7
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2016, Jelle van der Waa <jelle@vdwaa.nl>
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <asm/unaligned.h>
+
+#define ZET6223_MAX_FINGERS            16
+#define ZET6223_MAX_PKT_SIZE           (3 + 4 * ZET6223_MAX_FINGERS)
+
+#define ZET6223_CMD_INFO               0xB2
+#define ZET6223_CMD_INFO_LENGTH                17
+#define ZET6223_VALID_PACKET           0x3c
+
+#define ZET6223_POWER_ON_DELAY_MSEC    30
+
+struct zet6223_ts {
+       struct i2c_client *client;
+       struct input_dev *input;
+       struct regulator *vcc;
+       struct regulator *vio;
+       struct touchscreen_properties prop;
+       struct regulator_bulk_data supplies[2];
+       u16 max_x;
+       u16 max_y;
+       u8 fingernum;
+};
+
+static int zet6223_start(struct input_dev *dev)
+{
+       struct zet6223_ts *ts = input_get_drvdata(dev);
+
+       enable_irq(ts->client->irq);
+
+       return 0;
+}
+
+static void zet6223_stop(struct input_dev *dev)
+{
+       struct zet6223_ts *ts = input_get_drvdata(dev);
+
+       disable_irq(ts->client->irq);
+}
+
+static irqreturn_t zet6223_irq(int irq, void *dev_id)
+{
+       struct zet6223_ts *ts = dev_id;
+       u16 finger_bits;
+
+       /*
+        * First 3 bytes are an identifier, two bytes of finger data.
+        * X, Y data per finger is 4 bytes.
+        */
+       u8 bufsize = 3 + 4 * ts->fingernum;
+       u8 buf[ZET6223_MAX_PKT_SIZE];
+       int i;
+       int ret;
+       int error;
+
+       ret = i2c_master_recv(ts->client, buf, bufsize);
+       if (ret != bufsize) {
+               error = ret < 0 ? ret : -EIO;
+               dev_err_ratelimited(&ts->client->dev,
+                                   "Error reading input data: %d\n", error);
+               return IRQ_HANDLED;
+       }
+
+       if (buf[0] != ZET6223_VALID_PACKET)
+               return IRQ_HANDLED;
+
+       finger_bits = get_unaligned_be16(buf + 1);
+       for (i = 0; i < ts->fingernum; i++) {
+               if (!(finger_bits & BIT(15 - i)))
+                       continue;
+
+               input_mt_slot(ts->input, i);
+               input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
+               input_event(ts->input, EV_ABS, ABS_MT_POSITION_X,
+                               ((buf[i + 3] >> 4) << 8) + buf[i + 4]);
+               input_event(ts->input, EV_ABS, ABS_MT_POSITION_Y,
+                               ((buf[i + 3] & 0xF) << 8) + buf[i + 5]);
+       }
+
+       input_mt_sync_frame(ts->input);
+       input_sync(ts->input);
+
+       return IRQ_HANDLED;
+}
+
+static void zet6223_power_off(void *_ts)
+{
+       struct zet6223_ts *ts = _ts;
+
+       regulator_bulk_disable(ARRAY_SIZE(ts->supplies), ts->supplies);
+}
+
+static int zet6223_power_on(struct zet6223_ts *ts)
+{
+       struct device *dev = &ts->client->dev;
+       int error;
+
+       ts->supplies[0].supply = "vio";
+       ts->supplies[1].supply = "vcc";
+
+       error = devm_regulator_bulk_get(dev, ARRAY_SIZE(ts->supplies),
+                                       ts->supplies);
+       if (error)
+               return error;
+
+       error = regulator_bulk_enable(ARRAY_SIZE(ts->supplies), ts->supplies);
+       if (error)
+               return error;
+
+       msleep(ZET6223_POWER_ON_DELAY_MSEC);
+
+       error = devm_add_action_or_reset(dev, zet6223_power_off, ts);
+       if (error) {
+               dev_err(dev, "failed to install poweroff action: %d\n", error);
+               return error;
+       }
+
+       return 0;
+}
+
+static int zet6223_query_device(struct zet6223_ts *ts)
+{
+       u8 buf[ZET6223_CMD_INFO_LENGTH];
+       u8 cmd = ZET6223_CMD_INFO;
+       int ret;
+       int error;
+
+       ret = i2c_master_send(ts->client, &cmd, sizeof(cmd));
+       if (ret != sizeof(cmd)) {
+               error = ret < 0 ? ret : -EIO;
+               dev_err(&ts->client->dev,
+                       "touchpanel info cmd failed: %d\n", error);
+               return error;
+       }
+
+       ret = i2c_master_recv(ts->client, buf, sizeof(buf));
+       if (ret != sizeof(buf)) {
+               error = ret < 0 ? ret : -EIO;
+               dev_err(&ts->client->dev,
+                       "failed to retrieve touchpanel info: %d\n", error);
+               return error;
+       }
+
+       ts->fingernum = buf[15] & 0x7F;
+       if (ts->fingernum > ZET6223_MAX_FINGERS) {
+               dev_warn(&ts->client->dev,
+                        "touchpanel reports %d fingers, limiting to %d\n",
+                        ts->fingernum, ZET6223_MAX_FINGERS);
+               ts->fingernum = ZET6223_MAX_FINGERS;
+       }
+
+       ts->max_x = get_unaligned_le16(&buf[8]);
+       ts->max_y = get_unaligned_le16(&buf[10]);
+
+       return 0;
+}
+
+static int zet6223_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct device *dev = &client->dev;
+       struct zet6223_ts *ts;
+       struct input_dev *input;
+       int error;
+
+       if (!client->irq) {
+               dev_err(dev, "no irq specified\n");
+               return -EINVAL;
+       }
+
+       ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
+       if (!ts)
+               return -ENOMEM;
+
+       ts->client = client;
+
+       error = zet6223_power_on(ts);
+       if (error)
+               return error;
+
+       error = zet6223_query_device(ts);
+       if (error)
+               return error;
+
+       ts->input = input = devm_input_allocate_device(dev);
+       if (!input)
+               return -ENOMEM;
+
+       input_set_drvdata(input, ts);
+
+       input->name = client->name;
+       input->id.bustype = BUS_I2C;
+       input->open = zet6223_start;
+       input->close = zet6223_stop;
+
+       input_set_abs_params(input, ABS_MT_POSITION_X, 0, ts->max_x, 0, 0);
+       input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ts->max_y, 0, 0);
+
+       touchscreen_parse_properties(input, true, &ts->prop);
+
+       error = input_mt_init_slots(input, ts->fingernum,
+                                   INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+       if (error)
+               return error;
+
+       error = devm_request_threaded_irq(dev, client->irq, NULL, zet6223_irq,
+                                         IRQF_ONESHOT, client->name, ts);
+       if (error) {
+               dev_err(dev, "failed to request irq %d: %d\n",
+                       client->irq, error);
+               return error;
+       }
+
+       zet6223_stop(input);
+
+       error = input_register_device(input);
+       if (error)
+               return error;
+
+       return 0;
+}
+
+static const struct of_device_id zet6223_of_match[] = {
+       { .compatible = "zeitec,zet6223" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, zet6223_of_match);
+
+static const struct i2c_device_id zet6223_id[] = {
+       { "zet6223", 0},
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, zet6223_id);
+
+static struct i2c_driver zet6223_driver = {
+       .driver = {
+               .name = "zet6223",
+               .of_match_table = zet6223_of_match,
+       },
+       .probe = zet6223_probe,
+       .id_table = zet6223_id
+};
+module_i2c_driver(zet6223_driver);
+
+MODULE_AUTHOR("Jelle van der Waa <jelle@vdwaa.nl>");
+MODULE_DESCRIPTION("ZEITEC zet622x I2C touchscreen driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/i2c/mpr121_touchkey.h b/include/linux/i2c/mpr121_touchkey.h
deleted file mode 100644 (file)
index f0bcc38..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Header file for Freescale MPR121 Capacitive Touch Sensor */
-
-#ifndef _MPR121_TOUCHKEY_H
-#define _MPR121_TOUCHKEY_H
-
-/**
- * struct mpr121_platform_data - platform data for mpr121 sensor
- * @keymap: pointer to array of KEY_* values representing keymap
- * @keymap_size: size of the keymap
- * @wakeup: configure the button as a wake-up source
- * @vdd_uv: VDD voltage in uV
- */
-struct mpr121_platform_data {
-       const unsigned short *keymap;
-       unsigned int keymap_size;
-       bool wakeup;
-       int vdd_uv;
-};
-
-#endif /* _MPR121_TOUCHKEY_H */
index 27e06acc509adf25e6ec4463e683efaae78befa5..37b04a0fdea4e004a63c053bfb3c90d5de3612f1 100644 (file)
@@ -80,24 +80,9 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
                               unsigned int rows, unsigned int cols,
                               unsigned short *keymap,
                               struct input_dev *input_dev);
+int matrix_keypad_parse_properties(struct device *dev,
+                                  unsigned int *rows, unsigned int *cols);
 
-#ifdef CONFIG_OF
-/**
- * matrix_keypad_parse_of_params() - Read parameters from matrix-keypad node
- *
- * @dev: Device containing of_node
- * @rows: Returns number of matrix rows
- * @cols: Returns number of matrix columns
- * @return 0 if OK, <0 on error
- */
-int matrix_keypad_parse_of_params(struct device *dev,
-                                 unsigned int *rows, unsigned int *cols);
-#else
-static inline int matrix_keypad_parse_of_params(struct device *dev,
-                                 unsigned int *rows, unsigned int *cols)
-{
-       return -ENOSYS;
-}
-#endif /* CONFIG_OF */
+#define matrix_keypad_parse_of_params matrix_keypad_parse_properties
 
 #endif /* _MATRIX_KEYPAD_H */
diff --git a/include/linux/input/tca8418_keypad.h b/include/linux/input/tca8418_keypad.h
deleted file mode 100644 (file)
index e71a85d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * TCA8418 keypad platform support
- *
- * Copyright (C) 2011 Fuel7, Inc.  All rights reserved.
- *
- * Author: Kyle Manna <kyle.manna@fuel7.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * 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 021110-1307, USA.
- *
- * If you can't comply with GPLv2, alternative licensing terms may be
- * arranged. Please contact Fuel7, Inc. (http://fuel7.com/) for proprietary
- * alternative licensing inquiries.
- */
-
-#ifndef _TCA8418_KEYPAD_H
-#define _TCA8418_KEYPAD_H
-
-#include <linux/types.h>
-#include <linux/input/matrix_keypad.h>
-
-#define TCA8418_I2C_ADDR       0x34
-#define        TCA8418_NAME            "tca8418_keypad"
-
-struct tca8418_keypad_platform_data {
-       const struct matrix_keymap_data *keymap_data;
-       unsigned rows;
-       unsigned cols;
-       bool rep;
-       bool irq_is_gpio;
-};
-
-#endif
diff --git a/include/linux/spi/tsc2005.h b/include/linux/spi/tsc2005.h
deleted file mode 100644 (file)
index 563b3b1..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * This file is part of TSC2005 touchscreen driver
- *
- * Copyright (C) 2009-2010 Nokia Corporation
- *
- * 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.
- *
- * 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.
- */
-
-#ifndef _LINUX_SPI_TSC2005_H
-#define _LINUX_SPI_TSC2005_H
-
-#include <linux/types.h>
-
-struct tsc2005_platform_data {
-       int             ts_pressure_max;
-       int             ts_pressure_fudge;
-       int             ts_x_max;
-       int             ts_x_fudge;
-       int             ts_y_max;
-       int             ts_y_fudge;
-       int             ts_x_plate_ohm;
-       unsigned int    esd_timeout_ms;
-       void            (*set_reset)(bool enable);
-};
-
-#endif
index f2447a83ac8d936262f848df3a317c02bb094063..ccd0ccd00f470b92090f1a6eff4a5a03940fa7f6 100644 (file)
 /*
  * bit masks for use in "interrupt" flags (3rd argument)
  */
-#define SERIO_TIMEOUT  1
-#define SERIO_PARITY   2
-#define SERIO_FRAME    4
+#define SERIO_TIMEOUT  BIT(0)
+#define SERIO_PARITY   BIT(1)
+#define SERIO_FRAME    BIT(2)
+#define SERIO_OOB_DATA BIT(3)
 
 /*
  * Serio types