From 890fa16762c7b43677228014387a817380e6114d Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 15 Jan 2017 14:43:15 -0800 Subject: Input: mpr121 - annotate PM methods as __maybe_unused Instead of using #ifdef, let's mark suspend and resume methods as __maybe_unused to provide better compile coverage. Suggested-by: Dmitry Torokhov Signed-off-by: Akinobu Mita Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/mpr121_touchkey.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 0fd612dd76ed..a3fd6e5ebfb5 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -266,8 +266,7 @@ static int mpr_touchkey_probe(struct i2c_client *client, return 0; } -#ifdef CONFIG_PM_SLEEP -static int mpr_suspend(struct device *dev) +static int __maybe_unused mpr_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -279,7 +278,7 @@ static int mpr_suspend(struct device *dev) return 0; } -static int mpr_resume(struct device *dev) +static int __maybe_unused mpr_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client); @@ -292,7 +291,6 @@ static int mpr_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(mpr121_touchkey_pm_ops, mpr_suspend, mpr_resume); -- cgit v1.2.3 From a4b1aeb72662c2a35740bdf2b7e2e19593dd5d48 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 15 Jan 2017 14:43:40 -0800 Subject: Input: mpr121 - remove unused field in struct mpr121_touchkey Remove unused key_val field in struct mpr121_touchkey. Signed-off-by: Akinobu Mita Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/mpr121_touchkey.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index a3fd6e5ebfb5..90be99d58c85 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -59,7 +59,6 @@ struct mpr121_touchkey { struct i2c_client *client; struct input_dev *input_dev; - unsigned int key_val; unsigned int statusbits; unsigned int keycount; u16 keycodes[MPR121_MAX_KEY_COUNT]; -- cgit v1.2.3 From 9723ddc8fe0d76ce41fe0dc16afb241ec7d0a29d Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 15 Jan 2017 14:44:05 -0800 Subject: Input: mpr121 - set missing event capability This driver reports misc scan input events on the sensor's status register changes. But the event capability for them was not set in the device initialization, so these events were ignored. This change adds the missing event capability. Signed-off-by: Akinobu Mita Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/mpr121_touchkey.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 90be99d58c85..2558c602f099 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -230,6 +230,7 @@ static int mpr_touchkey_probe(struct i2c_client *client, input_dev->id.bustype = BUS_I2C; input_dev->dev.parent = &client->dev; input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_dev->keycode = mpr121->keycodes; input_dev->keycodesize = sizeof(mpr121->keycodes[0]); -- cgit v1.2.3 From 08fea55e37f58371bffc5336a59e55d1f155955a Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 15 Jan 2017 14:44:30 -0800 Subject: Input: mpr121 - handle multiple bits change of status register This driver reports input events on their interrupts which are triggered by the sensor's status register changes. But only single bit change is reported in the interrupt handler. So if there are multiple bits are changed at almost the same time, other press or release events are ignored. This fixes it by detecting all changed bits in the status register. Signed-off-by: Akinobu Mita Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/mpr121_touchkey.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 2558c602f099..83dd5616e470 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -86,7 +86,8 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) struct mpr121_touchkey *mpr121 = dev_id; struct i2c_client *client = mpr121->client; struct input_dev *input = mpr121->input_dev; - unsigned int key_num, key_val, pressed; + unsigned long bit_changed; + unsigned int key_num; int reg; reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR); @@ -104,18 +105,22 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) reg &= TOUCH_STATUS_MASK; /* use old press bit to figure out which bit changed */ - key_num = ffs(reg ^ mpr121->statusbits) - 1; - pressed = reg & (1 << key_num); + bit_changed = reg ^ mpr121->statusbits; mpr121->statusbits = reg; + for_each_set_bit(key_num, &bit_changed, mpr121->keycount) { + unsigned int key_val, pressed; - key_val = mpr121->keycodes[key_num]; + pressed = reg & BIT(key_num); + key_val = mpr121->keycodes[key_num]; - input_event(input, EV_MSC, MSC_SCAN, key_num); - input_report_key(input, key_val, pressed); - input_sync(input); + input_event(input, EV_MSC, MSC_SCAN, key_num); + input_report_key(input, key_val, pressed); + + dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val, + pressed ? "pressed" : "released"); - dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val, - pressed ? "pressed" : "released"); + } + input_sync(input); out: return IRQ_HANDLED; -- cgit v1.2.3 From de901cc31d151c4c855346c29fb61eaf5ffac3ad Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sun, 15 Jan 2017 14:51:12 -0800 Subject: Input: mpr121 - switch to device tree probe This driver currently only supports legacy platform data probe. This change adds device tree support and gets rid of platform data probe code since no one is actually using mpr121 platform data in the mainline. The device tree property parsing code is based on the work of atmel_captouch driver. Signed-off-by: Akinobu Mita Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/mpr121-touchkey.txt | 30 +++++ drivers/input/keyboard/mpr121_touchkey.c | 137 ++++++++++++++------- include/linux/i2c/mpr121_touchkey.h | 20 --- 3 files changed, 124 insertions(+), 63 deletions(-) create mode 100644 Documentation/devicetree/bindings/input/mpr121-touchkey.txt delete mode 100644 include/linux/i2c/mpr121_touchkey.h (limited to 'drivers/input/keyboard') diff --git a/Documentation/devicetree/bindings/input/mpr121-touchkey.txt b/Documentation/devicetree/bindings/input/mpr121-touchkey.txt new file mode 100644 index 000000000000..b7c61ee5841b --- /dev/null +++ b/Documentation/devicetree/bindings/input/mpr121-touchkey.txt @@ -0,0 +1,30 @@ +* Freescale MPR121 Controllor + +Required Properties: +- compatible: Should be "fsl,mpr121-touchkey" +- reg: The I2C slave address of the device. +- interrupts: The interrupt number to the cpu. +- vdd-supply: Phandle to the Vdd power supply. +- linux,keycodes: Specifies an array of numeric keycode values to + be used for reporting button presses. The array can + contain up to 12 entries. + +Optional Properties: +- wakeup-source: Use any event on keypad as wakeup event. +- autorepeat: Enable autorepeat feature. + +Example: + +#include "dt-bindings/input/input.h" + + touchkey: mpr121@5a { + compatible = "fsl,mpr121-touchkey"; + reg = <0x5a>; + interrupt-parent = <&gpio1>; + interrupts = <28 2>; + autorepeat; + vdd-supply = <&ldo4_reg>; + linux,keycodes = , , , , + , , , + , , , ; + }; diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 83dd5616e470..989ca66f63af 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -12,14 +12,16 @@ * */ -#include -#include -#include -#include -#include #include +#include +#include +#include #include -#include +#include +#include +#include +#include +#include /* Register definitions */ #define ELE_TOUCH_STATUS_0_ADDR 0x0 @@ -61,7 +63,7 @@ struct mpr121_touchkey { struct input_dev *input_dev; unsigned int statusbits; unsigned int keycount; - u16 keycodes[MPR121_MAX_KEY_COUNT]; + u32 keycodes[MPR121_MAX_KEY_COUNT]; }; struct mpr121_init_register { @@ -81,6 +83,42 @@ static const struct mpr121_init_register init_reg_table[] = { { AUTO_CONFIG_CTRL_ADDR, 0x0b }, }; +static void mpr121_vdd_supply_disable(void *data) +{ + struct regulator *vdd_supply = data; + + regulator_disable(vdd_supply); +} + +static struct regulator *mpr121_vdd_supply_init(struct device *dev) +{ + struct regulator *vdd_supply; + int err; + + vdd_supply = devm_regulator_get(dev, "vdd"); + if (IS_ERR(vdd_supply)) { + dev_err(dev, "failed to get vdd regulator: %ld\n", + PTR_ERR(vdd_supply)); + return vdd_supply; + } + + err = regulator_enable(vdd_supply); + if (err) { + dev_err(dev, "failed to enable vdd regulator: %d\n", err); + return ERR_PTR(err); + } + + err = devm_add_action(dev, mpr121_vdd_supply_disable, vdd_supply); + if (err) { + regulator_disable(vdd_supply); + dev_err(dev, "failed to add disable regulator action: %d\n", + err); + return ERR_PTR(err); + } + + return vdd_supply; +} + static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) { struct mpr121_touchkey *mpr121 = dev_id; @@ -126,9 +164,8 @@ out: return IRQ_HANDLED; } -static int mpr121_phys_init(const struct mpr121_platform_data *pdata, - struct mpr121_touchkey *mpr121, - struct i2c_client *client) +static int mpr121_phys_init(struct mpr121_touchkey *mpr121, + struct i2c_client *client, int vdd_uv) { const struct mpr121_init_register *reg; unsigned char usl, lsl, tl, eleconf; @@ -158,9 +195,9 @@ static int mpr121_phys_init(const struct mpr121_platform_data *pdata, /* * Capacitance on sensing input varies and needs to be compensated. * The internal MPR121-auto-configuration can do this if it's - * registers are set properly (based on pdata->vdd_uv). + * registers are set properly (based on vdd_uv). */ - vdd = pdata->vdd_uv / 1000; + vdd = vdd_uv / 1000; usl = ((vdd - 700) * 256) / vdd; lsl = (usl * 65) / 100; tl = (usl * 90) / 100; @@ -191,35 +228,26 @@ err_i2c_write: static int mpr_touchkey_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct mpr121_platform_data *pdata = - dev_get_platdata(&client->dev); + struct device *dev = &client->dev; + struct regulator *vdd_supply; + int vdd_uv; struct mpr121_touchkey *mpr121; struct input_dev *input_dev; int error; int i; - if (!pdata) { - dev_err(&client->dev, "no platform data defined\n"); - return -EINVAL; - } - - if (!pdata->keymap || !pdata->keymap_size) { - dev_err(&client->dev, "missing keymap data\n"); - return -EINVAL; - } - - if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) { - dev_err(&client->dev, "too many keys defined\n"); - return -EINVAL; - } - if (!client->irq) { dev_err(&client->dev, "irq number should not be zero\n"); return -EINVAL; } - mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121), - GFP_KERNEL); + vdd_supply = mpr121_vdd_supply_init(dev); + if (IS_ERR(vdd_supply)) + return PTR_ERR(vdd_supply); + + vdd_uv = regulator_get_voltage(vdd_supply); + + mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121), GFP_KERNEL); if (!mpr121) return -ENOMEM; @@ -229,33 +257,46 @@ static int mpr_touchkey_probe(struct i2c_client *client, mpr121->client = client; mpr121->input_dev = input_dev; - mpr121->keycount = pdata->keymap_size; + mpr121->keycount = device_property_read_u32_array(dev, "linux,keycodes", + NULL, 0); + if (mpr121->keycount > MPR121_MAX_KEY_COUNT) { + dev_err(dev, "too many keys defined (%d)\n", mpr121->keycount); + return -EINVAL; + } + + error = device_property_read_u32_array(dev, "linux,keycodes", + mpr121->keycodes, + mpr121->keycount); + if (error) { + dev_err(dev, + "failed to read linux,keycode property: %d\n", error); + return error; + } input_dev->name = "Freescale MPR121 Touchkey"; input_dev->id.bustype = BUS_I2C; input_dev->dev.parent = &client->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + if (device_property_read_bool(dev, "autorepeat")) + __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_dev->keycode = mpr121->keycodes; input_dev->keycodesize = sizeof(mpr121->keycodes[0]); input_dev->keycodemax = mpr121->keycount; - for (i = 0; i < pdata->keymap_size; i++) { - input_set_capability(input_dev, EV_KEY, pdata->keymap[i]); - mpr121->keycodes[i] = pdata->keymap[i]; - } + for (i = 0; i < mpr121->keycount; i++) + input_set_capability(input_dev, EV_KEY, mpr121->keycodes[i]); - error = mpr121_phys_init(pdata, mpr121, client); + error = mpr121_phys_init(mpr121, client, vdd_uv); if (error) { dev_err(&client->dev, "Failed to init register\n"); return error; } - error = devm_request_threaded_irq(&client->dev, client->irq, NULL, - mpr_touchkey_interrupt, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - client->dev.driver->name, mpr121); + error = devm_request_threaded_irq(&client->dev, client->irq, + NULL, mpr_touchkey_interrupt, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + client->dev.driver->name, mpr121); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); return error; @@ -266,7 +307,8 @@ static int mpr_touchkey_probe(struct i2c_client *client, return error; i2c_set_clientdata(client, mpr121); - device_init_wakeup(&client->dev, pdata->wakeup); + device_init_wakeup(dev, + device_property_read_bool(dev, "wakeup-source")); return 0; } @@ -305,10 +347,19 @@ static const struct i2c_device_id mpr121_id[] = { }; MODULE_DEVICE_TABLE(i2c, mpr121_id); +#ifdef CONFIG_OF +static const struct of_device_id mpr121_touchkey_dt_match_table[] = { + { .compatible = "fsl,mpr121-touchkey" }, + { }, +}; +MODULE_DEVICE_TABLE(of, mpr121_touchkey_dt_match_table); +#endif + static struct i2c_driver mpr_touchkey_driver = { .driver = { .name = "mpr121", .pm = &mpr121_touchkey_pm_ops, + .of_match_table = of_match_ptr(mpr121_touchkey_dt_match_table), }, .id_table = mpr121_id, .probe = mpr_touchkey_probe, diff --git a/include/linux/i2c/mpr121_touchkey.h b/include/linux/i2c/mpr121_touchkey.h deleted file mode 100644 index f0bcc38bbb97..000000000000 --- a/include/linux/i2c/mpr121_touchkey.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Header file for Freescale MPR121 Capacitive Touch Sensor */ - -#ifndef _MPR121_TOUCHKEY_H -#define _MPR121_TOUCHKEY_H - -/** - * struct mpr121_platform_data - platform data for mpr121 sensor - * @keymap: pointer to array of KEY_* values representing keymap - * @keymap_size: size of the keymap - * @wakeup: configure the button as a wake-up source - * @vdd_uv: VDD voltage in uV - */ -struct mpr121_platform_data { - const unsigned short *keymap; - unsigned int keymap_size; - bool wakeup; - int vdd_uv; -}; - -#endif /* _MPR121_TOUCHKEY_H */ -- cgit v1.2.3 From 259b77ef853cc375a5c9198cf81f9b79fc19413c Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 17 Jan 2017 13:24:22 -0800 Subject: Input: tca8418 - use the interrupt trigger from the device tree The TCA8418 might be used using different interrupt triggers on various boards. This is not working so far because the current code forces a falling edge trigger. The device tree already provides a trigger type, so let's use whatever it sets up, and since we can be loaded without DT, keep the old behaviour for the non-DT case. Signed-off-by: Maxime Ripard Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/tca8418_keypad.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 3048ef3e3e16..11d5c76d9fb4 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -277,6 +277,7 @@ static int tca8418_keypad_probe(struct i2c_client *client, bool irq_is_gpio = false; int irq; int error, row_shift, max_keys; + unsigned long trigger = 0; /* Copy the platform data */ if (pdata) { @@ -289,6 +290,7 @@ static int tca8418_keypad_probe(struct i2c_client *client, cols = pdata->cols; rep = pdata->rep; irq_is_gpio = pdata->irq_is_gpio; + trigger = IRQF_TRIGGER_FALLING; } else { struct device_node *np = dev->of_node; int err; @@ -363,9 +365,7 @@ static int tca8418_keypad_probe(struct i2c_client *client, irq = gpio_to_irq(irq); error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler, - IRQF_TRIGGER_FALLING | - IRQF_SHARED | - IRQF_ONESHOT, + trigger | IRQF_SHARED | IRQF_ONESHOT, client->name, keypad_data); if (error) { dev_err(dev, "Unable to claim irq %d; error %d\n", -- cgit v1.2.3 From 2057e15945a8b5d867c086371a5fb946fd8221da Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 18 Jan 2017 10:37:49 -0800 Subject: Input: cros_ec_keyb - drop unnecessary call to dev_set_drvdata and other changes There is no call to platform_get_drvdata() or dev_get_drvdata(). Drop the unnecessary call to dev_set_drvdata(). Other relevant changes: Use existing variable 'dev' instead of dereferencing it several times This conversion was done automatically with coccinelle using the following semantic patches. The semantic patches and the scripts used to generate this commit log are available at https://github.com/groeck/coccinelle-patches - Drop dev_set_drvdata() - Use local variable 'struct device *dev' consistently Signed-off-by: Guenter Roeck Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/cros_ec_keyb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 4b0878f35471..165c722408aa 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -242,7 +242,7 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) struct device_node *np; int err; - np = pdev->dev.of_node; + np = dev->of_node; if (!np) return -ENODEV; @@ -272,7 +272,6 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) ckdev->ec = ec; ckdev->dev = dev; - dev_set_drvdata(dev, ckdev); idev->name = CROS_EC_DEV_NAME; idev->phys = ec->phys_name; -- cgit v1.2.3 From e634d08dec48023394f816cdf17cc9f040b8d56f Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 18 Jan 2017 11:45:25 -0800 Subject: Input: twl4030_keypad - drop unnecessary call to platform_set_drvdata There is no call to platform_get_drvdata() or dev_get_drvdata(). Drop the unnecessary call to platform_set_drvdata(). Signed-off-by: Guenter Roeck Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/twl4030_keypad.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 323a0fb575a4..29396ca69416 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -441,7 +441,6 @@ static int twl4030_kp_probe(struct platform_device *pdev) return -EIO; } - platform_set_drvdata(pdev, kp); return 0; } -- cgit v1.2.3 From 8beb7172b428a63634684a8a2bf8754002756056 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 18 Jan 2017 11:48:11 -0800 Subject: Input: bcm-keypad - drop unnecessary call to platform_set_drvdata There is no call to platform_get_drvdata() or dev_get_drvdata(). Drop the unnecessary call to platform_set_drvdata(). Signed-off-by: Guenter Roeck Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/bcm-keypad.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/bcm-keypad.c b/drivers/input/keyboard/bcm-keypad.c index 86a8b723ae15..2b4e63d81e6d 100644 --- a/drivers/input/keyboard/bcm-keypad.c +++ b/drivers/input/keyboard/bcm-keypad.c @@ -352,8 +352,6 @@ static int bcm_kp_probe(struct platform_device *pdev) kp->input_dev = input_dev; - platform_set_drvdata(pdev, kp); - error = bcm_kp_matrix_key_parse_dt(kp); if (error) return error; -- cgit v1.2.3 From 72d1f2346ded5b1743d7938f4522550b4da9c82d Mon Sep 17 00:00:00 2001 From: Jaechul Lee Date: Wed, 18 Jan 2017 14:35:42 -0800 Subject: Input: tm2-touchkey - add touchkey driver support for TM2 This patch adds support for the TM2 touch key and led functionality. The driver interfaces with userspace through an input device and reports KEY_PHONE and KEY_BACK event types. LED brightness can be controlled by "/sys/class/leds/tm2-touchkey/brightness". Signed-off-by: Beomho Seo Signed-off-by: Jaechul Lee Reviewed-by: Javier Martinez Canillas Reviewed-by: Andi Shyti Reviewed-by: Chanwoo Choi Tested-by: Chanwoo Choi Acked-by: Krzysztof Kozlowski Acked-by: Rob Herring Signed-off-by: Dmitry Torokhov --- .../bindings/input/cypress,tm2-touchkey.txt | 27 ++ drivers/input/keyboard/Kconfig | 11 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/tm2-touchkey.c | 286 +++++++++++++++++++++ 4 files changed, 325 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt create mode 100644 drivers/input/keyboard/tm2-touchkey.c (limited to 'drivers/input/keyboard') diff --git a/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt b/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt new file mode 100644 index 000000000000..635f62c756ee --- /dev/null +++ b/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt @@ -0,0 +1,27 @@ +Samsung tm2-touchkey + +Required properties: +- compatible: must be "cypress,tm2-touchkey" +- reg: I2C address of the chip. +- interrupt-parent: a phandle for the interrupt controller (see interrupt + binding[0]). +- interrupts: interrupt to which the chip is connected (see interrupt + binding[0]). +- vcc-supply : internal regulator output. 1.8V +- vdd-supply : power supply for IC 3.3V + +[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt + +Example: + &i2c0 { + /* ... */ + + touchkey@20 { + compatible = "cypress,tm2-touchkey"; + reg = <0x20>; + interrupt-parent = <&gpa3>; + interrupts = <2 IRQ_TYPE_EDGE_FALLING>; + vcc-supply=<&ldo32_reg>; + vdd-supply=<&ldo33_reg>; + }; + }; diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index cbd75cf44739..97acd6524ad7 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -666,6 +666,17 @@ config KEYBOARD_TC3589X To compile this driver as a module, choose M here: the module will be called tc3589x-keypad. +config KEYBOARD_TM2_TOUCHKEY + tristate "TM2 touchkey support" + depends on I2C + depends on LEDS_CLASS + help + Say Y here to enable device driver for tm2-touchkey with + LED control for the Exynos5433 TM2 board. + + To compile this driver as a module, choose M here. + module will be called tm2-touchkey. + config KEYBOARD_TWL4030 tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" depends on TWL4030_CORE diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index d9f4cfcf3410..7d9acff819a7 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -61,6 +61,7 @@ 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 +obj-$(CONFIG_KEYBOARD_TM2_TOUCHKEY) += tm2-touchkey.o obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o diff --git a/drivers/input/keyboard/tm2-touchkey.c b/drivers/input/keyboard/tm2-touchkey.c new file mode 100644 index 000000000000..916e2f3a9bbb --- /dev/null +++ b/drivers/input/keyboard/tm2-touchkey.c @@ -0,0 +1,286 @@ +/* + * TM2 touchkey device driver + * + * Copyright 2005 Phil Blundell + * Copyright 2016 Samsung Electronics Co., Ltd. + * + * Author: Beomho Seo + * Author: Jaechul Lee + * + * 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 + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TM2_TOUCHKEY_DEV_NAME "tm2-touchkey" +#define TM2_TOUCHKEY_KEYCODE_REG 0x03 +#define TM2_TOUCHKEY_BASE_REG 0x00 +#define TM2_TOUCHKEY_CMD_LED_ON 0x10 +#define TM2_TOUCHKEY_CMD_LED_OFF 0x20 +#define TM2_TOUCHKEY_BIT_PRESS_EV BIT(3) +#define TM2_TOUCHKEY_BIT_KEYCODE GENMASK(2, 0) +#define TM2_TOUCHKEY_LED_VOLTAGE_MIN 2500000 +#define TM2_TOUCHKEY_LED_VOLTAGE_MAX 3300000 + +enum { + TM2_TOUCHKEY_KEY_MENU = 0x1, + TM2_TOUCHKEY_KEY_BACK, +}; + +struct tm2_touchkey_data { + struct i2c_client *client; + struct input_dev *input_dev; + struct led_classdev led_dev; + struct regulator *vdd; + struct regulator_bulk_data regulators[2]; +}; + +static void tm2_touchkey_led_brightness_set(struct led_classdev *led_dev, + enum led_brightness brightness) +{ + struct tm2_touchkey_data *touchkey = + container_of(led_dev, struct tm2_touchkey_data, led_dev); + u32 volt; + u8 data; + + if (brightness == LED_OFF) { + volt = TM2_TOUCHKEY_LED_VOLTAGE_MIN; + data = TM2_TOUCHKEY_CMD_LED_OFF; + } else { + volt = TM2_TOUCHKEY_LED_VOLTAGE_MAX; + data = TM2_TOUCHKEY_CMD_LED_ON; + } + + regulator_set_voltage(touchkey->vdd, volt, volt); + i2c_smbus_write_byte_data(touchkey->client, + TM2_TOUCHKEY_BASE_REG, data); +} + +static int tm2_touchkey_power_enable(struct tm2_touchkey_data *touchkey) +{ + int error; + + error = regulator_bulk_enable(ARRAY_SIZE(touchkey->regulators), + touchkey->regulators); + if (error) + return error; + + /* waiting for device initialization, at least 150ms */ + msleep(150); + + return 0; +} + +static void tm2_touchkey_power_disable(void *data) +{ + struct tm2_touchkey_data *touchkey = data; + + regulator_bulk_disable(ARRAY_SIZE(touchkey->regulators), + touchkey->regulators); +} + +static irqreturn_t tm2_touchkey_irq_handler(int irq, void *devid) +{ + struct tm2_touchkey_data *touchkey = devid; + int data; + int key; + + data = i2c_smbus_read_byte_data(touchkey->client, + TM2_TOUCHKEY_KEYCODE_REG); + if (data < 0) { + dev_err(&touchkey->client->dev, + "failed to read i2c data: %d\n", data); + goto out; + } + + switch (data & TM2_TOUCHKEY_BIT_KEYCODE) { + case TM2_TOUCHKEY_KEY_MENU: + key = KEY_PHONE; + break; + + case TM2_TOUCHKEY_KEY_BACK: + key = KEY_BACK; + break; + + default: + dev_warn(&touchkey->client->dev, + "unhandled keycode, data %#02x\n", data); + goto out; + } + + if (data & TM2_TOUCHKEY_BIT_PRESS_EV) { + input_report_key(touchkey->input_dev, KEY_PHONE, 0); + input_report_key(touchkey->input_dev, KEY_BACK, 0); + } else { + input_report_key(touchkey->input_dev, key, 1); + } + + input_sync(touchkey->input_dev); + +out: + return IRQ_HANDLED; +} + +static int tm2_touchkey_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tm2_touchkey_data *touchkey; + int error; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&client->dev, "incompatible I2C adapter\n"); + return -EIO; + } + + touchkey = devm_kzalloc(&client->dev, sizeof(*touchkey), GFP_KERNEL); + if (!touchkey) + return -ENOMEM; + + touchkey->client = client; + i2c_set_clientdata(client, touchkey); + + touchkey->regulators[0].supply = "vcc"; + touchkey->regulators[1].supply = "vdd"; + error = devm_regulator_bulk_get(&client->dev, + ARRAY_SIZE(touchkey->regulators), + touchkey->regulators); + if (error) { + dev_err(&client->dev, "failed to get regulators: %d\n", error); + return error; + } + + /* Save VDD for easy access */ + touchkey->vdd = touchkey->regulators[1].consumer; + + error = tm2_touchkey_power_enable(touchkey); + if (error) { + dev_err(&client->dev, "failed to power up device: %d\n", error); + return error; + } + + error = devm_add_action_or_reset(&client->dev, + tm2_touchkey_power_disable, touchkey); + if (error) { + dev_err(&client->dev, + "failed to install poweroff handler: %d\n", error); + return error; + } + + /* input device */ + touchkey->input_dev = devm_input_allocate_device(&client->dev); + if (!touchkey->input_dev) { + dev_err(&client->dev, "failed to allocate input device\n"); + return -ENOMEM; + } + + touchkey->input_dev->name = TM2_TOUCHKEY_DEV_NAME; + touchkey->input_dev->id.bustype = BUS_I2C; + + input_set_capability(touchkey->input_dev, EV_KEY, KEY_PHONE); + input_set_capability(touchkey->input_dev, EV_KEY, KEY_BACK); + + input_set_drvdata(touchkey->input_dev, touchkey); + + error = input_register_device(touchkey->input_dev); + if (error) { + dev_err(&client->dev, + "failed to register input device: %d\n", error); + return error; + } + + error = devm_request_threaded_irq(&client->dev, client->irq, + NULL, tm2_touchkey_irq_handler, + IRQF_ONESHOT, + TM2_TOUCHKEY_DEV_NAME, touchkey); + if (error) { + dev_err(&client->dev, + "failed to request threaded irq: %d\n", error); + return error; + } + + /* led device */ + touchkey->led_dev.name = TM2_TOUCHKEY_DEV_NAME; + touchkey->led_dev.brightness = LED_FULL; + touchkey->led_dev.max_brightness = LED_FULL; + touchkey->led_dev.brightness_set = tm2_touchkey_led_brightness_set; + + error = devm_led_classdev_register(&client->dev, &touchkey->led_dev); + if (error) { + dev_err(&client->dev, + "failed to register touchkey led: %d\n", error); + return error; + } + + return 0; +} + +static int __maybe_unused tm2_touchkey_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct tm2_touchkey_data *touchkey = i2c_get_clientdata(client); + + disable_irq(client->irq); + tm2_touchkey_power_disable(touchkey); + + return 0; +} + +static int __maybe_unused tm2_touchkey_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct tm2_touchkey_data *touchkey = i2c_get_clientdata(client); + int ret; + + enable_irq(client->irq); + + ret = tm2_touchkey_power_enable(touchkey); + if (ret) + dev_err(dev, "failed to enable power: %d\n", ret); + + return ret; +} + +static SIMPLE_DEV_PM_OPS(tm2_touchkey_pm_ops, + tm2_touchkey_suspend, tm2_touchkey_resume); + +static const struct i2c_device_id tm2_touchkey_id_table[] = { + { TM2_TOUCHKEY_DEV_NAME, 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, tm2_touchkey_id_table); + +static const struct of_device_id tm2_touchkey_of_match[] = { + { .compatible = "cypress,tm2-touchkey", }, + { }, +}; +MODULE_DEVICE_TABLE(of, tm2_touchkey_of_match); + +static struct i2c_driver tm2_touchkey_driver = { + .driver = { + .name = TM2_TOUCHKEY_DEV_NAME, + .pm = &tm2_touchkey_pm_ops, + .of_match_table = of_match_ptr(tm2_touchkey_of_match), + }, + .probe = tm2_touchkey_probe, + .id_table = tm2_touchkey_id_table, +}; +module_i2c_driver(tm2_touchkey_driver); + +MODULE_AUTHOR("Beomho Seo "); +MODULE_AUTHOR("Jaechul Lee "); +MODULE_DESCRIPTION("Samsung touchkey driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 83e4947a569f4d544ef4a1361f51c91d73a9c915 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 21 Jan 2017 11:16:47 -0800 Subject: Input: gpio-keys - add support for setkeycode gpio-keys input devices created by the soc_button_array driver are configured with key-codes based on ACPI provided information. Unfortunately on some tablets this info is wrong, and we need to have a quirk to fix things up. Add support for input_setkeycode to the gpio-keys driver, so that the existing udev hwdb mechanism can be used to fix things up on these tablets. Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 40 ++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 582462d0af75..858bbc16b900 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -36,6 +36,8 @@ struct gpio_button_data { struct input_dev *input; struct gpio_desc *gpiod; + unsigned short *code; + struct timer_list release_timer; unsigned int release_delay; /* in msecs, for IRQ-only buttons */ @@ -52,6 +54,7 @@ struct gpio_keys_drvdata { const struct gpio_keys_platform_data *pdata; struct input_dev *input; struct mutex disable_lock; + unsigned short *keymap; struct gpio_button_data data[0]; }; @@ -203,7 +206,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, if (only_disabled && !bdata->disabled) continue; - __set_bit(bdata->button->code, bits); + __set_bit(*bdata->code, bits); } ret = scnprintf(buf, PAGE_SIZE - 1, "%*pbl", n_events, bits); @@ -254,7 +257,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, if (bdata->button->type != type) continue; - if (test_bit(bdata->button->code, bits) && + if (test_bit(*bdata->code, bits) && !bdata->button->can_disable) { error = -EINVAL; goto out; @@ -269,7 +272,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, if (bdata->button->type != type) continue; - if (test_bit(bdata->button->code, bits)) + if (test_bit(*bdata->code, bits)) gpio_keys_disable_button(bdata); else gpio_keys_enable_button(bdata); @@ -371,7 +374,7 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) if (state) input_event(input, type, button->code, button->value); } else { - input_event(input, type, button->code, state); + input_event(input, type, *bdata->code, state); } input_sync(input); } @@ -411,7 +414,7 @@ static void gpio_keys_irq_timer(unsigned long _data) spin_lock_irqsave(&bdata->lock, flags); if (bdata->key_pressed) { - input_event(input, EV_KEY, bdata->button->code, 0); + input_event(input, EV_KEY, *bdata->code, 0); input_sync(input); bdata->key_pressed = false; } @@ -421,7 +424,6 @@ static void gpio_keys_irq_timer(unsigned long _data) static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) { struct gpio_button_data *bdata = dev_id; - const struct gpio_keys_button *button = bdata->button; struct input_dev *input = bdata->input; unsigned long flags; @@ -433,11 +435,11 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) if (bdata->button->wakeup) pm_wakeup_event(bdata->input->dev.parent, 0); - input_event(input, EV_KEY, button->code, 1); + input_event(input, EV_KEY, *bdata->code, 1); input_sync(input); if (!bdata->release_delay) { - input_event(input, EV_KEY, button->code, 0); + input_event(input, EV_KEY, *bdata->code, 0); input_sync(input); goto out; } @@ -465,12 +467,14 @@ 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, + struct gpio_keys_drvdata *ddata, const struct gpio_keys_button *button, + int idx, struct fwnode_handle *child) { const char *desc = button->desc ? button->desc : "gpio_keys"; struct device *dev = &pdev->dev; + struct gpio_button_data *bdata = &ddata->data[idx]; irq_handler_t isr; unsigned long irqflags; int irq; @@ -577,7 +581,9 @@ static int gpio_keys_setup_key(struct platform_device *pdev, irqflags = 0; } - input_set_capability(input, button->type ?: EV_KEY, button->code); + bdata->code = &ddata->keymap[idx]; + *bdata->code = button->code; + input_set_capability(input, button->type ?: EV_KEY, *bdata->code); /* * Install custom action to cancel release timer and @@ -750,6 +756,12 @@ static int gpio_keys_probe(struct platform_device *pdev) return -ENOMEM; } + ddata->keymap = devm_kcalloc(dev, + pdata->nbuttons, sizeof(ddata->keymap[0]), + GFP_KERNEL); + if (!ddata->keymap) + return -ENOMEM; + input = devm_input_allocate_device(dev); if (!input) { dev_err(dev, "failed to allocate input device\n"); @@ -774,13 +786,16 @@ static int gpio_keys_probe(struct platform_device *pdev) input->id.product = 0x0001; input->id.version = 0x0100; + input->keycode = ddata->keymap; + input->keycodesize = sizeof(ddata->keymap[0]); + input->keycodemax = pdata->nbuttons; + /* Enable auto repeat feature of Linux input subsystem */ if (pdata->rep) __set_bit(EV_REP, input->evbit); for (i = 0; i < pdata->nbuttons; i++) { const struct gpio_keys_button *button = &pdata->buttons[i]; - struct gpio_button_data *bdata = &ddata->data[i]; if (!dev_get_platdata(dev)) { child = device_get_next_child_node(&pdev->dev, child); @@ -792,7 +807,8 @@ static int gpio_keys_probe(struct platform_device *pdev) } } - error = gpio_keys_setup_key(pdev, input, bdata, button, child); + error = gpio_keys_setup_key(pdev, input, ddata, + button, i, child); if (error) { fwnode_handle_put(child); return error; -- cgit v1.2.3 From 666c0b8366b8d5d44251a3889f6a2c264a38dee9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 21 Jan 2017 23:29:36 -0800 Subject: Input: keyboard - drop calls to platform_set_drvdata and i2c_set_clientdata There is no call to i2c_get_clientdata(), platform_get_drvdata(), or dev_get_drvdata() in any of the drivers in this patch. Signed-off-by: Guenter Roeck Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/adc-keys.c | 2 -- drivers/input/keyboard/cap11xx.c | 1 - drivers/input/keyboard/gpio_keys_polled.c | 1 - drivers/input/keyboard/jornada680_kbd.c | 2 -- drivers/input/keyboard/max7359_keypad.c | 1 - drivers/input/keyboard/nspire-keypad.c | 2 -- drivers/input/keyboard/opencores-kbd.c | 2 -- drivers/input/keyboard/sun4i-lradc-keys.c | 1 - 8 files changed, 12 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/adc-keys.c b/drivers/input/keyboard/adc-keys.c index f8cf2ccacefd..c255af21e71a 100644 --- a/drivers/input/keyboard/adc-keys.c +++ b/drivers/input/keyboard/adc-keys.c @@ -148,8 +148,6 @@ static int adc_keys_probe(struct platform_device *pdev) if (error) return error; - platform_set_drvdata(pdev, st); - poll_dev = devm_input_allocate_polled_device(dev); if (!poll_dev) { dev_err(dev, "failed to allocate input device\n"); diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c index 4401be225d64..1a1eacae3ea1 100644 --- a/drivers/input/keyboard/cap11xx.c +++ b/drivers/input/keyboard/cap11xx.c @@ -392,7 +392,6 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, return error; dev_info(dev, "CAP11XX detected, revision 0x%02x\n", rev); - i2c_set_clientdata(i2c_client, priv); node = dev->of_node; if (!of_property_read_u32(node, "microchip,sensor-gain", &gain32)) { diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index bed4f2086158..cc193e665358 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -365,7 +365,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) bdev->poll_dev = poll_dev; bdev->dev = dev; bdev->pdata = pdata; - platform_set_drvdata(pdev, bdev); error = input_register_polled_device(poll_dev); if (error) { diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 80c81278ad2c..0116ac99f44c 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c @@ -197,8 +197,6 @@ static int jornada680kbd_probe(struct platform_device *pdev) return -ENOMEM; } - platform_set_drvdata(pdev, jornadakbd); - jornadakbd->poll_dev = poll_dev; memcpy(jornadakbd->keymap, jornada_scancodes, diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index 5091133b7b8e..cd44d22d8770 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c @@ -241,7 +241,6 @@ static int max7359_probe(struct i2c_client *client, /* Initialize MAX7359 */ max7359_initialize(client); - i2c_set_clientdata(client, keypad); device_init_wakeup(&client->dev, 1); return 0; diff --git a/drivers/input/keyboard/nspire-keypad.c b/drivers/input/keyboard/nspire-keypad.c index 7abfd34eb87e..c7f26fa3034c 100644 --- a/drivers/input/keyboard/nspire-keypad.c +++ b/drivers/input/keyboard/nspire-keypad.c @@ -249,8 +249,6 @@ static int nspire_keypad_probe(struct platform_device *pdev) return error; } - platform_set_drvdata(pdev, keypad); - dev_dbg(&pdev->dev, "TI-NSPIRE keypad at %pR (scan_interval=%uus, row_delay=%uus%s)\n", res, keypad->row_delay, keypad->scan_interval, diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c index f8502bb29176..98ea6190f5f5 100644 --- a/drivers/input/keyboard/opencores-kbd.c +++ b/drivers/input/keyboard/opencores-kbd.c @@ -112,8 +112,6 @@ static int opencores_kbd_probe(struct platform_device *pdev) return error; } - platform_set_drvdata(pdev, opencores_kbd); - return 0; } diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c index cc8f7ddcee53..a37c172452e6 100644 --- a/drivers/input/keyboard/sun4i-lradc-keys.c +++ b/drivers/input/keyboard/sun4i-lradc-keys.c @@ -261,7 +261,6 @@ static int sun4i_lradc_probe(struct platform_device *pdev) if (error) return error; - platform_set_drvdata(pdev, lradc); return 0; } -- cgit v1.2.3 From b4e66e7d1948e0a54a38102462b016ee1ed489c2 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 21 Jan 2017 23:40:45 -0800 Subject: Input: keyboard - use local variables consistently If a function declares a variable to access a structure element, use it consistently. Signed-off-by: Guenter Roeck Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/davinci_keyscan.c | 4 ++-- drivers/input/keyboard/gpio_keys.c | 24 +++++++++++------------- drivers/input/keyboard/gpio_keys_polled.c | 6 +++--- drivers/input/keyboard/mpr121_touchkey.c | 18 +++++++++--------- 4 files changed, 25 insertions(+), 27 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index f363d1d2907a..b20a5d044caa 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c @@ -172,7 +172,7 @@ static int __init davinci_ks_probe(struct platform_device *pdev) struct input_dev *key_dev; struct resource *res, *mem; struct device *dev = &pdev->dev; - struct davinci_ks_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct davinci_ks_platform_data *pdata = dev_get_platdata(dev); int error, i; if (pdata->device_enable) { @@ -255,7 +255,7 @@ static int __init davinci_ks_probe(struct platform_device *pdev) key_dev->name = "davinci_keyscan"; key_dev->phys = "davinci_keyscan/input0"; - key_dev->dev.parent = &pdev->dev; + key_dev->dev.parent = dev; key_dev->id.bustype = BUS_HOST; key_dev->id.vendor = 0x0001; key_dev->id.product = 0x0001; diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 858bbc16b900..50b19b952698 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -518,8 +518,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev, if (button->active_low) flags |= GPIOF_ACTIVE_LOW; - error = devm_gpio_request_one(&pdev->dev, button->gpio, flags, - desc); + error = devm_gpio_request_one(dev, button->gpio, flags, desc); if (error < 0) { dev_err(dev, "Failed to request GPIO %d, error %d\n", button->gpio, error); @@ -589,10 +588,9 @@ static int gpio_keys_setup_key(struct platform_device *pdev, * Install custom action to cancel release timer and * workqueue item. */ - error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata); + error = devm_add_action(dev, gpio_keys_quiesce_key, bdata); if (error) { - dev_err(&pdev->dev, - "failed to register quiesce action, error: %d\n", + dev_err(dev, "failed to register quiesce action, error: %d\n", error); return error; } @@ -604,8 +602,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev, if (!button->can_disable) irqflags |= IRQF_SHARED; - error = devm_request_any_context_irq(&pdev->dev, bdata->irq, - isr, irqflags, desc, bdata); + error = devm_request_any_context_irq(dev, bdata->irq, isr, irqflags, + desc, bdata); if (error < 0) { dev_err(dev, "Unable to claim irq %d; error %d\n", bdata->irq, error); @@ -777,7 +775,7 @@ static int gpio_keys_probe(struct platform_device *pdev) input->name = pdata->name ? : pdev->name; input->phys = "gpio-keys/input0"; - input->dev.parent = &pdev->dev; + input->dev.parent = dev; input->open = gpio_keys_open; input->close = gpio_keys_close; @@ -798,9 +796,9 @@ static int gpio_keys_probe(struct platform_device *pdev) const struct gpio_keys_button *button = &pdata->buttons[i]; if (!dev_get_platdata(dev)) { - child = device_get_next_child_node(&pdev->dev, child); + child = device_get_next_child_node(dev, child); if (!child) { - dev_err(&pdev->dev, + dev_err(dev, "missing child device node for entry %d\n", i); return -EINVAL; @@ -820,7 +818,7 @@ static int gpio_keys_probe(struct platform_device *pdev) fwnode_handle_put(child); - error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); + error = sysfs_create_group(&dev->kobj, &gpio_keys_attr_group); if (error) { dev_err(dev, "Unable to export keys/switches, error: %d\n", error); @@ -834,12 +832,12 @@ static int gpio_keys_probe(struct platform_device *pdev) goto err_remove_group; } - device_init_wakeup(&pdev->dev, wakeup); + device_init_wakeup(dev, wakeup); return 0; err_remove_group: - sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); + sysfs_remove_group(&dev->kobj, &gpio_keys_attr_group); return error; } diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index cc193e665358..4fce43a6a0e0 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -252,13 +252,13 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) size = sizeof(struct gpio_keys_polled_dev) + pdata->nbuttons * sizeof(struct gpio_keys_button_data); - bdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + bdev = devm_kzalloc(dev, size, GFP_KERNEL); if (!bdev) { dev_err(dev, "no memory for private data\n"); return -ENOMEM; } - poll_dev = devm_input_allocate_polled_device(&pdev->dev); + poll_dev = devm_input_allocate_polled_device(dev); if (!poll_dev) { dev_err(dev, "no memory for polled device\n"); return -ENOMEM; @@ -332,7 +332,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) if (button->active_low) flags |= GPIOF_ACTIVE_LOW; - error = devm_gpio_request_one(&pdev->dev, button->gpio, + error = devm_gpio_request_one(dev, button->gpio, flags, button->desc ? : DRV_NAME); if (error) { dev_err(dev, diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 989ca66f63af..884a74d8a7ed 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -237,7 +237,7 @@ static int mpr_touchkey_probe(struct i2c_client *client, int i; if (!client->irq) { - dev_err(&client->dev, "irq number should not be zero\n"); + dev_err(dev, "irq number should not be zero\n"); return -EINVAL; } @@ -247,11 +247,11 @@ static int mpr_touchkey_probe(struct i2c_client *client, vdd_uv = regulator_get_voltage(vdd_supply); - mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121), GFP_KERNEL); + mpr121 = devm_kzalloc(dev, sizeof(*mpr121), GFP_KERNEL); if (!mpr121) return -ENOMEM; - input_dev = devm_input_allocate_device(&client->dev); + input_dev = devm_input_allocate_device(dev); if (!input_dev) return -ENOMEM; @@ -275,7 +275,7 @@ static int mpr_touchkey_probe(struct i2c_client *client, input_dev->name = "Freescale MPR121 Touchkey"; input_dev->id.bustype = BUS_I2C; - input_dev->dev.parent = &client->dev; + input_dev->dev.parent = dev; if (device_property_read_bool(dev, "autorepeat")) __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); @@ -289,16 +289,16 @@ static int mpr_touchkey_probe(struct i2c_client *client, error = mpr121_phys_init(mpr121, client, vdd_uv); if (error) { - dev_err(&client->dev, "Failed to init register\n"); + dev_err(dev, "Failed to init register\n"); return error; } - error = devm_request_threaded_irq(&client->dev, client->irq, - NULL, mpr_touchkey_interrupt, + error = devm_request_threaded_irq(dev, client->irq, NULL, + mpr_touchkey_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - client->dev.driver->name, mpr121); + dev->driver->name, mpr121); if (error) { - dev_err(&client->dev, "Failed to register interrupt\n"); + dev_err(dev, "Failed to register interrupt\n"); return error; } -- cgit v1.2.3 From de3a00ef21d6e803ee7c674c76a269016a1b308c Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 21 Jan 2017 23:47:44 -0800 Subject: Input: keyboard - drop unnecessary calls to device_init_wakeup Calling device_init_wakeup in the remove function is unnecessary since the device is going away, and thus won't be able to cause any wakeups under any circumstances. Besides, the driver cleanup code already handles the necessary cleanup. Similarly, disabling wakeup in the probe error path is unnecessary, as is disabling wakeup in the probe function in the first place. Signed-off-by: Guenter Roeck Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/gpio_keys.c | 2 -- drivers/input/keyboard/matrix_keypad.c | 2 -- drivers/input/keyboard/omap4-keypad.c | 3 --- drivers/input/keyboard/samsung-keypad.c | 2 -- drivers/input/keyboard/spear-keyboard.c | 2 -- 5 files changed, 11 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 50b19b952698..9c92cdf196e3 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -845,8 +845,6 @@ static int gpio_keys_remove(struct platform_device *pdev) { sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); - device_init_wakeup(&pdev->dev, 0); - return 0; } diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 7f12b6579f82..18839cd5f76e 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -545,8 +545,6 @@ static int matrix_keypad_remove(struct platform_device *pdev) { struct matrix_keypad *keypad = platform_get_drvdata(pdev); - device_init_wakeup(&pdev->dev, 0); - matrix_keypad_free_gpio(keypad); input_unregister_device(keypad->input_dev); kfree(keypad); diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 6639b2b8528a..9ecb16701b13 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -375,7 +375,6 @@ static int omap4_keypad_probe(struct platform_device *pdev) err_pm_disable: pm_runtime_disable(&pdev->dev); - device_init_wakeup(&pdev->dev, false); free_irq(keypad_data->irq, keypad_data); err_free_keymap: kfree(keypad_data->keymap); @@ -401,8 +400,6 @@ static int omap4_keypad_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); - device_init_wakeup(&pdev->dev, false); - input_unregister_device(keypad_data->input); iounmap(keypad_data->base); diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 4e319eb9e19d..316414465c77 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -445,7 +445,6 @@ static int samsung_keypad_probe(struct platform_device *pdev) err_disable_runtime_pm: pm_runtime_disable(&pdev->dev); - device_init_wakeup(&pdev->dev, 0); err_unprepare_clk: clk_unprepare(keypad->clk); return error; @@ -456,7 +455,6 @@ static int samsung_keypad_remove(struct platform_device *pdev) struct samsung_keypad *keypad = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); - device_init_wakeup(&pdev->dev, 0); input_unregister_device(keypad->input_dev); diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 8083eaa0524a..7d25fa338ab4 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -283,8 +283,6 @@ static int spear_kbd_remove(struct platform_device *pdev) input_unregister_device(kbd->input); clk_unprepare(kbd->clk); - device_init_wakeup(&pdev->dev, 0); - return 0; } -- cgit v1.2.3 From 14fdb924afd9290d43e64eeb2377d51806de1197 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 22 Jan 2017 17:17:40 -0800 Subject: Input: keyboard - drop unnecessary calls to input_set_drvdata If there is no call to dev_get_drvdata() or input_get_drvdata(), the call to input_set_drvdata() is unnecessary and can be dropped. Signed-off-by: Guenter Roeck Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/adp5520-keys.c | 2 -- drivers/input/keyboard/bf54x-keys.c | 2 -- drivers/input/keyboard/maple_keyb.c | 1 - drivers/input/keyboard/opencores-kbd.c | 2 -- drivers/input/keyboard/tca8418_keypad.c | 2 -- drivers/input/keyboard/tm2-touchkey.c | 2 -- 6 files changed, 11 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c index db1004dad108..f0b9b37bde58 100644 --- a/drivers/input/keyboard/adp5520-keys.c +++ b/drivers/input/keyboard/adp5520-keys.c @@ -107,8 +107,6 @@ static int adp5520_keys_probe(struct platform_device *pdev) input->phys = "adp5520-keys/input0"; input->dev.parent = &pdev->dev; - input_set_drvdata(input, dev); - input->id.bustype = BUS_I2C; input->id.vendor = 0x0001; input->id.product = 0x5520; diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index 81b07dddae86..39bcbc38997f 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -268,8 +268,6 @@ static int bfin_kpad_probe(struct platform_device *pdev) input->phys = "bf54x-keys/input0"; input->dev.parent = &pdev->dev; - input_set_drvdata(input, bf54x_kpad); - input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; input->id.product = 0x0001; diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index 5aa2361aef95..78e3567ec18c 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c @@ -196,7 +196,6 @@ static int probe_maple_kbd(struct device *dev) __clear_bit(KEY_RESERVED, idev->keybit); input_set_capability(idev, EV_MSC, MSC_SCAN); - input_set_drvdata(idev, kbd); error = input_register_device(idev); if (error) diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c index 98ea6190f5f5..d62b4068c077 100644 --- a/drivers/input/keyboard/opencores-kbd.c +++ b/drivers/input/keyboard/opencores-kbd.c @@ -75,8 +75,6 @@ static int opencores_kbd_probe(struct platform_device *pdev) input->name = pdev->name; input->phys = "opencores-kbd/input0"; - input_set_drvdata(input, opencores_kbd); - input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; input->id.product = 0x0001; diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 11d5c76d9fb4..9f6308fac0b4 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -358,8 +358,6 @@ static int tca8418_keypad_probe(struct i2c_client *client, __set_bit(EV_REP, input->evbit); input_set_capability(input, EV_MSC, MSC_SCAN); - input_set_drvdata(input, keypad_data); - irq = client->irq; if (irq_is_gpio) irq = gpio_to_irq(irq); diff --git a/drivers/input/keyboard/tm2-touchkey.c b/drivers/input/keyboard/tm2-touchkey.c index 916e2f3a9bbb..485900f953e0 100644 --- a/drivers/input/keyboard/tm2-touchkey.c +++ b/drivers/input/keyboard/tm2-touchkey.c @@ -193,8 +193,6 @@ static int tm2_touchkey_probe(struct i2c_client *client, input_set_capability(touchkey->input_dev, EV_KEY, KEY_PHONE); input_set_capability(touchkey->input_dev, EV_KEY, KEY_BACK); - input_set_drvdata(touchkey->input_dev, touchkey); - error = input_register_device(touchkey->input_dev); if (error) { dev_err(&client->dev, -- cgit v1.2.3 From aef01aad89e457e34a60ff6e8fd69ff6740cf201 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 11 Nov 2016 12:43:12 -0800 Subject: Input: matrix-keypad - switch to using generic device properties Instead of being OF-specific, let's switch to using generic device properties, which will make this code usable on ACPI, device tree and legacy boards that use property sets. As part of the change let's rename matrix_keypad_parse_of_params() to matrix_keypad_parse_properties(). Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/bcm-keypad.c | 2 +- drivers/input/keyboard/cros_ec_keyb.c | 3 +- drivers/input/keyboard/lpc32xx-keys.c | 2 +- drivers/input/keyboard/omap4-keypad.c | 4 +- drivers/input/keyboard/pmic8xxx-keypad.c | 2 +- drivers/input/keyboard/pxa27x_keypad.c | 2 +- drivers/input/keyboard/st-keyscan.c | 4 +- drivers/input/keyboard/stmpe-keypad.c | 2 +- drivers/input/keyboard/tca8418_keypad.c | 2 +- drivers/input/keyboard/twl4030_keypad.c | 4 +- drivers/input/matrix-keymap.c | 109 ++++++++++++++++--------------- include/linux/input/matrix_keypad.h | 21 +----- 12 files changed, 73 insertions(+), 84 deletions(-) (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/bcm-keypad.c b/drivers/input/keyboard/bcm-keypad.c index 2b4e63d81e6d..e1cf63ee148f 100644 --- a/drivers/input/keyboard/bcm-keypad.c +++ b/drivers/input/keyboard/bcm-keypad.c @@ -213,7 +213,7 @@ static int bcm_kp_matrix_key_parse_dt(struct bcm_kp *kp) /* Initialize the KPCR Keypad Configuration Register */ kp->kpcr = KPCR_STATUSFILTERENABLE | KPCR_COLFILTERENABLE; - error = matrix_keypad_parse_of_params(dev, &kp->n_rows, &kp->n_cols); + error = matrix_keypad_parse_properties(dev, &kp->n_rows, &kp->n_cols); if (error) { dev_err(dev, "failed to parse kp params\n"); return error; diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 87d071ae21da..780977dcf92d 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -229,7 +229,8 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) ckdev = devm_kzalloc(dev, sizeof(*ckdev), GFP_KERNEL); if (!ckdev) return -ENOMEM; - err = matrix_keypad_parse_of_params(dev, &ckdev->rows, &ckdev->cols); + + err = matrix_keypad_parse_properties(dev, &ckdev->rows, &ckdev->cols); if (err) return err; diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c index 632523d4f5dc..1dd57ac0e7a2 100644 --- a/drivers/input/keyboard/lpc32xx-keys.c +++ b/drivers/input/keyboard/lpc32xx-keys.c @@ -145,7 +145,7 @@ static int lpc32xx_parse_dt(struct device *dev, u32 rows = 0, columns = 0; int err; - err = matrix_keypad_parse_of_params(dev, &rows, &columns); + err = matrix_keypad_parse_properties(dev, &rows, &columns); if (err) return err; if (rows != columns) { diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 9ecb16701b13..ebc67ba41fe2 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -223,8 +223,8 @@ static int omap4_keypad_parse_dt(struct device *dev, struct device_node *np = dev->of_node; int err; - err = matrix_keypad_parse_of_params(dev, &keypad_data->rows, - &keypad_data->cols); + err = matrix_keypad_parse_properties(dev, &keypad_data->rows, + &keypad_data->cols); if (err) return err; diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 5c68e3f096bc..97c5424f49b9 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -515,7 +515,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) int rc; unsigned int ctrl_val; - rc = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols); + rc = matrix_keypad_parse_properties(&pdev->dev, &rows, &cols); if (rc) return rc; diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index e24443376e75..3841fa30db33 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -126,7 +126,7 @@ static int pxa27x_keypad_matrix_key_parse_dt(struct pxa27x_keypad *keypad, u32 rows, cols; int error; - error = matrix_keypad_parse_of_params(dev, &rows, &cols); + error = matrix_keypad_parse_properties(dev, &rows, &cols); if (error) return error; diff --git a/drivers/input/keyboard/st-keyscan.c b/drivers/input/keyboard/st-keyscan.c index de7be4f03d91..babcfb165e4f 100644 --- a/drivers/input/keyboard/st-keyscan.c +++ b/drivers/input/keyboard/st-keyscan.c @@ -106,8 +106,8 @@ static int keypad_matrix_key_parse_dt(struct st_keyscan *keypad_data) struct device_node *np = dev->of_node; int error; - error = matrix_keypad_parse_of_params(dev, &keypad_data->n_rows, - &keypad_data->n_cols); + error = matrix_keypad_parse_properties(dev, &keypad_data->n_rows, + &keypad_data->n_cols); if (error) { dev_err(dev, "failed to parse keypad params\n"); return error; diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index fe6e3f22eed7..8c6c0b9109c7 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c @@ -354,7 +354,7 @@ static int stmpe_keypad_probe(struct platform_device *pdev) input->id.bustype = BUS_I2C; input->dev.parent = &pdev->dev; - error = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols); + error = matrix_keypad_parse_properties(&pdev->dev, &rows, &cols); if (error) return error; diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 9f6308fac0b4..ccff9d1b7135 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -295,7 +295,7 @@ static int tca8418_keypad_probe(struct i2c_client *client, struct device_node *np = dev->of_node; int err; - err = matrix_keypad_parse_of_params(dev, &rows, &cols); + err = matrix_keypad_parse_properties(dev, &rows, &cols); if (err) return err; rep = of_property_read_bool(np, "keypad,autorepeat"); diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 29396ca69416..39e72b3219d8 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -374,8 +374,8 @@ static int twl4030_kp_probe(struct platform_device *pdev) kp->autorepeat = pdata->rep; keymap_data = pdata->keymap_data; } else { - error = matrix_keypad_parse_of_params(&pdev->dev, &kp->n_rows, - &kp->n_cols); + error = matrix_keypad_parse_properties(&pdev->dev, &kp->n_rows, + &kp->n_cols); if (error) return error; diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c index 08b61f506db6..8ccefc15c7a4 100644 --- a/drivers/input/matrix-keymap.c +++ b/drivers/input/matrix-keymap.c @@ -14,18 +14,18 @@ * 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. - * */ #include +#include #include -#include -#include #include -#include -#include -#include #include +#include +#include +#include +#include +#include static bool matrix_keypad_map_key(struct input_dev *input_dev, unsigned int rows, unsigned int cols, @@ -49,18 +49,22 @@ static bool matrix_keypad_map_key(struct input_dev *input_dev, return true; } -#ifdef CONFIG_OF -int matrix_keypad_parse_of_params(struct device *dev, - unsigned int *rows, unsigned int *cols) +/** + * matrix_keypad_parse_properties() - Read properties of matrix keypad + * + * @dev: Device containing properties + * @rows: Returns number of matrix rows + * @cols: Returns number of matrix columns + * @return 0 if OK, <0 on error + */ +int matrix_keypad_parse_properties(struct device *dev, + unsigned int *rows, unsigned int *cols) { - struct device_node *np = dev->of_node; + *rows = *cols = 0; + + device_property_read_u32(dev, "keypad,num-rows", rows); + device_property_read_u32(dev, "keypad,num-columns", cols); - if (!np) { - dev_err(dev, "missing DT data"); - return -EINVAL; - } - of_property_read_u32(np, "keypad,num-rows", rows); - of_property_read_u32(np, "keypad,num-columns", cols); if (!*rows || !*cols) { dev_err(dev, "number of keypad rows/columns not specified\n"); return -EINVAL; @@ -68,62 +72,61 @@ int matrix_keypad_parse_of_params(struct device *dev, return 0; } -EXPORT_SYMBOL_GPL(matrix_keypad_parse_of_params); +EXPORT_SYMBOL_GPL(matrix_keypad_parse_properties); -static int matrix_keypad_parse_of_keymap(const char *propname, - unsigned int rows, unsigned int cols, - struct input_dev *input_dev) +static int matrix_keypad_parse_keymap(const char *propname, + unsigned int rows, unsigned int cols, + struct input_dev *input_dev) { struct device *dev = input_dev->dev.parent; - struct device_node *np = dev->of_node; unsigned int row_shift = get_count_order(cols); unsigned int max_keys = rows << row_shift; - unsigned int proplen, i, size; - const __be32 *prop; - - if (!np) - return -ENOENT; + u32 *keys; + int i; + int size; + int retval; if (!propname) propname = "linux,keymap"; - prop = of_get_property(np, propname, &proplen); - if (!prop) { - dev_err(dev, "OF: %s property not defined in %s\n", - propname, np->full_name); - return -ENOENT; + size = device_property_read_u32_array(dev, propname, NULL, 0); + if (size <= 0) { + dev_err(dev, "missing or malformed property %s: %d\n", + propname, size); + return size < 0 ? size : -EINVAL; } - if (proplen % sizeof(u32)) { - dev_err(dev, "OF: Malformed keycode property %s in %s\n", - propname, np->full_name); + if (size > max_keys) { + dev_err(dev, "%s size overflow (%d vs max %u)\n", + propname, size, max_keys); return -EINVAL; } - size = proplen / sizeof(u32); - if (size > max_keys) { - dev_err(dev, "OF: %s size overflow\n", propname); - return -EINVAL; + keys = kmalloc_array(size, sizeof(u32), GFP_KERNEL); + if (!keys) + return -ENOMEM; + + retval = device_property_read_u32_array(dev, propname, keys, size); + if (retval) { + dev_err(dev, "failed to read %s property: %d\n", + propname, retval); + goto out; } for (i = 0; i < size; i++) { - unsigned int key = be32_to_cpup(prop + i); - if (!matrix_keypad_map_key(input_dev, rows, cols, - row_shift, key)) - return -EINVAL; + row_shift, keys[i])) { + retval = -EINVAL; + goto out; + } } - return 0; -} -#else -static int matrix_keypad_parse_of_keymap(const char *propname, - unsigned int rows, unsigned int cols, - struct input_dev *input_dev) -{ - return -ENOSYS; + retval = 0; + +out: + kfree(keys); + return retval; } -#endif /** * matrix_keypad_build_keymap - convert platform keymap into matrix keymap @@ -192,8 +195,8 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, return -EINVAL; } } else { - error = matrix_keypad_parse_of_keymap(keymap_name, rows, cols, - input_dev); + error = matrix_keypad_parse_keymap(keymap_name, rows, cols, + input_dev); if (error) return error; } diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h index 27e06acc509a..37b04a0fdea4 100644 --- a/include/linux/input/matrix_keypad.h +++ b/include/linux/input/matrix_keypad.h @@ -80,24 +80,9 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, unsigned int rows, unsigned int cols, unsigned short *keymap, struct input_dev *input_dev); +int matrix_keypad_parse_properties(struct device *dev, + unsigned int *rows, unsigned int *cols); -#ifdef CONFIG_OF -/** - * matrix_keypad_parse_of_params() - Read parameters from matrix-keypad node - * - * @dev: Device containing of_node - * @rows: Returns number of matrix rows - * @cols: Returns number of matrix columns - * @return 0 if OK, <0 on error - */ -int matrix_keypad_parse_of_params(struct device *dev, - unsigned int *rows, unsigned int *cols); -#else -static inline int matrix_keypad_parse_of_params(struct device *dev, - unsigned int *rows, unsigned int *cols) -{ - return -ENOSYS; -} -#endif /* CONFIG_OF */ +#define matrix_keypad_parse_of_params matrix_keypad_parse_properties #endif /* _MATRIX_KEYPAD_H */ -- cgit v1.2.3 From 8b1a315b35a961198336b944635c6936321b4a77 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 17 Jan 2017 14:18:50 -0800 Subject: Input: tca8418 - switch to using generic device properties Let's drop legacy platform data support (there are no users in mainline) and switch to using generic device properties, which will make the driver simpler (non-OF boards can use property sets to describe hardware). Reviewed-by: Maxime Ripard Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/tca8418_keypad.c | 90 ++++++++++----------------------- include/linux/input/tca8418_keypad.h | 44 ---------------- 2 files changed, 26 insertions(+), 108 deletions(-) delete mode 100644 include/linux/input/tca8418_keypad.h (limited to 'drivers/input/keyboard') diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index ccff9d1b7135..44dd7689c571 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -24,18 +24,17 @@ * alternative licensing inquiries. */ -#include -#include -#include #include -#include -#include -#include -#include #include +#include #include -#include +#include +#include +#include #include +#include +#include +#include /* TCA8418 hardware limits */ #define TCA8418_MAX_ROWS 8 @@ -264,43 +263,25 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data, } static int tca8418_keypad_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct device *dev = &client->dev; - const struct tca8418_keypad_platform_data *pdata = - dev_get_platdata(dev); struct tca8418_keypad *keypad_data; struct input_dev *input; - const struct matrix_keymap_data *keymap_data = NULL; u32 rows = 0, cols = 0; - bool rep = false; - bool irq_is_gpio = false; - int irq; int error, row_shift, max_keys; - unsigned long trigger = 0; - /* Copy the platform data */ - if (pdata) { - if (!pdata->keymap_data) { - dev_err(dev, "no keymap data defined\n"); - return -EINVAL; - } - keymap_data = pdata->keymap_data; - rows = pdata->rows; - cols = pdata->cols; - rep = pdata->rep; - irq_is_gpio = pdata->irq_is_gpio; - trigger = IRQF_TRIGGER_FALLING; - } else { - struct device_node *np = dev->of_node; - int err; - - err = matrix_keypad_parse_properties(dev, &rows, &cols); - if (err) - return err; - rep = of_property_read_bool(np, "keypad,autorepeat"); + /* Check i2c driver capabilities */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { + dev_err(dev, "%s adapter not supported\n", + dev_driver_string(&client->adapter->dev)); + return -ENODEV; } + error = matrix_keypad_parse_properties(dev, &rows, &cols); + if (error) + return error; + if (!rows || rows > TCA8418_MAX_ROWS) { dev_err(dev, "invalid rows\n"); return -EINVAL; @@ -311,13 +292,6 @@ static int tca8418_keypad_probe(struct i2c_client *client, return -EINVAL; } - /* Check i2c driver capabilities */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { - dev_err(dev, "%s adapter not supported\n", - dev_driver_string(&client->adapter->dev)); - return -ENODEV; - } - row_shift = get_count_order(cols); max_keys = rows << row_shift; @@ -347,23 +321,20 @@ static int tca8418_keypad_probe(struct i2c_client *client, input->id.product = 0x001; input->id.version = 0x0001; - error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols, - NULL, input); + error = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL, input); if (error) { dev_err(dev, "Failed to build keymap\n"); return error; } - if (rep) + if (device_property_read_bool(dev, "keypad,autorepeat")) __set_bit(EV_REP, input->evbit); - input_set_capability(input, EV_MSC, MSC_SCAN); - irq = client->irq; - if (irq_is_gpio) - irq = gpio_to_irq(irq); + input_set_capability(input, EV_MSC, MSC_SCAN); - error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler, - trigger | IRQF_SHARED | IRQF_ONESHOT, + error = devm_request_threaded_irq(dev, client->irq, + NULL, tca8418_irq_handler, + IRQF_SHARED | IRQF_ONESHOT, client->name, keypad_data); if (error) { dev_err(dev, "Unable to claim irq %d; error %d\n", @@ -382,30 +353,21 @@ static int tca8418_keypad_probe(struct i2c_client *client, } static const struct i2c_device_id tca8418_id[] = { - { TCA8418_NAME, 8418, }, + { "tca8418", 8418, }, { } }; MODULE_DEVICE_TABLE(i2c, tca8418_id); -#ifdef CONFIG_OF static const struct of_device_id tca8418_dt_ids[] = { { .compatible = "ti,tca8418", }, { } }; MODULE_DEVICE_TABLE(of, tca8418_dt_ids); -/* - * The device tree based i2c loader looks for - * "i2c:" + second_component_of(property("compatible")) - * and therefore we need an alias to be found. - */ -MODULE_ALIAS("i2c:tca8418"); -#endif - static struct i2c_driver tca8418_keypad_driver = { .driver = { - .name = TCA8418_NAME, - .of_match_table = of_match_ptr(tca8418_dt_ids), + .name = "tca8418_keypad", + .of_match_table = tca8418_dt_ids, }, .probe = tca8418_keypad_probe, .id_table = tca8418_id, diff --git a/include/linux/input/tca8418_keypad.h b/include/linux/input/tca8418_keypad.h deleted file mode 100644 index e71a85dc2cbd..000000000000 --- a/include/linux/input/tca8418_keypad.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * TCA8418 keypad platform support - * - * Copyright (C) 2011 Fuel7, Inc. All rights reserved. - * - * Author: Kyle Manna - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License v2 as published by the Free Software Foundation. - * - * 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. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - * If you can't comply with GPLv2, alternative licensing terms may be - * arranged. Please contact Fuel7, Inc. (http://fuel7.com/) for proprietary - * alternative licensing inquiries. - */ - -#ifndef _TCA8418_KEYPAD_H -#define _TCA8418_KEYPAD_H - -#include -#include - -#define TCA8418_I2C_ADDR 0x34 -#define TCA8418_NAME "tca8418_keypad" - -struct tca8418_keypad_platform_data { - const struct matrix_keymap_data *keymap_data; - unsigned rows; - unsigned cols; - bool rep; - bool irq_is_gpio; -}; - -#endif -- cgit v1.2.3