diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-14 18:07:18 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-14 18:07:18 -0800 |
commit | 9f7a9b1191b0252184b1971c7248c304d4e38e5e (patch) | |
tree | d946c6bddc459a76b79b6effc01160c4536fa460 /drivers/input/mouse | |
parent | 4e4510fec4af08ead21f6934c1410af1f19a8cad (diff) | |
parent | c25141062a82ae8bddced1b3ce2b57a1c0efabe0 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov:
- three new touchscreen drivers: EETI EXC3000, HiDeep, and Samsung
S6SY761
- the timer API conversion (setup_timer() -> timer_setup())
- a few drivers swiytched to using managed API for creating custom
device attributes
- other assorted fixed and cleanups.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (50 commits)
Input: gamecon - mark expected switch fall-throughs
Input: sidewinder - mark expected switch fall-throughs
Input: spaceball - mark expected switch fall-throughs
Input: uinput - unlock on allocation failure in ioctl
Input: add support for the Samsung S6SY761 touchscreen
Input: add support for HiDeep touchscreen
Input: st1232 - remove obsolete platform device support
Input: convert autorepeat timer to use timer_setup()
media: ttpci: remove autorepeat handling and use timer_setup
Input: cyttsp4 - avoid overflows when calculating memory sizes
Input: mxs-lradc - remove redundant assignment to pointer input
Input: add I2C attached EETI EXC3000 multi touch driver
Input: goodix - support gt1151 touchpanel
Input: ps2-gpio - actually abort probe when connected to sleeping GPIOs
Input: hil_mlc - convert to using timer_setup()
Input: hp_sdc - convert to using timer_setup()
Input: touchsceen - convert timers to use timer_setup()
Input: keyboard - convert timers to use timer_setup()
Input: uinput - fold header into the driver proper
Input: uinput - remove uinput_allocate_device()
...
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r-- | drivers/input/mouse/alps.c | 8 | ||||
-rw-r--r-- | drivers/input/mouse/byd.c | 10 | ||||
-rw-r--r-- | drivers/input/mouse/elan_i2c_core.c | 11 | ||||
-rw-r--r-- | drivers/input/mouse/gpio_mouse.c | 206 |
4 files changed, 118 insertions, 117 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 850b00e3ad8e..579b899add26 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -1587,10 +1587,10 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) return PSMOUSE_GOOD_DATA; } -static void alps_flush_packet(unsigned long data) +static void alps_flush_packet(struct timer_list *t) { - struct psmouse *psmouse = (struct psmouse *)data; - struct alps_data *priv = psmouse->private; + struct alps_data *priv = from_timer(priv, t, timer); + struct psmouse *psmouse = priv->psmouse; serio_pause_rx(psmouse->ps2dev.serio); @@ -2702,7 +2702,7 @@ static int alps_set_protocol(struct psmouse *psmouse, { psmouse->private = priv; - setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse); + timer_setup(&priv->timer, alps_flush_packet, 0); priv->proto_version = protocol->version; priv->byte0 = protocol->byte0; diff --git a/drivers/input/mouse/byd.c b/drivers/input/mouse/byd.c index b64b81599f7e..f2aabf7f906f 100644 --- a/drivers/input/mouse/byd.c +++ b/drivers/input/mouse/byd.c @@ -227,6 +227,7 @@ struct byd_data { struct timer_list timer; + struct psmouse *psmouse; s32 abs_x; s32 abs_y; typeof(jiffies) last_touch_time; @@ -251,10 +252,10 @@ static void byd_report_input(struct psmouse *psmouse) input_sync(dev); } -static void byd_clear_touch(unsigned long data) +static void byd_clear_touch(struct timer_list *t) { - struct psmouse *psmouse = (struct psmouse *)data; - struct byd_data *priv = psmouse->private; + struct byd_data *priv = from_timer(priv, t, timer); + struct psmouse *psmouse = priv->psmouse; serio_pause_rx(psmouse->ps2dev.serio); priv->touch = false; @@ -478,7 +479,8 @@ int byd_init(struct psmouse *psmouse) if (!priv) return -ENOMEM; - setup_timer(&priv->timer, byd_clear_touch, (unsigned long) psmouse); + priv->psmouse = psmouse; + timer_setup(&priv->timer, byd_clear_touch, 0); psmouse->private = priv; psmouse->disconnect = byd_disconnect; diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index d6135900da64..2111a85d0b17 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -26,6 +26,7 @@ #include <linux/init.h> #include <linux/input/mt.h> #include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/kernel.h> @@ -1141,10 +1142,13 @@ static int elan_probe(struct i2c_client *client, return error; /* - * Systems using device tree should set up interrupt via DTS, - * the rest will use the default falling edge interrupts. + * Platform code (ACPI, DTS) should normally set up interrupt + * for us, but in case it did not let's fall back to using falling + * edge to be compatible with older Chromebooks. */ - irqflags = dev->of_node ? 0 : IRQF_TRIGGER_FALLING; + irqflags = irq_get_trigger_type(client->irq); + if (!irqflags) + irqflags = IRQF_TRIGGER_FALLING; error = devm_request_threaded_irq(dev, client->irq, NULL, elan_isr, irqflags | IRQF_ONESHOT, @@ -1255,7 +1259,6 @@ static const struct acpi_device_id elan_acpi_id[] = { { "ELAN0602", 0 }, { "ELAN0605", 0 }, { "ELAN0608", 0 }, - { "ELAN0605", 0 }, { "ELAN0609", 0 }, { "ELAN060B", 0 }, { "ELAN060C", 0 }, diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c index ced07391304b..a26d8be6f795 100644 --- a/drivers/input/mouse/gpio_mouse.c +++ b/drivers/input/mouse/gpio_mouse.c @@ -2,6 +2,7 @@ * Driver for simulating a mouse on GPIO lines. * * Copyright (C) 2007 Atmel Corporation + * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> * * 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 @@ -11,9 +12,35 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/input-polldev.h> -#include <linux/gpio.h> -#include <linux/gpio_mouse.h> - +#include <linux/gpio/consumer.h> +#include <linux/property.h> +#include <linux/of.h> + +/** + * struct gpio_mouse + * @scan_ms: the scan interval in milliseconds. + * @up: GPIO line for up value. + * @down: GPIO line for down value. + * @left: GPIO line for left value. + * @right: GPIO line for right value. + * @bleft: GPIO line for left button. + * @bmiddle: GPIO line for middle button. + * @bright: GPIO line for right button. + * + * This struct must be added to the platform_device in the board code. + * It is used by the gpio_mouse driver to setup GPIO lines and to + * calculate mouse movement. + */ +struct gpio_mouse { + u32 scan_ms; + struct gpio_desc *up; + struct gpio_desc *down; + struct gpio_desc *left; + struct gpio_desc *right; + struct gpio_desc *bleft; + struct gpio_desc *bmiddle; + struct gpio_desc *bright; +}; /* * Timer function which is run every scan_ms ms when the device is opened. @@ -21,24 +48,22 @@ */ static void gpio_mouse_scan(struct input_polled_dev *dev) { - struct gpio_mouse_platform_data *gpio = dev->private; + struct gpio_mouse *gpio = dev->private; struct input_dev *input = dev->input; int x, y; - if (gpio->bleft >= 0) + if (gpio->bleft) input_report_key(input, BTN_LEFT, - gpio_get_value(gpio->bleft) ^ gpio->polarity); - if (gpio->bmiddle >= 0) + gpiod_get_value(gpio->bleft)); + if (gpio->bmiddle) input_report_key(input, BTN_MIDDLE, - gpio_get_value(gpio->bmiddle) ^ gpio->polarity); - if (gpio->bright >= 0) + gpiod_get_value(gpio->bmiddle)); + if (gpio->bright) input_report_key(input, BTN_RIGHT, - gpio_get_value(gpio->bright) ^ gpio->polarity); + gpiod_get_value(gpio->bright)); - x = (gpio_get_value(gpio->right) ^ gpio->polarity) - - (gpio_get_value(gpio->left) ^ gpio->polarity); - y = (gpio_get_value(gpio->down) ^ gpio->polarity) - - (gpio_get_value(gpio->up) ^ gpio->polarity); + x = gpiod_get_value(gpio->right) - gpiod_get_value(gpio->left); + y = gpiod_get_value(gpio->down) - gpiod_get_value(gpio->up); input_report_rel(input, REL_X, x); input_report_rel(input, REL_Y, y); @@ -47,65 +72,61 @@ 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 = dev_get_platdata(&pdev->dev); + struct device *dev = &pdev->dev; + struct gpio_mouse *gmouse; struct input_polled_dev *input_poll; struct input_dev *input; - int pin, i; - int error; - - if (!pdata) { - dev_err(&pdev->dev, "no platform data\n"); - error = -ENXIO; - goto out; - } - - if (pdata->scan_ms < 0) { - dev_err(&pdev->dev, "invalid scan time\n"); - error = -EINVAL; - goto out; - } - - for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) { - pin = pdata->pins[i]; - - if (pin < 0) { - - if (i <= GPIO_MOUSE_PIN_RIGHT) { - /* Mouse direction is required. */ - dev_err(&pdev->dev, - "missing GPIO for directions\n"); - error = -EINVAL; - goto out_free_gpios; - } - - if (i == GPIO_MOUSE_PIN_BLEFT) - dev_dbg(&pdev->dev, "no left button defined\n"); - - } else { - error = gpio_request(pin, "gpio_mouse"); - if (error) { - dev_err(&pdev->dev, "fail %d pin (%d idx)\n", - pin, i); - goto out_free_gpios; - } - - gpio_direction_input(pin); - } + int ret; + + gmouse = devm_kzalloc(dev, sizeof(*gmouse), GFP_KERNEL); + if (!gmouse) + return -ENOMEM; + + /* Assign some default scanning time */ + ret = device_property_read_u32(dev, "scan-interval-ms", + &gmouse->scan_ms); + if (ret || gmouse->scan_ms == 0) { + dev_warn(dev, "invalid scan time, set to 50 ms\n"); + gmouse->scan_ms = 50; } - input_poll = input_allocate_polled_device(); + gmouse->up = devm_gpiod_get(dev, "up", GPIOD_IN); + if (IS_ERR(gmouse->up)) + return PTR_ERR(gmouse->up); + gmouse->down = devm_gpiod_get(dev, "down", GPIOD_IN); + if (IS_ERR(gmouse->down)) + return PTR_ERR(gmouse->down); + gmouse->left = devm_gpiod_get(dev, "left", GPIOD_IN); + if (IS_ERR(gmouse->left)) + return PTR_ERR(gmouse->left); + gmouse->right = devm_gpiod_get(dev, "right", GPIOD_IN); + if (IS_ERR(gmouse->right)) + return PTR_ERR(gmouse->right); + + gmouse->bleft = devm_gpiod_get_optional(dev, "button-left", GPIOD_IN); + if (IS_ERR(gmouse->bleft)) + return PTR_ERR(gmouse->bleft); + gmouse->bmiddle = devm_gpiod_get_optional(dev, "button-middle", + GPIOD_IN); + if (IS_ERR(gmouse->bmiddle)) + return PTR_ERR(gmouse->bmiddle); + gmouse->bright = devm_gpiod_get_optional(dev, "button-right", + GPIOD_IN); + if (IS_ERR(gmouse->bright)) + return PTR_ERR(gmouse->bright); + + input_poll = devm_input_allocate_polled_device(dev); if (!input_poll) { - dev_err(&pdev->dev, "not enough memory for input device\n"); - error = -ENOMEM; - goto out_free_gpios; + dev_err(dev, "not enough memory for input device\n"); + return -ENOMEM; } platform_set_drvdata(pdev, input_poll); /* set input-polldev handlers */ - input_poll->private = pdata; + input_poll->private = gmouse; input_poll->poll = gpio_mouse_scan; - input_poll->poll_interval = pdata->scan_ms; + input_poll->poll_interval = gmouse->scan_ms; input = input_poll->input; input->name = pdev->name; @@ -114,63 +135,39 @@ static int gpio_mouse_probe(struct platform_device *pdev) input_set_capability(input, EV_REL, REL_X); input_set_capability(input, EV_REL, REL_Y); - if (pdata->bleft >= 0) + if (gmouse->bleft) input_set_capability(input, EV_KEY, BTN_LEFT); - if (pdata->bmiddle >= 0) + if (gmouse->bmiddle) input_set_capability(input, EV_KEY, BTN_MIDDLE); - if (pdata->bright >= 0) + if (gmouse->bright) input_set_capability(input, EV_KEY, BTN_RIGHT); - error = input_register_polled_device(input_poll); - if (error) { - dev_err(&pdev->dev, "could not register input device\n"); - goto out_free_polldev; + ret = input_register_polled_device(input_poll); + if (ret) { + dev_err(dev, "could not register input device\n"); + return ret; } - dev_dbg(&pdev->dev, "%d ms scan time, buttons: %s%s%s\n", - pdata->scan_ms, - pdata->bleft < 0 ? "" : "left ", - pdata->bmiddle < 0 ? "" : "middle ", - pdata->bright < 0 ? "" : "right"); + dev_dbg(dev, "%d ms scan time, buttons: %s%s%s\n", + gmouse->scan_ms, + gmouse->bleft ? "" : "left ", + gmouse->bmiddle ? "" : "middle ", + gmouse->bright ? "" : "right"); return 0; - - out_free_polldev: - input_free_polled_device(input_poll); - - out_free_gpios: - while (--i >= 0) { - pin = pdata->pins[i]; - if (pin) - gpio_free(pin); - } - out: - return error; } -static int gpio_mouse_remove(struct platform_device *pdev) -{ - struct input_polled_dev *input = platform_get_drvdata(pdev); - struct gpio_mouse_platform_data *pdata = input->private; - int pin, i; - - input_unregister_polled_device(input); - input_free_polled_device(input); - - for (i = 0; i < GPIO_MOUSE_PIN_MAX; i++) { - pin = pdata->pins[i]; - if (pin >= 0) - gpio_free(pin); - } - - return 0; -} +static const struct of_device_id gpio_mouse_of_match[] = { + { .compatible = "gpio-mouse", }, + { }, +}; +MODULE_DEVICE_TABLE(of, gpio_mouse_of_match); static struct platform_driver gpio_mouse_device_driver = { .probe = gpio_mouse_probe, - .remove = gpio_mouse_remove, .driver = { .name = "gpio_mouse", + .of_match_table = gpio_mouse_of_match, } }; module_platform_driver(gpio_mouse_device_driver); @@ -179,4 +176,3 @@ MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); MODULE_DESCRIPTION("GPIO mouse driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:gpio_mouse"); /* work with hotplug and coldplug */ - |