diff options
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r-- | drivers/input/keyboard/Kconfig | 6 | ||||
-rw-r--r-- | drivers/input/keyboard/adp5589-keys.c | 1 | ||||
-rw-r--r-- | drivers/input/keyboard/cap11xx.c | 145 | ||||
-rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 9 | ||||
-rw-r--r-- | drivers/input/keyboard/gpio_keys_polled.c | 5 | ||||
-rw-r--r-- | drivers/input/keyboard/lm8333.c | 1 | ||||
-rw-r--r-- | drivers/input/keyboard/matrix_keypad.c | 6 | ||||
-rw-r--r-- | drivers/input/keyboard/mcs_touchkey.c | 1 | ||||
-rw-r--r-- | drivers/input/keyboard/mpr121_touchkey.c | 1 | ||||
-rw-r--r-- | drivers/input/keyboard/pmic8xxx-keypad.c | 10 | ||||
-rw-r--r-- | drivers/input/keyboard/qt1070.c | 1 | ||||
-rw-r--r-- | drivers/input/keyboard/qt2160.c | 1 | ||||
-rw-r--r-- | drivers/input/keyboard/samsung-keypad.c | 6 | ||||
-rw-r--r-- | drivers/input/keyboard/tc3589x-keypad.c | 63 | ||||
-rw-r--r-- | drivers/input/keyboard/tca8418_keypad.c | 1 |
15 files changed, 194 insertions, 63 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 82a8fb50afac..2e80107ff630 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -187,7 +187,7 @@ config KEYBOARD_EP93XX config KEYBOARD_GPIO tristate "GPIO Buttons" - depends on GPIOLIB + depends on GPIOLIB || COMPILE_TEST help This driver implements support for buttons connected to GPIO pins of various CPUs (and some other chips). @@ -253,7 +253,7 @@ config KEYBOARD_TCA8418 config KEYBOARD_MATRIX tristate "GPIO driven matrix keypad support" - depends on GPIOLIB + depends on GPIOLIB || COMPILE_TEST select INPUT_MATRIXKMAP help Enable support for GPIO driven matrix keypad. @@ -689,7 +689,7 @@ config KEYBOARD_W90P910 config KEYBOARD_CROS_EC tristate "ChromeOS EC keyboard" select INPUT_MATRIXKMAP - depends on CROS_EC_PROTO + depends on MFD_CROS_EC help Say Y here to enable the matrix keyboard used by ChromeOS devices and implemented on the ChromeOS EC. You must enable one bus option diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index 6ed83cf8b74e..4d446d5085aa 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c @@ -1097,7 +1097,6 @@ MODULE_DEVICE_TABLE(i2c, adp5589_id); static struct i2c_driver adp5589_driver = { .driver = { .name = KBUILD_MODNAME, - .owner = THIS_MODULE, .pm = &adp5589_dev_pm_ops, }, .probe = adp5589_probe, diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c index f07461a64d85..378db10001df 100644 --- a/drivers/input/keyboard/cap11xx.c +++ b/drivers/input/keyboard/cap11xx.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/interrupt.h> #include <linux/input.h> +#include <linux/leds.h> #include <linux/of_irq.h> #include <linux/regmap.h> #include <linux/i2c.h> @@ -47,6 +48,20 @@ #define CAP11XX_REG_CONFIG2 0x44 #define CAP11XX_REG_CONFIG2_ALT_POL BIT(6) #define CAP11XX_REG_SENSOR_BASE_CNT(X) (0x50 + (X)) +#define CAP11XX_REG_LED_POLARITY 0x73 +#define CAP11XX_REG_LED_OUTPUT_CONTROL 0x74 + +#define CAP11XX_REG_LED_DUTY_CYCLE_1 0x90 +#define CAP11XX_REG_LED_DUTY_CYCLE_2 0x91 +#define CAP11XX_REG_LED_DUTY_CYCLE_3 0x92 +#define CAP11XX_REG_LED_DUTY_CYCLE_4 0x93 + +#define CAP11XX_REG_LED_DUTY_MIN_MASK (0x0f) +#define CAP11XX_REG_LED_DUTY_MIN_MASK_SHIFT (0) +#define CAP11XX_REG_LED_DUTY_MAX_MASK (0xf0) +#define CAP11XX_REG_LED_DUTY_MAX_MASK_SHIFT (4) +#define CAP11XX_REG_LED_DUTY_MAX_VALUE (15) + #define CAP11XX_REG_SENSOR_CALIB (0xb1 + (X)) #define CAP11XX_REG_SENSOR_CALIB_LSB1 0xb9 #define CAP11XX_REG_SENSOR_CALIB_LSB2 0xba @@ -56,10 +71,23 @@ #define CAP11XX_MANUFACTURER_ID 0x5d +#ifdef CONFIG_LEDS_CLASS +struct cap11xx_led { + struct cap11xx_priv *priv; + struct led_classdev cdev; + struct work_struct work; + u32 reg; + enum led_brightness new_brightness; +}; +#endif + struct cap11xx_priv { struct regmap *regmap; struct input_dev *idev; + struct cap11xx_led *leds; + int num_leds; + /* config */ u32 keycodes[]; }; @@ -67,6 +95,7 @@ struct cap11xx_priv { struct cap11xx_hw_model { u8 product_id; unsigned int num_channels; + unsigned int num_leds; }; enum { @@ -76,9 +105,9 @@ enum { }; static const struct cap11xx_hw_model cap11xx_devices[] = { - [CAP1106] = { .product_id = 0x55, .num_channels = 6 }, - [CAP1126] = { .product_id = 0x53, .num_channels = 6 }, - [CAP1188] = { .product_id = 0x50, .num_channels = 8 }, + [CAP1106] = { .product_id = 0x55, .num_channels = 6, .num_leds = 0 }, + [CAP1126] = { .product_id = 0x53, .num_channels = 6, .num_leds = 2 }, + [CAP1188] = { .product_id = 0x50, .num_channels = 8, .num_leds = 8 }, }; static const struct reg_default cap11xx_reg_defaults[] = { @@ -111,6 +140,7 @@ static const struct reg_default cap11xx_reg_defaults[] = { { CAP11XX_REG_STANDBY_SENSITIVITY, 0x02 }, { CAP11XX_REG_STANDBY_THRESH, 0x40 }, { CAP11XX_REG_CONFIG2, 0x40 }, + { CAP11XX_REG_LED_POLARITY, 0x00 }, { CAP11XX_REG_SENSOR_CALIB_LSB1, 0x00 }, { CAP11XX_REG_SENSOR_CALIB_LSB2, 0x00 }, }; @@ -177,6 +207,12 @@ out: static int cap11xx_set_sleep(struct cap11xx_priv *priv, bool sleep) { + /* + * DLSEEP mode will turn off all LEDS, prevent this + */ + if (IS_ENABLED(CONFIG_LEDS_CLASS) && priv->num_leds) + return 0; + return regmap_update_bits(priv->regmap, CAP11XX_REG_MAIN_CONTROL, CAP11XX_REG_MAIN_CONTROL_DLSEEP, sleep ? CAP11XX_REG_MAIN_CONTROL_DLSEEP : 0); @@ -196,6 +232,104 @@ static void cap11xx_input_close(struct input_dev *idev) cap11xx_set_sleep(priv, true); } +#ifdef CONFIG_LEDS_CLASS +static void cap11xx_led_work(struct work_struct *work) +{ + struct cap11xx_led *led = container_of(work, struct cap11xx_led, work); + struct cap11xx_priv *priv = led->priv; + int value = led->new_brightness; + + /* + * All LEDs share the same duty cycle as this is a HW limitation. + * Brightness levels per LED are either 0 (OFF) and 1 (ON). + */ + regmap_update_bits(priv->regmap, CAP11XX_REG_LED_OUTPUT_CONTROL, + BIT(led->reg), value ? BIT(led->reg) : 0); +} + +static void cap11xx_led_set(struct led_classdev *cdev, + enum led_brightness value) +{ + struct cap11xx_led *led = container_of(cdev, struct cap11xx_led, cdev); + + if (led->new_brightness == value) + return; + + led->new_brightness = value; + schedule_work(&led->work); +} + +static int cap11xx_init_leds(struct device *dev, + struct cap11xx_priv *priv, int num_leds) +{ + struct device_node *node = dev->of_node, *child; + struct cap11xx_led *led; + int cnt = of_get_child_count(node); + int error; + + if (!num_leds || !cnt) + return 0; + + if (cnt > num_leds) + return -EINVAL; + + led = devm_kcalloc(dev, cnt, sizeof(struct cap11xx_led), GFP_KERNEL); + if (!led) + return -ENOMEM; + + priv->leds = led; + + error = regmap_update_bits(priv->regmap, + CAP11XX_REG_LED_OUTPUT_CONTROL, 0xff, 0); + if (error) + return error; + + error = regmap_update_bits(priv->regmap, CAP11XX_REG_LED_DUTY_CYCLE_4, + CAP11XX_REG_LED_DUTY_MAX_MASK, + CAP11XX_REG_LED_DUTY_MAX_VALUE << + CAP11XX_REG_LED_DUTY_MAX_MASK_SHIFT); + if (error) + return error; + + for_each_child_of_node(node, child) { + u32 reg; + + led->cdev.name = + of_get_property(child, "label", NULL) ? : child->name; + led->cdev.default_trigger = + of_get_property(child, "linux,default-trigger", NULL); + led->cdev.flags = 0; + led->cdev.brightness_set = cap11xx_led_set; + led->cdev.max_brightness = 1; + led->cdev.brightness = LED_OFF; + + error = of_property_read_u32(child, "reg", ®); + if (error != 0 || reg >= num_leds) + return -EINVAL; + + led->reg = reg; + led->priv = priv; + + INIT_WORK(&led->work, cap11xx_led_work); + + error = devm_led_classdev_register(dev, &led->cdev); + if (error) + return error; + + priv->num_leds++; + led++; + } + + return 0; +} +#else +static int cap11xx_init_leds(struct device *dev, + struct cap11xx_priv *priv, int num_leds) +{ + return 0; +} +#endif + static int cap11xx_i2c_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) { @@ -316,6 +450,10 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, priv->idev->open = cap11xx_input_open; priv->idev->close = cap11xx_input_close; + error = cap11xx_init_leds(dev, priv, cap->num_leds); + if (error) + return error; + input_set_drvdata(priv->idev, priv); /* @@ -361,7 +499,6 @@ MODULE_DEVICE_TABLE(i2c, cap11xx_i2c_ids); static struct i2c_driver cap11xx_i2c_driver = { .driver = { .name = "cap11xx", - .owner = THIS_MODULE, .of_match_table = cap11xx_dt_ids, }, .id_table = cap11xx_i2c_ids, diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index ddf4045de084..9d517ca7eb5a 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -239,6 +239,11 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, } } + if (i == ddata->pdata->nbuttons) { + error = -EINVAL; + goto out; + } + mutex_lock(&ddata->disable_lock); for (i = 0; i < ddata->pdata->nbuttons; i++) { @@ -655,7 +660,9 @@ gpio_keys_get_devtree_pdata(struct device *dev) if (of_property_read_u32(pp, "linux,input-type", &button->type)) button->type = EV_KEY; - button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); + button->wakeup = of_property_read_bool(pp, "wakeup-source") || + /* legacy name */ + of_property_read_bool(pp, "gpio-key,wakeup"); button->can_disable = !!of_get_property(pp, "linux,can-disable", NULL); diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index c6dc644aa580..870cfa6e2c44 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -152,7 +152,10 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct &button->type)) button->type = EV_KEY; - button->wakeup = fwnode_property_present(child, "gpio-key,wakeup"); + button->wakeup = + fwnode_property_read_bool(child, "wakeup-source") || + /* legacy name */ + fwnode_property_read_bool(child, "gpio-key,wakeup"); if (fwnode_property_read_u32(child, "debounce-interval", &button->debounce_interval)) diff --git a/drivers/input/keyboard/lm8333.c b/drivers/input/keyboard/lm8333.c index 0ad422b8a260..c717e8f3c964 100644 --- a/drivers/input/keyboard/lm8333.c +++ b/drivers/input/keyboard/lm8333.c @@ -223,7 +223,6 @@ MODULE_DEVICE_TABLE(i2c, lm8333_id); static struct i2c_driver lm8333_driver = { .driver = { .name = "lm8333", - .owner = THIS_MODULE, }, .probe = lm8333_probe, .remove = lm8333_remove, diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index b370a59cb759..7f12b6579f82 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -425,8 +425,10 @@ matrix_keypad_parse_dt(struct device *dev) if (of_get_property(np, "linux,no-autorepeat", NULL)) pdata->no_autorepeat = true; - if (of_get_property(np, "linux,wakeup", NULL)) - pdata->wakeup = true; + + pdata->wakeup = of_property_read_bool(np, "wakeup-source") || + of_property_read_bool(np, "linux,wakeup"); /* legacy */ + if (of_get_property(np, "gpio-activelow", NULL)) pdata->active_low = true; diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c index 375b05ca8e2a..31090d71a685 100644 --- a/drivers/input/keyboard/mcs_touchkey.c +++ b/drivers/input/keyboard/mcs_touchkey.c @@ -265,7 +265,6 @@ MODULE_DEVICE_TABLE(i2c, mcs_touchkey_id); static struct i2c_driver mcs_touchkey_driver = { .driver = { .name = "mcs_touchkey", - .owner = THIS_MODULE, .pm = &mcs_touchkey_pm_ops, }, .probe = mcs_touchkey_probe, diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 3aa2ec45bcab..0fd612dd76ed 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -305,7 +305,6 @@ MODULE_DEVICE_TABLE(i2c, mpr121_id); static struct i2c_driver mpr_touchkey_driver = { .driver = { .name = "mpr121", - .owner = THIS_MODULE, .pm = &mpr121_touchkey_pm_ops, }, .id_table = mpr121_id, diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 32580afecc26..5c68e3f096bc 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -507,6 +507,7 @@ static void pmic8xxx_kp_close(struct input_dev *dev) */ static int pmic8xxx_kp_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; unsigned int rows, cols; bool repeat; bool wakeup; @@ -524,10 +525,11 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) return -EINVAL; } - repeat = !of_property_read_bool(pdev->dev.of_node, - "linux,input-no-autorepeat"); - wakeup = of_property_read_bool(pdev->dev.of_node, - "linux,keypad-wakeup"); + repeat = !of_property_read_bool(np, "linux,input-no-autorepeat"); + + wakeup = of_property_read_bool(np, "wakeup-source") || + /* legacy name */ + of_property_read_bool(np, "linux,keypad-wakeup"); kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL); if (!kp) diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c index 52cd6e88acd7..5a5778729e37 100644 --- a/drivers/input/keyboard/qt1070.c +++ b/drivers/input/keyboard/qt1070.c @@ -277,7 +277,6 @@ MODULE_DEVICE_TABLE(i2c, qt1070_id); static struct i2c_driver qt1070_driver = { .driver = { .name = "qt1070", - .owner = THIS_MODULE, .pm = &qt1070_pm_ops, }, .id_table = qt1070_id, diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c index 819b22897c13..43b86482dda0 100644 --- a/drivers/input/keyboard/qt2160.c +++ b/drivers/input/keyboard/qt2160.c @@ -497,7 +497,6 @@ MODULE_DEVICE_TABLE(i2c, qt2160_idtable); static struct i2c_driver qt2160_driver = { .driver = { .name = "qt2160", - .owner = THIS_MODULE, }, .id_table = qt2160_idtable, diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 43e48dac7687..4e319eb9e19d 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -299,8 +299,10 @@ samsung_keypad_parse_dt(struct device *dev) if (of_get_property(np, "linux,input-no-autorepeat", NULL)) pdata->no_autorepeat = true; - if (of_get_property(np, "linux,input-wakeup", NULL)) - pdata->wakeup = true; + pdata->wakeup = of_property_read_bool(np, "wakeup-source") || + /* legacy name */ + of_property_read_bool(np, "linux,input-wakeup"); + return pdata; } diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c index 31c606a4dd31..e92dfd8889c2 100644 --- a/drivers/input/keyboard/tc3589x-keypad.c +++ b/drivers/input/keyboard/tc3589x-keypad.c @@ -17,6 +17,7 @@ #include <linux/i2c.h> #include <linux/slab.h> #include <linux/mfd/tc3589x.h> +#include <linux/device.h> /* Maximum supported keypad matrix row/columns size */ #define TC3589x_MAX_KPROW 8 @@ -352,7 +353,10 @@ tc3589x_keypad_of_probe(struct device *dev) } plat->no_autorepeat = of_property_read_bool(np, "linux,no-autorepeat"); - plat->enable_wakeup = of_property_read_bool(np, "linux,wakeup"); + + plat->enable_wakeup = of_property_read_bool(np, "wakeup-source") || + /* legacy name */ + of_property_read_bool(np, "linux,wakeup"); /* The custom delay format is ms/16 */ of_property_read_u32(np, "debounce-delay-ms", &debounce_ms); @@ -386,12 +390,15 @@ static int tc3589x_keypad_probe(struct platform_device *pdev) if (irq < 0) return irq; - keypad = kzalloc(sizeof(struct tc_keypad), GFP_KERNEL); - input = input_allocate_device(); - if (!keypad || !input) { - dev_err(&pdev->dev, "failed to allocate keypad memory\n"); - error = -ENOMEM; - goto err_free_mem; + keypad = devm_kzalloc(&pdev->dev, sizeof(struct tc_keypad), + GFP_KERNEL); + if (!keypad) + return -ENOMEM; + + input = devm_input_allocate_device(&pdev->dev); + if (!input) { + dev_err(&pdev->dev, "failed to allocate input device\n"); + return -ENOMEM; } keypad->board = plat; @@ -410,7 +417,7 @@ static int tc3589x_keypad_probe(struct platform_device *pdev) NULL, input); if (error) { dev_err(&pdev->dev, "Failed to build keymap\n"); - goto err_free_mem; + return error; } keypad->keymap = input->keycode; @@ -421,20 +428,23 @@ static int tc3589x_keypad_probe(struct platform_device *pdev) input_set_drvdata(input, keypad); - error = request_threaded_irq(irq, NULL, tc3589x_keypad_irq, - plat->irqtype | IRQF_ONESHOT, - "tc3589x-keypad", keypad); - if (error < 0) { + tc3589x_keypad_disable(keypad); + + error = devm_request_threaded_irq(&pdev->dev, irq, + NULL, tc3589x_keypad_irq, + plat->irqtype | IRQF_ONESHOT, + "tc3589x-keypad", keypad); + if (error) { dev_err(&pdev->dev, "Could not allocate irq %d,error %d\n", irq, error); - goto err_free_mem; + return error; } error = input_register_device(input); if (error) { dev_err(&pdev->dev, "Could not register input device\n"); - goto err_free_irq; + return error; } /* let platform decide if keypad is a wakeup source or not */ @@ -444,30 +454,6 @@ static int tc3589x_keypad_probe(struct platform_device *pdev) platform_set_drvdata(pdev, keypad); return 0; - -err_free_irq: - free_irq(irq, keypad); -err_free_mem: - input_free_device(input); - kfree(keypad); - return error; -} - -static int tc3589x_keypad_remove(struct platform_device *pdev) -{ - struct tc_keypad *keypad = platform_get_drvdata(pdev); - int irq = platform_get_irq(pdev, 0); - - if (!keypad->keypad_stopped) - tc3589x_keypad_disable(keypad); - - free_irq(irq, keypad); - - input_unregister_device(keypad->input); - - kfree(keypad); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -518,7 +504,6 @@ static struct platform_driver tc3589x_keypad_driver = { .pm = &tc3589x_keypad_dev_pm_ops, }, .probe = tc3589x_keypad_probe, - .remove = tc3589x_keypad_remove, }; module_platform_driver(tc3589x_keypad_driver); diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 4e491c1762cf..9002298698fc 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -404,7 +404,6 @@ MODULE_ALIAS("i2c:tca8418"); static struct i2c_driver tca8418_keypad_driver = { .driver = { .name = TCA8418_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(tca8418_dt_ids), }, .probe = tca8418_keypad_probe, |