diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-18 03:45:00 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-18 03:45:00 +0300 |
commit | af79ce47efabba36d1db0902d46a80de7f251411 (patch) | |
tree | 571106db25ed2da54891995aed38407f85e6ac4b /drivers/input/keyboard | |
parent | c07dee7348e2451bcf2f178bf0e7830268e2c31a (diff) | |
parent | f26e8817b235d8764363bffcc9cbfc61867371f2 (diff) | |
download | linux-af79ce47efabba36d1db0902d46a80de7f251411.tar.xz |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input subsystem updates from Dmitry Torokhov:
- updated support for Synaptics RMI4 devices, including support for
SMBus controllers, firmware update support, sensor tuning, and PS/2
guest support
- ALPS driver now supports tracksticks on SS5 controllers
- i8042 now uses chassis info to skip selftest on Asus laptops as list
of individual models became too unwieldy
- miscellaneous fixes to other drivers
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (67 commits)
Input: imx6ul_tsc - generalize the averaging property
Input: drv260x - use generic device properties
Input: drv260x - use temporary for &client->dev
Input: drv260x - fix input device's parent assignment
Input: synaptics-rmi4 - add support for F34 V7 bootloader
Input: drv260x - fix initializing overdrive voltage
Input: ALPS - fix protcol -> protocol
Input: i8042 - comment #else/#endif of CONFIG_PNP
Input: lpc32xx-keys - fix invalid error handling of a requested irq
Input: synaptics-rmi4 - fix debug for sensor clip
Input: synaptics-rmi4 - store the attn data in the driver
Input: synaptics-rmi4 - allow to add attention data
Input: synaptics-rmi4 - f03 - grab data passed by transport device
Input: synaptics-rmi4 - add support for F03
Input: imx6ul_tsc - convert int to u32
Input: imx6ul_tsc - add mask when set REG_ADC_CFG
Input: synaptics-rmi4 - have only one struct platform data
Input: synaptics-rmi4 - remove EXPORT_SYMBOL_GPL for internal functions
Input: synaptics-rmi4 - remove mutex calls while updating the firmware
Input: drv2667 - fix misuse of regmap_update_bits
...
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 190 | ||||
-rw-r--r-- | drivers/input/keyboard/gpio_keys_polled.c | 128 | ||||
-rw-r--r-- | drivers/input/keyboard/lpc32xx-keys.c | 2 | ||||
-rw-r--r-- | drivers/input/keyboard/pxa27x_keypad.c | 2 | ||||
-rw-r--r-- | drivers/input/keyboard/tca8418_keypad.c | 21 |
5 files changed, 192 insertions, 151 deletions
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 29093657f2ef..582462d0af75 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -26,15 +26,15 @@ #include <linux/gpio_keys.h> #include <linux/workqueue.h> #include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/of.h> -#include <linux/of_platform.h> -#include <linux/of_gpio.h> #include <linux/of_irq.h> #include <linux/spinlock.h> struct gpio_button_data { const struct gpio_keys_button *button; struct input_dev *input; + struct gpio_desc *gpiod; struct timer_list release_timer; unsigned int release_delay; /* in msecs, for IRQ-only buttons */ @@ -140,7 +140,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata) */ disable_irq(bdata->irq); - if (gpio_is_valid(bdata->button->gpio)) + if (bdata->gpiod) cancel_delayed_work_sync(&bdata->work); else del_timer_sync(&bdata->release_timer); @@ -358,19 +358,20 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) const struct gpio_keys_button *button = bdata->button; struct input_dev *input = bdata->input; unsigned int type = button->type ?: EV_KEY; - int state = gpio_get_value_cansleep(button->gpio); + int state; + state = gpiod_get_value_cansleep(bdata->gpiod); if (state < 0) { - dev_err(input->dev.parent, "failed to get gpio state\n"); + dev_err(input->dev.parent, + "failed to get gpio state: %d\n", state); return; } - state = (state ? 1 : 0) ^ button->active_low; if (type == EV_ABS) { if (state) input_event(input, type, button->code, button->value); } else { - input_event(input, type, button->code, !!state); + input_event(input, type, button->code, state); } input_sync(input); } @@ -456,7 +457,7 @@ static void gpio_keys_quiesce_key(void *data) { struct gpio_button_data *bdata = data; - if (gpio_is_valid(bdata->button->gpio)) + if (bdata->gpiod) cancel_delayed_work_sync(&bdata->work); else del_timer_sync(&bdata->release_timer); @@ -465,7 +466,8 @@ static void gpio_keys_quiesce_key(void *data) static int gpio_keys_setup_key(struct platform_device *pdev, struct input_dev *input, struct gpio_button_data *bdata, - const struct gpio_keys_button *button) + const struct gpio_keys_button *button, + struct fwnode_handle *child) { const char *desc = button->desc ? button->desc : "gpio_keys"; struct device *dev = &pdev->dev; @@ -478,18 +480,56 @@ static int gpio_keys_setup_key(struct platform_device *pdev, bdata->button = button; spin_lock_init(&bdata->lock); - if (gpio_is_valid(button->gpio)) { + if (child) { + bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, child); + if (IS_ERR(bdata->gpiod)) { + error = PTR_ERR(bdata->gpiod); + if (error == -ENOENT) { + /* + * GPIO is optional, we may be dealing with + * purely interrupt-driven setup. + */ + bdata->gpiod = NULL; + } else { + if (error != -EPROBE_DEFER) + dev_err(dev, "failed to get gpio: %d\n", + error); + return error; + } + } else { + error = gpiod_direction_input(bdata->gpiod); + if (error) { + dev_err(dev, "Failed to configure GPIO %d as input: %d\n", + desc_to_gpio(bdata->gpiod), error); + return error; + } + } + } else if (gpio_is_valid(button->gpio)) { + /* + * Legacy GPIO number, so request the GPIO here and + * convert it to descriptor. + */ + unsigned flags = GPIOF_IN; + + if (button->active_low) + flags |= GPIOF_ACTIVE_LOW; - error = devm_gpio_request_one(&pdev->dev, button->gpio, - GPIOF_IN, desc); + error = devm_gpio_request_one(&pdev->dev, button->gpio, flags, + desc); if (error < 0) { dev_err(dev, "Failed to request GPIO %d, error %d\n", button->gpio, error); return error; } + bdata->gpiod = gpio_to_desc(button->gpio); + if (!bdata->gpiod) + return -EINVAL; + } + + if (bdata->gpiod) { if (button->debounce_interval) { - error = gpio_set_debounce(button->gpio, + error = gpiod_set_debounce(bdata->gpiod, button->debounce_interval * 1000); /* use timer if gpiolib doesn't provide debounce */ if (error < 0) @@ -500,7 +540,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev, if (button->irq) { bdata->irq = button->irq; } else { - irq = gpio_to_irq(button->gpio); + irq = gpiod_to_irq(bdata->gpiod); if (irq < 0) { error = irq; dev_err(dev, @@ -518,9 +558,10 @@ static int gpio_keys_setup_key(struct platform_device *pdev, } else { if (!button->irq) { - dev_err(dev, "No IRQ specified\n"); + dev_err(dev, "Found button without gpio or irq\n"); return -EINVAL; } + bdata->irq = button->irq; if (button->type && button->type != EV_KEY) { @@ -575,7 +616,7 @@ static void gpio_keys_report_state(struct gpio_keys_drvdata *ddata) for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; - if (gpio_is_valid(bdata->button->gpio)) + if (bdata->gpiod) gpio_keys_gpio_report_event(bdata); } input_sync(input); @@ -612,25 +653,18 @@ static void gpio_keys_close(struct input_dev *input) * Handlers for alternative sources of platform_data */ -#ifdef CONFIG_OF /* - * Translate OpenFirmware node properties into platform_data + * Translate properties into platform_data */ static struct gpio_keys_platform_data * gpio_keys_get_devtree_pdata(struct device *dev) { - struct device_node *node, *pp; struct gpio_keys_platform_data *pdata; struct gpio_keys_button *button; - int error; + struct fwnode_handle *child; int nbuttons; - int i; - node = dev->of_node; - if (!node) - return ERR_PTR(-ENODEV); - - nbuttons = of_get_available_child_count(node); + nbuttons = device_get_child_node_count(dev); if (nbuttons == 0) return ERR_PTR(-ENODEV); @@ -640,64 +674,47 @@ gpio_keys_get_devtree_pdata(struct device *dev) if (!pdata) 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_string(node, "label", &pdata->name); - - i = 0; - for_each_available_child_of_node(node, pp) { - enum of_gpio_flags flags; + button = (struct gpio_keys_button *)(pdata + 1); - button = &pdata->buttons[i++]; + pdata->buttons = button; + pdata->nbuttons = nbuttons; - button->gpio = of_get_gpio_flags(pp, 0, &flags); - if (button->gpio < 0) { - error = button->gpio; - if (error != -ENOENT) { - if (error != -EPROBE_DEFER) - dev_err(dev, - "Failed to get gpio flags, error: %d\n", - error); - return ERR_PTR(error); - } - } else { - button->active_low = flags & OF_GPIO_ACTIVE_LOW; - } + pdata->rep = device_property_read_bool(dev, "autorepeat"); - button->irq = irq_of_parse_and_map(pp, 0); + device_property_read_string(dev, "label", &pdata->name); - if (!gpio_is_valid(button->gpio) && !button->irq) { - dev_err(dev, "Found button without gpios or irqs\n"); - return ERR_PTR(-EINVAL); - } + device_for_each_child_node(dev, child) { + if (is_of_node(child)) + button->irq = + irq_of_parse_and_map(to_of_node(child), 0); - 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\n"); + 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_property_read_bool(pp, "wakeup-source") || - /* legacy name */ - of_property_read_bool(pp, "gpio-key,wakeup"); + button->wakeup = + fwnode_property_read_bool(child, "wakeup-source") || + /* legacy name */ + fwnode_property_read_bool(child, "gpio-key,wakeup"); - button->can_disable = !!of_get_property(pp, "linux,can-disable", NULL); + button->can_disable = + fwnode_property_read_bool(child, "linux,can-disable"); - if (of_property_read_u32(pp, "debounce-interval", + if (fwnode_property_read_u32(child, "debounce-interval", &button->debounce_interval)) button->debounce_interval = 5; - } - if (pdata->nbuttons == 0) - return ERR_PTR(-EINVAL); + button++; + } return pdata; } @@ -708,20 +725,11 @@ static const struct of_device_id gpio_keys_of_match[] = { }; MODULE_DEVICE_TABLE(of, gpio_keys_of_match); -#else - -static inline struct gpio_keys_platform_data * -gpio_keys_get_devtree_pdata(struct device *dev) -{ - return ERR_PTR(-ENODEV); -} - -#endif - static int gpio_keys_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); + struct fwnode_handle *child = NULL; struct gpio_keys_drvdata *ddata; struct input_dev *input; size_t size; @@ -774,14 +782,28 @@ static int gpio_keys_probe(struct platform_device *pdev) const struct gpio_keys_button *button = &pdata->buttons[i]; struct gpio_button_data *bdata = &ddata->data[i]; - error = gpio_keys_setup_key(pdev, input, bdata, button); - if (error) + if (!dev_get_platdata(dev)) { + child = device_get_next_child_node(&pdev->dev, child); + if (!child) { + dev_err(&pdev->dev, + "missing child device node for entry %d\n", + i); + return -EINVAL; + } + } + + error = gpio_keys_setup_key(pdev, input, bdata, button, child); + if (error) { + fwnode_handle_put(child); return error; + } if (button->wakeup) wakeup = 1; } + fwnode_handle_put(child); + error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); if (error) { dev_err(dev, "Unable to export keys/switches, error: %d\n", @@ -814,8 +836,7 @@ static int gpio_keys_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int gpio_keys_suspend(struct device *dev) +static int __maybe_unused gpio_keys_suspend(struct device *dev) { struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); struct input_dev *input = ddata->input; @@ -837,7 +858,7 @@ static int gpio_keys_suspend(struct device *dev) return 0; } -static int gpio_keys_resume(struct device *dev) +static int __maybe_unused gpio_keys_resume(struct device *dev) { struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); struct input_dev *input = ddata->input; @@ -863,7 +884,6 @@ static int gpio_keys_resume(struct device *dev) gpio_keys_report_state(ddata); return 0; } -#endif static SIMPLE_DEV_PM_OPS(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume); @@ -873,7 +893,7 @@ static struct platform_driver gpio_keys_device_driver = { .driver = { .name = "gpio-keys", .pm = &gpio_keys_pm_ops, - .of_match_table = of_match_ptr(gpio_keys_of_match), + .of_match_table = gpio_keys_of_match, } }; diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 62bdb1d48c49..bed4f2086158 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -30,10 +30,10 @@ #define DRV_NAME "gpio-keys-polled" struct gpio_keys_button_data { + struct gpio_desc *gpiod; int last_state; int count; int threshold; - int can_sleep; }; struct gpio_keys_polled_dev { @@ -46,7 +46,7 @@ struct gpio_keys_polled_dev { }; static void gpio_keys_button_event(struct input_polled_dev *dev, - struct gpio_keys_button *button, + const struct gpio_keys_button *button, int state) { struct gpio_keys_polled_dev *bdev = dev->private; @@ -70,21 +70,22 @@ static void gpio_keys_button_event(struct input_polled_dev *dev, } static void gpio_keys_polled_check_state(struct input_polled_dev *dev, - struct gpio_keys_button *button, + const struct gpio_keys_button *button, struct gpio_keys_button_data *bdata) { int state; - if (bdata->can_sleep) - state = !!gpiod_get_value_cansleep(button->gpiod); - else - state = !!gpiod_get_value(button->gpiod); - - gpio_keys_button_event(dev, button, state); + state = gpiod_get_value_cansleep(bdata->gpiod); + if (state < 0) { + dev_err(dev->input->dev.parent, + "failed to get gpio state: %d\n", state); + } else { + gpio_keys_button_event(dev, button, state); - if (state != bdata->last_state) { - bdata->count = 0; - bdata->last_state = state; + if (state != bdata->last_state) { + bdata->count = 0; + bdata->last_state = state; + } } } @@ -142,48 +143,35 @@ static void gpio_keys_polled_close(struct input_polled_dev *dev) pdata->disable(bdev->dev); } -static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct device *dev) +static struct gpio_keys_platform_data * +gpio_keys_polled_get_devtree_pdata(struct device *dev) { struct gpio_keys_platform_data *pdata; struct gpio_keys_button *button; struct fwnode_handle *child; - int error; int nbuttons; nbuttons = device_get_child_node_count(dev); if (nbuttons == 0) - return NULL; + return ERR_PTR(-EINVAL); pdata = devm_kzalloc(dev, sizeof(*pdata) + nbuttons * sizeof(*button), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM); - pdata->buttons = (struct gpio_keys_button *)(pdata + 1); + button = (struct gpio_keys_button *)(pdata + 1); + + pdata->buttons = button; + pdata->nbuttons = nbuttons; pdata->rep = device_property_present(dev, "autorepeat"); device_property_read_u32(dev, "poll-interval", &pdata->poll_interval); device_for_each_child_node(dev, child) { - struct gpio_desc *desc; - - desc = devm_get_gpiod_from_child(dev, NULL, 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[pdata->nbuttons++]; - button->gpiod = desc; - - if (fwnode_property_read_u32(child, "linux,code", &button->code)) { - dev_err(dev, "Button without keycode: %d\n", - pdata->nbuttons - 1); + if (fwnode_property_read_u32(child, "linux,code", + &button->code)) { + dev_err(dev, "button without keycode\n"); fwnode_handle_put(child); return ERR_PTR(-EINVAL); } @@ -206,10 +194,9 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct if (fwnode_property_read_u32(child, "debounce-interval", &button->debounce_interval)) button->debounce_interval = 5; - } - if (pdata->nbuttons == 0) - return ERR_PTR(-EINVAL); + button++; + } return pdata; } @@ -220,7 +207,7 @@ static void gpio_keys_polled_set_abs_params(struct input_dev *input, int i, min = 0, max = 0; for (i = 0; i < pdata->nbuttons; i++) { - struct gpio_keys_button *button = &pdata->buttons[i]; + const struct gpio_keys_button *button = &pdata->buttons[i]; if (button->type != EV_ABS || button->code != code) continue; @@ -230,6 +217,7 @@ static void gpio_keys_polled_set_abs_params(struct input_dev *input, if (button->value > max) max = button->value; } + input_set_abs_params(input, code, min, max, 0, 0); } @@ -242,6 +230,7 @@ MODULE_DEVICE_TABLE(of, gpio_keys_polled_of_match); static int gpio_keys_polled_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct fwnode_handle *child = NULL; const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); struct gpio_keys_polled_dev *bdev; struct input_polled_dev *poll_dev; @@ -254,10 +243,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) pdata = gpio_keys_polled_get_devtree_pdata(dev); if (IS_ERR(pdata)) return PTR_ERR(pdata); - if (!pdata) { - dev_err(dev, "missing platform data\n"); - return -EINVAL; - } } if (!pdata->poll_interval) { @@ -300,20 +285,48 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) __set_bit(EV_REP, input->evbit); for (i = 0; i < pdata->nbuttons; i++) { - struct gpio_keys_button *button = &pdata->buttons[i]; + const struct gpio_keys_button *button = &pdata->buttons[i]; struct gpio_keys_button_data *bdata = &bdev->data[i]; unsigned int type = button->type ?: EV_KEY; if (button->wakeup) { dev_err(dev, DRV_NAME " does not support wakeup\n"); + fwnode_handle_put(child); return -EINVAL; } - /* - * Legacy GPIO number so request the GPIO here and - * convert it to descriptor. - */ - if (!button->gpiod && gpio_is_valid(button->gpio)) { + if (!dev_get_platdata(dev)) { + /* No legacy static platform data */ + child = device_get_next_child_node(dev, child); + if (!child) { + dev_err(dev, "missing child device node\n"); + return -EINVAL; + } + + bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, + child); + if (IS_ERR(bdata->gpiod)) { + error = PTR_ERR(bdata->gpiod); + if (error != -EPROBE_DEFER) + dev_err(dev, + "failed to get gpio: %d\n", + error); + fwnode_handle_put(child); + return error; + } + + error = gpiod_direction_input(bdata->gpiod); + if (error) { + dev_err(dev, "Failed to configure GPIO %d as input: %d\n", + desc_to_gpio(bdata->gpiod), error); + fwnode_handle_put(child); + return error; + } + } else if (gpio_is_valid(button->gpio)) { + /* + * Legacy GPIO number so request the GPIO here and + * convert it to descriptor. + */ unsigned flags = GPIOF_IN; if (button->active_low) @@ -322,18 +335,21 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) 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", + dev_err(dev, + "unable to claim gpio %u, err=%d\n", button->gpio, error); return error; } - button->gpiod = gpio_to_desc(button->gpio); + bdata->gpiod = gpio_to_desc(button->gpio); + if (!bdata->gpiod) { + dev_err(dev, + "unable to convert gpio %u to descriptor\n", + button->gpio); + return -EINVAL; + } } - 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); @@ -344,6 +360,8 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) button->code); } + fwnode_handle_put(child); + bdev->poll_dev = poll_dev; bdev->dev = dev; bdev->pdata = pdata; diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c index 265d641c40e2..632523d4f5dc 100644 --- a/drivers/input/keyboard/lpc32xx-keys.c +++ b/drivers/input/keyboard/lpc32xx-keys.c @@ -182,7 +182,7 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq < 0 || irq >= NR_IRQS) { + if (irq < 0) { dev_err(&pdev->dev, "failed to get platform irq\n"); return -EINVAL; } diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index fcef5d1365e2..e24443376e75 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -316,7 +316,7 @@ static int pxa27x_keypad_build_keycode_from_dt(struct pxa27x_keypad *keypad) error = of_property_read_u32(np, "marvell,debounce-interval", &pdata->debounce_interval); if (error) { - dev_err(dev, "failed to parse debpunce-interval\n"); + dev_err(dev, "failed to parse debounce-interval\n"); return error; } diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 9002298698fc..3048ef3e3e16 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -164,11 +164,18 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) int error, col, row; u8 reg, state, code; - /* Initial read of the key event FIFO */ - error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®); + do { + error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®); + if (error < 0) { + dev_err(&keypad_data->client->dev, + "unable to read REG_KEY_EVENT_A\n"); + break; + } + + /* Assume that key code 0 signifies empty FIFO */ + if (reg <= 0) + break; - /* Assume that key code 0 signifies empty FIFO */ - while (error >= 0 && reg > 0) { state = reg & KEY_EVENT_VALUE; code = reg & KEY_EVENT_CODE; @@ -184,11 +191,7 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) /* Read for next loop */ error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®); - } - - if (error < 0) - dev_err(&keypad_data->client->dev, - "unable to read REG_KEY_EVENT_A\n"); + } while (1); input_sync(input); } |