diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-10 10:55:52 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-10 10:55:52 -0800 |
commit | dbe950f201a8edd353b0bd9079e8d536ee4ce37c (patch) | |
tree | dffbada6b3d33cc67383758570de22b4f45693b6 /drivers/input/misc | |
parent | f62f61917d72c1fb0101ad405664f6fc868d676b (diff) | |
parent | da733563be5a9da26fe81d9f007262d00b846e22 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (64 commits)
Input: tc3589x-keypad - add missing kerneldoc
Input: ucb1400-ts - switch to using dev_xxx() for diagnostic messages
Input: ucb1400_ts - convert to threaded IRQ
Input: ucb1400_ts - drop inline annotations
Input: usb1400_ts - add __devinit/__devexit section annotations
Input: ucb1400_ts - set driver owner
Input: ucb1400_ts - convert to use dev_pm_ops
Input: psmouse - make sure we do not use stale methods
Input: evdev - do not block waiting for an event if fd is nonblock
Input: evdev - if no events and non-block, return EAGAIN not 0
Input: evdev - only allow reading events if a full packet is present
Input: add driver for pixcir i2c touchscreens
Input: samsung-keypad - implement runtime power management support
Input: tegra-kbc - report wakeup key for some platforms
Input: tegra-kbc - add device tree bindings
Input: add driver for AUO In-Cell touchscreens using pixcir ICs
Input: mpu3050 - configure the sampling method
Input: mpu3050 - ensure we enable interrupts
Input: mpu3050 - add of_match table for device-tree probing
Input: sentelic - document the latest hardware
...
Fix up fairly trivial conflicts (device tree matching conflicting with
some independent cleanups) in drivers/input/keyboard/samsung-keypad.c
Diffstat (limited to 'drivers/input/misc')
29 files changed, 703 insertions, 282 deletions
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c index 3dca3c14510e..f2e0cbc5ab64 100644 --- a/drivers/input/misc/88pm860x_onkey.c +++ b/drivers/input/misc/88pm860x_onkey.c @@ -137,18 +137,7 @@ static struct platform_driver pm860x_onkey_driver = { .probe = pm860x_onkey_probe, .remove = __devexit_p(pm860x_onkey_remove), }; - -static int __init pm860x_onkey_init(void) -{ - return platform_driver_register(&pm860x_onkey_driver); -} -module_init(pm860x_onkey_init); - -static void __exit pm860x_onkey_exit(void) -{ - platform_driver_unregister(&pm860x_onkey_driver); -} -module_exit(pm860x_onkey_exit); +module_platform_driver(pm860x_onkey_driver); MODULE_DESCRIPTION("Marvell 88PM860x ONKEY driver"); MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 22d875fde53a..7b46781c30c9 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -179,6 +179,31 @@ config INPUT_APANEL To compile this driver as a module, choose M here: the module will be called apanel. +config INPUT_GP2A + tristate "Sharp GP2AP002A00F I2C Proximity/Opto sensor driver" + depends on I2C + depends on GENERIC_GPIO + help + Say Y here if you have a Sharp GP2AP002A00F proximity/als combo-chip + hooked to an I2C bus. + + To compile this driver as a module, choose M here: the + module will be called gp2ap002a00f. + +config INPUT_GPIO_TILT_POLLED + tristate "Polled GPIO tilt switch" + depends on GENERIC_GPIO + select INPUT_POLLDEV + help + This driver implements support for tilt switches connected + to GPIO pins that are not capable of generating interrupts. + + The list of gpios to use and the mapping of their states + to specific angles is done via platform data. + + To compile this driver as a module, choose M here: the + module will be called gpio_tilt_polled. + config INPUT_IXP4XX_BEEPER tristate "IXP4XX Beeper support" depends on ARCH_IXP4XX diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index a244fc6a781c..46671a875b91 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -22,6 +22,8 @@ obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o +obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o +obj-$(CONFIG_INPUT_GPIO_TILT_POLLED) += gpio_tilt_polled.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index 3d3288a78fdc..79d901633635 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c @@ -139,18 +139,7 @@ static struct platform_driver ab8500_ponkey_driver = { .probe = ab8500_ponkey_probe, .remove = __devexit_p(ab8500_ponkey_remove), }; - -static int __init ab8500_ponkey_init(void) -{ - return platform_driver_register(&ab8500_ponkey_driver); -} -module_init(ab8500_ponkey_init); - -static void __exit ab8500_ponkey_exit(void) -{ - platform_driver_unregister(&ab8500_ponkey_driver); -} -module_exit(ab8500_ponkey_exit); +module_platform_driver(ab8500_ponkey_driver); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>"); diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c index f29de22fdda0..34d401efd4a1 100644 --- a/drivers/input/misc/adxl34x-spi.c +++ b/drivers/input/misc/adxl34x-spi.c @@ -122,7 +122,6 @@ static SIMPLE_DEV_PM_OPS(adxl34x_spi_pm, adxl34x_spi_suspend, static struct spi_driver adxl34x_driver = { .driver = { .name = "adxl34x", - .bus = &spi_bus_type, .owner = THIS_MODULE, .pm = &adxl34x_spi_pm, }, diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index 09244804fb97..1cf72fe513e6 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -452,10 +452,10 @@ static ssize_t adxl34x_disable_store(struct device *dev, const char *buf, size_t count) { struct adxl34x *ac = dev_get_drvdata(dev); - unsigned long val; + unsigned int val; int error; - error = strict_strtoul(buf, 10, &val); + error = kstrtouint(buf, 10, &val); if (error) return error; @@ -541,10 +541,10 @@ static ssize_t adxl34x_rate_store(struct device *dev, const char *buf, size_t count) { struct adxl34x *ac = dev_get_drvdata(dev); - unsigned long val; + unsigned char val; int error; - error = strict_strtoul(buf, 10, &val); + error = kstrtou8(buf, 10, &val); if (error) return error; @@ -576,10 +576,10 @@ static ssize_t adxl34x_autosleep_store(struct device *dev, const char *buf, size_t count) { struct adxl34x *ac = dev_get_drvdata(dev); - unsigned long val; + unsigned int val; int error; - error = strict_strtoul(buf, 10, &val); + error = kstrtouint(buf, 10, &val); if (error) return error; @@ -623,13 +623,13 @@ static ssize_t adxl34x_write_store(struct device *dev, const char *buf, size_t count) { struct adxl34x *ac = dev_get_drvdata(dev); - unsigned long val; + unsigned int val; int error; /* * This allows basic ADXL register write access for debug purposes. */ - error = strict_strtoul(buf, 16, &val); + error = kstrtouint(buf, 16, &val); if (error) return error; diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 874a51c2fbb2..f63341f20b91 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -42,13 +42,13 @@ static int ati_remote2_set_mask(const char *val, const struct kernel_param *kp, unsigned int max) { - unsigned long mask; + unsigned int mask; int ret; if (!val) return -EINVAL; - ret = strict_strtoul(val, 0, &mask); + ret = kstrtouint(val, 0, &mask); if (ret) return ret; @@ -720,11 +720,12 @@ static ssize_t ati_remote2_store_channel_mask(struct device *dev, struct usb_device *udev = to_usb_device(dev); struct usb_interface *intf = usb_ifnum_to_if(udev, 0); struct ati_remote2 *ar2 = usb_get_intfdata(intf); - unsigned long mask; + unsigned int mask; int r; - if (strict_strtoul(buf, 0, &mask)) - return -EINVAL; + r = kstrtouint(buf, 0, &mask); + if (r) + return r; if (mask & ~ATI_REMOTE2_MAX_CHANNEL_MASK) return -EINVAL; @@ -769,10 +770,12 @@ static ssize_t ati_remote2_store_mode_mask(struct device *dev, struct usb_device *udev = to_usb_device(dev); struct usb_interface *intf = usb_ifnum_to_if(udev, 0); struct ati_remote2 *ar2 = usb_get_intfdata(intf); - unsigned long mask; + unsigned int mask; + int err; - if (strict_strtoul(buf, 0, &mask)) - return -EINVAL; + err = kstrtouint(buf, 0, &mask); + if (err) + return err; if (mask & ~ATI_REMOTE2_MAX_MODE_MASK) return -EINVAL; diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index d00edc9f39d1..1c4146fccfdf 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c @@ -264,18 +264,7 @@ static struct platform_driver bfin_rotary_device_driver = { #endif }, }; - -static int __init bfin_rotary_init(void) -{ - return platform_driver_register(&bfin_rotary_device_driver); -} -module_init(bfin_rotary_init); - -static void __exit bfin_rotary_exit(void) -{ - platform_driver_unregister(&bfin_rotary_device_driver); -} -module_exit(bfin_rotary_exit); +module_platform_driver(bfin_rotary_device_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index fd8407a29631..53e43d295148 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c @@ -163,16 +163,4 @@ static struct platform_driver cobalt_buttons_driver = { .owner = THIS_MODULE, }, }; - -static int __init cobalt_buttons_init(void) -{ - return platform_driver_register(&cobalt_buttons_driver); -} - -static void __exit cobalt_buttons_exit(void) -{ - platform_driver_unregister(&cobalt_buttons_driver); -} - -module_init(cobalt_buttons_init); -module_exit(cobalt_buttons_exit); +module_platform_driver(cobalt_buttons_driver); diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c index 7283dd2a1ad3..35083c6836c3 100644 --- a/drivers/input/misc/dm355evm_keys.c +++ b/drivers/input/misc/dm355evm_keys.c @@ -267,17 +267,6 @@ static struct platform_driver dm355evm_keys_driver = { .name = "dm355evm_keys", }, }; - -static int __init dm355evm_keys_init(void) -{ - return platform_driver_register(&dm355evm_keys_driver); -} -module_init(dm355evm_keys_init); - -static void __exit dm355evm_keys_exit(void) -{ - platform_driver_unregister(&dm355evm_keys_driver); -} -module_exit(dm355evm_keys_exit); +module_platform_driver(dm355evm_keys_driver); MODULE_LICENSE("GPL"); diff --git a/drivers/input/misc/gp2ap002a00f.c b/drivers/input/misc/gp2ap002a00f.c new file mode 100644 index 000000000000..71fba8c2fc66 --- /dev/null +++ b/drivers/input/misc/gp2ap002a00f.c @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2011 Sony Ericsson Mobile Communications Inc. + * + * Author: Courtney Cavin <courtney.cavin@sonyericsson.com> + * Prepared for up-stream by: Oskar Andero <oskar.andero@sonyericsson.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + */ + +#include <linux/i2c.h> +#include <linux/irq.h> +#include <linux/slab.h> +#include <linux/input.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/input/gp2ap002a00f.h> + +struct gp2a_data { + struct input_dev *input; + const struct gp2a_platform_data *pdata; + struct i2c_client *i2c_client; +}; + +enum gp2a_addr { + GP2A_ADDR_PROX = 0x0, + GP2A_ADDR_GAIN = 0x1, + GP2A_ADDR_HYS = 0x2, + GP2A_ADDR_CYCLE = 0x3, + GP2A_ADDR_OPMOD = 0x4, + GP2A_ADDR_CON = 0x6 +}; + +enum gp2a_controls { + /* Software Shutdown control: 0 = shutdown, 1 = normal operation */ + GP2A_CTRL_SSD = 0x01 +}; + +static int gp2a_report(struct gp2a_data *dt) +{ + int vo = gpio_get_value(dt->pdata->vout_gpio); + + input_report_switch(dt->input, SW_FRONT_PROXIMITY, !vo); + input_sync(dt->input); + + return 0; +} + +static irqreturn_t gp2a_irq(int irq, void *handle) +{ + struct gp2a_data *dt = handle; + + gp2a_report(dt); + + return IRQ_HANDLED; +} + +static int gp2a_enable(struct gp2a_data *dt) +{ + return i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_OPMOD, + GP2A_CTRL_SSD); +} + +static int gp2a_disable(struct gp2a_data *dt) +{ + return i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_OPMOD, + 0x00); +} + +static int gp2a_device_open(struct input_dev *dev) +{ + struct gp2a_data *dt = input_get_drvdata(dev); + int error; + + error = gp2a_enable(dt); + if (error < 0) { + dev_err(&dt->i2c_client->dev, + "unable to activate, err %d\n", error); + return error; + } + + gp2a_report(dt); + + return 0; +} + +static void gp2a_device_close(struct input_dev *dev) +{ + struct gp2a_data *dt = input_get_drvdata(dev); + int error; + + error = gp2a_disable(dt); + if (error < 0) + dev_err(&dt->i2c_client->dev, + "unable to deactivate, err %d\n", error); +} + +static int __devinit gp2a_initialize(struct gp2a_data *dt) +{ + int error; + + error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_GAIN, + 0x08); + if (error < 0) + return error; + + error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_HYS, + 0xc2); + if (error < 0) + return error; + + error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_CYCLE, + 0x04); + if (error < 0) + return error; + + error = gp2a_disable(dt); + + return error; +} + +static int __devinit gp2a_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + const struct gp2a_platform_data *pdata = client->dev.platform_data; + struct gp2a_data *dt; + int error; + + if (!pdata) + return -EINVAL; + + if (pdata->hw_setup) { + error = pdata->hw_setup(client); + if (error < 0) + return error; + } + + error = gpio_request_one(pdata->vout_gpio, GPIOF_IN, GP2A_I2C_NAME); + if (error) + goto err_hw_shutdown; + + dt = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL); + if (!dt) { + error = -ENOMEM; + goto err_free_gpio; + } + + dt->pdata = pdata; + dt->i2c_client = client; + + error = gp2a_initialize(dt); + if (error < 0) + goto err_free_mem; + + dt->input = input_allocate_device(); + if (!dt->input) { + error = -ENOMEM; + goto err_free_mem; + } + + input_set_drvdata(dt->input, dt); + + dt->input->open = gp2a_device_open; + dt->input->close = gp2a_device_close; + dt->input->name = GP2A_I2C_NAME; + dt->input->id.bustype = BUS_I2C; + dt->input->dev.parent = &client->dev; + + input_set_capability(dt->input, EV_SW, SW_FRONT_PROXIMITY); + + error = request_threaded_irq(client->irq, NULL, gp2a_irq, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + GP2A_I2C_NAME, dt); + if (error) { + dev_err(&client->dev, "irq request failed\n"); + goto err_free_input_dev; + } + + error = input_register_device(dt->input); + if (error) { + dev_err(&client->dev, "device registration failed\n"); + goto err_free_irq; + } + + device_init_wakeup(&client->dev, pdata->wakeup); + i2c_set_clientdata(client, dt); + + return 0; + +err_free_irq: + free_irq(client->irq, dt); +err_free_input_dev: + input_free_device(dt->input); +err_free_mem: + kfree(dt); +err_free_gpio: + gpio_free(pdata->vout_gpio); +err_hw_shutdown: + if (pdata->hw_shutdown) + pdata->hw_shutdown(client); + return error; +} + +static int __devexit gp2a_remove(struct i2c_client *client) +{ + struct gp2a_data *dt = i2c_get_clientdata(client); + const struct gp2a_platform_data *pdata = dt->pdata; + + device_init_wakeup(&client->dev, false); + + free_irq(client->irq, dt); + + input_unregister_device(dt->input); + kfree(dt); + + gpio_free(pdata->vout_gpio); + + if (pdata->hw_shutdown) + pdata->hw_shutdown(client); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int gp2a_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct gp2a_data *dt = i2c_get_clientdata(client); + int retval = 0; + + if (device_may_wakeup(&client->dev)) { + enable_irq_wake(client->irq); + } else { + mutex_lock(&dt->input->mutex); + if (dt->input->users) + retval = gp2a_disable(dt); + mutex_unlock(&dt->input->mutex); + } + + return retval; +} + +static int gp2a_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct gp2a_data *dt = i2c_get_clientdata(client); + int retval = 0; + + if (device_may_wakeup(&client->dev)) { + disable_irq_wake(client->irq); + } else { + mutex_lock(&dt->input->mutex); + if (dt->input->users) + retval = gp2a_enable(dt); + mutex_unlock(&dt->input->mutex); + } + + return retval; +} +#endif + +static SIMPLE_DEV_PM_OPS(gp2a_pm, gp2a_suspend, gp2a_resume); + +static const struct i2c_device_id gp2a_i2c_id[] = { + { GP2A_I2C_NAME, 0 }, + { } +}; + +static struct i2c_driver gp2a_i2c_driver = { + .driver = { + .name = GP2A_I2C_NAME, + .owner = THIS_MODULE, + .pm = &gp2a_pm, + }, + .probe = gp2a_probe, + .remove = __devexit_p(gp2a_remove), + .id_table = gp2a_i2c_id, +}; + +static int __init gp2a_init(void) +{ + return i2c_add_driver(&gp2a_i2c_driver); +} + +static void __exit gp2a_exit(void) +{ + i2c_del_driver(&gp2a_i2c_driver); +} + +module_init(gp2a_init); +module_exit(gp2a_exit); + +MODULE_AUTHOR("Courtney Cavin <courtney.cavin@sonyericsson.com>"); +MODULE_DESCRIPTION("Sharp GP2AP002A00F I2C Proximity/Opto sensor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/misc/gpio_tilt_polled.c b/drivers/input/misc/gpio_tilt_polled.c new file mode 100644 index 000000000000..277a0574c199 --- /dev/null +++ b/drivers/input/misc/gpio_tilt_polled.c @@ -0,0 +1,213 @@ +/* + * Driver for tilt switches connected via GPIO lines + * not capable of generating interrupts + * + * Copyright (C) 2011 Heiko Stuebner <heiko@sntech.de> + * + * based on: drivers/input/keyboard/gpio_keys_polled.c + * + * Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/input.h> +#include <linux/input-polldev.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/input/gpio_tilt.h> + +#define DRV_NAME "gpio-tilt-polled" + +struct gpio_tilt_polled_dev { + struct input_polled_dev *poll_dev; + struct device *dev; + const struct gpio_tilt_platform_data *pdata; + + int last_state; + + int threshold; + int count; +}; + +static void gpio_tilt_polled_poll(struct input_polled_dev *dev) +{ + struct gpio_tilt_polled_dev *tdev = dev->private; + const struct gpio_tilt_platform_data *pdata = tdev->pdata; + struct input_dev *input = dev->input; + struct gpio_tilt_state *tilt_state = NULL; + int state, i; + + if (tdev->count < tdev->threshold) { + tdev->count++; + } else { + state = 0; + for (i = 0; i < pdata->nr_gpios; i++) + state |= (!!gpio_get_value(pdata->gpios[i].gpio) << i); + + if (state != tdev->last_state) { + for (i = 0; i < pdata->nr_states; i++) + if (pdata->states[i].gpios == state) + tilt_state = &pdata->states[i]; + + if (tilt_state) { + for (i = 0; i < pdata->nr_axes; i++) + input_report_abs(input, + pdata->axes[i].axis, + tilt_state->axes[i]); + + input_sync(input); + } + + tdev->count = 0; + tdev->last_state = state; + } + } +} + +static void gpio_tilt_polled_open(struct input_polled_dev *dev) +{ + struct gpio_tilt_polled_dev *tdev = dev->private; + const struct gpio_tilt_platform_data *pdata = tdev->pdata; + + if (pdata->enable) + pdata->enable(tdev->dev); + + /* report initial state of the axes */ + tdev->last_state = -1; + tdev->count = tdev->threshold; + gpio_tilt_polled_poll(tdev->poll_dev); +} + +static void gpio_tilt_polled_close(struct input_polled_dev *dev) +{ + struct gpio_tilt_polled_dev *tdev = dev->private; + const struct gpio_tilt_platform_data *pdata = tdev->pdata; + + if (pdata->disable) + pdata->disable(tdev->dev); +} + +static int __devinit gpio_tilt_polled_probe(struct platform_device *pdev) +{ + const struct gpio_tilt_platform_data *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + struct gpio_tilt_polled_dev *tdev; + struct input_polled_dev *poll_dev; + struct input_dev *input; + int error, i; + + if (!pdata || !pdata->poll_interval) + return -EINVAL; + + tdev = kzalloc(sizeof(struct gpio_tilt_polled_dev), GFP_KERNEL); + if (!tdev) { + dev_err(dev, "no memory for private data\n"); + return -ENOMEM; + } + + error = gpio_request_array(pdata->gpios, pdata->nr_gpios); + if (error) { + dev_err(dev, + "Could not request tilt GPIOs: %d\n", error); + goto err_free_tdev; + } + + poll_dev = input_allocate_polled_device(); + if (!poll_dev) { + dev_err(dev, "no memory for polled device\n"); + error = -ENOMEM; + goto err_free_gpios; + } + + poll_dev->private = tdev; + poll_dev->poll = gpio_tilt_polled_poll; + poll_dev->poll_interval = pdata->poll_interval; + poll_dev->open = gpio_tilt_polled_open; + poll_dev->close = gpio_tilt_polled_close; + + input = poll_dev->input; + + input->name = pdev->name; + input->phys = DRV_NAME"/input0"; + input->dev.parent = &pdev->dev; + + input->id.bustype = BUS_HOST; + input->id.vendor = 0x0001; + input->id.product = 0x0001; + input->id.version = 0x0100; + + __set_bit(EV_ABS, input->evbit); + for (i = 0; i < pdata->nr_axes; i++) + input_set_abs_params(input, pdata->axes[i].axis, + pdata->axes[i].min, pdata->axes[i].max, + pdata->axes[i].fuzz, pdata->axes[i].flat); + + tdev->threshold = DIV_ROUND_UP(pdata->debounce_interval, + pdata->poll_interval); + + tdev->poll_dev = poll_dev; + tdev->dev = dev; + tdev->pdata = pdata; + + error = input_register_polled_device(poll_dev); + if (error) { + dev_err(dev, "unable to register polled device, err=%d\n", + error); + goto err_free_polldev; + } + + platform_set_drvdata(pdev, tdev); + + return 0; + +err_free_polldev: + input_free_polled_device(poll_dev); +err_free_gpios: + gpio_free_array(pdata->gpios, pdata->nr_gpios); +err_free_tdev: + kfree(tdev); + + return error; +} + +static int __devexit gpio_tilt_polled_remove(struct platform_device *pdev) +{ + struct gpio_tilt_polled_dev *tdev = platform_get_drvdata(pdev); + const struct gpio_tilt_platform_data *pdata = tdev->pdata; + + platform_set_drvdata(pdev, NULL); + + input_unregister_polled_device(tdev->poll_dev); + input_free_polled_device(tdev->poll_dev); + + gpio_free_array(pdata->gpios, pdata->nr_gpios); + + kfree(tdev); + + return 0; +} + +static struct platform_driver gpio_tilt_polled_driver = { + .probe = gpio_tilt_polled_probe, + .remove = __devexit_p(gpio_tilt_polled_remove), + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(gpio_tilt_polled_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); +MODULE_DESCRIPTION("Polled GPIO tilt driver"); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c index 302ab46ce752..50e283068301 100644 --- a/drivers/input/misc/ixp4xx-beeper.c +++ b/drivers/input/misc/ixp4xx-beeper.c @@ -168,16 +168,5 @@ static struct platform_driver ixp4xx_spkr_platform_driver = { .remove = __devexit_p(ixp4xx_spkr_remove), .shutdown = ixp4xx_spkr_shutdown, }; +module_platform_driver(ixp4xx_spkr_platform_driver); -static int __init ixp4xx_spkr_init(void) -{ - return platform_driver_register(&ixp4xx_spkr_platform_driver); -} - -static void __exit ixp4xx_spkr_exit(void) -{ - platform_driver_unregister(&ixp4xx_spkr_platform_driver); -} - -module_init(ixp4xx_spkr_init); -module_exit(ixp4xx_spkr_exit); diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c index 7de0ded4ccc3..23cf08271049 100644 --- a/drivers/input/misc/max8925_onkey.c +++ b/drivers/input/misc/max8925_onkey.c @@ -166,18 +166,7 @@ static struct platform_driver max8925_onkey_driver = { .probe = max8925_onkey_probe, .remove = __devexit_p(max8925_onkey_remove), }; - -static int __init max8925_onkey_init(void) -{ - return platform_driver_register(&max8925_onkey_driver); -} -module_init(max8925_onkey_init); - -static void __exit max8925_onkey_exit(void) -{ - platform_driver_unregister(&max8925_onkey_driver); -} -module_exit(max8925_onkey_exit); +module_platform_driver(max8925_onkey_driver); MODULE_DESCRIPTION("Maxim MAX8925 ONKEY driver"); MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c index 09b052288657..8428f1e8e83e 100644 --- a/drivers/input/misc/mc13783-pwrbutton.c +++ b/drivers/input/misc/mc13783-pwrbutton.c @@ -255,7 +255,7 @@ static int __devexit mc13783_pwrbutton_remove(struct |