diff options
author | Jiri Kosina <jkosina@suse.cz> | 2014-02-20 14:54:28 +0100 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2014-02-20 14:54:28 +0100 |
commit | d4263348f796f29546f90802177865dd4379dd0a (patch) | |
tree | adcbdaebae584eee2f32fab95e826e8e49eef385 /drivers/input | |
parent | be873ac782f5ff5ee6675f83929f4fe6737eead2 (diff) | |
parent | 6d0abeca3242a88cab8232e4acd7e2bf088f3bc2 (diff) |
Merge branch 'master' into for-next
Diffstat (limited to 'drivers/input')
186 files changed, 1150 insertions, 752 deletions
diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index fa7a95c1da0e..2909e9561cf3 100644 --- a/drivers/input/gameport/emu10k1-gp.c +++ b/drivers/input/gameport/emu10k1-gp.c @@ -30,7 +30,6 @@ #include <linux/module.h> #include <linux/ioport.h> -#include <linux/init.h> #include <linux/gameport.h> #include <linux/slab.h> #include <linux/pci.h> diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index ae912d3aee4e..7c03114158e0 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c @@ -27,7 +27,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/gameport.h> diff --git a/drivers/input/input.c b/drivers/input/input.c index 846ccdd905b1..1c4c0db05550 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1653,35 +1653,36 @@ static void input_dev_toggle(struct input_dev *dev, bool activate) */ void input_reset_device(struct input_dev *dev) { - mutex_lock(&dev->mutex); + unsigned long flags; - if (dev->users) { - input_dev_toggle(dev, true); + mutex_lock(&dev->mutex); + spin_lock_irqsave(&dev->event_lock, flags); - /* - * Keys that have been pressed at suspend time are unlikely - * to be still pressed when we resume. - */ - spin_lock_irq(&dev->event_lock); - input_dev_release_keys(dev); - spin_unlock_irq(&dev->event_lock); - } + input_dev_toggle(dev, true); + input_dev_release_keys(dev); + spin_unlock_irqrestore(&dev->event_lock, flags); mutex_unlock(&dev->mutex); } EXPORT_SYMBOL(input_reset_device); -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int input_dev_suspend(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - mutex_lock(&input_dev->mutex); + spin_lock_irq(&input_dev->event_lock); - if (input_dev->users) - input_dev_toggle(input_dev, false); + /* + * Keys that are pressed now are unlikely to be + * still pressed when we resume. + */ + input_dev_release_keys(input_dev); + + /* Turn off LEDs and sounds, if any are active. */ + input_dev_toggle(input_dev, false); - mutex_unlock(&input_dev->mutex); + spin_unlock_irq(&input_dev->event_lock); return 0; } @@ -1690,7 +1691,43 @@ static int input_dev_resume(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - input_reset_device(input_dev); + spin_lock_irq(&input_dev->event_lock); + + /* Restore state of LEDs and sounds, if any were active. */ + input_dev_toggle(input_dev, true); + + spin_unlock_irq(&input_dev->event_lock); + + return 0; +} + +static int input_dev_freeze(struct device *dev) +{ + struct input_dev *input_dev = to_input_dev(dev); + + spin_lock_irq(&input_dev->event_lock); + + /* + * Keys that are pressed now are unlikely to be + * still pressed when we resume. + */ + input_dev_release_keys(input_dev); + + spin_unlock_irq(&input_dev->event_lock); + + return 0; +} + +static int input_dev_poweroff(struct device *dev) +{ + struct input_dev *input_dev = to_input_dev(dev); + + spin_lock_irq(&input_dev->event_lock); + + /* Turn off LEDs and sounds, if any are active. */ + input_dev_toggle(input_dev, false); + + spin_unlock_irq(&input_dev->event_lock); return 0; } @@ -1698,7 +1735,8 @@ static int input_dev_resume(struct device *dev) static const struct dev_pm_ops input_dev_pm_ops = { .suspend = input_dev_suspend, .resume = input_dev_resume, - .poweroff = input_dev_suspend, + .freeze = input_dev_freeze, + .poweroff = input_dev_poweroff, .restore = input_dev_resume, }; #endif /* CONFIG_PM */ @@ -1707,7 +1745,7 @@ static struct device_type input_dev_type = { .groups = input_dev_attr_groups, .release = input_dev_release, .uevent = input_dev_uevent, -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP .pm = &input_dev_pm_ops, #endif }; @@ -1871,6 +1909,10 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int break; case EV_ABS: + input_alloc_absinfo(dev); + if (!dev->absinfo) + return; + __set_bit(code, dev->absbit); break; diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index 85bc8dc07cfc..55efdfc7eb62 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c @@ -29,7 +29,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> -#include <linux/init.h> #include <linux/gameport.h> #include <linux/input.h> #include <linux/jiffies.h> diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index 0cbfd2dfabf4..b78425765d3e 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c @@ -33,7 +33,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/gameport.h> -#include <linux/init.h> #include <linux/jiffies.h> #define DRIVER_DESC "Logitech ADI joystick family driver" diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index 65367e44d715..ae3ee24a2368 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c @@ -29,7 +29,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> -#include <linux/init.h> #include <linux/gameport.h> #include <linux/input.h> #include <linux/jiffies.h> diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index ab1cf2882004..0f519db64748 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c @@ -30,7 +30,6 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/gameport.h> #include <linux/jiffies.h> diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index 9e1beff57c33..eac9c5b8d73e 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -28,7 +28,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/gameport.h> #include <linux/input.h> diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index c0f9c7b7eb4e..573191dd78e8 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c @@ -11,7 +11,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/gameport.h> #include <linux/input.h> diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index 55196f730af6..a9ac2f9cfce0 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c @@ -30,7 +30,6 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/delay.h> -#include <linux/init.h> #include <linux/gameport.h> #include <linux/input.h> #include <linux/jiffies.h> diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h index b1d7d9b0eb86..96ae4f5bd0eb 100644 --- a/drivers/input/joystick/iforce/iforce.h +++ b/drivers/input/joystick/iforce/iforce.h @@ -29,7 +29,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/spinlock.h> #include <linux/usb.h> #include <linux/serio.h> diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index 88c22623a2e8..17c2c800743c 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c @@ -33,7 +33,6 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/delay.h> -#include <linux/init.h> #include <linux/gameport.h> #include <linux/input.h> #include <linux/jiffies.h> diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c index 7eb878bab968..d1c6e4846a4a 100644 --- a/drivers/input/joystick/joydump.c +++ b/drivers/input/joystick/joydump.c @@ -31,7 +31,6 @@ #include <linux/gameport.h> #include <linux/kernel.h> #include <linux/delay.h> -#include <linux/init.h> #include <linux/slab.h> #define DRIVER_DESC "Gameport data dumper module" diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index 9fb153eef2fc..c5358ba1f571 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c @@ -31,7 +31,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Magellan and SpaceMouse 6dof controller driver" diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index 04c69af37148..4a95b224169f 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -30,7 +30,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/gameport.h> #include <linux/jiffies.h> diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index 80a7b27a457a..f4445a4e8d6a 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c @@ -33,7 +33,6 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/serio.h> diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index a41f291652e6..f2667820e8c5 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c @@ -32,7 +32,6 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/serio.h> diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index 0f51a60e14a7..099c6d7b5e08 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c @@ -32,7 +32,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Gravis Stinger gamepad driver" diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c index 5ef9bcdb0345..7e17cde464f0 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c @@ -33,7 +33,6 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/gameport.h> #include <linux/input.h> #include <linux/jiffies.h> diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 2556a8193579..7f7e5ab3f9e3 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c @@ -52,7 +52,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Handykey Twiddler keyboard as a joystick driver" diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index 23b3071abb6e..e13a9144a25d 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c @@ -31,7 +31,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Logitech WingMan Warrior joystick driver" diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 75e3b102ce45..603fe0dd3682 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -74,7 +74,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/stat.h> #include <linux/module.h> @@ -125,6 +124,8 @@ static const struct xpad_device { { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, + { 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 }, + { 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 }, { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, @@ -166,8 +167,8 @@ static const struct xpad_device { { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 }, { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, - { 0x1689, 0xfd00, "Razer Onza Tournament Edition", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, - { 0x1689, 0xfd01, "Razer Onza Classic Edition", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, + { 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 }, + { 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 }, { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 }, { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, { 0x1bad, 0xf016, "Mad Catz Xbox 360 Controller", 0, XTYPE_XBOX360 }, diff --git a/drivers/input/joystick/zhenhua.c b/drivers/input/joystick/zhenhua.c index c4de4388fd7f..30af2e8c670c 100644 --- a/drivers/input/joystick/zhenhua.c +++ b/drivers/input/joystick/zhenhua.c @@ -49,7 +49,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "RC transmitter with 5-byte Zhen Hua protocol joystick driver" diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index bb174c1a9886..a673c9f3a0b9 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -525,7 +525,7 @@ config KEYBOARD_SUNKBD config KEYBOARD_SH_KEYSC tristate "SuperH KEYSC keypad support" - depends on SUPERH || ARM || COMPILE_TEST + depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST help Say Y here if you want to use a keypad attached to the KEYSC block on SuperH processors such as sh7722 and sh7343. diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c index ef26b17fb159..4cc14c2fa7d5 100644 --- a/drivers/input/keyboard/adp5520-keys.c +++ b/drivers/input/keyboard/adp5520-keys.c @@ -8,7 +8,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/input.h> #include <linux/mfd/adp5520.h> @@ -71,7 +70,7 @@ static int adp5520_keys_notifier(struct notifier_block *nb, static int adp5520_keys_probe(struct platform_device *pdev) { - struct adp5520_keys_platform_data *pdata = pdev->dev.platform_data; + struct adp5520_keys_platform_data *pdata = dev_get_platdata(&pdev->dev); struct input_dev *input; struct adp5520_keys *dev; int ret, i; diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 3ed23513d881..bb3b57bea8ba 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -9,7 +9,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/workqueue.h> @@ -173,7 +172,7 @@ static int adp5588_build_gpiomap(struct adp5588_kpad *kpad, static int adp5588_gpio_add(struct adp5588_kpad *kpad) { struct device *dev = &kpad->client->dev; - const struct adp5588_kpad_platform_data *pdata = dev->platform_data; + const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(dev); const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; int i, error; @@ -227,7 +226,7 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) static void adp5588_gpio_remove(struct adp5588_kpad *kpad) { struct device *dev = &kpad->client->dev; - const struct adp5588_kpad_platform_data *pdata = dev->platform_data; + const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(dev); const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; int error; @@ -321,7 +320,8 @@ static irqreturn_t adp5588_irq(int irq, void *handle) static int adp5588_setup(struct i2c_client *client) { - const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; + const struct adp5588_kpad_platform_data *pdata = + dev_get_platdata(&client->dev); const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data; int i, ret; unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; @@ -424,7 +424,8 @@ static int adp5588_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct adp5588_kpad *kpad; - const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data; + const struct adp5588_kpad_platform_data *pdata = + dev_get_platdata(&client->dev); struct input_dev *input; unsigned int revid; int ret, i; diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index 60dafd4fa692..6329549bf6ad 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c @@ -8,7 +8,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/workqueue.h> @@ -499,7 +498,7 @@ static int adp5589_build_gpiomap(struct adp5589_kpad *kpad, static int adp5589_gpio_add(struct adp5589_kpad *kpad) { struct device *dev = &kpad->client->dev; - const struct adp5589_kpad_platform_data *pdata = dev->platform_data; + const struct adp5589_kpad_platform_data *pdata = dev_get_platdata(dev); const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data; int i, error; @@ -553,7 +552,7 @@ static int adp5589_gpio_add(struct adp5589_kpad *kpad) static void adp5589_gpio_remove(struct adp5589_kpad *kpad) { struct device *dev = &kpad->client->dev; - const struct adp5589_kpad_platform_data *pdata = dev->platform_data; + const struct adp5589_kpad_platform_data *pdata = dev_get_platdata(dev); const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data; int error; @@ -658,7 +657,7 @@ static int adp5589_setup(struct adp5589_kpad *kpad) { struct i2c_client *client = kpad->client; const struct adp5589_kpad_platform_data *pdata = - client->dev.platform_data; + dev_get_platdata(&client->dev); u8 (*reg) (u8) = kpad->var->reg; unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; unsigned char pull_mask = 0; @@ -864,7 +863,7 @@ static int adp5589_probe(struct i2c_client *client, { struct adp5589_kpad *kpad; const struct adp5589_kpad_platform_data *pdata = - client->dev.platform_data; + dev_get_platdata(&client->dev); struct input_dev *input; unsigned int revid; int ret, i; diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index 09b91d093087..e6d46c5994d7 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -30,7 +30,6 @@ #include <linux/module.h> -#include <linux/init.h> #include <linux/fs.h> #include <linux/interrupt.h> #include <linux/irq.h> @@ -180,7 +179,7 @@ static irqreturn_t bfin_kpad_isr(int irq, void *dev_id) static int bfin_kpad_probe(struct platform_device *pdev) { struct bf54x_kpad *bf54x_kpad; - struct bfin_kpad_platform_data *pdata = pdev->dev.platform_data; + struct bfin_kpad_platform_data *pdata = dev_get_platdata(&pdev->dev); struct input_dev *input; int i, error; @@ -333,7 +332,7 @@ out: static int bfin_kpad_remove(struct platform_device *pdev) { - struct bfin_kpad_platform_data *pdata = pdev->dev.platform_data; + struct bfin_kpad_platform_data *pdata = dev_get_platdata(&pdev->dev); struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev); del_timer_sync(&bf54x_kpad->timer); diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 7e8b0a52af25..408379669d3c 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -38,6 +38,7 @@ * @row_shift: log2 or number of rows, rounded up * @keymap_data: Matrix keymap data used to convert to keyscan values * @ghost_filter: true to enable the matrix key-ghosting filter + * @old_kb_state: bitmap of keys pressed last scan * @dev: Device pointer * @idev: Input device * @ec: Top level ChromeOS device to use to talk to EC @@ -49,6 +50,7 @@ struct cros_ec_keyb { int row_shift; const struct matrix_keymap_data *keymap_data; bool ghost_filter; + uint8_t *old_kb_state; struct device *dev; struct input_dev *idev; @@ -135,6 +137,7 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, struct input_dev *idev = ckdev->idev; int col, row; int new_state; + int old_state; int num_cols; num_cols = len; @@ -153,18 +156,19 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, for (row = 0; row < ckdev->rows; row++) { int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift); const unsigned short *keycodes = idev->keycode; - int code; - code = keycodes[pos]; new_state = kb_state[col] & (1 << row); - if (!!new_state != test_bit(code, idev->key)) { + old_state = ckdev->old_kb_state[col] & (1 << row); + if (new_state != old_state) { dev_dbg(ckdev->dev, "changed: [r%d c%d]: byte %02x\n", row, col, new_state); - input_report_key(idev, code, new_state); + input_report_key(idev, keycodes[pos], + new_state); } } + ckdev->old_kb_state[col] = kb_state[col]; } input_sync(ckdev->idev); } @@ -226,6 +230,9 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) &ckdev->cols); if (err) return err; + ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); + if (!ckdev->old_kb_state) + return -ENOMEM; idev = devm_input_allocate_device(&pdev->dev); if (!idev) diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index d15977a8361e..1559dc1cf951 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c @@ -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 = pdev->dev.platform_data; + struct davinci_ks_platform_data *pdata = dev_get_platdata(&pdev->dev); int error, i; if (pdata->device_enable) { diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index 47206bdba411..e59876212b8c 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c @@ -244,7 +244,7 @@ static int ep93xx_keypad_probe(struct platform_device *pdev) if (!keypad) return -ENOMEM; - keypad->pdata = pdev->dev.platform_data; + keypad->pdata = dev_get_platdata(&pdev->dev); if (!keypad->pdata) { err = -EINVAL; goto failed_free; diff --git a/drivers/input/keyboard/goldfish_events.c b/drivers/input/keyboard/goldfish_events.c index 9f60a2ec88db..69e854763370 100644 --- a/drivers/input/keyboard/goldfish_events.c +++ b/drivers/input/keyboard/goldfish_events.c @@ -14,7 +14,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/types.h> #include <linux/input.h> diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 4e428199e580..e571e194ff84 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -17,7 +17,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/input-polldev.h> diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 589e3c258f3f..610a8af795a1 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -36,7 +36,6 @@ #include <linux/serio.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/completion.h> #include <linux/slab.h> #include <linux/pci_ids.h> diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index 328cfc1eed95..cbf4f8038cba 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -13,7 +13,6 @@ #include <linux/delay.h> #include <linux/device.h> #include <linux/err.h> -#include <linux/init.h> #include <linux/input/matrix_keypad.h> #include <linux/interrupt.h> #include <linux/io.h> @@ -425,7 +424,8 @@ MODULE_DEVICE_TABLE(of, imx_keypad_of_match); static int imx_keypad_probe(struct platform_device *pdev) { - const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data; + const struct matrix_keymap_data *keymap_data = + dev_get_platdata(&pdev->dev); struct imx_keypad *keypad; struct input_dev *input_dev; struct resource *res; diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index a2a034c25f0b..69b1f002ff52 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c @@ -16,7 +16,6 @@ * published by the Free Software Foundation. */ -#include <linux/init.h> #include <linux/input.h> #include <linux/input-polldev.h> #include <linux/interrupt.h> diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c index b0ad457ca9d8..cd729d485e98 100644 --- a/drivers/input/keyboard/jornada720_kbd.c +++ b/drivers/input/keyboard/jornada720_kbd.c @@ -18,7 +18,6 @@ #include <linux/device.h> #include <linux/errno.h> #include <linux/interrupt.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index fc0a63c2f278..9fcd9f1d5dc8 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c @@ -65,7 +65,6 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/interrupt.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/serio.h> #include <linux/workqueue.h> diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index 0de23f41b2d3..0b42118cbf8f 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c @@ -627,7 +627,7 @@ static DEVICE_ATTR(disable_kp, 0644, lm8323_show_disable, lm8323_set_disable); static int lm8323_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct lm8323_platform_data *pdata = client->dev.platform_data; + struct lm8323_platform_data *pdata = dev_get_platdata(&client->dev); struct input_dev *idev; struct lm8323_chip *lm; int pwm; diff --git a/drivers/input/keyboard/lm8333.c b/drivers/input/keyboard/lm8333.c index 5a8ca35dc9af..9081cbef11ea 100644 --- a/drivers/input/keyboard/lm8333.c +++ b/drivers/input/keyboard/lm8333.c @@ -131,7 +131,8 @@ static irqreturn_t lm8333_irq_thread(int irq, void *data) static int lm8333_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct lm8333_platform_data *pdata = client->dev.platform_data; + const struct lm8333_platform_data *pdata = + dev_get_platdata(&client->dev); struct lm8333 *lm8333; struct input_dev *input; int err, active_time; diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 90ff73ace424..8d2e19e81e1e 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -14,7 +14,6 @@ #include <linux/types.h> #include <linux/delay.h> #include <linux/platform_device.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/irq.h> #include <linux/interrupt.h> diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index bc2cdaf563fd..430b54539720 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c @@ -182,7 +182,8 @@ static void max7359_initialize(struct i2c_client *client) static int max7359_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct matrix_keymap_data *keymap_data = client->dev.platform_data; + const struct matrix_keymap_data *keymap_data = + dev_get_platdata(&client->dev); struct max7359_keypad *keypad; struct input_dev *input_dev; int ret; diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c index 7c236f9c6a51..1da8e0b44b56 100644 --- a/drivers/input/keyboard/mcs_touchkey.c +++ b/drivers/input/keyboard/mcs_touchkey.c @@ -12,7 +12,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/i2c.h> #include <linux/i2c/mcs.h> #include <linux/interrupt.h> @@ -108,7 +107,7 @@ static int mcs_touchkey_probe(struct i2c_client *client, int error; int i; - pdata = client->dev.platform_data; + pdata = dev_get_platdata(&client->dev); if (!pdata) { dev_err(&client->dev, "no platform data defined\n"); return -EINVAL; diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index f7f3e9a9fd3f..009c82256e89 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -13,7 +13,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/i2c.h> #include <linux/slab.h> @@ -188,7 +187,8 @@ err_i2c_write: static int mpr_touchkey_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct mpr121_platform_data *pdata = client->dev.platform_data; + const struct mpr121_platform_data *pdata = + dev_get_platdata(&client->dev); struct mpr121_touchkey *mpr121; struct input_dev *input_dev; int error; diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index f971898ad591..20f044377990 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c @@ -29,7 +29,6 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/input.h> -#include <linux/init.h> #include <linux/serio.h> #define DRIVER_DESC "Newton keyboard driver" diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index c7d505cce72f..63332e2f8628 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -222,7 +222,8 @@ static irqreturn_t ske_keypad_irq(int irq, void *dev_id) static int __init ske_keypad_probe(struct platform_device *pdev) { - const struct ske_keypad_platform_data *plat = pdev->dev.platform_data; + const struct ske_keypad_platform_data *plat = + dev_get_platdata(&pdev->dev); struct ske_keypad *keypad; struct input_dev *input; struct resource *res; diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index d0d5226d9cd4..b1acc9852eb7 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -25,7 +25,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/types.h> #include <linux/input.h> @@ -248,7 +247,7 @@ static int omap_kp_probe(struct platform_device *pdev) { struct omap_kp *omap_kp; struct input_dev *input_dev; - struct omap_kp_platform_data *pdata = pdev->dev.platform_data; + struct omap_kp_platform_data *pdata = dev_get_platdata(&pdev->dev); int i, col_idx, row_idx, ret; unsigned int row_shift, keycodemax; diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 30acfd49fa6c..0400b3f2b4b9 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -22,7 +22,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/errno.h> diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 186138c720c7..d8241ba0afa0 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -18,7 +18,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/input.h> #include <linux/device.h> diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c index 248cdcf95296..374ca0246c8f 100644 --- a/drivers/input/keyboard/pxa930_rotary.c +++ b/drivers/input/keyboard/pxa930_rotary.c @@ -8,7 +8,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/input.h> #include <linux/platform_device.h> @@ -84,7 +83,8 @@ static void pxa930_rotary_close(struct input_dev *dev) static int pxa930_rotary_probe(struct platform_device *pdev) { - struct pxa930_rotary_platform_data *pdata = pdev->dev.platform_data; + struct pxa930_rotary_platform_data *pdata = + dev_get_platdata(&pdev->dev); struct pxa930_rotary *r; struct input_dev *input_dev; struct resource *res; diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c index 6c561ec3cc09..52cd6e88acd7 100644 --- a/drivers/input/keyboard/qt1070.c +++ b/drivers/input/keyboard/qt1070.c @@ -25,7 +25,6 @@ */ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/i2c.h> #include <linux/input.h> #include <linux/slab.h> diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index 1c0ddad0a1cc..819b22897c13 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c @@ -19,7 +19,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/leds.h> #include <linux/module.h> #include <linux/slab.h> diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index ac43a486c775..5e80fbf7b5ed 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -14,7 +14,6 @@ #include <linux/clk.h> #include <linux/delay.h> #include <linux/err.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/io.h> @@ -244,8 +243,8 @@ static void samsung_keypad_close(struct input_dev *input_dev) } #ifdef CONFIG_OF -static struct samsung_keypad_platdata *samsung_keypad_parse_dt( - struct device *dev) +static struct samsung_keypad_platdata * +samsung_keypad_parse_dt(struct device *dev) { struct samsung_keypad_platdata *pdata; struct matrix_keymap_data *keymap_data; @@ -253,17 +252,22 @@ static struct samsung_keypad_platdata *samsung_keypad_parse_dt( struct device_node *np = dev->of_node, *key_np; unsigned int key_count; + if (!np) { + dev_err(dev, "missing device tree data\n"); + return ERR_PTR(-EINVAL); + } + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(dev, "could not allocate memory for platform data\n"); - return NULL; + return ERR_PTR(-ENOMEM); } of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows); of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols); if (!num_rows || !num_cols) { dev_err(dev, "number of keypad rows/columns not specified\n"); - return NULL; + return ERR_PTR(-EINVAL); } pdata->rows = num_rows; pdata->cols = num_cols; @@ -271,7 +275,7 @@ static struct samsung_keypad_platdata *samsung_keypad_parse_dt( keymap_data = devm_kzalloc(dev, sizeof(*keymap_data), GFP_KERNEL); if (!keymap_data) { dev_err(dev, "could not allocate memory for keymap data\n"); - return NULL; + return ERR_PTR(-ENOMEM); } pdata->keymap_data = keymap_data; @@ -280,7 +284,7 @@ static struct samsung_keypad_platdata *samsung_keypad_parse_dt( keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL); if (!keymap) { dev_err(dev, "could not allocate memory for keymap\n"); - return NULL; + return ERR_PTR(-ENOMEM); } keymap_data->keymap = keymap; @@ -294,16 +298,19 @@ static struct samsung_keypad_platdata *samsung_keypad_parse_dt( if (of_get_property(np, "linux,input-no-autorepeat", NULL)) pdata->no_autorepeat = true; + if (of_get_property(np, "linux,input-wakeup", NULL)) pdata->wakeup = true; return pdata; } #else -static -struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev) +static struct samsung_keypad_platdata * +samsung_keypad_parse_dt(struct device *dev) { - return NULL; + dev_err(dev, "no platform data defined\n"); + + return ERR_PTR(-EINVAL); } #endif @@ -318,13 +325,11 @@ static int samsung_keypad_probe(struct platform_device *pdev) unsigned int keymap_size; int error; - if (pdev->dev.of_node) - pdata = samsung_keypad_parse_dt(&pdev->dev); - else - pdata = pdev->dev.platform_data; + pdata = dev_get_platdata(&pdev->dev); if (!pdata) { - dev_err(&pdev->dev, "no platform data defined\n"); - return -EINVAL; + pdata = samsung_keypad_parse_dt(&pdev->dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); } keymap_data = pdata->keymap_data; diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index fe0e498d2479..7abf03b4cc9c 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -12,7 +12,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/delay.h> @@ -171,7 +170,7 @@ static int sh_keysc_probe(struct platform_device *pdev) int i; int irq, error; - if (!pdev->dev.platform_data) { + if (!dev_get_platdata(&pdev->dev)) { dev_err(&pdev->dev, "no platform data defined\n"); error = -EINVAL; goto err0; @@ -198,7 +197,7 @@ static int sh_keysc_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, priv); - memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); + memcpy(&priv->pdata, dev_get_platdata(&pdev->dev), sizeof(priv->pdata)); pdata = &priv->pdata; priv->iomem_base = ioremap_nocache(res->start, resource_size(res)); diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 85ff530d9a91..258af10e5811 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -12,7 +12,6 @@ #include <linux/clk.h> #include <linux/errno.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/input.h> #include <linux/io.h> diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index 5cbec56f7720..c6727dda68f2 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c @@ -6,7 +6,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/interrupt.h> diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c index cc612c5d5427..a6e0d565e306 100644 --- a/drivers/input/keyboard/stowaway.c +++ b/drivers/input/keyboard/stowaway.c @@ -32,7 +32,6 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/input.h> -#include <linux/init.h> #include <linux/serio.h> #define DRIVER_DESC "Stowaway keyboard driver" diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index 5f836b1638c1..dc6bb9d5b4f0 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c @@ -31,7 +31,6 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/interrupt.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/serio.h> #include <linux/workqueue.h> diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c index 208de7cbb7fa..74494a357522 100644 --- a/drivers/input/keyboard/tc3589x-keypad.c +++ b/drivers/input/keyboard/tc3589x-keypad.c @@ -10,7 +10,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/input.h> #include <linux/platform_device.h> diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c index bfc832c35a7c..dc983ab6c0ad 100644 --- a/drivers/input/keyboard/tca6416-keypad.c +++ b/drivers/input/keyboard/tca6416-keypad.c @@ -213,7 +213,7 @@ static int tca6416_keypad_probe(struct i2c_client *client, return -ENODEV; } - pdata = client->dev.platform_data; + pdata = dev_get_platdata(&client->dev); if (!pdata) { dev_dbg(&client->dev, "no platform data\n"); return -EINVAL; diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 8508879f6faf..9757a58bc897 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -31,7 +31,7 @@ #include <linux/clk.h> #include <linux/slab.h> #include <linux/input/matrix_keypad.h> -#include <linux/clk/tegra.h> +#include <linux/reset.h> #include <linux/err.h> #define KBC_MAX_KPENT 8 @@ -116,6 +116,7 @@ struct tegra_kbc { u32 wakeup_key; struct timer_list timer; struct clk *clk; + struct reset_control *rst; const struct tegra_kbc_hw_support *hw_support; int max_keys; int num_rows_and_columns; @@ -373,9 +374,9 @@ static int tegra_kbc_start(struct tegra_kbc *kbc) clk_prepare_enable(kbc->clk); /* Reset the KBC controller to clear all previous status.*/ - tegra_periph_reset_assert(kbc->clk); + reset_control_assert(kbc->rst); udelay(100); - tegra_periph_reset_deassert(kbc->clk); + reset_control_assert(kbc->rst); udelay(100); tegra_kbc_config_pins(kbc); @@ -663,6 +664,12 @@ static int tegra_kbc_probe(struct platform_device *pdev) return PTR_ERR(kbc->clk); } + kbc->rst = devm_reset_control_get(&pdev->dev, "kbc"); + if (IS_ERR(kbc->rst)) { + dev_err(&pdev->dev, "failed to get keyboard reset\n"); + return PTR_ERR(kbc->rst); + } + /* * The time delay between two consecutive reads of the FIFO is * the sum of the repeat time and the time taken for scanning diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c index 8bd24d52bf1b..086511c2121b 100644 --- a/drivers/input/keyboard/tnetv107x-keypad.c +++ b/drivers/input/keyboard/tnetv107x-keypad.c @@ -162,7 +162,7 @@ static int keypad_probe(struct platform_device *pdev) int error = 0, sz, row_shift; u32 rev = 0; - pdata = pdev->dev.platform_data; + pdata = dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(dev, "cannot find device data\n"); return -EINVAL; diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index d2d178c84ea7..c5a11700a1bf 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -27,12 +27,12 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/input.h> #include <linux/platform_device.h> #include <linux/i2c/twl.h> #include <linux/slab.h> +#include <linux/of.h> /* * The TWL4030 family chips include a keypad controller that supports @@ -60,6 +60,7 @@ struct twl4030_keypad { unsigned short keymap[TWL4030_KEYMAP_SIZE]; u16 kp_state[TWL4030_MAX_ROWS]; + bool autorepeat; unsigned n_rows; unsigned n_cols; unsigned irq; @@ -330,70 +331,89 @@ static int twl4030_kp_program(struct twl4030_keypad *kp) */ static int twl4030_kp_probe(struct platform_device *pdev) { - struct twl4030_keypad_data *pdata = pdev->dev.platform_data; - const struct matrix_keymap_data *keymap_data; + struct twl4030_keypad_data *pdata = dev_get_platdata(&pdev->dev); + const struct matrix_keymap_data *keymap_data = NULL; struct twl4030_keypad *kp; struct input_dev *input; u8 reg; int error; - if (!pdata || !pdata->rows || !pdata->cols || !pdata->keymap_data || - pdata->rows > TWL4030_MAX_ROWS || pdata->cols > TWL4030_MAX_COLS) { - dev_err(&pdev->dev, "Invalid platform_data\n"); - return -EINVAL; - } + kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL); + if (!kp) + return -ENOMEM; - keymap_data = pdata->keymap_data; - - kp = kzalloc(sizeof(*kp), GFP_KERNEL); - input = input_allocate_device(); - if (!kp || !input) { - error = -ENOMEM; - goto err1; - } + input = devm_input_allocate_device(&pdev->dev); + if (!input) + return -ENOMEM; - /* Get the debug Device */ - kp->dbg_dev = &pdev->dev; - kp->input = input; - - kp->n_rows = pdata->rows; - kp->n_cols = pdata->cols; - kp->irq = platform_get_irq(pdev, 0); + /* get the debug device */ + kp->dbg_dev = &pdev->dev; + kp->input = input; /* setup input device */ input->name = "TWL4030 Keypad"; input->phys = "twl4030_keypad/input0"; - input->dev.parent = &pdev->dev; input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; input->id.product = 0x0001; input->id.version = 0x0003; + if (pdata) { + if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { + dev_err(&pdev->dev, "Missing platform_data\n"); + return -EINVAL; + } + + kp->n_rows = pdata->rows; + kp->n_cols = pdata->cols; + kp->autorepeat = pdata->rep; + keymap_data = pdata->keymap_data; + } else { + error = matrix_keypad_parse_of_params(&pdev->dev, &kp->n_rows, + &kp->n_cols); + if (error) + return error; + + kp->autorepeat = true; + } + + if (kp->n_rows > TWL4030_MAX_ROWS || kp->n_cols > TWL4030_MAX_COLS) { + dev_err(&pdev->dev, + "Invalid rows/cols amount specified in platform/devicetree data\n"); + return -EINVAL; + } + + kp->irq = platform_get_irq(pdev, 0); + if (!kp->irq) { + dev_err(&pdev->dev, "no keyboard irq assigned\n"); + return -EINVAL; + } + error = matrix_keypad_build_keymap(keymap_data, NULL, TWL4030_MAX_ROWS, 1 << TWL4030_ROW_SHIFT, kp->keymap, input); if (error) { dev_err(kp->dbg_dev, "Failed to build keymap\n"); - goto err1; + return error; } input_set_capability(input, EV_MSC, MSC_SCAN); /* Enable auto repeat feature of Linux input subsystem */ - if (pdata->rep) + if (kp->autorepeat) __set_bit(EV_REP, input->evbit); error = input_register_device(input); if (error) { dev_err(kp->dbg_dev, "Unable to register twl4030 keypad device\n"); - goto err1; + return error; } error = twl4030_kp_program(kp); if (error) - goto err2; + return error; /* * This ISR will always execute in kernel thread context because of @@ -401,47 +421,33 @@ static int twl4030_kp_probe(struct platform_device *pdev) * * NOTE: we assume this host is wired to TWL4040 INT1, not INT2 ... */ - error = request_threaded_irq(kp->irq, NULL, do_kp_irq, - 0, pdev->name, kp); + error = devm_request_threaded_irq(&pdev->dev, kp->irq, NULL, do_kp_irq, + 0, pdev->name, kp); if (error) { - dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n", - kp->irq); - goto err2; + dev_info(kp->dbg_dev, "request_irq failed for irq no=%d: %d\n", + kp->irq, error); + return error; } /* Enable KP and TO interrupts now. */ reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO); if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) { - error = -EIO; - goto err3; + /* mask all events - we don't care about the result */ + (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1); + return -EIO; } platform_set_drvdata(pdev, kp); return 0; - -err3: - /* mask all events - we don't care about the result */ - (void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1); - free_irq(kp->irq, kp); -err2: - input_unregister_device(input); - input = NULL; -err1: - input_free_device(input); - kfree(kp); - return error; } -static int twl4030_kp_remove(struct platform_device *pdev) -{ - struct twl4030_keypad *kp = platform_get_drvdata(pdev); - - free_irq(kp->irq, kp); - input_unregister_device(kp->input); - kfree(kp); - - return 0; -} +#ifdef CONFIG_OF +static const struct of_device_id twl4030_keypad_dt_match_table[] = { + { .compatible = "ti,twl4030-keypad" }, + {}, +}; +MODULE_DEVICE_TABLE(of, twl4030_keypad_dt_match_table); +#endif /* * NOTE: twl4030 are multi-function devices connected via I2C. @@ -451,10 +457,10 @@ static int twl4030_kp_remove(struct platform_device *pdev) static struct platform_driver twl4030_kp_driver = { .probe = twl4030_kp_probe, - .remove = twl4030_kp_remove, .driver = { .name = "twl4030_keypad", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(twl4030_keypad_dt_match_table), }, }; module_platform_driver(twl4030_kp_driver); diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index 7b039162a3f8..e8b9d94daae7 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c @@ -11,7 +11,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/input.h> #include <linux/device.h> @@ -121,7 +120,7 @@ static void w90p910_keypad_close(struct input_dev *dev) static int w90p910_keypad_probe(struct platform_device *pdev) { const struct w90p910_keypad_platform_data *pdata = - pdev->dev.platform_data; + dev_get_platdata(&pdev->dev); const struct matrix_keymap_data *keymap_data; struct w90p910_keypad *keypad; struct input_dev *input_dev; diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index d050d9d0011b..7c2325bd7408 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c @@ -29,7 +29,6 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/input.h> -#include <linux/init.h> #include <linux/serio.h> #define DRIVER_DESC "XT keyboard driver" diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 5f4967d01bc3..7904ab05527a 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -168,7 +168,7 @@ config INPUT_MAX8997_HAPTIC config INPUT_MC13783_PWRBUTTON tristate "MC13783 ON buttons" - depends on MFD_MC13783 + depends on MFD_MC13XXX help Support the ON buttons of MC13783 PMIC as an input device reporting power button status. @@ -222,6 +222,15 @@ config INPUT_GP2A To compile this driver as a module, choose M here: the module will be called gp2ap002a00f. +config INPUT_GPIO_BEEPER + tristate "Generic GPIO Beeper support" + depends on OF_GPIO + help + Say Y here if you have a beeper connected to a GPIO pin. + + To compile this driver as a module, choose M here: the + module will be called gpio-beeper. + config INPUT_GPIO_TILT_POLLED tristate "Polled GPIO tilt switch" depends on GPIOLIB diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 0ebfb6dbf0f7..cda71fc52fb3 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_INPUT_DA9052_ONKEY) += da9052_onkey.o obj-$(CONFIG_INPUT_DA9055_ONKEY) += da9055_onkey.o obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o +obj-$(CONFIG_INPUT_GPIO_BEEPER) += gpio-beeper.o obj-$(CONFIG_INPUT_GPIO_TILT_POLLED) += gpio_tilt_polled.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o obj-$(CONFIG_INPUT_IMS_PCU) += ims-pcu.o diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c index 2e5d5e1de647..7a61e9ee682c 100644 --- a/drivers/input/misc/ad714x.c +++ b/drivers/input/misc/ad714x.c @@ -7,7 +7,6 @@ */ #include <linux/device.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/slab.h> @@ -969,7 +968,7 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, int error; struct input_dev *input[MAX_DEVICE_NUM]; - struct ad714x_platform_data *plat_data = dev->platform_data; + struct ad714x_platform_data *plat_data = dev_get_platdata(dev); struct ad714x_chip *ad714x; void *drv_mem; unsigned long irqflags; @@ -986,7 +985,7 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, goto err_out; } - if (dev->platform_data == NULL) { + if (dev_get_platdata(dev) == NULL) { dev_err(dev, "platform data for ad714x doesn't exist\n"); error = -EINVAL; goto err_out; diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index 1cb1da294419..2b2d02f408bb 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -8,7 +8,6 @@ */ #include <linux/device.h> -#include <linux/init.h> #include <linux/delay.h> #include <linux/input.h> #include <linux/interrupt.h> @@ -714,7 +713,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, ac->fifo_delay = fifo_delay_default; - pdata = dev->platform_data; + pdata = dev_get_platdata(dev); if (!pdata) { dev_dbg(dev, "No platform data: Using default initialization\n"); diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 5d4402365a52..638165c78e75 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c @@ -25,11 +25,10 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/types.h> +#include <linux/acpi.h> #include <asm/uaccess.h> -#include <acpi/acpi_drivers.h> #define ACPI_ATLAS_NAME "Atlas ACPI" #define ACPI_ATLAS_CLASS "Atlas" diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index cd139cb17e32..e69d9bcb37e1 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c @@ -6,7 +6,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/pm.h> @@ -92,7 +91,7 @@ static irqreturn_t bfin_rotary_isr(int irq, void *dev_id) static int bfin_rotary_probe(struct platform_device *pdev) { - struct bfin_rotary_platform_data *pdata = pdev->dev.platform_data; + struct bfin_rotary_platform_data *pdata = dev_get_platdata(&pdev->dev); struct bfin_rot *rotary; struct input_dev *input; int error; diff --git a/drivers/input/misc/bma150.c b/drivers/input/misc/bma150.c index 865c2f9d25b9..52d3a9b28f0b 100644 --- a/drivers/input/misc/bma150.c +++ b/drivers/input/misc/bma150.c @@ -526,7 +526,8 @@ static int bma150_register_polled_device(struct bma150_data *bma150) static int bma150_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct bma150_platform_data *pdata = client->dev.platform_data; + const struct bma150_platform_data *pdata = + dev_get_platdata(&client->dev); const struct bma150_cfg *cfg; struct bma150_data *bma150; int chip_id; diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c index df9b756594f8..c7d00748277b 100644 --- a/drivers/input/misc/cma3000_d0x.c +++ b/drivers/input/misc/cma3000_d0x.c @@ -284,7 +284,7 @@ EXPORT_SYMBOL(cma3000_resume); struct cma3000_accl_data *cma3000_init(struct device *dev, int irq, const struct cma3000_bus_ops *bops) { - const struct cma3000_platform_data *pdata = dev->platform_data; + const struct cma3000_platform_data *pdata = dev_get_platdata(dev); struct cma3000_accl_data *data; struct input_dev *input_dev; int rev; diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index b5d71d245854..3e11510ff82d 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <linux/init.h> #include <linux/input-polldev.h> #include <linux/ioport.h> #include <linux/module.h> diff --git a/drivers/input/misc/da9052_onkey.c b/drivers/input/misc/da9052_onkey.c index 020569a499f2..1f695f229ea8 100644 --- a/drivers/input/misc/da9052_onkey.c +++ b/drivers/input/misc/da9052_onkey.c @@ -11,7 +11,6 @@ * option) any later version. */ -#include <linux/init.h> #include <linux/input.h> #include <linux/module.h> #include <linux/platform_device.h> diff --git a/drivers/input/misc/da9055_onkey.c b/drivers/input/misc/da9055_onkey.c index a0af8b2506ce..4b11ede34950 100644 --- a/drivers/input/misc/da9055_onkey.c +++ b/drivers/input/misc/da9055_onkey.c @@ -11,7 +11,6 @@ * option) any later version. */ -#include <linux/init.h> #include <linux/input.h> #include <linux/module.h> #include <linux/platform_device.h> diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c index a309a5c0899e..0eba94f581df 100644 --- a/drivers/input/misc/dm355evm_keys.c +++ b/drivers/input/misc/dm355evm_keys.c @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/input/sparse-keymap.h> diff --git a/drivers/input/misc/gp2ap002a00f.c b/drivers/input/misc/gp2ap002a00f.c index fe30bd0fe4bd..de21e317da32 100644 --- a/drivers/input/misc/gp2ap002a00f.c +++ b/drivers/input/misc/gp2ap002a00f.c @@ -125,7 +125,7 @@ static int gp2a_initialize(struct gp2a_data *dt) static int gp2a_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct gp2a_platform_data *pdata = client->dev.platform_data; + const struct gp2a_platform_data *pdata = dev_get_platdata(&client->dev); struct gp2a_data *dt; int error; diff --git a/drivers/input/misc/gpio-beeper.c b/drivers/input/misc/gpio-beeper.c new file mode 100644 index 000000000000..b757435e2b3d --- /dev/null +++ b/drivers/input/misc/gpio-beeper.c @@ -0,0 +1,127 @@ +/* + * Generic GPIO beeper driver + * + * Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru> + * + * 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. + */ + +#include <linux/input.h> +#include <linux/module.h> +#include <linux/of_gpio.h> +#include <linux/workqueue.h> +#include <linux/platform_device.h> + +#define BEEPER_MODNAME "gpio-beeper" + +struct gpio_beeper { + struct work_struct work; + int gpio; + bool active_low; + bool beeping; +}; + +static void gpio_beeper_toggle(struct gpio_beeper *beep, bool on) +{ + gpio_set_value_cansleep(beep->gpio, on ^ beep->active_low); +} + +static void gpio_beeper_work(struct work_struct *work) +{ + struct gpio_beeper *beep = container_of(work, struct gpio_beeper, work); + + gpio_beeper_toggle(beep, beep->beeping); +} + +static int gpio_beeper_event(struct input_dev *dev, unsigned int type, + unsigned int code, int value) +{ + struct gpio_beeper *beep = input_get_drvdata(dev); + + if (type != EV_SND || code != SND_BELL) + return -ENOTSUPP; + + if (value < 0) + return -EINVAL; + + beep->beeping = value; + /* Schedule work to actually turn the beeper on or off */ + schedule_work(&beep->work); + + return 0; +} + +static void gpio_beeper_close(struct input_dev *input) +{ + struct gpio_beeper *beep = input_get_drvdata(input); + + cancel_work_sync(&beep->work); + gpio_beeper_toggle(beep, false); +} + +static int gpio_beeper_probe(struct platform_device *pdev) +{ + struct gpio_beeper *beep; + enum of_gpio_flags flags; + struct input_dev *input; + unsigned long gflags; + int err; + + beep = devm_kzalloc(&pdev->dev, sizeof(*beep), GFP_KERNEL); + if (!beep) + return -ENOMEM; + + beep->gpio = of_get_gpio_flags(pdev->dev.of_node, 0, &flags); + if (!gpio_is_valid(beep->gpio)) + return beep->gpio; + + input = devm_input_allocate_device(&pdev->dev); + if (!input) + return -ENOMEM; + + INIT_WORK(&beep->work, gpio_beeper_work); + + input->name = pdev->name; + input->id.bustype = BUS_HOST; + input->id.vendor = 0x0001; + input->id.product = 0x0001; + input->id.version = 0x0100; + input->close = gpio_beeper_close; + input->event = gpio_beeper_event; + + input_set_capability(input, EV_SND, SND_BELL); + + beep->active_low = flags & OF_GPIO_ACTIVE_LOW; + gflags = beep->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; + + err = devm_gpio_request_one(&pdev->dev, beep->gpio, gflags, pdev->name); + if (err) + return err; + + input_set_drvdata(input, beep); + + return input_register_device(input); +} + +static struct of_device_id gpio_beeper_of_match[] = { + { .compatible = BEEPER_MODNAME, }, + { } +}; +MODULE_DEVICE_TABLE(of, gpio_beeper_of_match); + +static struct platform_driver gpio_beeper_platform_driver = { + .driver = { + .name = BEEPER_MODNAME, + .owner = THIS_MODULE, + .of_match_table = gpio_beeper_of_match, + }, + .probe = gpio_beeper_probe, +}; +module_platform_driver(gpio_beeper_platform_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); +MODULE_DESCRIPTION("Generic GPIO beeper driver"); diff --git a/drivers/input/misc/gpio_tilt_polled.c b/drivers/input/misc/gpio_tilt_polled.c index 714c68369134..1a81d9115226 100644 --- a/drivers/input/misc/gpio_tilt_polled.c +++ b/drivers/input/misc/gpio_tilt_polled.c @@ -16,7 +16,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/input-polldev.h> @@ -98,7 +97,8 @@ static void gpio_tilt_polled_close(struct input_polled_dev *dev) static int gpio_tilt_polled_probe(struct platform_device *pdev) { - const struct gpio_tilt_platform_data *pdata = pdev->dev.platform_data; + const struct gpio_tilt_platform_data *pdata = + dev_get_platdata(&pdev->dev); struct device *dev = &pdev->dev; struct gpio_tilt_polled_dev *tdev; struct input_polled_dev *poll_dev; diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c index 290fa5f97ded..01f3b5b300f3 100644 --- a/drivers/input/misc/keyspan_remote.c +++ b/drivers/input/misc/keyspan_remote.c @@ -13,7 +13,6 @@ #include <linux/kernel.h> #include <linux/errno.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/usb/input.h> diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c index a993b67a8a5b..d708478bc5b5 100644 --- a/drivers/input/misc/kxtj9.c +++ b/drivers/input/misc/kxtj9.c @@ -509,7 +509,8 @@ out: static int kxtj9_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct kxtj9_platform_data *pdata = client->dev.platform_data; + const struct kxtj9_platform_data *pdata = + dev_get_platdata(&client->dev); struct kxtj9_data *tj9; int err; diff --git a/drivers/input/misc/max8997_haptic.c b/drivers/input/misc/max8997_haptic.c index e973133212a5..1fea5484941f 100644 --- a/drivers/input/misc/max8997_haptic.c +++ b/drivers/input/misc/max8997_haptic.c @@ -23,7 +23,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/platform_device.h> #include <linux/err.h> diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c index d0277a7b1579..0df6e8d8bd03 100644 --- a/drivers/input/misc/mc13783-pwrbutton.c +++ b/drivers/input/misc/mc13783-pwrbutton.c @@ -20,7 +20,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/input.h> diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c index 6983ffbbfb94..5e5051351c3a 100644 --- a/drivers/input/misc/mpu3050.c +++ b/drivers/input/misc/mpu3050.c @@ -30,7 +30,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/mutex.h> diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c index 40ac9a5adf89..cd230365166e 100644 --- a/drivers/input/misc/pcap_keys.c +++ b/drivers/input/misc/pcap_keys.c @@ -12,7 +12,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/input.h> diff --git a/drivers/input/misc/pcf50633-input.c b/drivers/input/misc/pcf50633-input.c index 73b13ebabe56..db92f4f3c99b 100644 --- a/drivers/input/misc/pcf50633-input.c +++ b/drivers/input/misc/pcf50633-input.c @@ -16,7 +16,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/device.h> #include <linux/platform_device.h> #include <linux/input.h> diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c index 0deca5a3c87f..97f711a7bd20 100644 --- a/drivers/input/misc/pcf8574_keypad.c +++ b/drivers/input/misc/pcf8574_keypad.c @@ -7,7 +7,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/i2c.h> diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 7288b267613d..674a2cfc3c0e 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c @@ -15,7 +15,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/i8253.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/platform_device.h> #include <linux/timex.h> diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c index ec086f6f3cc3..b88b7cbf93e2 100644 --- a/drivers/input/misc/pm8xxx-vibrator.c +++ b/drivers/input/misc/pm8xxx-vibrator.c @@ -11,13 +11,12 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/platform_device.h> #include <linux/input.h> #include <linux/slab.h> -#include <linux/mfd/pm8xxx/core.h> +#include <linux/regmap.h> #define VIB_DRV 0x4A @@ -35,7 +34,7 @@ * struct pm8xxx_vib - structure to hold vibrator data * @vib_input_dev: input device supporting force feedback * @work: work structure to set the vibration parameters - * @dev: device supporting force feedback + * @regmap: regmap for register read/write * @speed: speed of vibration set from userland * @active: state of vibrator * @level: level of vibration to set in the chip @@ -44,7 +43,7 @@ struct pm8xxx_vib { struct input_dev *vib_input_dev; struct work_struct work; - struct device *dev; + struct regmap *regmap; int speed; int level; bool active; @@ -52,42 +51,6 @@ struct pm8xxx_vib { }; /** - * pm8xxx_vib_read_u8 - helper to read a byte from pmic chip - * @vib: pointer to vibrator structure - * @data: placeholder for data to be read - * @reg: register address - */ -static int pm8xxx_vib_read_u8(struct pm8xxx_vib *vib, - u8 *data, u16 reg) -{ - int rc; - - rc = pm8xxx_readb(vib->dev->parent, reg, data); - if (rc < 0) - dev_warn(vib->dev, "Error reading pm8xxx reg 0x%x(0x%x)\n", - reg, rc); - return rc; -} - -/** - * pm8xxx_vib_write_u8 - helper to write a byte to pmic chip - * @vib: pointer to vibrator structure - * @data: data to write - * @reg: register address - */ -static int pm8xxx_vib_write_u8(struct pm8xxx_vib *vib, - u8 data, u16 reg) -{ - int rc; - - rc = pm8xxx_writeb(vib->dev->parent, reg, data); - if (rc < 0) - dev_warn(vib->dev, "Error writing pm8xxx reg 0x%x(0x%x)\n", - reg, rc); - return rc; -} - -/** * pm8xxx_vib_set - handler to start/stop vibration * @vib: pointer to vibrator structure * @on: state to set @@ -95,14 +58,14 @@ static int pm8xxx_vib_write_u8(struct pm8xxx_vib *vib, static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on) { int rc; - u8 val = vib->reg_vib_drv; + unsigned int val = vib->reg_vib_drv; if (on) val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK); else val &= ~VIB_DRV_SEL_MASK; - rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV); + rc = regmap_write(vib->regmap, VIB_DRV, val); if (rc < 0) return rc; @@ -118,9 +81,9 @@ static void pm8xxx_work_handler(struct work_struct *work) { struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work); int rc; - u8 val; + unsigned int val; - rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV); + rc = regmap_read(vib->regmap, VIB_DRV, &val); if (rc < 0) return; @@ -184,34 +147,37 @@ static int pm8xxx_vib_probe(struct platform_device *pdev) struct pm8xxx_vib *vib; struct input_dev *input_dev; int error; - u8 val; - - vib = kzalloc(sizeof(*vib), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!vib || !input_dev) { - dev_err(&pdev->dev, "couldn't allocate memory\n"); - error = -ENOMEM; - goto err_free_mem; - } + unsigned int val; + + vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL); + if (!vib) + return -ENOMEM; + + vib->regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!vib->regmap) + return -ENODEV; + + input_dev = devm_input_allocate_device(&pdev->dev); + if (!input_dev) + return -ENOMEM; INIT_WORK(&vib->work, pm8xxx_work_handler); - vib->dev = &pdev->dev; vib->vib_input_dev = input_dev; /* operate in manual mode */ - error = pm8xxx_vib_read_u8(vib, &val, VIB_DRV); + error = regmap_read(vib->regmap, VIB_DRV, &val); if (error < 0) - goto err_free_mem; + return error; + val &= ~VIB_DRV_EN_MANUAL_MASK; - error = pm8xxx_vib_write_u8(vib, val, VIB_DRV); + error = regmap_write(vib->regmap, VIB_DRV, val); if (error < 0) - goto err_free_mem; + return error; vib->reg_vib_drv = val; input_dev->name = "pm8xxx_vib_ffmemless"; input_dev->id.version = 1; - input_dev->dev.parent = &pdev->dev; input_dev->close = pm8xxx_vib_close; input_set_drvdata(input_dev, vib); input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE); @@ -221,35 +187,17 @@ static int pm8xxx_vib_probe(struct platform_device *pdev) if (error) { dev_err(&pdev->dev, "couldn't register vibrator as FF device\n"); - goto err_free_mem; + return error; } error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "couldn't register input device\n"); - goto err_destroy_memless; + return error; } platform_set_drvdata(pdev, vib); return 0; - -err_destroy_memless: - input_ff_destroy(input_dev); -err_free_mem: - input_free_device(input_dev); - kfree(vib); - - return error; -} - -static int pm8xxx_vib_remove(struct platform_device *pdev) -{ - struct pm8xxx_vib *vib = platform_get_drvdata(pdev); - - input_unregister_device(vib->vib_input_dev); - kfree(vib); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -268,7 +216,6 @@ static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL); static struct platform_driver pm8xxx_vib_driver = { .probe = pm8xxx_vib_probe, - .remove = pm8xxx_vib_remove, .driver = { .name = "pm8xxx-vib", .owner = THIS_MODULE, diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c index b49b738aa9c6..0e1a05f95858 100644 --- a/drivers/input/misc/pmic8xxx-pwrkey.c +++ b/drivers/input/misc/pmic8xxx-pwrkey.c @@ -11,16 +11,15 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/platform_device.h> +#include <linux/regmap.h> #include <linux/log2.h> -#include <linux/mfd/pm8xxx/core.h> #include <linux/input/pmic8xxx-pwrkey.h> #define PON_CNTL_1 0x1C @@ -32,26 +31,25 @@ * @key_press_irq: key press irq number */ struct pmic8xxx_pwrkey { - struct input_dev *pwr; int key_press_irq; }; -static irqreturn_t pwrkey_press_irq(int irq, void *_pwrkey) +static irqreturn_t pwrkey_press_irq(int irq, void *_pwr) { - struct pmic8xxx_pwrkey *pwrkey = _pwrkey; + struct input_dev *pwr = _pwr; - input_report_key(pwrkey->pwr, KEY_POWER, 1); - input_sync(pwrkey->pwr); + input_report_key(pwr, KEY_POWER, 1); + input_sync(pwr); return IRQ_HANDLED; } -static irqreturn_t pwrkey_release_irq(int irq, void *_pwrkey) +static irqreturn_t pwrkey_release_irq(int irq, void *_pwr) { - struct pmic8xxx_pwrkey *pwrkey = _pwrkey; + struct input_dev *pwr = _pwr; - input_report_key(pwrkey->pwr, KEY_POWER, 0); - input_sync(pwrkey->pwr); + input_report_key(pwr, KEY_POWER, 0); + input_sync(pwr); return IRQ_HANDLED; } @@ -88,7 +86,8 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev) int key_press_irq = platform_get_irq(pdev, 1); int err; unsigned int delay; - u8 pon_cntl; + unsigned int pon_cntl; + struct regmap *regmap; struct pmic8xxx_pwrkey *pwrkey; const struct pm8xxx_pwrkey_platform_data *pdata = dev_get_platdata(&pdev->dev); @@ -103,30 +102,36 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev) return -EINVAL; } - pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL); + regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!regmap) { + dev_err(&pdev->dev, "failed to locate regmap for the device\n"); + return -ENODEV; + } + + pwrkey = devm_kzalloc(&pdev->dev, sizeof(*pwrkey), GFP_KERNEL); if (!pwrkey) return -ENOMEM; - pwr = input_allocate_device(); + pwrkey->key_press_irq = key_press_irq; + + pwr = devm_input_allocate_device(&pdev->dev); if (!pwr) { dev_dbg(&pdev->dev, "Can't allocate power button\n"); - err = -ENOMEM; - goto free_pwrkey; + return -ENOMEM; } input_set_capability(pwr, EV_KEY, KEY_POWER); pwr->name = "pmic8xxx_pwrkey"; pwr->phys = "pmic8xxx_pwrkey/input0"; - pwr->dev.parent = &pdev->dev; delay = (pdata->kpd_trigger_delay_us << 10) / USEC_PER_SEC; delay = 1 + ilog2(delay); - err = pm8xxx_readb(pdev->dev.parent, PON_CNTL_1, &pon_cntl); + err = regmap_read(regmap, PON_CNTL_1, &pon_cntl); if (err < 0) { dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err); - goto free_input_dev; + return err; } pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK; @@ -136,69 +141,46 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev) else pon_cntl &= ~PON_CNTL_PULL_UP; - err = pm8xxx_writeb(pdev->dev.parent, PON_CNTL_1, pon_cntl); + err = regmap_write(regmap, PON_CNTL_1, pon_cntl); if (err < 0) { dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err); - goto free_input_dev; + return err; } - err = input_register_device(pwr); + err = devm_request_irq(&pdev->dev, key_press_irq, pwrkey_press_irq, + IRQF_TRIGGER_RISING, + "pmic8xxx_pwrkey_press", pwr); if (err) { - dev_dbg(&pdev->dev, "Can't register power key: %d\n", err); - goto free_input_dev; + dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", + key_press_irq, err); + return err; } - pwrkey->key_press_irq = key_press_irq; - pwrkey->pwr = pwr; - - platform_set_drvdata(pdev, pwrkey); - - err = request_irq(key_press_irq, pwrkey_press_irq, - IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_press", pwrkey); - if (err < 0) { - dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", - key_press_irq, err); - goto unreg_input_dev; + err = devm_request_irq(&pdev->dev, key_release_irq, pwrkey_release_irq, + IRQF_TRIGGER_RISING, + "pmic8xxx_pwrkey_release", pwr); + if (err) { + dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", + key_release_irq, err); + return err; } - err = request_irq(key_release_irq, pwrkey_release_irq, - IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_release", pwrkey); - if (err < 0) { - dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n", - key_release_irq, err); - - goto free_press_irq; + err = input_register_device(pwr); + if (err) { + dev_err(&pdev->dev, "Can't register power key: %d\n", err); + return err; } + platform_set_drvdata(pdev, pwrkey); device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; - -free_press_irq: - free_irq(key_press_irq, pwrkey); -unreg_input_dev: - input_unregister_device(pwr); - pwr = NULL; -free_input_dev: - input_free_device(pwr); -free_pwrkey: - kfree(pwrkey); - return err; } static int pmic8xxx_pwrkey_remove(struct platform_device *pdev) { - struct pmic8xxx_pwrkey *pwrkey = platform_get_drvdata(pdev); - int key_release_irq = platform_get_irq(pdev, 0); - int key_press_irq = platform_get_irq(pdev, 1); - device_init_wakeup(&pdev->dev, 0); - free_irq(key_press_irq, pwrkey); - free_irq(key_release_irq, pwrkey); - input_unregister_device(pwrkey->pwr); - kfree(pwrkey); - return 0; } diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index 49c0c3ebd321..63b539d3daba 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c @@ -31,7 +31,6 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/spinlock.h> #include <linux/usb/input.h> diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index 940566e7be13..8ef288e7c971 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c @@ -68,7 +68,7 @@ static int pwm_beeper_event(struct input_dev *input, static int pwm_beeper_probe(struct platform_device *pdev) { - unsigned long pwm_id = (unsigned long)pdev->dev.platform_data; + unsigned long pwm_id = (unsigned long)dev_get_platdata(&pdev->dev); struct pwm_beeper *beeper; int error; diff --git a/drivers/input/misc/retu-pwrbutton.c b/drivers/input/misc/retu-pwrbutton.c index 7ca09baa0016..4bff1aa9b0db 100644 --- a/drivers/input/misc/retu-pwrbutton.c +++ b/drivers/input/misc/retu-pwrbutton.c @@ -17,7 +17,6 @@ */ #include <linux/irq.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/input.h> diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index f920ba7ab51f..99b9e42aa748 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -16,7 +16,6 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/input.h> #include <linux/device.h> diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c index 95cf299ef9a3..f10474937a64 100644 --- a/drivers/input/misc/sgi_btns.c +++ b/drivers/input/misc/sgi_btns.c @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <linux/init.h> #include <linux/input-polldev.h> #include <linux/ioport.h> #include <linux/module.h> diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c index 7b8b03e0d0be..e8897c36d21b 100644 --- a/drivers/input/misc/sirfsoc-onkey.c +++ b/drivers/input/misc/sirfsoc-onkey.c @@ -7,7 +7,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/platform_device.h> diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index b9a05fda03e4..fb3b63b2f85c 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c @@ -52,15 +52,15 @@ static irqreturn_t powerbutton_irq(int irq, void *_pwr) return IRQ_HANDLED; } -static int __init twl4030_pwrbutton_probe(struct platform_device *pdev) +static int twl4030_pwrbutton_probe(struct platform_device *pdev) { struct input_dev *pwr; int irq = platform_get_irq(pdev, 0); int err; - pwr = input_allocate_device(); + pwr = devm_input_allocate_device(&pdev->dev); if (!pwr) { - dev_dbg(&pdev->dev, "Can't allocate power button\n"); + dev_err(&pdev->dev, "Can't allocate power button\n"); return -ENOMEM; } @@ -70,52 +70,42 @@ static int __init twl4030_pwrbutton_probe(struct platform_device *pdev) pwr->phys = "twl4030_pwrbutton/input0"; pwr->dev.parent = &pdev->dev; - err = request_threaded_irq(irq, NULL, powerbutton_irq, + err = devm_request_threaded_irq(&pwr->dev, irq, NULL, powerbutton_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl4030_pwrbutton", pwr); if (err < 0) { - dev_dbg(&pdev->dev, "Can't get IRQ for pwrbutton: %d\n", err); - goto free_input_dev; + dev_err(&pdev->dev, "Can't get IRQ for pwrbutton: %d\n", err); + return err; } err = input_register_device(pwr); if (err) { - dev_dbg(&pdev->dev, "Can't register power button: %d\n", err); - goto free_irq; + dev_err(&pdev->dev, "Can't register power button: %d\n", err); + return err; } platform_set_drvdata(pdev, pwr); return 0; - -free_irq: - free_irq(irq, pwr); -free_input_dev: - input_free_device(pwr); - return err; } -static int __exit twl4030_pwrbutton_remove(struct platform_device *pdev) -{ - struct input_dev *pwr = platform_get_drvdata(pdev); - int irq = platform_get_irq(pdev, 0); - - free_irq(irq, pwr); - input_unregister_device(pwr); - - return 0; -} +#ifdef CONFIG_OF +static const struct of_device_id twl4030_pwrbutton_dt_match_table[] = { + { .compatible = "ti,twl4030-pwrbutton" }, + {}, +}; +MODULE_DEVICE_TABLE(of, twl4030_pwrbutton_dt_match_table); +#endif static struct platform_driver twl4030_pwrbutton_driver = { - .remove = __exit_p(twl4030_pwrbutton_remove), + .probe = twl4030_pwrbutton_probe, .driver = { .name = "twl4030_pwrbutton", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(twl4030_pwrbutton_dt_match_table), }, }; - -module_platform_driver_probe(twl4030_pwrbutton_driver, - twl4030_pwrbutton_probe); +module_platform_driver(twl4030_pwrbutton_driver); MODULE_ALIAS("platform:twl4030_pwrbutton"); MODULE_DESCRIPTION("Triton2 Power Button"); diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index 68a5f33152a8..960ef2a70910 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c @@ -185,15 +185,17 @@ static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata, if (pdata && pdata->coexist) return true; - if (of_find_node_by_name(node, "codec")) + if (of_find_node_by_name(node, "codec")) { + of_node_put(node); return true; + } return false; } static int twl4030_vibra_probe(struct platform_device *pdev) { - struct twl4030_vibra_data *pdata = pdev->dev.platform_data; + struct twl4030_vibra_data *pdata = dev_get_platdata(&pdev->dev); struct device_node *twl4030_core_node = pdev->dev.parent->of_node; struct vibra_info *info; int ret; diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 7864b0c3ebb3..77dc23b94eb1 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c @@ -258,17 +258,14 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); static int twl6040_vibra_probe(struct platform_device *pdev) { struct device *twl6040_core_dev = pdev->dev.parent; - struct device_node *twl6040_core_node = NULL; + struct device_node *twl6040_core_node; struct vibra_info *info; int vddvibl_uV = 0; int vddvibr_uV = 0; int ret; -#ifdef CONFIG_OF twl6040_core_node = of_find_node_by_name(twl6040_core_dev->of_node, "vibra"); -#endif - if (!twl6040_core_node) { dev_err(&pdev->dev, "parent of node is missing?\n"); return -EINVAL; @@ -276,6 +273,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev) info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) { + of_node_put(twl6040_core_node); dev_err(&pdev->dev, "couldn't allocate memory\n"); return -ENOMEM; } @@ -295,6 +293,8 @@ static int twl6040_vibra_probe(struct platform_device *pdev) of_property_read_u32(twl6040_core_node, "ti,vddvibl-uV", &vddvibl_uV); of_property_read_u32(twl6040_core_node, "ti,vddvibr-uV", &vddvibr_uV); + of_node_put(twl6040_core_node); + if ((!info->vibldrv_res && !info->viblmotor_res) || (!info->vibrdrv_res && !info->vibrmotor_res)) { dev_err(info->dev, "invalid vibra driver/motor resistance\n"); diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c index caa2c4068f09..173b6dcca0da 100644 --- a/drivers/input/misc/wm831x-on.c +++ b/drivers/input/misc/wm831x-on.c @@ -18,7 +18,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c index e21c1816a8f9..fbfdc10573be 100644 --- a/drivers/input/misc/xen-kbdfront.c +++ b/drivers/input/misc/xen-kbdfront.c @@ -29,6 +29,7 @@ #include <xen/interface/io/fbif.h> #include <xen/interface/io/kbdif.h> #include <xen/xenbus.h> +#include <xen/platform_pci.h> struct xenkbd_info { struct input_dev *kbd; @@ -380,6 +381,9 @@ static int __init xenkbd_init(void) if (xen_initial_domain()) return -ENODEV; + if (!xen_has_pv_devices()) + return -ENODEV; + return xenbus_register_frontend(&xenkbd_driver); } diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c index 285a5bd6cbc9..79c964c075f1 100644 --- a/drivers/input/misc/yealink.c +++ b/drivers/input/misc/yealink.c @@ -47,7 +47,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/rwsem.h> diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 5cf62e315218..fb15c64ffb95 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -277,6 +277,57 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse) } /* + * Process bitmap data for V5 protocols. Return value is null. + * + * The bitmaps don't have enough data to track fingers, so this function + * only generates points representing a bounding box of at most two contacts. + * These two points are returned in x1, y1, x2, and y2. + */ +static void alps_process_bitmap_dolphin(struct alps_data *priv, + struct alps_fields *fields, + int *x1, int *y1, int *x2, int *y2) +{ + int box_middle_x, box_middle_y; + unsigned int x_map, y_map; + unsigned char start_bit, end_bit; + unsigned char x_msb, x_lsb, y_msb, y_lsb; + + x_map = fields->x_map; + y_map = fields->y_map; + + if (!x_map || !y_map) + return; + + /* Get Most-significant and Least-significant bit */ + x_msb = fls(x_map); + x_lsb = ffs(x_map); + y_msb = fls(y_map); + y_lsb = ffs(y_map); + + /* Most-significant bit should never exceed max sensor line number */ + if (x_msb > priv->x_bits || y_msb > priv->y_bits) + return; + + *x1 = *y1 = *x2 = *y2 = 0; + + if (fields->fingers > 1) { + start_bit = priv->x_bits - x_msb; + end_bit = priv->x_bits - x_lsb; + box_middle_x = (priv->x_max * (start_bit + end_bit)) / + (2 * (priv->x_bits - 1)); + + start_bit = y_lsb - 1; + end_bit = y_msb - 1; + box_middle_y = (priv->y_max * (start_bit + end_bit)) / + (2 * (priv->y_bits - 1)); + *x1 = fields->x; + *y1 = fields->y; + *x2 = 2 * box_middle_x - *x1; + *y2 = 2 * box_middle_y - *y1; + } +} + +/* * Process bitmap data from v3 and v4 protocols. Returns the number of * fingers detected. A return value of 0 means at least one of the * bitmaps was empty. @@ -481,7 +532,8 @@ static void alps_decode_buttons_v3(struct alps_fields *f, unsigned char *p) f->ts_middle = !!(p[3] & 0x40); } -static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p) +static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p, + struct psmouse *psmouse) { f->first_mp = !!(p[4] & 0x40); f->is_mp = !!(p[0] & 0x40); @@ -502,48 +554,61 @@ static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p) alps_decode_buttons_v3(f, p); } -static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p) +static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p, + struct psmouse *psmouse) { - alps_decode_pinnacle(f, p); + alps_decode_pinnacle(f, p, psmouse); f->x_map |= (p[5] & 0x10) << 11; f->y_map |= (p[5] & 0x20) << 6; } -static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p) +static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p, + struct psmouse *psmouse) { + u64 palm_data = 0; + struct alps_data *priv = psmouse->private; + f->first_mp = !!(p[0] & 0x02); f->is_mp = !!(p[0] & 0x20); - f->fingers = ((p[0] & 0x6) >> 1 | + if (!f->is_mp) { + f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7)); + f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3)); + f->z = (p[0] & 4) ? 0 : p[5] & 0x7f; + alps_decode_buttons_v3(f, p); + } else { + f->fingers = ((p[0] & 0x6) >> 1 | (p[0] & 0x10) >> 2); - f->x_map = ((p[2] & 0x60) >> 5) | - ((p[4] & 0x7f) << 2) | - ((p[5] & 0x7f) << 9) | - ((p[3] & 0x07) << 16) | - ((p[3] & 0x70) << 15) | - ((p[0] & 0x01) << 22); - f->y_map = (p[1] & 0x7f) | - ((p[2] & 0x1f) << 7); - - f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7)); - f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3)); - f->z = (p[0] & 4) ? 0 : p[5] & 0x7f; - alps_decode_buttons_v3(f, p); + palm_data = (p[1] & 0x7f) | + ((p[2] & 0x7f) << 7) | + ((p[4] & 0x7f) << 14) | + ((p[5] & 0x7f) << 21) | + ((p[3] & 0x07) << 28) | + (((u64)p[3] & 0x70) << 27) | + (((u64)p[0] & 0x01) << 34); + + /* Y-profile is stored in P(0) to p(n-1), n = y_bits; */ + f->y_map = palm_data & (BIT(priv->y_bits) - 1); + + /* X-profile is stored in p(n) to p(n+m-1), m = x_bits; */ + f->x_map = (palm_data >> priv->y_bits) & + (BIT(priv->x_bits) - 1); + } } -static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) +static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse) { struct alps_data *priv = psmouse->private; unsigned char *packet = psmouse->packet; struct input_dev *dev = psmouse->dev; struct input_dev *dev2 = priv->dev2; int x1 = 0, y1 = 0, x2 = 0, y2 = 0; - int fingers = 0, bmap_fingers; - struct alps_fields f; + int fingers = 0, bmap_fn; + struct alps_fields f = {0}; - priv->decode_fields(&f, packet); + priv->decode_fields(&f, packet, psmouse); /* * There's no single feature of touchpad position and bitmap packets @@ -560,19 +625,38 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) */ if (f.is_mp) { fingers = f.fingers; - bmap_fingers = alps_process_bitmap(priv, - f.x_map, f.y_map, - &x1, &y1, &x2, &y2); - - /* - * We shouldn't report more than one finger if - * we don't have two coordinates. - */ - if (fingers > 1 && bmap_fingers < 2) - fingers = bmap_fingers; - - /* Now process position packet */ - priv->decode_fields(&f, priv->multi_data); + if (priv->proto_version == ALPS_PROTO_V3) { + bmap_fn = alps_process_bitmap(priv, f.x_map, + f.y_map, &x1, &y1, + &x2, &y2); + + /* + * We shouldn't report more than one finger if + * we don't have two coordinates. + */ + if (fingers > 1 && bmap_fn < 2) + fingers = bmap_fn; + + /* Now process position packet */ + priv->decode_fields(&f, priv->multi_data, + psmouse); + } else { + /* + * Because Dolphin uses position packet's + * coordinate data as Pt1 and uses it to + * calculate Pt2, so we need to do position + * packet decode first. + */ + priv->decode_fields(&f, priv->multi_data, + psmouse); + + /* + * Since Dolphin's finger number is reliable, + * there is no need to compare with bmap_fn. + */ + alps_process_bitmap_dolphin(priv, &f, &x1, &y1, + &x2, &y2); + } } else { priv->multi_packet = 0; } @@ -662,7 +746,7 @@ static void alps_process_packet_v3(struct psmouse *psmouse) return; } - alps_process_touchpad_packet_v3(psmouse); + alps_process_touchpad_packet_v3_v5(psmouse); } static void alps_process_packet_v6(struct psmouse *psmouse) @@ -1709,6 +1793,52 @@ error: return -1; } +static int alps_dolphin_get_device_area(struct psmouse *psmouse, + struct alps_data *priv) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + unsigned char param[4] = {0}; + int num_x_electrode, num_y_electrode; + + if (alps_enter_command_mode(psmouse)) + return -1; + + param[0] = 0x0a; + if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL) || + ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL) || + ps2_command(ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE) || + ps2_command(ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE)) + return -1; + + if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) + return -1; + + /* + * Dolphin's sensor line number is not fixed. It can be calculated + * by adding the device's register value with DOLPHIN_PROFILE_X/YOFFSET. + * Further more, we can get device's x_max and y_max by multiplying + * sensor line number with DOLPHIN_COUNT_PER_ELECTRODE. + * + * e.g. When we get register's sensor_x = 11 & sensor_y = 8, + * real sensor line number X = 11 + 8 = 19, and + * real sensor line number Y = 8 + 1 = 9. + * So, x_max = (19 - 1) * 64 = 1152, and + * y_max = (9 - 1) * 64 = 512. + */ + num_x_electrode = DOLPHIN_PROFILE_XOFFSET + (param[2] & 0x0F); + num_y_electrode = DOLPHIN_PROFILE_YOFFSET + ((param[2] >> 4) & 0x0F); + priv->x_bits = num_x_electrode; + priv->y_bits = num_y_electrode; + priv->x_max = (num_x_electrode - 1) * DOLPHIN_COUNT_PER_ELECTRODE; + priv->y_max = (num_y_electrode - 1) * DOLPHIN_COUNT_PER_ELECTRODE; + + if (alps_exit_command_mode(psmouse)) + return -1; + + return 0; +} + static int alps_hw_init_dolphin_v1(struct psmouse *psmouse) { struct ps2dev *ps2dev = &psmouse->ps2dev; @@ -1763,13 +1893,13 @@ static void alps_set_defaults(struct alps_data *priv) break; case ALPS_PROTO_V5: priv->hw_init = alps_hw_init_dolphin_v1; - priv->process_packet = alps_process_packet_v3; + priv->process_packet = alps_process_touchpad_packet_v3_v5; priv->decode_fields = alps_decode_dolphin; priv->set_abs_params = alps_set_abs_params_mt; priv->nibble_commands = alps_v3_nibble_commands; priv->addr_command = PSMOUSE_CMD_RESET_WRAP; priv->byte0 = 0xc8; - priv->mask0 = 0xc8; + priv->mask0 = 0xd8; priv->flags = 0; priv->x_max = 1360; priv->y_max = 660; @@ -1845,11 +1975,13 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) if (alps_match_table(psmouse, priv, e7, ec) == 0) { return 0; } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && - ec[0] == 0x73 && ec[1] == 0x01) { + ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) { priv->proto_version = ALPS_PROTO_V5; alps_set_defaults(priv); - - return 0; + if (alps_dolphin_get_device_area(psmouse, priv)) + return -EIO; + else + return 0; } else if (ec[0] == 0x88 && ec[1] == 0x08) { priv->proto_version = ALPS_PROTO_V3; alps_set_defaults(priv); diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index 704f0f924307..03f88b6940c7 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -19,6 +19,10 @@ #define ALPS_PROTO_V5 5 #define ALPS_PROTO_V6 6 +#define DOLPHIN_COUNT_PER_ELECTRODE 64 +#define DOLPHIN_PROFILE_XOFFSET 8 /* x-electrode offset */ +#define DOLPHIN_PROFILE_YOFFSET 1 /* y-electrode offset */ + /** * struct alps_model_info - touchpad ID table * @signature: E7 response string to match. @@ -146,7 +150,8 @@ struct alps_data { int (*hw_init)(struct psmouse *psmouse); void (*process_packet)(struct psmouse *psmouse); - void (*decode_fields)(struct alps_fields *f, unsigned char *p); + void (*decode_fields)(struct alps_fields *f, unsigned char *p, + struct psmouse *psmouse); void (*set_abs_params)(struct alps_data *priv, struct input_dev *dev1); int prev_fin; diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index e42f1fa8cdc0..800ca7dfafc2 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c @@ -30,7 +30,6 @@ #include <linux/kernel.h> #include <linux/errno.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/usb/input.h> diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index a73f9618b0ad..c329cdb0b91a 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -34,7 +34,6 @@ #include <linux/kernel.h> #include <linux/errno.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/usb/input.h> diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index a5869a856ea5..87095e2f5153 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -15,7 +15,6 @@ * the Free Software Foundation. */ -#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/slab.h> diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 597e9b8fc18d..ef1cf52f8bb9 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -486,6 +486,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse) unsigned char *packet = psmouse->packet; input_report_key(dev, BTN_LEFT, packet[0] & 0x01); + input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); input_mt_report_pointer_emulation(dev, true); input_sync(dev); } @@ -984,6 +985,44 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, } /* + * Advertise INPUT_PROP_BUTTONPAD for clickpads. The testing of bit 12 in + * fw_version for this is based on the following fw_version & caps table: + * + * Laptop-model: fw_version: caps: buttons: + * Acer S3 0x461f00 10, 13, 0e clickpad + * Acer S7-392 0x581f01 50, 17, 0d clickpad + * Acer V5-131 0x461f02 01, 16, 0c clickpad + * Acer V5-551 0x461f00 ? clickpad + * Asus K53SV 0x450f01 78, 15, 0c 2 hw buttons + * Asus G46VW 0x460f02 00, 18, 0c 2 hw buttons + * Asus G750JX 0x360f00 00, 16, 0c 2 hw buttons + * Asus UX31 0x361f00 20, 15, 0e clickpad + * Asus UX32VD 0x361f02 00, 15, 0e clickpad + * Avatar AVIU-145A2 0x361f00 ? clickpad + * Gigabyte U2442 0x450f01 58, 17, 0c 2 hw buttons + * Lenovo L430 0x350f02 b9, 15, 0c 2 hw buttons (*) + * Samsung NF210 0x150b00 78, 14, 0a 2 hw buttons + * Samsung NP770Z5E 0x575f01 10, 15, 0f clickpad + * Samsung NP700Z5B 0x361f06 21, 15, 0f clickpad + * Samsung NP900X3E-A02 0x575f03 ? clickpad + * Samsung NP-QX410 0x851b00 19, 14, 0c clickpad + * Samsung RC512 0x450f00 08, 15, 0c 2 hw buttons + * Samsung RF710 0x450f00 ? 2 hw buttons + * System76 Pangolin 0x250f01 ? 2 hw buttons + * (*) + 3 trackpoint buttons + */ +static void elantech_set_buttonpad_prop(struct psmouse *psmouse) +{ + struct input_dev *dev = psmouse->dev; + struct elantech_data *etd = psmouse->private; + + if (etd->fw_version & 0x001000) { + __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); + __clear_bit(BTN_RIGHT, dev->keybit); + } +} + +/* * Set the appropriate event bits for the input subsystem */ static int elantech_set_input_params(struct psmouse *psmouse) @@ -1026,6 +1065,8 @@ static int elantech_set_input_params(struct psmouse *psmouse) __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); /* fall through */ case 3: + if (etd->hw_version == 3) + elantech_set_buttonpad_prop(psmouse); input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); if (etd->reports_pressure) { @@ -1047,9 +1088,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) */ psmouse_warn(psmouse, "couldn't query resolution data.\n"); } - /* v4 is clickpad, with only one button. */ - __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); - __clear_bit(BTN_RIGHT, dev->keybit); + elantech_set_buttonpad_prop(psmouse); __set_bit(BTN_TOOL_QUADTAP, dev->keybit); /* For X to recognize me as touchpad. */ input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c index 6b44413f54e3..8c7d94200bdb 100644 --- a/drivers/input/mouse/gpio_mouse.c +++ b/drivers/input/mouse/gpio_mouse.c @@ -8,7 +8,6 @@ * published by the Free Software Foundation. */ -#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/input-polldev.h> @@ -48,7 +47,7 @@ static void gpio_mouse_scan(struct input_polled_dev *dev) static int gpio_mouse_probe(struct platform_device *pdev) { - struct gpio_mouse_platform_data *pdata = pdev->dev.platform_data; + struct gpio_mouse_platform_data *pdata = dev_get_platdata(&pdev->dev); struct input_polled_dev *input_poll; struct input_dev *input; int pin, i; diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 84de2fc6acc1..136e222e2a16 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -220,7 +220,7 @@ static const struct ps2pp_info *get_model_info(unsigned char model) { 61, PS2PP_KIND_MX, /* MX700 */ PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, - { 66, PS2PP_KIND_MX, /* MX3100 reciver */ + { 66, PS2PP_KIND_MX, /* MX3100 receiver */ PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL }, { 72, PS2PP_KIND_TRACKMAN, 0 }, /* T-CH11: TrackMan Marble */ diff --git a/drivers/input/mouse/navpoint.c b/drivers/input/mouse/navpoint.c index 0b8d33591dee..1ccc88af1f0b 100644 --- a/drivers/input/mouse/navpoint.c +++ b/drivers/input/mouse/navpoint.c @@ -9,7 +9,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/clk.h> diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index 0ecb9e7945eb..9b4d9a59e229 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c @@ -10,7 +10,6 @@ * published by the Free Software Foundation. */ -#include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/module.h> @@ -166,7 +165,7 @@ static int pxa930_trkball_probe(struct platform_device *pdev) if (!trkball) return -ENOMEM; - trkball->pdata = pdev->dev.platform_data; + trkball->pdata = dev_get_platdata(&pdev->dev); if (!trkball->pdata) { dev_err(&pdev->dev, "no platform data defined\n"); error = -EINVAL; diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index d5928fd0c914..8df526620ebf 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c @@ -32,7 +32,6 @@ #include <linux/interrupt.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Serial mouse driver" diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c index 64cf34ea7604..e122bda16aab 100644 --- a/drivers/input/mouse/synaptics_usb.c +++ b/drivers/input/mouse/synaptics_usb.c @@ -39,7 +39,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/moduleparam.h> diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index e900d465aaf6..38298232124f 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -82,7 +82,6 @@ #include <linux/interrupt.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Driver for DEC VSXXX-AA and -GA mice and VSXXX-AB tablet" diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 8541f949778d..aec54e283580 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -16,14 +16,19 @@ config SERIO To compile this driver as a module, choose M here: the module will be called serio. +config ARCH_MIGHT_HAVE_PC_SERIO + bool + help + Select this config option from the architecture Kconfig if + the architecture might use a PC serio device (i8042) to + communicate with keyboard, mouse, etc. + if SERIO config SERIO_I8042 tristate "i8042 PC Keyboard controller" default y - depends on !PARISC && (!ARM || FOOTBRIDGE_HOST) && \ - (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !S390 && \ - !ARC + depends on ARCH_MIGHT_HAVE_PC_SERIO help i8042 is the chip over which the standard AT keyboard and PS/2 mouse are connected to the computer. If you use these devices, diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index 4777a73cd390..cce69d6b9587 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c @@ -12,7 +12,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/serio.h> #include <linux/interrupt.h> diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index 4e2fd44865e1..762b08432de0 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c @@ -10,7 +10,6 @@ * (at your option) any later version. */ #include <linux/module.h> -#include <linux/init.h> #include <linux/serio.h> #include <linux/errno.h> #include <linux/interrupt.h> @@ -167,8 +166,6 @@ static int amba_kmi_remove(struct amba_device *dev) { struct amba_kmi_port *kmi = amba_get_drvdata(dev); - amba_set_drvdata(dev, NULL); - serio_unregister_port(kmi->io); clk_put(kmi->clk); iounmap(kmi->base); diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c index 3a83c3c14b23..613261994621 100644 --- a/drivers/input/serio/hyperv-keyboard.c +++ b/drivers/input/serio/hyperv-keyboard.c @@ -160,7 +160,9 @@ static void hv_kbd_on_receive(struct hv_device *hv_dev, if (info & IS_E0) serio_interrupt(kbd_dev->hv_serio, XTKBD_EMUL0, 0); - + if (info & IS_E1) + serio_interrupt(kbd_dev->hv_serio, + XTKBD_EMUL1, 0); scan_code = __le16_to_cpu(ks_msg->make_code); if (info & IS_BREAK) scan_code |= XTKBD_RELEASE; diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 07a8363f3c5c..75516996db20 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -18,7 +18,6 @@ #include <linux/input.h> #include <linux/serio.h> #include <linux/i8042.h> -#include <linux/init.h> #include <linux/libps2.h> #define DRIVER_DESC "PS/2 driver library" diff --git a/drivers/input/serio/olpc_apsp.c b/drivers/input/serio/olpc_apsp.c index 51b1d40cc286..5d2fe7ece7ca 100644 --- a/drivers/input/serio/olpc_apsp.c +++ b/drivers/input/serio/olpc_apsp.c @@ -16,7 +16,6 @@ #include <linux/module.h> #include <linux/interrupt.h> -#include <linux/init.h> #include <linux/serio.h> #include <linux/err.h> #include <linux/platform_device.h> diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c index 76f83836fd5a..e862c6ea9d9e 100644 --- a/drivers/input/serio/pcips2.c +++ b/drivers/input/serio/pcips2.c @@ -16,7 +16,6 @@ #include <linux/input.h> #include <linux/pci.h> #include <linux/slab.h> -#include <linux/init.h> #include <linux/serio.h> #include <linux/delay.h> #include <asm/io.h> @@ -181,7 +180,6 @@ static void pcips2_remove(struct pci_dev *dev) struct pcips2_data *ps2if = pci_get_drvdata(dev); serio_unregister_port(ps2if->io); - pci_set_drvdata(dev, NULL); kfree(ps2if); pci_release_regions(dev); pci_disable_device(dev); diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index 7a65a1bc5226..594256c38554 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -30,7 +30,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/serio.h> #include <linux/interrupt.h> #include <linux/err.h> diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 567566ae0dae..e462e7791bb8 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -29,7 +29,6 @@ #include <linux/module.h> #include <linux/interrupt.h> -#include <linux/init.h> #include <linux/serio.h> #include <linux/err.h> #include <linux/platform_device.h> diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 59df2e7317a3..c9a02fe57576 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -15,7 +15,6 @@ #include <linux/poll.h> #include <linux/module.h> #include <linux/serio.h> -#include <linux/init.h> #include <linux/major.h> #include <linux/device.h> #include <linux/miscdevice.h> diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 8755f5f3ad37..0cb7ef59071b 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -124,7 +124,7 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c { struct serport *serport = (struct serport*) tty->disc_data; unsigned long flags; - unsigned int ch_flags; + unsigned int ch_flags = 0; int i; spin_lock_irqsave(&serport->lock, flags); @@ -133,18 +133,20 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c goto out; for (i = 0; i < count; i++) { - switch (fp[i]) { - case TTY_FRAME: - ch_flags = SERIO_FRAME; - break; - - case TTY_PARITY: - ch_flags = SERIO_PARITY; - break; - - default: - ch_flags = 0; - break; + if (fp) { + switch (fp[i]) { + case TTY_FRAME: + ch_flags = SERIO_FRAME; + break; + + case TTY_PARITY: + ch_flags = SERIO_PARITY; + break; + + default: + ch_flags = 0; + break; + } } serio_interrupt(serport->serio, cp[i], ch_flags); diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index dfbcd872f95e..e6cf52ebad87 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -20,7 +20,6 @@ #include <linux/interrupt.h> #include <linux/errno.h> #include <linux/slab.h> -#include <linux/init.h> #include <linux/list.h> #include <linux/io.h> #include <linux/of_address.h> diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index e062ec899ca1..889f6b77e8cb 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c @@ -28,7 +28,6 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/usb/input.h> /* diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index ee83c3904ee8..e7f966da6efa 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -74,7 +74,6 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/usb/input.h> #include <asm/uaccess.h> #include <asm/unaligned.h> diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c index 29e01ab6859f..caecffe8caff 100644 --- a/drivers/input/tablet/gtco.c +++ b/drivers/input/tablet/gtco.c @@ -53,7 +53,6 @@ Scott Hill shill@gtcocalcomp.com #include <linux/kernel.h> #include <linux/module.h> #include <linux/errno.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/usb.h> diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c index 5cc04124995c..cd852059b99e 100644 --- a/drivers/input/tablet/hanwang.c +++ b/drivers/input/tablet/hanwang.c @@ -26,7 +26,6 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/usb/input.h> #define DRIVER_AUTHOR "Xing Wei <weixing@hanwang.com.cn>" diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c index 3fba74b9b602..d2ac7c2b5b82 100644 --- a/drivers/input/tablet/kbtab.c +++ b/drivers/input/tablet/kbtab.c @@ -1,7 +1,6 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/usb/input.h> #include <asm/unaligned.h> diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index b79d45198d82..9ebf0ed3b3b3 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h @@ -86,7 +86,6 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/mod_devicetable.h> -#include <linux/init.h> #include <linux/usb/input.h> #include <linux/power_supply.h> #include <asm/unaligned.h> diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 867e7c33ac55..b16ebef5b911 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -304,7 +304,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct usb_device *dev = interface_to_usbdev(intf); char limit = 0; /* result has to be defined as int for some devices */ - int result = 0; + int result = 0, touch_max = 0; int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; unsigned char *report; @@ -351,7 +351,8 @@ static int wacom_parse_hid(struct usb_interface *intf, if (usage == WCM_DESKTOP) { if (finger) { features->device_type = BTN_TOOL_FINGER; - + /* touch device at least supports one touch point */ + touch_max = 1; switch (features->type) { case TABLETPC2FG: features->pktlen = WACOM_PKGLEN_TPC2FG; @@ -504,6 +505,8 @@ static int wacom_parse_hid(struct usb_interface *intf, } out: + if (!features->touch_max && touch_max) + features->touch_max = touch_max; result = 0; kfree(report); return result; @@ -1194,12 +1197,15 @@ static void wacom_wireless_work(struct work_struct *work) wacom_wac1->features.device_type = BTN_TOOL_PEN; snprintf(wacom_wac1->name, WACOM_NAME_MAX, "%s (WL) Pen", wacom_wac1->features.name); + wacom_wac1->shared->touch_max = wacom_wac1->features.touch_max; + wacom_wac1->shared->type = wacom_wac1->features.type; error = wacom_register_input(wacom1); if (error) goto fail; /* Touch interface */ - if (wacom_wac1->features.touch_max) { + if (wacom_wac1->features.touch_max || + wacom_wac1->features.type == INTUOSHT) { wacom_wac2->features = *((struct wacom_features *)id->driver_info); wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; @@ -1214,6 +1220,10 @@ static void wacom_wireless_work(struct work_struct *work) error = wacom_register_input(wacom2); if (error) goto fail; + + if (wacom_wac1->features.type == INTUOSHT && + wacom_wac1->features.touch_max) + wacom_wac->shared->touch_input = wacom_wac2->input; } error = wacom_initialize_battery(wacom); @@ -1322,7 +1332,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i * HID descriptor. If this is the touch interface (wMaxPacketSize * of WACOM_PKGLEN_BBTOUCH3), override the table values. */ - if (features->type >= INTUOS5S && features->type <= INTUOSPL) { + if (features->type >= INTUOS5S && features->type <= INTUOSHT) { if (endpoint->wMaxPacketSize == WACOM_PKGLEN_BBTOUCH3) { features->device_type = BTN_TOOL_FINGER; features->pktlen = WACOM_PKGLEN_BBTOUCH3; @@ -1393,6 +1403,11 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i } } + if (wacom_wac->features.type == INTUOSHT && wacom_wac->features.touch_max) { + if (wacom_wac->features.device_type == BTN_TOOL_FINGER) + wacom_wac->shared->touch_input = wacom_wac->input; + } + return 0; fail5: wacom_destroy_leds(wacom); diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 782c2535f1d8..05f371df6c40 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -210,6 +210,62 @@ static int wacom_dtu_irq(struct wacom_wac *wacom) return 1; } +static int wacom_dtus_irq(struct wacom_wac *wacom) +{ + char *data = wacom->data; + struct input_dev *input = wacom->input; + unsigned short prox, pressure = 0; + + if (data[0] != WACOM_REPORT_DTUS && data[0] != WACOM_REPORT_DTUSPAD) { + dev_dbg(input->dev.parent, + "%s: received unknown report #%d", __func__, data[0]); + return 0; + } else if (data[0] == WACOM_REPORT_DTUSPAD) { + input_report_key(input, BTN_0, (data[1] & 0x01)); + input_report_key(input, BTN_1, (data[1] & 0x02)); + input_report_key(input, BTN_2, (data[1] & 0x04)); + input_report_key(input, BTN_3, (data[1] & 0x08)); + input_report_abs(input, ABS_MISC, + data[1] & 0x0f ? PAD_DEVICE_ID : 0); + /* + * Serial number is required when expresskeys are + * reported through pen interface. + */ + input_event(input, EV_MSC, MSC_SERIAL, 0xf0); + return 1; + } else { + prox = data[1] & 0x80; + if (prox) { + switch ((data[1] >> 3) & 3) { + case 1: /* Rubber */ + wacom->tool[0] = BTN_TOOL_RUBBER; + wacom->id[0] = ERASER_DEVICE_ID; + break; + + case 2: /* Pen */ + wacom->tool[0] = BTN_TOOL_PEN; + wacom->id[0] = STYLUS_DEVICE_ID; + break; + } + } + + input_report_key(input, BTN_STYLUS, data[1] & 0x20); + input_report_key(input, BTN_STYLUS2, data[1] & 0x40); + input_report_abs(input, ABS_X, get_unaligned_be16(&data[3])); + input_report_abs(input, ABS_Y, get_unaligned_be16(&data[5])); + pressure = ((data[1] & 0x03) << 8) | (data[2] & 0xff); + input_report_abs(input, ABS_PRESSURE, pressure); + input_report_key(input, BTN_TOUCH, pressure > 10); + + if (!prox) /* out-prox */ + wacom->id[0] = 0; + input_report_key(input, wacom->tool[0], prox); + input_report_abs(input, ABS_MISC, wacom->id[0]); + input_event(input, EV_MSC, MSC_SERIAL, 1); + return 1; + } +} + static int wacom_graphire_irq(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; @@ -331,7 +387,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) /* Enter report */ if ((data[1] & 0xfc) == 0xc0) { - if (features->quirks == WACOM_QUIRK_MULTI_INPUT) + if (features->quirks & WACOM_QUIRK_MULTI_INPUT) wacom->shared->stylus_in_proximity = true; /* serial number of the tool */ @@ -436,7 +492,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) /* Exit report */ if ((data[1] & 0xfe) == 0x80) { - if (features->quirks == WACOM_QUIRK_MULTI_INPUT) + if (features->quirks & WACOM_QUIRK_MULTI_INPUT) wacom->shared->stylus_in_proximity = false; /* @@ -1151,8 +1207,8 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) int width, height; if (features->type >= INTUOSPS && features->type <= INTUOSPL) { - width = data[5]; - height = data[6]; + width = data[5] * 100; + height = data[6] * 100; } else { /* * "a" is a scaled-down area which we assume is @@ -1176,10 +1232,16 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data) { struct input_dev *input = wacom->input; + struct wacom_features *features = &wacom->features; - input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); + if (features->type == INTUOSHT) { + input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0); + input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0); + } else { + input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0); + input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0); + } input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0); - input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0); input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0); } @@ -1213,13 +1275,23 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom) static int wacom_bpt_pen(struct wacom_wac *wacom) { + struct wacom_features *features = &wacom->features; struct input_dev *input = wacom->input; unsigned char *data = wacom->data; int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0; - if (data[0] != 0x02) + if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_USB) return 0; + if (data[0] == WACOM_REPORT_USB) { + if (features->type == INTUOSHT && features->touch_max) { + input_report_switch(wacom->shared->touch_input, + SW_MUTE_DEVICE, data[8] & 0x40); + input_sync(wacom->shared->touch_input); + } + return 0; + } + prox = (data[1] & 0x20) == 0x20; /* @@ -1252,8 +1324,8 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) * touching and applying pressure; do not report negative * distance. */ - if (data[8] <= wacom->features.distance_max) - d = wacom->features.distance_max - data[8]; + if (data[8] <= features->distance_max) + d = features->distance_max - data[8]; pen = data[1] & 0x01; btn1 = data[1] & 0x02; @@ -1297,13 +1369,20 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) unsigned char *data = wacom->data; int connected; - if (len != WACOM_PKGLEN_WIRELESS || data[0] != 0x80) + if (len != WACOM_PKGLEN_WIRELESS || data[0] != WACOM_REPORT_WL) return 0; connected = data[1] & 0x01; if (connected) { int pid, battery; + if ((wacom->shared->type == INTUOSHT) && + wacom->shared->touch_max) { + input_report_switch(wacom->shared->touch_input, + SW_MUTE_DEVICE, data[5] & 0x40); + input_sync(wacom->shared->touch_input); + } + pid = get_unaligned_be16(&data[6]); battery = data[5] & 0x3f; if (wacom->pid != pid) { @@ -1348,6 +1427,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) sync = wacom_dtu_irq(wacom_wac); break; + case DTUS: + sync = wacom_dtus_irq(wacom_wac); + break; + case INTUOS: case INTUOS3S: case INTUOS3: @@ -1391,6 +1474,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) break; case BAMBOO_PT: + case INTUOSHT: sync = wacom_bpt_irq(wacom_wac, len); break; @@ -1459,7 +1543,7 @@ void wacom_setup_device_quirks(struct wacom_features *features) /* these device have multiple inputs */ if (features->type >= WIRELESS || - (features->type >= INTUOS5S && features->type <= INTUOSPL) || + (features->type >= INTUOS5S && features->type <= INTUOSHT) || (features->oVid && features->oPid)) features->quirks |= WACOM_QUIRK_MULTI_INPUT; @@ -1538,7 +1622,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, wacom_abs_set_axis(input_dev, wacom_wac); - switch (wacom_wac->features.type) { + switch (features->type) { case WACOM_MO: input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); /* fall through */ @@ -1749,8 +1833,14 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, /* fall through */ + case DTUS: case PL: case DTU: + if (features->type == DTUS) { + input_set_capability(input_dev, EV_MSC, MSC_SERIAL); + for (i = 0; i < 3; i++) + __set_bit(BTN_0 + i, input_dev->keybit); + } __set_bit(BTN_TOOL_PEN, input_dev->keybit); __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); __set_bit(BTN_STYLUS, input_dev->keybit); @@ -1771,33 +1861,50 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, __set_bit(INPUT_PROP_POINTER, input_dev->propbit); break; + case INTUOSHT: + if (features->touch_max && + features->device_type == BTN_TOOL_FINGER) { + input_dev->evbit[0] |= BIT_MASK(EV_SW); + __set_bit(SW_MUTE_DEVICE, input_dev->swbit); + } + /* fall through */ + case BAMBOO_PT: __clear_bit(ABS_MISC, input_dev->absbit); - __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - if (features->device_type == BTN_TOOL_FINGER) { - unsigned int flags = INPUT_MT_POINTER; __set_bit(BTN_LEFT, input_dev->keybit); __set_bit(BTN_FORWARD, input_dev->keybit); __set_bit(BTN_BACK, input_dev->keybit); __set_bit(BTN_RIGHT, input_dev->keybit); - if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { - input_set_abs_params(input_dev, + if (features->touch_max) { + /* touch interface */ + unsigned int flags = INPUT_MT_POINTER; + + __set_bit(INPUT_PROP_POINTER, input_dev->propbit); + if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0); - input_set_abs_params(input_dev, + input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0, features->y_max, 0, 0); + } else { + __set_bit(BTN_TOOL_FINGER, input_dev->keybit); + __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); + flags = 0; + } + input_mt_init_slots(input_dev, features->touch_max, flags); } else { - __set_bit(BTN_TOOL_FINGER, input_dev->keybit); - __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); - flags = 0; + /* buttons/keys only interface */ + __clear_bit(ABS_X, input_dev->absbit); + __clear_bit(ABS_Y, input_dev->absbit); + __clear_bit(BTN_TOUCH, input_dev->keybit); } - input_mt_init_slots(input_dev, features->touch_max, flags); } else if (features->device_type == BTN_TOOL_PEN) { + __set_bit(INPUT_PROP_POINTER, input_dev->propbit); __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); __set_bit(BTN_TOOL_PEN, input_dev->keybit); __set_bit(BTN_STYLUS, input_dev->keybit); @@ -2055,6 +2162,9 @@ static const struct wacom_features wacom_features_0xCE = static const struct wacom_features wacom_features_0xF0 = { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, 0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xFB = + { "Wacom DTU1031", WACOM_PKGLEN_DTUS, 22096, 13960, 511, + 0, DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x57 = { "Wacom DTK2241", WACOM_PKGLEN_INTUOS, 95840, 54260, 2047, 63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES}; @@ -2200,6 +2310,17 @@ static const struct wacom_features wacom_features_0x300 = static const struct wacom_features wacom_features_0x301 = { "Wacom Bamboo One M", WACOM_PKGLEN_BBPEN, 21648, 13530, 1023, 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0x302 = + { "Wacom Intuos PT S", WACOM_PKGLEN_BBPEN, 15200, 9500, 1023, + 31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, + .touch_max = 16 }; +static const struct wacom_features wacom_features_0x303 = + { "Wacom Intuos PT M", WACOM_PKGLEN_BBPEN, 21600, 13500, 1023, + 31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, + .touch_max = 16 }; +static const struct wacom_features wacom_features_0x30E = + { "Wacom Intuos S", WACOM_PKGLEN_BBPEN, 15200, 9500, 1023, + 31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x6004 = { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; @@ -2337,6 +2458,9 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x10F) }, { USB_DEVICE_WACOM(0x300) }, { USB_DEVICE_WACOM(0x301) }, + { USB_DEVICE_DETAILED(0x302, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_DETAILED(0x303, USB_CLASS_HID, 0, 0) }, + { USB_DEVICE_DETAILED(0x30E, USB_CLASS_HID, 0, 0) }, { USB_DEVICE_WACOM(0x304) }, { USB_DEVICE_DETAILED(0x314, USB_CLASS_HID, 0, 0) }, { USB_DEVICE_DETAILED(0x315, USB_CLASS_HID, 0, 0) }, @@ -2347,6 +2471,7 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0xF8) }, { USB_DEVICE_DETAILED(0xF6, USB_CLASS_HID, 0, 0) }, { USB_DEVICE_WACOM(0xFA) }, + { USB_DEVICE_WACOM(0xFB) }, { USB_DEVICE_WACOM(0x0307) }, { USB_DEVICE_DETAILED(0x0309, USB_CLASS_HID, 0, 0) }, { USB_DEVICE_LENOVO(0x6004) }, diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index fd23a3790605..f69c0ebe7fa9 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -12,7 +12,7 @@ #include <linux/types.h> /* maximum packet length for USB devices */ -#define WACOM_PKGLEN_MAX 64 +#define WACOM_PKGLEN_MAX 68 #define WACOM_NAME_MAX 64 @@ -29,6 +29,7 @@ #define WACOM_PKGLEN_WIRELESS 32 #define WACOM_PKGLEN_MTOUCH 62 #define WACOM_PKGLEN_MTTPC 40 +#define WACOM_PKGLEN_DTUS 68 /* wacom data size per MT contact */ #define WACOM_BYTES_PER_MT_PACKET 11 @@ -47,13 +48,17 @@ #define WACOM_REPORT_INTUOSWRITE 6 #define WACOM_REPORT_INTUOSPAD 12 #define WACOM_REPORT_INTUOS5PAD 3 +#define WACOM_REPORT_DTUSPAD 21 #define WACOM_REPORT_TPC1FG 6 #define WACOM_REPORT_TPC2FG 13 #define WACOM_REPORT_TPCMT 13 #define WACOM_REPORT_TPCHID 15 #define WACOM_REPORT_TPCST 16 +#define WACOM_REPORT_DTUS 17 #define WACOM_REPORT_TPC1FGE 18 #define WACOM_REPORT_24HDT 1 +#define WACOM_REPORT_WL 128 +#define WACOM_REPORT_USB 192 /* device quirks */ #define WACOM_QUIRK_MULTI_INPUT 0x0001 @@ -68,6 +73,7 @@ enum { PTU, PL, DTU, + DTUS, INTUOS, INTUOS3S, INTUOS3, @@ -81,6 +87,7 @@ enum { INTUOSPS, INTUOSPM, INTUOSPL, + INTUOSHT, WACOM_21UX2, WACOM_22HD, DTK, @@ -129,6 +136,10 @@ struct wacom_features { struct wacom_shared { bool stylus_in_proximity; bool touch_down; + /* for wireless device to access USB interfaces */ + unsigned touch_max; + int type; + struct input_dev *touch_input; }; struct wacom_wac { diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c index f7de14a268bf..544e20c551f8 100644 --- a/drivers/input/touchscreen/88pm860x-ts.c +++ b/drivers/input/touchscreen/88pm860x-ts.c @@ -172,7 +172,7 @@ static int pm860x_touch_dt_init(struct platform_device *pdev, static int pm860x_touch_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); - struct pm860x_touch_pdata *pdata = pdev->dev.platform_data; + struct pm860x_touch_pdata *pdata = dev_get_platdata(&pdev->dev); struct pm860x_touch *touch; struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ : chip->companion; diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 961d58d32647..07e9e82029d1 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -717,7 +717,7 @@ config TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_MC13783 tristate "Freescale MC13783 touchscreen input driver" - depends on MFD_MC13783 + depends on MFD_MC13XXX help Say Y here if you have an Freescale MC13783 PMIC on your board and want to use its touchscreen diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index 69834dd3c313..6793c85903ae 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c @@ -37,7 +37,6 @@ #include <linux/device.h> -#include <linux/init.h> #include <linux/delay.h> #include <linux/input.h> #include <linux/interrupt.h> @@ -686,7 +685,7 @@ static int ad7877_probe(struct spi_device *spi) { struct ad7877 *ts; struct input_dev *input_dev; - struct ad7877_platform_data *pdata = spi->dev.platform_data; + struct ad7877_platform_data *pdata = dev_get_platdata(&spi->dev); int err; u16 verify; diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index facd3057b62d..fce590677b7b 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c @@ -22,7 +22,6 @@ */ #include <linux/device.h> -#include <linux/init.h> #include <linux/delay.h> #include <linux/input.h> #include <linux/interrupt.h> @@ -470,7 +469,7 @@ static int ad7879_gpio_add(struct ad7879 *ts, static void ad7879_gpio_remove(struct ad7879 *ts) { - const struct ad7879_platform_data *pdata = ts->dev->platform_data; + const struct ad7879_platform_data *pdata = dev_get_platdata(ts->dev); int ret; if (pdata->gpio_export) { @@ -495,7 +494,7 @@ static inline void ad7879_gpio_remove(struct ad7879 *ts) struct ad7879 *ad7879_probe(struct device *dev, u8 devid, unsigned int irq, const struct ad7879_bus_ops *bops) { - struct ad7879_platform_data *pdata = dev->platform_data; + struct ad7879_platform_data *pdata = dev_get_platdata(dev); struct ad7879 *ts; struct input_dev *input_dev; int err; diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index ea195360747e..45a06e495ed2 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -19,7 +19,6 @@ */ #include <linux/types.h> #include <linux/hwmon.h> -#include <linux/init.h> #include <linux/err.h> #include <linux/sched.h> #include <linux/delay.h> @@ -101,8 +100,7 @@ struct ads7846 { struct spi_device *spi; struct regulator *reg; -#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) - struct attribute_group *attr_group; +#if IS_ENABLED(CONFIG_HWMON) struct device *hwmon; #endif @@ -421,7 +419,7 @@ static int ads7845_read12_ser(struct device *dev, unsigned command) return status; } -#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) +#if IS_ENABLED(CONFIG_HWMON) #define SHOW(name, var, adjust) static ssize_t \ name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ @@ -479,42 +477,36 @@ static inline unsigned vbatt_adjust(struct ads7846 *ts, ssize_t v) SHOW(in0_input, vaux, vaux_adjust) SHOW(in1_input, vbatt, vbatt_adjust) -static struct attribute *ads7846_attributes[] = { - &dev_attr_temp0.attr, - &dev_attr_temp1.attr, - &dev_attr_in0_input.attr, - &dev_attr_in1_input.attr, - NULL, -}; - -static struct attribute_group ads7846_attr_group = { - .attrs = ads7846_attributes, -}; +static umode_t ads7846_is_visible(struct kobject *kobj, struct attribute *attr, + int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct ads7846 *ts = dev_get_drvdata(dev); -static struct attribute *ads7843_attributes[] = { - &dev_attr_in0_input.attr, - &dev_attr_in1_input.attr, - NULL, -}; + if (ts->model == 7843 && index < 2) /* in0, in1 */ + return 0; + if (ts->model == 7845 && index != 2) /* in0 */ + return 0; -static struct attribute_group ads7843_attr_group = { - .attrs = ads7843_attributes, -}; + return attr->mode; +} -static struct attribute *ads7845_attributes[] = { - &dev_attr_in0_input.attr, +static struct attribute *ads7846_attributes[] = { + &dev_attr_temp0.attr, /* 0 */ + &dev_attr_temp1.attr, /* 1 */ + &dev_attr_in0_input.attr, /* 2 */ + &dev_attr_in1_input.attr, /* 3 */ NULL, }; -static struct attribute_group ads7845_attr_group = { - .attrs = ads7845_attributes, +static struct attribute_group ads7846_attr_group = { + .attrs = ads7846_attributes, + .is_visible = ads7846_is_visible, }; +__ATTRIBUTE_GROUPS(ads7846_attr); static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) { - struct device *hwmon; - int err; - /* hwmon sensors need a reference voltage */ switch (ts->model) { case 7846: @@ -535,43 +527,19 @@ static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) break; } - /* different chips have different sensor groups */ - switch (ts->model) { - case 7846: - ts->attr_group = &ads7846_attr_group; - break; - case 7845: - ts->attr_group = &ads7845_attr_group; - break; - case 7843: - ts->attr_group = &ads7843_attr_group; - break; - default: - dev_dbg(&spi->dev, "ADS%d not recognized\n", ts->model); - return 0; - } - - err = sysfs_create_group(&spi->dev.kobj, ts->attr_group); - if (err) - return err; - - hwmon = hwmon_device_register(&spi->dev); - if (IS_ERR(hwmon)) { - sysfs_remove_group(&spi->dev.kobj, ts->attr_group); - return PTR_ERR(hwmon); - } + ts->hwmon = hwmon_device_register_with_groups(&spi->dev, spi->modalias, + ts, ads7846_attr_groups); + if (IS_ERR(ts->hwmon)) + return PTR_ERR(ts->hwmon); - ts->hwmon = hwmon; return 0; } static void ads784x_hwmon_unregister(struct spi_device *spi, struct ads7846 *ts) { - if (ts->hwmon) { - sysfs_remove_group(&spi->dev.kobj, ts->attr_group); + if (ts->hwmon) hwmon_device_unregister(ts->hwmon); - } } #else diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 59aa24002c7b..a70400754e92 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -12,7 +12,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/delay.h> #include <linux/firmware.h> #include <linux/i2c.h> @@ -1130,7 +1129,7 @@ static void mxt_input_close(struct input_dev *dev) static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct mxt_platform_data *pdata = client->dev.platform_data; + const struct mxt_platform_data *pdata = dev_get_platdata(&client->dev); struct mxt_data *data; struct input_dev *input_dev; int error; diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c index bddabc595077..a7c9d6967d1e 100644 --- a/drivers/input/touchscreen/atmel_tsadcc.c +++ b/drivers/input/touchscreen/atmel_tsadcc.c @@ -12,7 +12,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include <linux/init.h> #include <linux/err.h> #include <linux/kernel.h> #include <linux/module.h> @@ -182,7 +181,7 @@ static int atmel_tsadcc_probe(struct platform_device *pdev) struct atmel_tsadcc *ts_dev; struct input_dev *input_dev; struct resource *res; - struct at91_tsadcc_data *pdata = pdev->dev.platform_data; + struct at91_tsadcc_data *pdata = dev_get_platdata(&pdev->dev); int err; unsigned int prsc; unsigned int reg; diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index 8c651985a5c4..5bf1aeeea825 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c @@ -178,7 +178,7 @@ static irqreturn_t cy8ctmg110_irq_thread(int irq, void *dev_id) static int cy8ctmg110_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct cy8ctmg110_pdata *pdata = client->dev.platform_data; + const struct cy8ctmg110_pdata *pdata = dev_get_platdata(&client->dev); struct cy8ctmg110 *ts; struct input_dev *input_dev; int err; diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c index 4204841cdc49..eee656f77a2e 100644 --- a/drivers/input/touchscreen/cyttsp_core.c +++ b/drivers/input/touchscreen/cyttsp_core.c @@ -534,7 +534,7 @@ static void cyttsp_close(struct input_dev *dev) struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops, struct device *dev, int irq, size_t xfer_buf_size) { - const struct cyttsp_platform_data *pdata = dev->platform_data; + const struct cyttsp_platform_data *pdata = dev_get_platdata(dev); struct cyttsp *ts; struct input_dev *input_dev; int error; @@ -553,7 +553,7 @@ struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops, ts->dev = dev; ts->input = input_dev; - ts->pdata = dev->platform_data; + ts->pdata = dev_get_platdata(dev); ts->bus_ops = bus_ops; ts->irq = irq; diff --git a/drivers/input/touchscreen/cyttsp_i2c_common.c b/drivers/input/touchscreen/cyttsp_i2c_common.c index 1d7b6f154168..ccefa56ca212 100644 --- a/drivers/input/touchscreen/cyttsp_i2c_common.c +++ b/drivers/input/touchscreen/cyttsp_i2c_common.c @@ -31,6 +31,8 @@ #include <linux/module.h> #include <linux/types.h> +#include "cyttsp4_core.h" + int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u16 addr, u8 length, void *values) { diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c index 34ad84105e6e..8ccf7bb4028a 100644 --- a/drivers/input/touchscreen/da9034-ts.c +++ b/drivers/input/touchscreen/da9034-ts.c @@ -13,7 +13,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/input.h> @@ -299,7 +298,7 @@ static void da9034_touch_close(struct input_dev *dev) static int da9034_touch_probe(struct platform_device *pdev) { - struct da9034_touch_pdata *pdata = pdev->dev.platform_data; + struct da9034_touch_pdata *pdata = dev_get_platdata(&pdev->dev); struct da9034_touch *touch; struct input_dev *input_dev; int ret; diff --git a/drivers/input/touchscreen/dynapro.c b/drivers/input/touchscreen/dynapro.c index 1809677a6513..86237a910876 100644 --- a/drivers/input/touchscreen/dynapro.c +++ b/drivers/input/touchscreen/dynapro.c @@ -24,7 +24,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Dynapro serial touchscreen driver" diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 83fa1b15a97f..412a85ec9ba5 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -623,8 +623,9 @@ static int edt_ft5x06_ts_reset(struct i2c_client *client, if (gpio_is_valid(reset_pin)) { /* this pulls reset down, enabling the low active reset */ - error = gpio_request_one(reset_pin, GPIOF_OUT_INIT_LOW, - "edt-ft5x06 reset"); + error = devm_gpio_request_one(&client->dev, reset_pin, + GPIOF_OUT_INIT_LOW, + "edt-ft5x06 reset"); if (error) { dev_err(&client->dev, "Failed to request GPIO %d as reset pin, error %d\n", @@ -705,7 +706,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { const struct edt_ft5x06_platform_data *pdata = - client->dev.platform_data; + dev_get_platdata(&client->dev); struct edt_ft5x06_ts_data *tsdata; struct input_dev *input; int error; @@ -723,8 +724,8 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, return error; if (gpio_is_valid(pdata->irq_pin)) { - error = gpio_request_one(pdata->irq_pin, - GPIOF_IN, "edt-ft5x06 irq"); + error = devm_gpio_request_one(&client->dev, pdata->irq_pin, + GPIOF_IN, "edt-ft5x06 irq"); if (error) { dev_err(&client->dev, "Failed to request GPIO %d, error %d\n", @@ -733,12 +734,16 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, } } - tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL); - input = input_allocate_device(); - if (!tsdata || !input) { + tsdata = devm_kzalloc(&client->dev, sizeof(*tsdata), GFP_KERNEL); + if (!tsdata) { dev_err(&client->dev, "failed to allocate driver data.\n"); - error = -ENOMEM; - goto err_free_mem; + return -ENOMEM; + } + + input = devm_input_allocate_device(&client->dev); + if (!input) { + dev_err(&client->dev, "failed to allocate input device.\n"); + return -ENOMEM; } mutex_init(&tsdata->mutex); @@ -749,7 +754,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, error = edt_ft5x06_ts_identify(client, tsdata->name, fw_version); if (error) { dev_err(&client->dev, "touchscreen probe failed\n"); - goto err_free_mem; + return error; } edt_ft5x06_ts_get_defaults(tsdata, pdata); @@ -776,27 +781,30 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, error = input_mt_init_slots(input, MAX_SUPPORT_POINTS, 0); if (error) { dev_err(&client->dev, "Unable to init MT slots.\n"); - goto err_free_mem; + return error; } input_set_drvdata(input, tsdata); i2c_set_clientdata(client, tsdata); - error = request_threaded_irq(client->irq, NULL, edt_ft5x06_ts_isr, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - client->name, tsdata); + error = devm_request_threaded_irq(&client->dev, client->irq, + NULL, edt_ft5x06_ts_isr, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + client->name, tsdata); if (error) { dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); - goto err_free_mem; + return error; } error = sysfs_create_group(&client->dev.kobj, &edt_ft5x06_attr_group); if (error) - goto err_free_irq; + return error; error = input_register_device(input); - if (error) - goto err_remove_attrs; + if (error) { + sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group); + return error; + } edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev)); device_init_wakeup(&client->dev, 1); @@ -806,40 +814,15 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, pdata->irq_pin, pdata->reset_pin); return 0; - -err_remove_attrs: - sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group); -err_free_irq: - free_irq(client->irq, tsdata); -err_free_mem: - input_free_device(input); - kfree(tsdata); - - if (gpio_is_valid(pdata->irq_pin)) - gpio_free(pdata->irq_pin); - - return error; } static int edt_ft5x06_ts_remove(struct i2c_client *client) { - const struct edt_ft5x06_platform_data *pdata = - dev_get_platdata(&client->dev); struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client); edt_ft5x06_ts_teardown_debugfs(tsdata); sysfs_remove_group(&client->dev.kobj, &edt_ft5x06_attr_group); - free_irq(client->irq, tsdata); - input_unregister_device(tsdata->input); - - if (gpio_is_valid(pdata->irq_pin)) - gpio_free(pdata->irq_pin); - if (gpio_is_valid(pdata->reset_pin)) - gpio_free(pdata->reset_pin); - - kfree(tsdata); - return 0; } diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 1ce3d29ffca5..b1884ddd7a84 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c @@ -157,7 +157,7 @@ static void eeti_ts_close(struct input_dev *dev) static int eeti_ts_probe(struct i2c_client *client, const struct i2c_device_id *idp) { - struct eeti_ts_platform_data *pdata = client->dev.platform_data; + struct eeti_ts_platform_data *pdata = dev_get_platdata(&client->dev); struct eeti_ts_priv *priv; struct input_dev *input; unsigned int irq_flags; diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index 054d22583248..e6bcb13680b2 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c @@ -18,7 +18,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/input.h> diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 957423d1471d..8051a4b704ea 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c @@ -22,7 +22,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #include <linux/ctype.h> #define DRIVER_DESC "Elo serial touchscreen driver" diff --git a/drivers/input/touchscreen/fujitsu_ts.c b/drivers/input/touchscreen/fujitsu_ts.c index 10794ddbdf58..d0e46a7e183b 100644 --- a/drivers/input/touchscreen/fujitsu_ts.c +++ b/drivers/input/touchscreen/fujitsu_ts.c @@ -16,7 +16,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Fujitsu serial touchscreen driver" diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index 41c71766bf18..e2ee62615273 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c @@ -32,7 +32,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Gunze AHL-51S touchscreen driver" diff --git a/drivers/input/touchscreen/hampshire.c b/drivers/input/touchscreen/hampshire.c index 0cc47ea98acf..ecb1e0e01328 100644 --- a/drivers/input/touchscreen/hampshire.c +++ b/drivers/input/touchscreen/hampshire.c @@ -23,7 +23,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Hampshire serial touchscreen driver" diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 1418bdda61bb..2a5089139818 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -184,7 +184,7 @@ static int ili210x_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; - const struct ili210x_platform_data *pdata = dev->platform_data; + const struct ili210x_platform_data *pdata = dev_get_platdata(dev); struct ili210x *priv; struct input_dev *input; struct panel_info panel; diff --git a/drivers/input/touchscreen/inexio.c b/drivers/input/touchscreen/inexio.c index a29c99c32245..adb80b65a259 100644 --- a/drivers/input/touchscreen/inexio.c +++ b/drivers/input/touchscreen/inexio.c @@ -23,7 +23,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "iNexio serial touchscreen driver" diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c index e30d837dae2f..4f6b156144e9 100644 --- a/drivers/input/touchscreen/intel-mid-touch.c +++ b/drivers/input/touchscreen/intel-mid-touch.c @@ -27,7 +27,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/err.h> diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c index e463a79ffecc..7324c5c0fb86 100644 --- a/drivers/input/touchscreen/jornada720_ts.c +++ b/drivers/input/touchscreen/jornada720_ts.c @@ -14,7 +14,6 @@ */ #include <linux/platform_device.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/module.h> diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c index 9101ee529c92..2058253b55d9 100644 --- a/drivers/input/touchscreen/lpc32xx_ts.c +++ b/drivers/input/touchscreen/lpc32xx_ts.c @@ -15,7 +15,6 @@ */ #include <linux/platform_device.h> -#include <linux/init.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/module.h> diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index 7d2b2136e5ad..0786010d7ed0 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c @@ -25,7 +25,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/delay.h> #include <linux/irq.h> #include <linux/interrupt.h> diff --git a/drivers/input/touchscreen/max11801_ts.c b/drivers/input/touchscreen/max11801_ts.c index 9f84fcd08732..a68ec142ee9a 100644 --- a/drivers/input/touchscreen/max11801_ts.c +++ b/drivers/input/touchscreen/max11801_ts.c @@ -33,7 +33,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/input.h> diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index f9f4e0c56eda..647e36f5930e 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c @@ -14,7 +14,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/i2c.h> #include <linux/i2c/mcs.h> #include <linux/interrupt.h> @@ -194,7 +193,7 @@ static int mcs5000_ts_probe(struct i2c_client *client, struct input_dev *input_dev; int ret; - if (!client->dev.platform_data) + if (!dev_get_platdata(&client->dev)) return -EINVAL; data = kzalloc(sizeof(struct mcs5000_ts_data), GFP_KERNEL); @@ -207,7 +206,7 @@ static int mcs5000_ts_probe(struct i2c_client *client, data->client = client; data->input_dev = input_dev; - data->platform_data = client->dev.platform_data; + data->platform_data = dev_get_platdata(&client->dev); input_dev->name = "MELPAS MCS-5000 Touchscreen"; input_dev->id.bustype = BUS_I2C; diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 1443532fe6c4..8a598c065391 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -8,7 +8,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/delay.h> #include <linux/of.h> #include <linux/i2c.h> diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index eb66b7c37c2f..9b5552a26169 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c @@ -21,7 +21,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "MicroTouch serial touchscreen driver" diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c index f22e04dd4e16..cff2376817e5 100644 --- a/drivers/input/touchscreen/pcap_ts.c +++ b/drivers/input/touchscreen/pcap_ts.c @@ -11,7 +11,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/fs.h> #include <linux/string.h> #include <linux/slab.h> diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c index b49f0b836925..417d87379265 100644 --- a/drivers/input/touchscreen/penmount.c +++ b/drivers/input/touchscreen/penmount.c @@ -21,7 +21,6 @@ #include <linux/input.h> #include <linux/input/mt.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "PenMount serial touchscreen driver" diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index 6cc6b36663ff..02392d2061d6 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -128,7 +128,8 @@ static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops, static int pixcir_i2c_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct pixcir_ts_platform_data *pdata = client->dev.platform_data; + const struct pixcir_ts_platform_data *pdata = + dev_get_platdata(&client->dev); struct pixcir_i2c_ts_data *tsdata; struct input_dev *input; int error; diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index b061af2c8376..19cb247dbb86 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -28,7 +28,6 @@ #include <linux/module.h> #include <linux/gpio.h> #include <linux/input.h> -#include <linux/init.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/platform_device.h> @@ -251,7 +250,7 @@ static int s3c2410ts_probe(struct platform_device *pdev) ts.dev = dev; - info = pdev->dev.platform_data; + info = dev_get_platdata(&pdev->dev); if (!info) { dev_err(dev, "no platform data, cannot attach\n"); return -EINVAL; @@ -392,7 +391,7 @@ static int s3c2410ts_suspend(struct device *dev) static int s3c2410ts_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); - struct s3c2410_ts_mach_info *info = pdev->dev.platform_data; + struct s3c2410_ts_mach_info *info = dev_get_platdata(&pdev->dev); clk_enable(ts.clock); enable_irq(ts.irq_tc); diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 2f03b2f289dd..5c342b3139e8 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -154,7 +154,7 @@ static int st1232_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct st1232_ts_data *ts; - struct st1232_pdata *pdata = client->dev.platform_data; + struct st1232_pdata *pdata = dev_get_platdata(&client->dev); struct input_dev *input_dev; int error; diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c index 59e81b00f244..42ce31afa259 100644 --- a/drivers/input/touchscreen/stmpe-ts.c +++ b/drivers/input/touchscreen/stmpe-ts.c @@ -15,7 +15,6 @@ #include <linux/module.h> #include <linux/sched.h> #include <linux/interrupt.h> -#include <linux/init.h> #include <linux/device.h> #include <linux/of.h> #include <linux/platform_device.h> diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index 68beadaabceb..4e793a17361f 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c @@ -14,7 +14,6 @@ */ -#include <linux/init.h> #include <linux/kernel.h> #include <linux/err.h> #include <linux/module.h> @@ -198,7 +197,7 @@ static void titsc_step_config(struct titsc *ts_dev) /* The steps1 … end and bit 0 for TS_Charge */ stepenable = (1 << (end_step + 2)) - 1; ts_dev->step_mask = stepenable; - am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask); + am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask); } static void titsc_read_coordinates(struct titsc *ts_dev, @@ -322,7 +321,7 @@ static irqreturn_t titsc_irq(int irq, void *dev) if (irqclr) { titsc_writel(ts_dev, REG_IRQSTATUS, irqclr); - am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask); + am335x_tsc_se_set_cache(ts_dev->mfd_tscadc, ts_dev->step_mask); return IRQ_HANDLED; } return IRQ_NONE; diff --git a/drivers/input/touchscreen/touchit213.c b/drivers/input/touchscreen/touchit213.c index 5f29e5b8e1c1..c27cf8f3d1ca 100644 --- a/drivers/input/touchscreen/touchit213.c +++ b/drivers/input/touchscreen/touchit213.c @@ -21,7 +21,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Sahara TouchIT-213 serial touchscreen driver" diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c index 8a2887daf194..4000e5205407 100644 --- a/drivers/input/touchscreen/touchright.c +++ b/drivers/input/touchscreen/touchright.c @@ -20,7 +20,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Touchright serial touchscreen driver" diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c index 588cdcb839dd..ba90f447df75 100644 --- a/drivers/input/touchscreen/touchwin.c +++ b/drivers/input/touchscreen/touchwin.c @@ -27,7 +27,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define DRIVER_DESC "Touchwindow serial touchscreen driver" diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 811353353917..550adcbbfc23 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c @@ -571,7 +571,7 @@ static void tsc2005_setup_spi_xfer(struct tsc2005 *ts) static int tsc2005_probe(struct spi_device *spi) { - const struct tsc2005_platform_data *pdata = spi->dev.platform_data; + const struct tsc2005_platform_data *pdata = dev_get_platdata(&spi->dev); struct tsc2005 *ts; struct input_dev *input_dev; unsigned int max_x, max_y, max_p; diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 0b67ba476b4c..1bf9906b5a3f 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c @@ -26,6 +26,9 @@ #include <linux/interrupt.h> #include <linux/i2c.h> #include <linux/i2c/tsc2007.h> +#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/of_gpio.h> #define TSC2007_MEASURE_TEMP0 (0x0 << 4) #define TSC2007_MEASURE_AUX (0x2 << 4) @@ -72,15 +75,18 @@ struct tsc2007 { u16 model; u16 x_plate_ohms; u16 max_rt; - unsigned long poll_delay; unsigned long poll_period; + int fuzzx; + int fuzzy; + int fuzzz; + unsigned gpio; int irq; wait_queue_head_t wait; bool stopped; - int (*get_pendown_state)(void); + int (*get_pendown_state)(struct device *); void (*clear_penirq)(void); }; @@ -161,7 +167,7 @@ static bool tsc2007_is_pen_down(struct tsc2007 *ts) if (!ts->get_pendown_state) return true; - return ts->get_pendown_state(); + return ts->get_pendown_state(&ts->client->dev); } static irqreturn_t tsc2007_soft_irq(int irq, void *handle) @@ -178,7 +184,7 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle) rt = tsc2007_calculate_pressure(ts, &tc); - if (rt == 0 && !ts->get_pendown_state) { + if (!rt && !ts->get_pendown_state) { /* * If pressure reported is 0 and we don't have * callback to check pendown state, we have to @@ -228,7 +234,7 @@ static irqreturn_t tsc2007_hard_irq(int irq, void *handle) { struct tsc2007 *ts = handle; - if (!ts->get_pendown_state || likely(ts->get_pendown_state())) + if (tsc2007_is_pen_down(ts)) return IRQ_WAKE_THREAD; if (ts->clear_penirq) @@ -273,49 +279,134 @@ static void tsc2007_close(struct input_dev *input_dev) tsc2007_stop(ts); } -static int tsc2007_probe(struct i2c_client *client, - const struct i2c_device_id *id) +#ifdef CONFIG_OF +static int tsc2007_get_pendown_state_gpio(struct device *dev) { - struct tsc2007 *ts; - struct tsc2007_platform_data *pdata = client->dev.platform_data; - struct input_dev *input_dev; - int err; + struct i2c_client *client = to_i2c_client(dev); + struct tsc2007 *ts = i2c_get_clientdata(client); + + return !gpio_get_value(ts->gpio); +} + +static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts) +{ + struct device_node *np = client->dev.of_node; + u32 val32; + u64 val64; - if (!pdata) { - dev_err(&client->dev, "platform data is required!\n"); + if (!np) { + dev_err(&client->dev, "missing device tree data\n"); return -EINVAL; } - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_WORD_DATA)) - return -EIO; + if (!of_property_read_u32(np, "ti,max-rt", &val32)) + ts->max_rt = val32; + else + ts->max_rt = MAX_12BIT; + + if (!of_property_read_u32(np, "ti,fuzzx", &val32)) + ts->fuzzx = val32; + + if (!of_property_read_u32(np, "ti,fuzzy", &val32)) + ts->fuzzy = val32; + + if (!of_property_read_u32(np, "ti,fuzzz", &val32)) + ts->fuzzz = val32; + + if (!of_property_read_u64(np, "ti,poll-period", &val64)) + ts->poll_period = val64; + else + ts->poll_period = 1; - ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!ts || !input_dev) { - err = -ENOMEM; - goto err_free_mem; + if (!of_property_read_u32(np, "ti,x-plate-ohms", &val32)) { + ts->x_plate_ohms = val32; + } else { + dev_err(&client->dev, "missing ti,x-plate-ohms devicetree property."); + return -EINVAL; } - ts->client = client; - ts->irq = client->irq; - ts->input = input_dev; - init_waitqueue_head(&ts->wait); + ts->gpio = of_get_gpio(np, 0); + if (gpio_is_valid(ts->gpio)) + ts->get_pendown_state = tsc2007_get_pendown_state_gpio; + else + dev_warn(&client->dev, + "GPIO not specified in DT (of_get_gpio returned %d)\n", + ts->gpio); + + return 0; +} +#else +static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts) +{ + dev_err(&client->dev, "platform data is required!\n"); + return -EINVAL; +} +#endif +static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts, + const struct tsc2007_platform_data *pdata, + const struct i2c_device_id *id) +{ ts->model = pdata->model; ts->x_plate_ohms = pdata->x_plate_ohms; ts->max_rt = pdata->max_rt ? : MAX_12BIT; - ts->poll_delay = pdata->poll_delay ? : 1; ts->poll_period = pdata->poll_period ? : 1; ts->get_pendown_state = pdata->get_pendown_state; ts->clear_penirq = pdata->clear_penirq; + ts->fuzzx = pdata->fuzzx; + ts->fuzzy = pdata->fuzzy; + ts->fuzzz = pdata->fuzzz; if (pdata->x_plate_ohms == 0) { dev_err(&client->dev, "x_plate_ohms is not set up in platform data"); - err = -EINVAL; - goto err_free_mem; + return -EINVAL; } + return 0; +} + +static void tsc2007_call_exit_platform_hw(void *data) +{ + struct device *dev = data; + const struct tsc2007_platform_data *pdata = dev_get_platdata(dev); + + pdata->exit_platform_hw(); +} + +static int tsc2007_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev); + struct tsc2007 *ts; + struct input_dev *input_dev; + int err; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) + return -EIO; + + ts = devm_kzalloc(&client->dev, sizeof(struct tsc2007), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + if (pdata) + err = tsc2007_probe_pdev(client, ts, pdata, id); + else + err = tsc2007_probe_dt(client, ts); + if (err) + return err; + + input_dev = devm_input_allocate_device(&client->dev); + if (!input_dev) + return -ENOMEM; + + i2c_set_clientdata(client, ts); + + ts->client = client; + ts->irq = client->irq; + ts->input = input_dev; + init_waitqueue_head(&ts->wait); + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&client->dev)); @@ -331,53 +422,46 @@ static int tsc2007_probe(struct i2c_client *client, input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0); - input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0); + input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzx, 0); + input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, - pdata->fuzzz, 0); + ts->fuzzz, 0); + + if (pdata) { + if (pdata->exit_platform_hw) { + err = devm_add_action(&client->dev, + tsc2007_call_exit_platform_hw, + &client->dev); + if (err) { + dev_err(&client->dev, + "Failed to register exit_platform_hw action, %d\n", + err); + return err; + } + } - if (pdata->init_platform_hw) - pdata->init_platform_hw(); + if (pdata->init_platform_hw) + pdata->init_platform_hw(); + } - err = request_threaded_irq(ts->irq, tsc2007_hard_irq, tsc2007_soft_irq, - IRQF_ONESHOT, client->dev.driver->name, ts); - if (err < 0) { - dev_err(&client->dev, "irq %d busy?\n", ts->irq); - goto err_free_mem; + err = devm_request_threaded_irq(&client->dev, ts->irq, + tsc2007_hard_irq, tsc2007_soft_irq, + IRQF_ONESHOT, + client->dev.driver->name, ts); + if (err) { + dev_err(&client->dev, "Failed to request irq %d: %d\n", + ts->irq, err); + return err; } tsc2007_stop(ts); err = input_register_device(input_dev); - if (err) - goto err_free_irq; - - i2c_set_clientdata(client, ts); - - return 0; - - err_free_irq: - free_irq(ts->irq, ts); - if (pdata->exit_platform_hw) - pdata->exit_platform_hw(); - err_free_mem: - input_free_device(input_dev); - kfree(ts); - return err; -} - -static int tsc2007_remove(struct i2c_client *client) -{ - struct tsc2007 *ts = i2c_get_clientdata(client); - struct tsc2007_platform_data *pdata = client->dev.platform_data; - - free_irq(ts->irq, ts); - - if (pdata->exit_platform_hw) - pdata->exit_platform_hw(); - - input_unregister_device(ts->input); - kfree(ts); + if (err) { + dev_err(&client->dev, + "Failed to register input device: %d\n", err); + return err; + } return 0; } @@ -389,14 +473,22 @@ static const struct i2c_device_id tsc2007_idtable[] = { MODULE_DEVICE_TABLE(i2c, tsc2007_idtable); +#ifdef CONFIG_OF +static const struct of_device_id tsc2007_of_match[] = { + { .compatible = "ti,tsc2007" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, tsc2007_of_match); +#endif + static struct i2c_driver tsc2007_driver = { .driver = { .owner = THIS_MODULE, - .name = "tsc2007" + .name = "tsc2007", + .of_match_table = of_match_ptr(tsc2007_of_match), }, .id_table = tsc2007_idtable, .probe = tsc2007_probe, - .remove = tsc2007_remove, }; module_i2c_driver(tsc2007_driver); diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c index eb96f168fb9d..29687872cb94 100644 --- a/drivers/input/touchscreen/tsc40.c +++ b/drivers/input/touchscreen/tsc40.c @@ -11,7 +11,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/serio.h> -#include <linux/init.h> #define PACKET_LENGTH 5 struct tsc_ser { diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 1271f97b4079..b46c55cd1bbb 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -19,7 +19,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/delay.h> #include <linux/sched.h> #include <linux/wait.h> @@ -320,7 +319,7 @@ static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb, static int ucb1400_ts_probe(struct platform_device *pdev) { - struct ucb1400_ts *ucb = pdev->dev.platform_data; + struct ucb1400_ts *ucb = dev_get_platdata(&pdev->dev); int error, x_res, y_res; u16 fcsr; @@ -399,7 +398,7 @@ err: static int ucb1400_ts_remove(struct platform_device *pdev) { - struct ucb1400_ts *ucb = pdev->dev.platform_data; + struct ucb1400_ts *ucb = dev_get_platdata(&pdev->dev); free_irq(ucb->irq, ucb); input_unregister_device(ucb->ts_idev); @@ -410,7 +409,7 @@ static int ucb1400_ts_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int ucb1400_ts_suspend(struct device *dev) { - struct ucb1400_ts *ucb = dev->platform_data; + struct ucb1400_ts *ucb = dev_get_platdata(dev); struct input_dev *idev = ucb->ts_idev; mutex_lock(&idev->mutex); @@ -424,7 +423,7 @@ static int ucb1400_ts_suspend(struct device *dev) static int ucb1400_ts_resume(struct device *dev) { - struct ucb1400_ts *ucb = dev->platform_data; + struct ucb1400_ts *ucb = dev_get_platdata(dev); struct input_dev *idev = ucb->ts_idev; mutex_lock(&idev->mutex); diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 5f87bed05467..a0966331a89b 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -51,7 +51,6 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/module.h> -#include <linux/init.h> #include <linux/usb.h> #include <linux/usb/input.h> #include <linux/hid.h> diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 9a83be6b6584..2792ca397dd0 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -18,7 +18,6 @@ #include <linux/slab.h> #include <linux/input/mt.h> #include <linux/serio.h> -#include <linux/init.h> #include <linux/ctype.h> #include <linux/delay.h> diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c index 6be2eb6a153a..1b953a066b2c 100644 --- a/drivers/input/touchscreen/wm831x-ts.c +++ b/drivers/input/touchscreen/wm831x-ts.c @@ -13,7 +13,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/string.h> #include <linux/pm.h> #include <linux/input.h> diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index 7e45c9f6e6b7..d0ef91fc87d1 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c @@ -584,7 +584,7 @@ static void wm97xx_ts_input_close(struct input_dev *idev) static int wm97xx_probe(struct device *dev) { struct wm97xx *wm; - struct wm97xx_pdata *pdata = dev->platform_data; + struct wm97xx_pdata *pdata = dev_get_platdata(dev); int ret = 0, id = 0; wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL); diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c index 75762d6ff3ba..2175f3419002 100644 --- a/drivers/input/touchscreen/zforce_ts.c +++ b/drivers/input/touchscreen/zforce_ts.c @@ -279,7 +279,8 @@ static int zforce_start(struct zforce_ts *ts) goto error; } - if (zforce_setconfig(ts, SETCONFIG_DUALTOUCH)) { + ret = zforce_setconfig(ts, SETCONFIG_DUALTOUCH); + if (ret) { dev_err(&client->dev, "Unable to set config\n"); goto error; } @@ -455,7 +456,18 @@ static void zforce_complete(struct zforce_ts *ts, int cmd, int result) } } -static irqreturn_t zforce_interrupt(int irq, void *dev_id) +static irqreturn_t zforce_irq(int irq, void *dev_id) +{ + struct zforce_ts *ts = dev_id; + struct i2c_client *client = ts->client; + + if (ts->suspended && device_may_wakeup(&client->dev)) + pm_wakeup_event(&client->dev, 500); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t zforce_irq_thread(int irq, void *dev_id) { struct zforce_ts *ts = dev_id; struct i2c_client *client = ts->client; @@ -465,12 +477,10 @@ static irqreturn_t zforce_interrupt(int irq, void *dev_id) u8 *payload; /* - * When suspended, emit a wakeup signal if necessary and return. + * When still suspended, return. * Due to the level-interrupt we will get re-triggered later. */ if (ts->suspended) { - if (device_may_wakeup(&client->dev)) - pm_wakeup_event(&client->dev, 500); msleep(20); return IRQ_HANDLED; } @@ -763,8 +773,8 @@ static int zforce_probe(struct i2c_client *client, * Therefore we can trigger the interrupt anytime it is low and do * not need to limit it to the interrupt edge. */ - ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, - zforce_interrupt, + ret = devm_request_threaded_irq(&client->dev, client->irq, + zforce_irq, zforce_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT, input_dev->name, ts); if (ret) { diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c index bf0869a7a78e..e2ccd683de6e 100644 --- a/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/drivers/input/touchscreen/zylonite-wm97xx.c @@ -20,7 +20,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/delay.h> #include <linux/gpio.h> #include <linux/irq.h> |