diff options
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/adp5588-keys.c | 10 | ||||
-rw-r--r-- | drivers/input/keyboard/adp5589-keys.c | 12 | ||||
-rw-r--r-- | drivers/input/keyboard/clps711x-keypad.c | 4 | ||||
-rw-r--r-- | drivers/input/keyboard/cros_ec_keyb.c | 135 |
4 files changed, 44 insertions, 117 deletions
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index 21a62d0fa764..53fe9a3fb620 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c @@ -73,7 +73,7 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val) #ifdef CONFIG_GPIOLIB static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) { - struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); + struct adp5588_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); int val; @@ -93,7 +93,7 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) static void adp5588_gpio_set_value(struct gpio_chip *chip, unsigned off, int val) { - struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); + struct adp5588_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); @@ -112,7 +112,7 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) { - struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); + struct adp5588_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); int ret; @@ -130,7 +130,7 @@ static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) static int adp5588_gpio_direction_output(struct gpio_chip *chip, unsigned off, int val) { - struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc); + struct adp5588_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]); unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]); int ret; @@ -210,7 +210,7 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad) mutex_init(&kpad->gpio_lock); - error = gpiochip_add(&kpad->gc); + error = gpiochip_add_data(&kpad->gc, kpad); if (error) { dev_err(dev, "gpiochip_add failed, err: %d\n", error); return error; diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index c01a1d648f9f..32d94c63dc33 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c @@ -387,7 +387,7 @@ static int adp5589_write(struct i2c_client *client, u8 reg, u8 val) #ifdef CONFIG_GPIOLIB static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off) { - struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); + struct adp5589_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); @@ -399,7 +399,7 @@ static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off) static void adp5589_gpio_set_value(struct gpio_chip *chip, unsigned off, int val) { - struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); + struct adp5589_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); @@ -418,7 +418,7 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip, static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off) { - struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); + struct adp5589_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); int ret; @@ -438,7 +438,7 @@ static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off) static int adp5589_gpio_direction_output(struct gpio_chip *chip, unsigned off, int val) { - struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); + struct adp5589_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); int ret; @@ -525,9 +525,9 @@ static int adp5589_gpio_add(struct adp5589_kpad *kpad) mutex_init(&kpad->gpio_lock); - error = gpiochip_add(&kpad->gc); + error = gpiochip_add_data(&kpad->gc, kpad); if (error) { - dev_err(dev, "gpiochip_add failed, err: %d\n", error); + dev_err(dev, "gpiochip_add_data() failed, err: %d\n", error); return error; } diff --git a/drivers/input/keyboard/clps711x-keypad.c b/drivers/input/keyboard/clps711x-keypad.c index b637f1af842e..997e3e97f573 100644 --- a/drivers/input/keyboard/clps711x-keypad.c +++ b/drivers/input/keyboard/clps711x-keypad.c @@ -101,7 +101,7 @@ static int clps711x_keypad_probe(struct platform_device *pdev) return -ENOMEM; priv->syscon = - syscon_regmap_lookup_by_compatible("cirrus,clps711x-syscon1"); + syscon_regmap_lookup_by_compatible("cirrus,ep7209-syscon1"); if (IS_ERR(priv->syscon)) return PTR_ERR(priv->syscon); @@ -181,7 +181,7 @@ static int clps711x_keypad_remove(struct platform_device *pdev) } static const struct of_device_id clps711x_keypad_of_match[] = { - { .compatible = "cirrus,clps711x-keypad", }, + { .compatible = "cirrus,ep7209-keypad", }, { } }; MODULE_DEVICE_TABLE(of, clps711x_keypad_of_match); diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 4b0878f35471..25943e9bc8bf 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -27,6 +27,7 @@ #include <linux/input.h> #include <linux/interrupt.h> #include <linux/kernel.h> +#include <linux/notifier.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/input/matrix_keypad.h> @@ -44,6 +45,7 @@ * @dev: Device pointer * @idev: Input device * @ec: Top level ChromeOS device to use to talk to EC + * @notifier: interrupt event notifier for transport devices */ struct cros_ec_keyb { unsigned int rows; @@ -57,6 +59,7 @@ struct cros_ec_keyb { struct device *dev; struct input_dev *idev; struct cros_ec_device *ec; + struct notifier_block notifier; }; @@ -146,67 +149,44 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, input_sync(ckdev->idev); } -static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) -{ - int ret = 0; - struct cros_ec_command *msg; - - msg = kmalloc(sizeof(*msg) + ckdev->cols, GFP_KERNEL); - if (!msg) - return -ENOMEM; - - msg->version = 0; - msg->command = EC_CMD_MKBP_STATE; - msg->insize = ckdev->cols; - msg->outsize = 0; - - ret = cros_ec_cmd_xfer(ckdev->ec, msg); - if (ret < 0) { - dev_err(ckdev->dev, "Error transferring EC message %d\n", ret); - goto exit; - } - - memcpy(kb_state, msg->data, ckdev->cols); -exit: - kfree(msg); - return ret; -} - -static irqreturn_t cros_ec_keyb_irq(int irq, void *data) +static int cros_ec_keyb_open(struct input_dev *dev) { - struct cros_ec_keyb *ckdev = data; - struct cros_ec_device *ec = ckdev->ec; - int ret; - uint8_t kb_state[ckdev->cols]; - - if (device_may_wakeup(ec->dev)) - pm_wakeup_event(ec->dev, 0); - - ret = cros_ec_keyb_get_state(ckdev, kb_state); - if (ret >= 0) - cros_ec_keyb_process(ckdev, kb_state, ret); - else - dev_err(ckdev->dev, "failed to get keyboard state: %d\n", ret); + struct cros_ec_keyb *ckdev = input_get_drvdata(dev); - return IRQ_HANDLED; + return blocking_notifier_chain_register(&ckdev->ec->event_notifier, + &ckdev->notifier); } -static int cros_ec_keyb_open(struct input_dev *dev) +static void cros_ec_keyb_close(struct input_dev *dev) { struct cros_ec_keyb *ckdev = input_get_drvdata(dev); - struct cros_ec_device *ec = ckdev->ec; - return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - "cros_ec_keyb", ckdev); + blocking_notifier_chain_unregister(&ckdev->ec->event_notifier, + &ckdev->notifier); } -static void cros_ec_keyb_close(struct input_dev *dev) +static int cros_ec_keyb_work(struct notifier_block *nb, + unsigned long queued_during_suspend, void *_notify) { - struct cros_ec_keyb *ckdev = input_get_drvdata(dev); - struct cros_ec_device *ec = ckdev->ec; + struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb, + notifier); - free_irq(ec->irq, ckdev); + if (ckdev->ec->event_data.event_type != EC_MKBP_EVENT_KEY_MATRIX) + return NOTIFY_DONE; + /* + * If EC is not the wake source, discard key state changes during + * suspend. + */ + if (queued_during_suspend) + return NOTIFY_OK; + if (ckdev->ec->event_size != ckdev->cols) { + dev_err(ckdev->dev, + "Discarded incomplete key matrix event.\n"); + return NOTIFY_OK; + } + cros_ec_keyb_process(ckdev, ckdev->ec->event_data.data.key_matrix, + ckdev->ec->event_size); + return NOTIFY_OK; } /* @@ -265,12 +245,8 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) if (!idev) return -ENOMEM; - if (!ec->irq) { - dev_err(dev, "no EC IRQ specified\n"); - return -EINVAL; - } - ckdev->ec = ec; + ckdev->notifier.notifier_call = cros_ec_keyb_work; ckdev->dev = dev; dev_set_drvdata(dev, ckdev); @@ -311,54 +287,6 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -/* Clear any keys in the buffer */ -static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev) -{ - uint8_t old_state[ckdev->cols]; - uint8_t new_state[ckdev->cols]; - unsigned long duration; - int i, ret; - - /* - * Keep reading until we see that the scan state does not change. - * That indicates that we are done. - * - * Assume that the EC keyscan buffer is at most 32 deep. - */ - duration = jiffies; - ret = cros_ec_keyb_get_state(ckdev, new_state); - for (i = 1; !ret && i < 32; i++) { - memcpy(old_state, new_state, sizeof(old_state)); - ret = cros_ec_keyb_get_state(ckdev, new_state); - if (0 == memcmp(old_state, new_state, sizeof(old_state))) - break; - } - duration = jiffies - duration; - dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i, - jiffies_to_usecs(duration)); -} - -static int cros_ec_keyb_resume(struct device *dev) -{ - struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); - - /* - * When the EC is not a wake source, then it could not have caused the - * resume, so we clear the EC's key scan buffer. If the EC was a - * wake source (e.g. the lid is open and the user might press a key to - * wake) then the key scan buffer should be preserved. - */ - if (!ckdev->ec->was_wake_device) - cros_ec_keyb_clear_keyboard(ckdev); - - return 0; -} - -#endif - -static SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume); - #ifdef CONFIG_OF static const struct of_device_id cros_ec_keyb_of_match[] = { { .compatible = "google,cros-ec-keyb" }, @@ -372,7 +300,6 @@ static struct platform_driver cros_ec_keyb_driver = { .driver = { .name = "cros-ec-keyb", .of_match_table = of_match_ptr(cros_ec_keyb_of_match), - .pm = &cros_ec_keyb_pm_ops, }, }; |