diff options
Diffstat (limited to 'drivers/input/keyboard')
35 files changed, 355 insertions, 104 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a5d9b3f3c871..a89ba7cb96f1 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -568,6 +568,16 @@ config KEYBOARD_STMPE To compile this driver as a module, choose M here: the module will be called stmpe-keypad. +config KEYBOARD_SUN4I_LRADC + tristate "Allwinner sun4i low res adc attached tablet keys support" + depends on ARCH_SUNXI + help + This selects support for the Allwinner low res adc attached tablet + keys found on Allwinner sunxi SoCs. + + To compile this driver as a module, choose M here: the + module will be called sun4i-lradc-keys. + config KEYBOARD_DAVINCI tristate "TI DaVinci Key Scan" depends on ARCH_DAVINCI_DM365 diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index febafa527eb6..470767884bd8 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -53,6 +53,7 @@ obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o obj-$(CONFIG_KEYBOARD_ST_KEYSCAN) += st-keyscan.o +obj-$(CONFIG_KEYBOARD_SUN4I_LRADC) += sun4i-lradc-keys.o obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c index 7f4a8b58efc1..db1004dad108 100644 --- a/drivers/input/keyboard/adp5520-keys.c +++ b/drivers/input/keyboard/adp5520-keys.c @@ -184,7 +184,6 @@ static int adp5520_keys_remove(struct platform_device *pdev) static struct platform_driver adp5520_keys_driver = { .driver = { .name = "adp5520-keys", - .owner = THIS_MODULE, }, .probe = adp5520_keys_probe, .remove = adp5520_keys_remove, diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 728133ec6d7b..21a62d0fa764 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -251,9 +251,7 @@ static void adp5588_gpio_remove(struct adp5588_kpad *kpad) dev_warn(dev, "teardown failed %d\n", error); } - error = gpiochip_remove(&kpad->gc); - if (error) - dev_warn(dev, "gpiochip_remove failed %d\n", error); + gpiochip_remove(&kpad->gc); } #else static inline int adp5588_gpio_add(struct adp5588_kpad *kpad) diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index 6329549bf6ad..a45267729dfc 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c @@ -567,9 +567,7 @@ static void adp5589_gpio_remove(struct adp5589_kpad *kpad) dev_warn(dev, "teardown failed %d\n", error); } - error = gpiochip_remove(&kpad->gc); - if (error) - dev_warn(dev, "gpiochip_remove failed %d\n", error); + gpiochip_remove(&kpad->gc); } #else static inline int adp5589_gpio_add(struct adp5589_kpad *kpad) diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c index 3196f2d29ade..e04a3b4e55d6 100644 --- a/drivers/input/keyboard/amikbd.c +++ b/drivers/input/keyboard/amikbd.c @@ -268,7 +268,6 @@ static struct platform_driver amikbd_driver = { .remove = __exit_p(amikbd_remove), .driver = { .name = "amiga-keyboard", - .owner = THIS_MODULE, }, }; diff --git a/drivers/input/keyboard/atakbd.c b/drivers/input/keyboard/atakbd.c index 10bcd4ae5402..f1235831283d 100644 --- a/drivers/input/keyboard/atakbd.c +++ b/drivers/input/keyboard/atakbd.c @@ -170,7 +170,7 @@ static unsigned char atakbd_keycode[0x72] = { /* American layout */ [93] = KEY_KPASTERISK, [94] = KEY_KPPLUS, [95] = KEY_HELP, - [96] = KEY_BACKSLASH, /* FIXME: '<' */ + [96] = KEY_102ND, [97] = KEY_KPASTERISK, /* FIXME */ [98] = KEY_KPSLASH, [99] = KEY_KPLEFTPAREN, diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index e6d46c5994d7..81b07dddae86 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -385,7 +385,6 @@ static int bfin_kpad_resume(struct platform_device *pdev) static struct platform_driver bfin_kpad_device_driver = { .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, .probe = bfin_kpad_probe, .remove = bfin_kpad_remove, diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c index 4f59f0bab28f..f07461a64d85 100644 --- a/drivers/input/keyboard/cap11xx.c +++ b/drivers/input/keyboard/cap11xx.c @@ -370,7 +370,6 @@ static struct i2c_driver cap11xx_i2c_driver = { module_i2c_driver(cap11xx_i2c_driver); -MODULE_ALIAS("platform:cap11xx"); MODULE_DESCRIPTION("Microchip CAP11XX driver"); MODULE_AUTHOR("Daniel Mack <linux@zonque.org>"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/keyboard/clps711x-keypad.c b/drivers/input/keyboard/clps711x-keypad.c index 552b65c6e6b0..27ef29f8fe6a 100644 --- a/drivers/input/keyboard/clps711x-keypad.c +++ b/drivers/input/keyboard/clps711x-keypad.c @@ -194,7 +194,6 @@ MODULE_DEVICE_TABLE(of, clps711x_keypad_of_match); static struct platform_driver clps711x_keypad_driver = { .driver = { .name = "clps711x-keypad", - .owner = THIS_MODULE, .of_match_table = clps711x_keypad_of_match, }, .probe = clps711x_keypad_probe, diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 1e83ef99098e..ffa989f2c785 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -157,7 +157,7 @@ static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) .insize = ckdev->cols, }; - return ckdev->ec->cmd_xfer(ckdev->ec, &msg); + return cros_ec_cmd_xfer(ckdev->ec, &msg); } static irqreturn_t cros_ec_keyb_irq(int irq, void *data) diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index 1559dc1cf951..f363d1d2907a 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c @@ -322,7 +322,6 @@ static int davinci_ks_remove(struct platform_device *pdev) static struct platform_driver davinci_ks_driver = { .driver = { .name = "davinci_keyscan", - .owner = THIS_MODULE, }, .remove = davinci_ks_remove, }; diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index e59876212b8c..f77b295e0123 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c @@ -373,7 +373,6 @@ static int ep93xx_keypad_remove(struct platform_device *pdev) static struct platform_driver ep93xx_keypad_driver = { .driver = { .name = "ep93xx-keypad", - .owner = THIS_MODULE, .pm = &ep93xx_keypad_pm_ops, }, .probe = ep93xx_keypad_probe, diff --git a/drivers/input/keyboard/goldfish_events.c b/drivers/input/keyboard/goldfish_events.c index 69e854763370..907e4e278fce 100644 --- a/drivers/input/keyboard/goldfish_events.c +++ b/drivers/input/keyboard/goldfish_events.c @@ -181,7 +181,6 @@ static int events_probe(struct platform_device *pdev) static struct platform_driver events_driver = { .probe = events_probe, .driver = { - .owner = THIS_MODULE, .name = "goldfish_events", }, }; diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index eefd976ab4eb..883d6aed5b9a 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -840,7 +840,6 @@ static struct platform_driver gpio_keys_device_driver = { .remove = gpio_keys_remove, .driver = { .name = "gpio-keys", - .owner = THIS_MODULE, .pm = &gpio_keys_pm_ops, .of_match_table = of_match_ptr(gpio_keys_of_match), } diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 432d36395f35..90df4df58b07 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -23,10 +23,9 @@ #include <linux/ioport.h> #include <linux/platform_device.h> #include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/gpio_keys.h> -#include <linux/of.h> -#include <linux/of_platform.h> -#include <linux/of_gpio.h> +#include <linux/property.h> #define DRV_NAME "gpio-keys-polled" @@ -51,15 +50,14 @@ static void gpio_keys_polled_check_state(struct input_dev *input, int state; if (bdata->can_sleep) - state = !!gpio_get_value_cansleep(button->gpio); + state = !!gpiod_get_value_cansleep(button->gpiod); else - state = !!gpio_get_value(button->gpio); + state = !!gpiod_get_value(button->gpiod); if (state != bdata->last_state) { unsigned int type = button->type ?: EV_KEY; - input_event(input, type, button->code, - !!(state ^ button->active_low)); + input_event(input, type, button->code, state); input_sync(input); bdata->count = 0; bdata->last_state = state; @@ -102,21 +100,15 @@ static void gpio_keys_polled_close(struct input_polled_dev *dev) pdata->disable(bdev->dev); } -#ifdef CONFIG_OF static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev) { - struct device_node *node, *pp; struct gpio_keys_platform_data *pdata; struct gpio_keys_button *button; + struct fwnode_handle *child; int error; int nbuttons; - int i; - - node = dev->of_node; - if (!node) - return NULL; - nbuttons = of_get_child_count(node); + nbuttons = device_get_child_node_count(dev); if (nbuttons == 0) return NULL; @@ -126,52 +118,44 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct return ERR_PTR(-ENOMEM); pdata->buttons = (struct gpio_keys_button *)(pdata + 1); - pdata->nbuttons = nbuttons; - pdata->rep = !!of_get_property(node, "autorepeat", NULL); - of_property_read_u32(node, "poll-interval", &pdata->poll_interval); + pdata->rep = device_property_present(dev, "autorepeat"); + device_property_read_u32(dev, "poll-interval", &pdata->poll_interval); - i = 0; - for_each_child_of_node(node, pp) { - int gpio; - enum of_gpio_flags flags; + device_for_each_child_node(dev, child) { + struct gpio_desc *desc; - if (!of_find_property(pp, "gpios", NULL)) { - pdata->nbuttons--; - dev_warn(dev, "Found button without gpios\n"); - continue; - } - - gpio = of_get_gpio_flags(pp, 0, &flags); - if (gpio < 0) { - error = gpio; + desc = devm_get_gpiod_from_child(dev, child); + if (IS_ERR(desc)) { + error = PTR_ERR(desc); if (error != -EPROBE_DEFER) dev_err(dev, "Failed to get gpio flags, error: %d\n", error); + fwnode_handle_put(child); return ERR_PTR(error); } - button = &pdata->buttons[i++]; - - button->gpio = gpio; - button->active_low = flags & OF_GPIO_ACTIVE_LOW; + button = &pdata->buttons[pdata->nbuttons++]; + button->gpiod = desc; - if (of_property_read_u32(pp, "linux,code", &button->code)) { - dev_err(dev, "Button without keycode: 0x%x\n", - button->gpio); + if (fwnode_property_read_u32(child, "linux,code", &button->code)) { + dev_err(dev, "Button without keycode: %d\n", + pdata->nbuttons - 1); + fwnode_handle_put(child); return ERR_PTR(-EINVAL); } - button->desc = of_get_property(pp, "label", NULL); + fwnode_property_read_string(child, "label", &button->desc); - if (of_property_read_u32(pp, "linux,input-type", &button->type)) + if (fwnode_property_read_u32(child, "linux,input-type", + &button->type)) button->type = EV_KEY; - button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); + button->wakeup = fwnode_property_present(child, "gpio-key,wakeup"); - if (of_property_read_u32(pp, "debounce-interval", - &button->debounce_interval)) + if (fwnode_property_read_u32(child, "debounce-interval", + &button->debounce_interval)) button->debounce_interval = 5; } @@ -187,15 +171,6 @@ static const struct of_device_id gpio_keys_polled_of_match[] = { }; MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match); -#else - -static inline struct gpio_keys_platform_data * -gpio_keys_polled_get_devtree_pdata(struct device *dev) -{ - return NULL; -} -#endif - static int gpio_keys_polled_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -259,7 +234,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) for (i = 0; i < pdata->nbuttons; i++) { struct gpio_keys_button *button = &pdata->buttons[i]; struct gpio_keys_button_data *bdata = &bdev->data[i]; - unsigned int gpio = button->gpio; unsigned int type = button->type ?: EV_KEY; if (button->wakeup) { @@ -267,15 +241,31 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) return -EINVAL; } - error = devm_gpio_request_one(&pdev->dev, gpio, GPIOF_IN, - button->desc ? : DRV_NAME); - if (error) { - dev_err(dev, "unable to claim gpio %u, err=%d\n", - gpio, error); - return error; + /* + * Legacy GPIO number so request the GPIO here and + * convert it to descriptor. + */ + if (!button->gpiod && gpio_is_valid(button->gpio)) { + unsigned flags = 0; + + if (button->active_low) + flags |= GPIOF_ACTIVE_LOW; + + error = devm_gpio_request_one(&pdev->dev, button->gpio, + flags, button->desc ? : DRV_NAME); + if (error) { + dev_err(dev, "unable to claim gpio %u, err=%d\n", + button->gpio, error); + return error; + } + + button->gpiod = gpio_to_desc(button->gpio); } - bdata->can_sleep = gpio_cansleep(gpio); + if (IS_ERR(button->gpiod)) + return PTR_ERR(button->gpiod); + + bdata->can_sleep = gpiod_cansleep(button->gpiod); bdata->last_state = -1; bdata->threshold = DIV_ROUND_UP(button->debounce_interval, pdata->poll_interval); @@ -307,8 +297,7 @@ static struct platform_driver gpio_keys_polled_driver = { .probe = gpio_keys_polled_probe, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(gpio_keys_polled_of_match), + .of_match_table = gpio_keys_polled_of_match, }, }; module_platform_driver(gpio_keys_polled_driver); diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index 20a99c368d16..2e855e6f3565 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -448,8 +448,7 @@ static int imx_keypad_probe(struct platform_device *pdev) return -ENOMEM; } - keypad = devm_kzalloc(&pdev->dev, sizeof(struct imx_keypad), - GFP_KERNEL); + keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL); if (!keypad) { dev_err(&pdev->dev, "not enough memory for driver data\n"); return -ENOMEM; @@ -580,7 +579,6 @@ static SIMPLE_DEV_PM_OPS(imx_kbd_pm_ops, imx_kbd_suspend, imx_kbd_resume); static struct platform_driver imx_keypad_driver = { .driver = { .name = "imx-keypad", - .owner = THIS_MODULE, .pm = &imx_kbd_pm_ops, .of_match_table = of_match_ptr(imx_keypad_of_match), }, diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 0ba4428da24a..80c81278ad2c 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c @@ -237,7 +237,6 @@ static int jornada680kbd_probe(struct platform_device *pdev) static struct platform_driver jornada680kbd_driver = { .driver = { .name = "jornada680_kbd", - .owner = THIS_MODULE, }, .probe = jornada680kbd_probe, }; diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c index cd729d485e98..421d9c55b0e8 100644 --- a/drivers/input/keyboard/jornada720_kbd.c +++ b/drivers/input/keyboard/jornada720_kbd.c @@ -167,7 +167,6 @@ MODULE_ALIAS("platform:jornada720_kbd"); static struct platform_driver jornada720_kbd_driver = { .driver = { .name = "jornada720_kbd", - .owner = THIS_MODULE, }, .probe = jornada720_kbd_probe, .remove = jornada720_kbd_remove, diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c index 9e9786d576cb..265d641c40e2 100644 --- a/drivers/input/keyboard/lpc32xx-keys.c +++ b/drivers/input/keyboard/lpc32xx-keys.c @@ -329,7 +329,6 @@ static struct platform_driver lpc32xx_kscan_driver = { .probe = lpc32xx_kscan_probe, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, .pm = &lpc32xx_kscan_pm_ops, .of_match_table = lpc32xx_kscan_match, } diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index e651fa692afe..b370a59cb759 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -565,7 +565,6 @@ static struct platform_driver matrix_keypad_driver = { .remove = matrix_keypad_remove, .driver = { .name = "matrix-keypad", - .owner = THIS_MODULE, .pm = &matrix_keypad_pm_ops, .of_match_table = of_match_ptr(matrix_keypad_dt_match), }, diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index 63332e2f8628..c7d5b1666fc3 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -425,7 +425,6 @@ static SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops, static struct platform_driver ske_keypad_driver = { .driver = { .name = "nmk-ske-keypad", - .owner = THIS_MODULE, .pm = &ske_keypad_dev_pm_ops, }, .remove = ske_keypad_remove, diff --git a/drivers/input/keyboard/nspire-keypad.c b/drivers/input/keyboard/nspire-keypad.c index b31064981e96..7abfd34eb87e 100644 --- a/drivers/input/keyboard/nspire-keypad.c +++ b/drivers/input/keyboard/nspire-keypad.c @@ -268,7 +268,6 @@ MODULE_DEVICE_TABLE(of, nspire_keypad_dt_match); static struct platform_driver nspire_keypad_driver = { .driver = { .name = "nspire-keypad", - .owner = THIS_MODULE, .of_match_table = nspire_keypad_dt_match, }, .probe = nspire_keypad_probe, diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index b1acc9852eb7..7502e46165fa 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -383,7 +383,6 @@ static struct platform_driver omap_kp_driver = { .resume = omap_kp_resume, .driver = { .name = "omap-keypad", - .owner = THIS_MODULE, }, }; module_platform_driver(omap_kp_driver); diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 024b7bdffe5b..b052afec9a11 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -460,7 +460,6 @@ static struct platform_driver omap4_keypad_driver = { .remove = omap4_keypad_remove, .driver = { .name = "omap4-keypad", - .owner = THIS_MODULE, .pm = &omap4_keypad_pm_ops, .of_match_table = omap_keypad_dt_match, }, diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 80c6b0ef3fc8..32580afecc26 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -687,7 +687,6 @@ static struct platform_driver pmic8xxx_kp_driver = { .probe = pmic8xxx_kp_probe, .driver = { .name = "pm8xxx-keypad", - .owner = THIS_MODULE, .pm = &pm8xxx_kp_pm_ops, .of_match_table = pm8xxx_match_table, }, diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index e08fc0ae913d..a89488aa1aa4 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -20,6 +20,7 @@ #include <linux/module.h> #include <linux/interrupt.h> #include <linux/input.h> +#include <linux/io.h> #include <linux/device.h> #include <linux/platform_device.h> #include <linux/clk.h> @@ -28,10 +29,6 @@ #include <linux/slab.h> #include <linux/of.h> -#include <asm/mach/arch.h> -#include <asm/mach/map.h> - -#include <mach/hardware.h> #include <linux/platform_data/keypad-pxa27x.h> /* * Keypad Controller registers @@ -835,7 +832,6 @@ static struct platform_driver pxa27x_keypad_driver = { .driver = { .name = "pxa27x-keypad", .of_match_table = of_match_ptr(pxa27x_keypad_dt_match), - .owner = THIS_MODULE, .pm = &pxa27x_keypad_pm_ops, }, }; diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c index 374ca0246c8f..1cf5211fddaa 100644 --- a/drivers/input/keyboard/pxa930_rotary.c +++ b/drivers/input/keyboard/pxa930_rotary.c @@ -189,7 +189,6 @@ static int pxa930_rotary_remove(struct platform_device *pdev) static struct platform_driver pxa930_rotary_driver = { .driver = { .name = "pxa930-rotary", - .owner = THIS_MODULE, }, .probe = pxa930_rotary_probe, .remove = pxa930_rotary_remove, diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 5e80fbf7b5ed..6b9fdf6cf8e8 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -463,7 +463,7 @@ static int samsung_keypad_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_RUNTIME +#ifdef CONFIG_PM static int samsung_keypad_runtime_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -602,7 +602,6 @@ static struct platform_driver samsung_keypad_driver = { .remove = samsung_keypad_remove, .driver = { .name = "samsung-keypad", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(samsung_keypad_dt_match), .pm = &samsung_keypad_pm_ops, }, diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 258af10e5811..f42a543db043 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -385,7 +385,6 @@ static struct platform_driver spear_kbd_driver = { .remove = spear_kbd_remove, .driver = { .name = "keyboard", - .owner = THIS_MODULE, .pm = &spear_kbd_pm_ops, .of_match_table = of_match_ptr(spear_kbd_id_table), }, diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c new file mode 100644 index 000000000000..cc8f7ddcee53 --- /dev/null +++ b/drivers/input/keyboard/sun4i-lradc-keys.c @@ -0,0 +1,286 @@ +/* + * Allwinner sun4i low res adc attached tablet keys driver + * + * Copyright (C) 2014 Hans de Goede <hdegoede@redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Allwinnner sunxi SoCs have a lradc which is specifically designed to have + * various (tablet) keys (ie home, back, search, etc). attached to it using + * a resistor network. This driver is for the keys on such boards. + * + * There are 2 channels, currently this driver only supports channel 0 since + * there are no boards known to use channel 1. + */ + +#include <linux/err.h> +#include <linux/init.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> + +#define LRADC_CTRL 0x00 +#define LRADC_INTC 0x04 +#define LRADC_INTS 0x08 +#define LRADC_DATA0 0x0c +#define LRADC_DATA1 0x10 + +/* LRADC_CTRL bits */ +#define FIRST_CONVERT_DLY(x) ((x) << 24) /* 8 bits */ +#define CHAN_SELECT(x) ((x) << 22) /* 2 bits */ +#define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */ +#define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */ +#define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */ +#define HOLD_EN(x) ((x) << 6) +#define LEVELB_VOL(x) ((x) << 4) /* 2 bits */ +#define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */ +#define ENABLE(x) ((x) << 0) + +/* LRADC_INTC and LRADC_INTS bits */ +#define CHAN1_KEYUP_IRQ BIT(12) +#define CHAN1_ALRDY_HOLD_IRQ BIT(11) +#define CHAN1_HOLD_IRQ BIT(10) +#define CHAN1_KEYDOWN_IRQ BIT(9) +#define CHAN1_DATA_IRQ BIT(8) +#define CHAN0_KEYUP_IRQ BIT(4) +#define CHAN0_ALRDY_HOLD_IRQ BIT(3) +#define CHAN0_HOLD_IRQ BIT(2) +#define CHAN0_KEYDOWN_IRQ BIT(1) +#define CHAN0_DATA_IRQ BIT(0) + +struct sun4i_lradc_keymap { + u32 voltage; + u32 keycode; +}; + +struct sun4i_lradc_data { + struct device *dev; + struct input_dev *input; + void __iomem *base; + struct regulator *vref_supply; + struct sun4i_lradc_keymap *chan0_map; + u32 chan0_map_count; + u32 chan0_keycode; + u32 vref; +}; + +static irqreturn_t sun4i_lradc_irq(int irq, void *dev_id) +{ + struct sun4i_lradc_data *lradc = dev_id; + u32 i, ints, val, voltage, diff, keycode = 0, closest = 0xffffffff; + + ints = readl(lradc->base + LRADC_INTS); + + /* + * lradc supports only one keypress at a time, release does not give + * any info as to which key was released, so we cache the keycode. + */ + + if (ints & CHAN0_KEYUP_IRQ) { + input_report_key(lradc->input, lradc->chan0_keycode, 0); + lradc->chan0_keycode = 0; + } + + if ((ints & CHAN0_KEYDOWN_IRQ) && lradc->chan0_keycode == 0) { + val = readl(lradc->base + LRADC_DATA0) & 0x3f; + voltage = val * lradc->vref / 63; + + for (i = 0; i < lradc->chan0_map_count; i++) { + diff = abs(lradc->chan0_map[i].voltage - voltage); + if (diff < closest) { + closest = diff; + keycode = lradc->chan0_map[i].keycode; + } + } + + lradc->chan0_keycode = keycode; + input_report_key(lradc->input, lradc->chan0_keycode, 1); + } + + input_sync(lradc->input); + + writel(ints, lradc->base + LRADC_INTS); + + return IRQ_HANDLED; +} + +static int sun4i_lradc_open(struct input_dev *dev) +{ + struct sun4i_lradc_data *lradc = input_get_drvdata(dev); + int error; + + error = regulator_enable(lradc->vref_supply); + if (error) + return error; + + /* lradc Vref internally is divided by 2/3 */ + lradc->vref = regulator_get_voltage(lradc->vref_supply) * 2 / 3; + + /* + * Set sample time to 4 ms / 250 Hz. Wait 2 * 4 ms for key to + * stabilize on press, wait (1 + 1) * 4 ms for key release + */ + writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) | + SAMPLE_RATE(0) | ENABLE(1), lradc->base + LRADC_CTRL); + + writel(CHAN0_KEYUP_IRQ | CHAN0_KEYDOWN_IRQ, lradc->base + LRADC_INTC); + + return 0; +} + +static void sun4i_lradc_close(struct input_dev *dev) +{ + struct sun4i_lradc_data *lradc = input_get_drvdata(dev); + + /* Disable lradc, leave other settings unchanged */ + writel(FIRST_CONVERT_DLY(2) | LEVELA_B_CNT(1) | HOLD_EN(1) | + SAMPLE_RATE(2), lradc->base + LRADC_CTRL); + writel(0, lradc->base + LRADC_INTC); + + regulator_disable(lradc->vref_supply); +} + +static int sun4i_lradc_load_dt_keymap(struct device *dev, + struct sun4i_lradc_data *lradc) +{ + struct device_node *np, *pp; + int i; + int error; + + np = dev->of_node; + if (!np) + return -EINVAL; + + lradc->chan0_map_count = of_get_child_count(np); + if (lradc->chan0_map_count == 0) { + dev_err(dev, "keymap is missing in device tree\n"); + return -EINVAL; + } + + lradc->chan0_map = devm_kmalloc_array(dev, lradc->chan0_map_count, + sizeof(struct sun4i_lradc_keymap), + GFP_KERNEL); + if (!lradc->chan0_map) + return -ENOMEM; + + i = 0; + for_each_child_of_node(np, pp) { + struct sun4i_lradc_keymap *map = &lradc->chan0_map[i]; + u32 channel; + + error = of_property_read_u32(pp, "channel", &channel); + if (error || channel != 0) { + dev_err(dev, "%s: Inval channel prop\n", pp->name); + return -EINVAL; + } + + error = of_property_read_u32(pp, "voltage", &map->voltage); + if (error) { + dev_err(dev, "%s: Inval voltage prop\n", pp->name); + return -EINVAL; + } + + error = of_property_read_u32(pp, "linux,code", &map->keycode); + if (error) { + dev_err(dev, "%s: Inval linux,code prop\n", pp->name); + return -EINVAL; + } + + i++; + } + + return 0; +} + +static int sun4i_lradc_probe(struct platform_device *pdev) +{ + struct sun4i_lradc_data *lradc; + struct device *dev = &pdev->dev; + int i; + int error; + + lradc = devm_kzalloc(dev, sizeof(struct sun4i_lradc_data), GFP_KERNEL); + if (!lradc) + return -ENOMEM; + + error = sun4i_lradc_load_dt_keymap(dev, lradc); + if (error) + return error; + + lradc->vref_supply = devm_regulator_get(dev, "vref"); + if (IS_ERR(lradc->vref_supply)) + return PTR_ERR(lradc->vref_supply); + + lradc->dev = dev; + lradc->input = devm_input_allocate_device(dev); + if (!lradc->input) + return -ENOMEM; + + lradc->input->name = pdev->name; + lradc->input->phys = "sun4i_lradc/input0"; + lradc->input->open = sun4i_lradc_open; + lradc->input->close = sun4i_lradc_close; + lradc->input->id.bustype = BUS_HOST; + lradc->input->id.vendor = 0x0001; + lradc->input->id.product = 0x0001; + lradc->input->id.version = 0x0100; + + __set_bit(EV_KEY, lradc->input->evbit); + for (i = 0; i < lradc->chan0_map_count; i++) + __set_bit(lradc->chan0_map[i].keycode, lradc->input->keybit); + + input_set_drvdata(lradc->input, lradc); + + lradc->base = devm_ioremap_resource(dev, + platform_get_resource(pdev, IORESOURCE_MEM, 0)); + if (IS_ERR(lradc->base)) + return PTR_ERR(lradc->base); + + error = devm_request_irq(dev, platform_get_irq(pdev, 0), + sun4i_lradc_irq, 0, + "sun4i-a10-lradc-keys", lradc); + if (error) + return error; + + error = input_register_device(lradc->input); + if (error) + return error; + + platform_set_drvdata(pdev, lradc); + return 0; +} + +static const struct of_device_id sun4i_lradc_of_match[] = { + { .compatible = "allwinner,sun4i-a10-lradc-keys", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match); + +static struct platform_driver sun4i_lradc_driver = { + .driver = { + .name = "sun4i-a10-lradc-keys", + .of_match_table = of_match_ptr(sun4i_lradc_of_match), + }, + .probe = sun4i_lradc_probe, +}; + +module_platform_driver(sun4i_lradc_driver); + +MODULE_DESCRIPTION("Allwinner sun4i low res adc attached tablet keys driver"); +MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c index ad7abae69078..8ff612d160b0 100644 --- a/drivers/input/keyboard/tc3589x-keypad.c +++ b/drivers/input/keyboard/tc3589x-keypad.c @@ -505,7 +505,6 @@ static SIMPLE_DEV_PM_OPS(tc3589x_keypad_dev_pm_ops, static struct platform_driver tc3589x_keypad_driver = { .driver = { .name = "tc3589x-keypad", - .owner = THIS_MODULE, .pm = &tc3589x_keypad_dev_pm_ops, }, .probe = tc3589x_keypad_probe, diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 9757a58bc897..f97c73bd14f8 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -822,7 +822,6 @@ static struct platform_driver tegra_kbc_driver = { .probe = tegra_kbc_probe, .driver = { .name = "tegra-kbc", - .owner = THIS_MODULE, .pm = &tegra_kbc_pm_ops, .of_match_table = tegra_kbc_of_match, }, diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index c5a11700a1bf..bbcccd67247d 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -459,7 +459,6 @@ static struct platform_driver twl4030_kp_driver = { .probe = twl4030_kp_probe, .driver = { .name = "twl4030_keypad", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(twl4030_keypad_dt_match_table), }, }; diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index e8b9d94daae7..a1ff69c53102 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c @@ -258,7 +258,6 @@ static struct platform_driver w90p910_keypad_driver = { .remove = w90p910_keypad_remove, .driver = { .name = "nuc900-kpi", - .owner = THIS_MODULE, }, }; module_platform_driver(w90p910_keypad_driver); |