diff options
Diffstat (limited to 'drivers/input/keyboard')
30 files changed, 537 insertions, 601 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 90e8a7f2f07c..4706ff09f0e8 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -16,7 +16,6 @@ if INPUT_KEYBOARD config KEYBOARD_ADC tristate "ADC Ladder Buttons" depends on IIO - select INPUT_POLLDEV help This driver implements support for buttons connected to an ADC using a resistor ladder. @@ -168,14 +167,14 @@ config KEYBOARD_QT1050 the module will be called qt1050 config KEYBOARD_QT1070 - tristate "Atmel AT42QT1070 Touch Sensor Chip" - depends on I2C - help - Say Y here if you want to use Atmel AT42QT1070 QTouch - Sensor chip as input device. + tristate "Atmel AT42QT1070 Touch Sensor Chip" + depends on I2C + help + Say Y here if you want to use Atmel AT42QT1070 QTouch + Sensor chip as input device. - To compile this driver as a module, choose M here: - the module will be called qt1070 + To compile this driver as a module, choose M here: + the module will be called qt1070 config KEYBOARD_QT2160 tristate "Atmel AT42QT2160 Touch Sensor Chip" @@ -191,7 +190,6 @@ config KEYBOARD_CLPS711X tristate "CLPS711X Keypad support" depends on OF_GPIO && (ARCH_CLPS711X || COMPILE_TEST) select INPUT_MATRIXKMAP - select INPUT_POLLDEV help Say Y here to enable the matrix keypad on the Cirrus Logic CLPS711X CPUs. @@ -250,7 +248,6 @@ config KEYBOARD_GPIO config KEYBOARD_GPIO_POLLED tristate "Polled GPIO buttons" depends on GPIOLIB - select INPUT_POLLDEV help This driver implements support for buttons connected to GPIO pins that are not capable of generating interrupts. @@ -342,7 +339,6 @@ config KEYBOARD_HIL config KEYBOARD_HP6XX tristate "HP Jornada 6xx keyboard" depends on SH_HP6XX - select INPUT_POLLDEV help Say Y here if you have a HP Jornada 620/660/680/690 and want to support the built-in keyboard. @@ -454,7 +450,7 @@ config KEYBOARD_SNVS_PWRKEY depends on OF help This is the snvs powerkey driver for the Freescale i.MX application - processors that are newer than i.MX6 SX. + processors. To compile this driver as a module, choose M here; the module will be called snvs_pwrkey. @@ -469,6 +465,16 @@ config KEYBOARD_IMX To compile this driver as a module, choose M here: the module will be called imx_keypad. +config KEYBOARD_IMX_SC_KEY + tristate "IMX SCU Key Driver" + depends on IMX_SCU + help + This is the system controller key driver for NXP i.MX SoCs with + system controller inside. + + To compile this driver as a module, choose M here: the + module will be called imx_sc_key. + config KEYBOARD_NEWTON tristate "Newton keyboard" select SERIO @@ -733,21 +739,10 @@ config KEYBOARD_XTKBD To compile this driver as a module, choose M here: the module will be called xtkbd. -config KEYBOARD_W90P910 - tristate "W90P910 Matrix Keypad support" - depends on ARCH_W90X900 - select INPUT_MATRIXKMAP - help - Say Y here to enable the matrix keypad on evaluation board - based on W90P910. - - To compile this driver as a module, choose M here: the - module will be called w90p910_keypad. - config KEYBOARD_CROS_EC tristate "ChromeOS EC keyboard" select INPUT_MATRIXKMAP - depends on MFD_CROS_EC + depends on 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/Makefile b/drivers/input/keyboard/Makefile index 06a0af6efeae..f5b17524adf2 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o obj-$(CONFIG_KEYBOARD_IPAQ_MICRO) += ipaq-micro-keys.o obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o +obj-$(CONFIG_KEYBOARD_IMX_SC_KEY) += imx_sc_key.o obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o @@ -68,4 +69,3 @@ 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/adc-keys.c b/drivers/input/keyboard/adc-keys.c index 9885fd56f5f9..6d5be48d1b3d 100644 --- a/drivers/input/keyboard/adc-keys.c +++ b/drivers/input/keyboard/adc-keys.c @@ -9,7 +9,6 @@ #include <linux/iio/consumer.h> #include <linux/iio/types.h> #include <linux/input.h> -#include <linux/input-polldev.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> @@ -30,9 +29,9 @@ struct adc_keys_state { const struct adc_keys_button *map; }; -static void adc_keys_poll(struct input_polled_dev *dev) +static void adc_keys_poll(struct input_dev *input) { - struct adc_keys_state *st = dev->private; + struct adc_keys_state *st = input_get_drvdata(input); int i, value, ret; u32 diff, closest = 0xffffffff; int keycode = 0; @@ -55,12 +54,12 @@ static void adc_keys_poll(struct input_polled_dev *dev) keycode = 0; if (st->last_key && st->last_key != keycode) - input_report_key(dev->input, st->last_key, 0); + input_report_key(input, st->last_key, 0); if (keycode) - input_report_key(dev->input, keycode, 1); + input_report_key(input, keycode, 1); - input_sync(dev->input); + input_sync(input); st->last_key = keycode; } @@ -108,7 +107,6 @@ static int adc_keys_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct adc_keys_state *st; - struct input_polled_dev *poll_dev; struct input_dev *input; enum iio_chan_type type; int i, value; @@ -145,19 +143,13 @@ static int adc_keys_probe(struct platform_device *pdev) if (error) return error; - poll_dev = devm_input_allocate_polled_device(dev); - if (!poll_dev) { + input = devm_input_allocate_device(dev); + if (!input) { dev_err(dev, "failed to allocate input device\n"); return -ENOMEM; } - if (!device_property_read_u32(dev, "poll-interval", &value)) - poll_dev->poll_interval = value; - - poll_dev->poll = adc_keys_poll; - poll_dev->private = st; - - input = poll_dev->input; + input_set_drvdata(input, st); input->name = pdev->name; input->phys = "adc-keys/input0"; @@ -174,7 +166,17 @@ static int adc_keys_probe(struct platform_device *pdev) if (device_property_read_bool(dev, "autorepeat")) __set_bit(EV_REP, input->evbit); - error = input_register_polled_device(poll_dev); + + error = input_setup_polling(input, adc_keys_poll); + if (error) { + dev_err(dev, "Unable to set up polling: %d\n", error); + return error; + } + + if (!device_property_read_u32(dev, "poll-interval", &value)) + input_set_poll_interval(input, value); + + error = input_register_device(input); if (error) { dev_err(dev, "Unable to register input device: %d\n", error); return error; diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index 4f96a4a99e5b..e7d58e7f0257 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c @@ -857,70 +857,35 @@ static void adp5589_report_switch_state(struct adp5589_kpad *kpad) input_sync(kpad->input); } -static int adp5589_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int adp5589_keypad_add(struct adp5589_kpad *kpad, unsigned int revid) { - struct adp5589_kpad *kpad; + struct i2c_client *client = kpad->client; const struct adp5589_kpad_platform_data *pdata = dev_get_platdata(&client->dev); struct input_dev *input; - unsigned int revid; - int ret, i; + unsigned int i; int error; - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); - return -EIO; - } - - if (!pdata) { - dev_err(&client->dev, "no platform data?\n"); - return -EINVAL; - } - - kpad = kzalloc(sizeof(*kpad), GFP_KERNEL); - if (!kpad) - return -ENOMEM; - - switch (id->driver_data) { - case ADP5585_02: - kpad->support_row5 = true; - /* fall through */ - case ADP5585_01: - kpad->is_adp5585 = true; - kpad->var = &const_adp5585; - break; - case ADP5589: - kpad->support_row5 = true; - kpad->var = &const_adp5589; - break; - } - if (!((pdata->keypad_en_mask & kpad->var->row_mask) && (pdata->keypad_en_mask >> kpad->var->col_shift)) || !pdata->keymap) { dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); - error = -EINVAL; - goto err_free_mem; + return -EINVAL; } if (pdata->keymapsize != kpad->var->keymapsize) { dev_err(&client->dev, "invalid keymapsize\n"); - error = -EINVAL; - goto err_free_mem; + return -EINVAL; } if (!pdata->gpimap && pdata->gpimapsize) { dev_err(&client->dev, "invalid gpimap from pdata\n"); - error = -EINVAL; - goto err_free_mem; + return -EINVAL; } if (pdata->gpimapsize > kpad->var->gpimapsize_max) { dev_err(&client->dev, "invalid gpimapsize\n"); - error = -EINVAL; - goto err_free_mem; + return -EINVAL; } for (i = 0; i < pdata->gpimapsize; i++) { @@ -929,41 +894,27 @@ static int adp5589_probe(struct i2c_client *client, if (pin < kpad->var->gpi_pin_base || pin > kpad->var->gpi_pin_end) { dev_err(&client->dev, "invalid gpi pin data\n"); - error = -EINVAL; - goto err_free_mem; + return -EINVAL; } if ((1 << (pin - kpad->var->gpi_pin_row_base)) & pdata->keypad_en_mask) { dev_err(&client->dev, "invalid gpi row/col data\n"); - error = -EINVAL; - goto err_free_mem; + return -EINVAL; } } if (!client->irq) { dev_err(&client->dev, "no IRQ?\n"); - error = -EINVAL; - goto err_free_mem; + return -EINVAL; } input = input_allocate_device(); - if (!input) { - error = -ENOMEM; - goto err_free_mem; - } + if (!input) + return -ENOMEM; - kpad->client = client; kpad->input = input; - ret = adp5589_read(client, ADP5589_5_ID); - if (ret < 0) { - error = ret; - goto err_free_input; - } - - revid = (u8) ret & ADP5589_5_DEVICE_ID_MASK; - input->name = client->name; input->phys = "adp5589-keys/input0"; input->dev.parent = &client->dev; @@ -1015,30 +966,99 @@ static int adp5589_probe(struct i2c_client *client, goto err_unreg_dev; } + device_init_wakeup(&client->dev, 1); + + return 0; + +err_unreg_dev: + input_unregister_device(input); + input = NULL; +err_free_input: + input_free_device(input); + + return error; +} + +static void adp5589_keypad_remove(struct adp5589_kpad *kpad) +{ + if (kpad->input) { + free_irq(kpad->client->irq, kpad); + input_unregister_device(kpad->input); + } +} + +static int adp5589_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adp5589_kpad *kpad; + const struct adp5589_kpad_platform_data *pdata = + dev_get_platdata(&client->dev); + unsigned int revid; + int error, ret; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&client->dev, "SMBUS Byte Data not Supported\n"); + return -EIO; + } + + if (!pdata) { + dev_err(&client->dev, "no platform data?\n"); + return -EINVAL; + } + + kpad = kzalloc(sizeof(*kpad), GFP_KERNEL); + if (!kpad) + return -ENOMEM; + + kpad->client = client; + + switch (id->driver_data) { + case ADP5585_02: + kpad->support_row5 = true; + /* fall through */ + case ADP5585_01: + kpad->is_adp5585 = true; + kpad->var = &const_adp5585; + break; + case ADP5589: + kpad->support_row5 = true; + kpad->var = &const_adp5589; + break; + } + + ret = adp5589_read(client, ADP5589_5_ID); + if (ret < 0) { + error = ret; + goto err_free_mem; + } + + revid = (u8) ret & ADP5589_5_DEVICE_ID_MASK; + + if (pdata->keymapsize) { + error = adp5589_keypad_add(kpad, revid); + if (error) + goto err_free_mem; + } + error = adp5589_setup(kpad); if (error) - goto err_free_irq; + goto err_keypad_remove; if (kpad->gpimapsize) adp5589_report_switch_state(kpad); error = adp5589_gpio_add(kpad); if (error) - goto err_free_irq; + goto err_keypad_remove; - device_init_wakeup(&client->dev, 1); i2c_set_clientdata(client, kpad); dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); return 0; -err_free_irq: - free_irq(client->irq, kpad); -err_unreg_dev: - input_unregister_device(input); - input = NULL; -err_free_input: - input_free_device(input); +err_keypad_remove: + adp5589_keypad_remove(kpad); err_free_mem: kfree(kpad); @@ -1050,8 +1070,7 @@ static int adp5589_remove(struct i2c_client *client) struct adp5589_kpad *kpad = i2c_get_clientdata(client); adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0); - free_irq(client->irq, kpad); - input_unregister_device(kpad->input); + adp5589_keypad_remove(kpad); adp5589_gpio_remove(kpad); kfree(kpad); @@ -1064,6 +1083,9 @@ static int adp5589_suspend(struct device *dev) struct adp5589_kpad *kpad = dev_get_drvdata(dev); struct i2c_client *client = kpad->client; + if (!kpad->input) + return 0; + disable_irq(client->irq); if (device_may_wakeup(&client->dev)) @@ -1077,6 +1099,9 @@ static int adp5589_resume(struct device *dev) struct adp5589_kpad *kpad = dev_get_drvdata(dev); struct i2c_client *client = kpad->client; + if (!kpad->input) + return 0; + if (device_may_wakeup(&client->dev)) disable_irq_wake(client->irq); diff --git a/drivers/input/keyboard/applespi.c b/drivers/input/keyboard/applespi.c index 584289b67fb3..d38398526965 100644 --- a/drivers/input/keyboard/applespi.c +++ b/drivers/input/keyboard/applespi.c @@ -1797,30 +1797,12 @@ static int applespi_probe(struct spi_device *spi) /* set up debugfs entries for touchpad dimensions logging */ applespi->debugfs_root = debugfs_create_dir("applespi", NULL); - if (IS_ERR(applespi->debugfs_root)) { - if (PTR_ERR(applespi->debugfs_root) != -ENODEV) - dev_warn(&applespi->spi->dev, - "Error creating debugfs root entry (%ld)\n", - PTR_ERR(applespi->debugfs_root)); - } else { - struct dentry *ret; - - ret = debugfs_create_bool("enable_tp_dim", 0600, - applespi->debugfs_root, - &applespi->debug_tp_dim); - if (IS_ERR(ret)) - dev_dbg(&applespi->spi->dev, - "Error creating debugfs entry enable_tp_dim (%ld)\n", - PTR_ERR(ret)); - - ret = debugfs_create_file("tp_dim", 0400, - applespi->debugfs_root, applespi, - &applespi_tp_dim_fops); - if (IS_ERR(ret)) - dev_dbg(&applespi->spi->dev, - "Error creating debugfs entry tp_dim (%ld)\n", - PTR_ERR(ret)); - } + + debugfs_create_bool("enable_tp_dim", 0600, applespi->debugfs_root, + &applespi->debug_tp_dim); + + debugfs_create_file("tp_dim", 0400, applespi->debugfs_root, applespi, + &applespi_tp_dim_fops); return 0; } diff --git a/drivers/input/keyboard/bcm-keypad.c b/drivers/input/keyboard/bcm-keypad.c index e1cf63ee148f..2b771c3a5578 100644 --- a/drivers/input/keyboard/bcm-keypad.c +++ b/drivers/input/keyboard/bcm-keypad.c @@ -413,10 +413,8 @@ static int bcm_kp_probe(struct platform_device *pdev) bcm_kp_stop(kp); kp->irq = platform_get_irq(pdev, 0); - if (kp->irq < 0) { - dev_err(&pdev->dev, "no IRQ specified\n"); + if (kp->irq < 0) return -EINVAL; - } error = devm_request_threaded_irq(&pdev->dev, kp->irq, NULL, bcm_kp_isr_thread, diff --git a/drivers/input/keyboard/clps711x-keypad.c b/drivers/input/keyboard/clps711x-keypad.c index c4a5c07a4b98..019dd6ed2c29 100644 --- a/drivers/input/keyboard/clps711x-keypad.c +++ b/drivers/input/keyboard/clps711x-keypad.c @@ -6,7 +6,6 @@ */ #include <linux/input.h> -#include <linux/input-polldev.h> #include <linux/module.h> #include <linux/of_gpio.h> #include <linux/platform_device.h> @@ -30,10 +29,10 @@ struct clps711x_keypad_data { struct clps711x_gpio_data *gpio_data; }; -static void clps711x_keypad_poll(struct input_polled_dev *dev) +static void clps711x_keypad_poll(struct input_dev *input) { - const unsigned short *keycodes = dev->input->keycode; - struct clps711x_keypad_data *priv = dev->private; + const unsigned short *keycodes = input->keycode; + struct clps711x_keypad_data *priv = input_get_drvdata(input); bool sync = false; int col, row; @@ -61,14 +60,14 @@ static void clps711x_keypad_poll(struct input_polled_dev *dev) if (state) { set_bit(col, data->last_state); - input_event(dev->input, EV_MSC, - MSC_SCAN, code); + input_event(input, + EV_MSC, MSC_SCAN, code); } else { clear_bit(col, data->last_state); } if (keycodes[code]) - input_report_key(dev->input, + input_report_key(input, keycodes[code], state); sync = true; } @@ -80,7 +79,7 @@ static void clps711x_keypad_poll(struct input_polled_dev *dev) } if (sync) - input_sync(dev->input); + input_sync(input); } static int clps711x_keypad_probe(struct platform_device *pdev) @@ -88,7 +87,7 @@ static int clps711x_keypad_probe(struct platform_device *pdev) struct clps711x_keypad_data *priv; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; - struct input_polled_dev *poll_dev; + struct input_dev *input; u32 poll_interval; int i, err; @@ -125,53 +124,43 @@ static int clps711x_keypad_probe(struct platform_device *pdev) if (err) return err; - poll_dev = input_allocate_polled_device(); - if (!poll_dev) + input = devm_input_allocate_device(dev); + if (!input) return -ENOMEM; - poll_dev->private = priv; - poll_dev->poll = clps711x_keypad_poll; - poll_dev->poll_interval = poll_interval; - poll_dev->input->name = pdev->name; - poll_dev->input->dev.parent = dev; - poll_dev->input->id.bustype = BUS_HOST; - poll_dev->input->id.vendor = 0x0001; - poll_dev->input->id.product = 0x0001; - poll_dev->input->id.version = 0x0100; + input_set_drvdata(input, priv); + + input->name = pdev->name; + input->dev.parent = dev; + input->id.bustype = BUS_HOST; + input->id.vendor = 0x0001; + input->id.product = 0x0001; + input->id.version = 0x0100; err = matrix_keypad_build_keymap(NULL, NULL, priv->row_count, CLPS711X_KEYPAD_COL_COUNT, - NULL, poll_dev->input); + NULL, input); if (err) - goto out_err; + return err; - input_set_capability(poll_dev->input, EV_MSC, MSC_SCAN); + input_set_capability(input, EV_MSC, MSC_SCAN); if (of_property_read_bool(np, "autorepeat")) - __set_bit(EV_REP, poll_dev->input->evbit); - - platform_set_drvdata(pdev, poll_dev); + __set_bit(EV_REP, input->evbit); /* Set all columns to low */ regmap_update_bits(priv->syscon, SYSCON_OFFSET, SYSCON1_KBDSCAN_MASK, SYSCON1_KBDSCAN(1)); - err = input_register_polled_device(poll_dev); - if (err) - goto out_err; - - return 0; -out_err: - input_free_polled_device(poll_dev); - return err; -} + err = input_setup_polling(input, clps711x_keypad_poll); + if (err) + return err; -static int clps711x_keypad_remove(struct platform_device *pdev) -{ - struct input_polled_dev *poll_dev = platform_get_drvdata(pdev); + input_set_poll_interval(input, poll_interval); - input_unregister_polled_device(poll_dev); - input_free_polled_device(poll_dev); + err = input_register_device(input); + if (err) + return err; return 0; } @@ -188,7 +177,6 @@ static struct platform_driver clps711x_keypad_driver = { .of_match_table = clps711x_keypad_of_match, }, .probe = clps711x_keypad_probe, - .remove = clps711x_keypad_remove, }; module_platform_driver(clps711x_keypad_driver); diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 38cb6d82d8fe..2b71c5a51f90 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -22,8 +22,8 @@ #include <linux/slab.h> #include <linux/sysrq.h> #include <linux/input/matrix_keypad.h> -#include <linux/mfd/cros_ec.h> -#include <linux/mfd/cros_ec_commands.h> +#include <linux/platform_data/cros_ec_commands.h> +#include <linux/platform_data/cros_ec_proto.h> #include <asm/unaligned.h> @@ -237,7 +237,7 @@ static int cros_ec_keyb_work(struct notifier_block *nb, if (queued_during_suspend && !device_may_wakeup(ckdev->dev)) return NOTIFY_OK; - switch (ckdev->ec->event_data.event_type & EC_MKBP_EVENT_TYPE_MASK) { + switch (ckdev->ec->event_data.event_type) { case EC_MKBP_EVENT_KEY_MATRIX: pm_wakeup_event(ckdev->dev, 0); diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index 1d94928db922..f489cd585b33 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c @@ -192,7 +192,6 @@ static int __init davinci_ks_probe(struct platform_device *pdev) davinci_ks->irq = platform_get_irq(pdev, 0); if (davinci_ks->irq < 0) { - dev_err(dev, "no key scan irq\n"); error = davinci_ks->irq; goto fail2; } diff --git a/drivers/input/keyboard/goldfish_events.c b/drivers/input/keyboard/goldfish_events.c index bc8c85a52a10..57d435fc5c73 100644 --- a/drivers/input/keyboard/goldfish_events.c +++ b/drivers/input/keyboard/goldfish_events.c @@ -30,7 +30,7 @@ struct event_dev { struct input_dev *input; int irq; void __iomem *addr; - char name[0]; + char name[]; }; static irqreturn_t events_interrupt(int irq, void *dev_id) diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 03f4d152f6b7..53c9ff338dea 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -55,7 +55,7 @@ struct gpio_keys_drvdata { struct input_dev *input; struct mutex disable_lock; unsigned short *keymap; - struct gpio_button_data data[0]; + struct gpio_button_data data[]; }; /* @@ -351,10 +351,7 @@ static struct attribute *gpio_keys_attrs[] = { &dev_attr_disabled_switches.attr, NULL, }; - -static const struct attribute_group gpio_keys_attr_group = { - .attrs = gpio_keys_attrs, -}; +ATTRIBUTE_GROUPS(gpio_keys); static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) { @@ -497,10 +494,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev, spin_lock_init(&bdata->lock); if (child) { - bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL, - child, - GPIOD_IN, - desc); + bdata->gpiod = devm_fwnode_gpiod_get(dev, child, + NULL, GPIOD_IN, desc); if (IS_ERR(bdata->gpiod)) { error = PTR_ERR(bdata->gpiod); if (error == -ENOENT) { @@ -851,13 +846,6 @@ static int gpio_keys_probe(struct platform_device *pdev) fwnode_handle_put(child); - error = devm_device_add_group(dev, &gpio_keys_attr_group); - if (error) { - dev_err(dev, "Unable to export keys/switches, error: %d\n", - error); - return error; - } - error = input_register_device(input); if (error) { dev_err(dev, "Unable to register input device, error: %d\n", @@ -1026,6 +1014,7 @@ static struct platform_driver gpio_keys_device_driver = { .name = "gpio-keys", .pm = &gpio_keys_pm_ops, .of_match_table = gpio_keys_of_match, + .dev_groups = gpio_keys_groups, } }; diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 465eecfa6b3f..c3937d2fc744 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -16,7 +16,6 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/input.h> -#include <linux/input-polldev.h> #include <linux/ioport.h> #include <linux/platform_device.h> #include <linux/gpio.h> @@ -34,20 +33,19 @@ struct gpio_keys_button_data { }; struct gpio_keys_polled_dev { - struct input_polled_dev *poll_dev; + struct input_dev *input; struct device *dev; const struct gpio_keys_platform_data *pdata; unsigned long rel_axis_seen[BITS_TO_LONGS(REL_CNT)]; unsigned long abs_axis_seen[BITS_TO_LONGS(ABS_CNT)]; - struct gpio_keys_button_data data[0]; + struct gpio_keys_button_data data[]; }; -static void gpio_keys_button_event(struct input_polled_dev *dev, +static void gpio_keys_button_event(struct input_dev *input, const struct gpio_keys_button *button, int state) { - struct gpio_keys_polled_dev *bdev = dev->private; - struct input_dev *input = dev->input; + struct gpio_keys_polled_dev *bdev = input_get_drvdata(input); unsigned int type = button->type ?: EV_KEY; if (type == EV_REL) { @@ -66,7 +64,7 @@ static void gpio_keys_button_event(struct input_polled_dev *dev, } } -static void gpio_keys_polled_check_state(struct input_polled_dev *dev, +static void gpio_keys_polled_check_state(struct input_dev *input, const struct gpio_keys_button *button, struct gpio_keys_button_data *bdata) { @@ -74,10 +72,10 @@ static void gpio_keys_polled_check_state(struct input_polled_dev *dev, state = gpiod_get_value_cansleep(bdata->gpiod); if (state < 0) { - dev_err(dev->input->dev.parent, + dev_err(input->dev.parent, "failed to get gpio state: %d\n", state); } else { - gpio_keys_button_event(dev, button, state); + gpio_keys_button_event(input, button, state); if (state != bdata->last_state) { bdata->count = 0; @@ -86,11 +84,10 @@ static void gpio_keys_polled_check_state(struct input_polled_dev *dev, } } -static void gpio_keys_polled_poll(struct input_polled_dev *dev) +static void gpio_keys_polled_poll(struct input_dev *input) { - struct gpio_keys_polled_dev *bdev = dev->private; + struct gpio_keys_polled_dev *bdev = input_get_drvdata(input); const struct gpio_keys_platform_data *pdata = bdev->pdata; - struct input_dev *input = dev->input; int i; memset(bdev->rel_axis_seen, 0, sizeof(bdev->rel_axis_seen)); @@ -101,10 +98,10 @@ static void gpio_keys_polled_poll(struct input_polled_dev *dev) if (bdata->count < bdata->threshold) { bdata->count++; - gpio_keys_button_event(dev, &pdata->buttons[i], + gpio_keys_button_event(input, &pdata->buttons[i], bdata->last_state); } else { - gpio_keys_polled_check_state(dev, &pdata->buttons[i], + gpio_keys_polled_check_state(input, &pdata->buttons[i], bdata); } } @@ -122,18 +119,20 @@ static void gpio_keys_polled_poll(struct input_polled_dev *dev) input_sync(input); } -static void gpio_keys_polled_open(struct input_polled_dev *dev) +static int gpio_keys_polled_open(struct input_dev *input) { - struct gpio_keys_polled_dev *bdev = dev->private; + struct gpio_keys_polled_dev *bdev = input_get_drvdata(input); const struct gpio_keys_platform_data *pdata = bdev->pdata; if (pdata->enable) pdata->enable(bdev->dev); + + return 0; } -static void gpio_keys_polled_close(struct input_polled_dev *dev) +static void gpio_keys_polled_close(struct input_dev *input) { - struct gpio_keys_polled_dev *bdev = dev->private; + struct gpio_keys_polled_dev *bdev = input_get_drvdata(input); const struct gpio_keys_platform_data *pdata = bdev->pdata; if (pdata->disable) @@ -232,7 +231,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) struct fwnode_handle *child = NULL; const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); struct gpio_keys_polled_dev *bdev; - struct input_polled_dev *poll_dev; struct input_dev *input; int error; int i; @@ -255,19 +253,13 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) return -ENOMEM; } - poll_dev = devm_input_allocate_polled_device(dev); - if (!poll_dev) { - dev_err(dev, "no memory for polled device\n"); + input = devm_input_allocate_device(dev); + if (!input) { + dev_err(dev, "no memory for input device\n"); return -ENOMEM; } - poll_dev->private = bdev; - poll_dev->poll = gpio_keys_polled_poll; - poll_dev->poll_interval = pdata->poll_interval; - poll_dev->open = gpio_keys_polled_open; - poll_dev->close = gpio_keys_polled_close; - - input = poll_dev->input; + input_set_drvdata(input, bdev); input->name = pdata->name ?: pdev->name; input->phys = DRV_NAME"/input0"; @@ -277,6 +269,9 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) input->id.product = 0x0001; input->id.version = 0x0100; + input->open = gpio_keys_polled_open; + input->close = gpio_keys_polled_close; + __set_bit(EV_KEY, input->evbit); if (pdata->rep) __set_bit(EV_REP, input->evbit); @@ -300,10 +295,9 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) return -EINVAL; } - bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, - NULL, child, - GPIOD_IN, - button->desc); + bdata->gpiod = devm_fwnode_gpiod_get(dev, child, + NULL, GPIOD_IN, + button->desc); if (IS_ERR(bdata->gpiod)) { error = PTR_ERR(bdata->gpiod); if (error != -EPROBE_DEFER) @@ -353,11 +347,19 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) fwnode_handle_put(child); - bdev->poll_dev = poll_dev; + bdev->input = input; bdev->dev = dev; bdev->pdata = pdata; - error = input_register_polled_device(poll_dev); + error = input_setup_polling(input, gpio_keys_polled_poll); + if (error) { + dev_err(dev, "unable to set up polling, err=%d\n", error); + return error; + } + + input_set_poll_interval(input, pdata->poll_interval); + + error = input_register_device(input); if (error) { dev_err(dev, "unable to register polled device, err=%d\n", error); @@ -366,7 +368,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) /* report initial state of the buttons */ for (i = 0; i < pdata->nbuttons; i++) - gpio_keys_polled_check_state(poll_dev, &pdata->buttons[i], + gpio_keys_polled_check_state(input, &pdata->buttons[i], &bdev->data[i]); input_sync(input); diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index 97500a2de2d5..5a46d113e909 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c @@ -430,10 +430,8 @@ static int imx_keypad_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "no irq defined in platform data\n"); + if (irq < 0) return irq; - } input_dev = devm_input_allocate_device(&pdev->dev); if (!input_dev) { diff --git a/drivers/input/keyboard/imx_sc_key.c b/drivers/input/keyboard/imx_sc_key.c new file mode 100644 index 000000000000..9f809aeb785c --- /dev/null +++ b/drivers/input/keyboard/imx_sc_key.c @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 NXP. + */ + +#include <linux/err.h> +#include <linux/device.h> +#include <linux/firmware/imx/sci.h> +#include <linux/init.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/jiffies.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/property.h> + +#define DEBOUNCE_TIME 30 +#define REPEAT_INTERVAL 60 + +#define SC_IRQ_BUTTON 1 +#define SC_IRQ_GROUP_WAKE 3 + +#define IMX_SC_MISC_FUNC_GET_BUTTON_STATUS 18 + +struct imx_key_drv_data { + u32 keycode; + bool keystate; /* true: pressed, false: released */ + struct delayed_work check_work; + struct input_dev *input; + struct imx_sc_ipc *key_ipc_handle; + struct notifier_block key_notifier; +}; + +struct imx_sc_msg_key { + struct imx_sc_rpc_msg hdr; + u32 state; +}; + +static int imx_sc_key_notify(struct notifier_block *nb, + unsigned long event, void *group) +{ + struct imx_key_drv_data *priv = + container_of(nb, + struct imx_key_drv_data, + key_notifier); + + if ((event & SC_IRQ_BUTTON) && (*(u8 *)group == SC_IRQ_GROUP_WAKE)) { + schedule_delayed_work(&priv->check_work, + msecs_to_jiffies(DEBOUNCE_TIME)); + pm_wakeup_event(priv->input->dev.parent, 0); + } + + return 0; +} + +static void imx_sc_check_for_events(struct work_struct *work) +{ + struct imx_key_drv_data *priv = + container_of(work, + struct imx_key_drv_data, + check_work.work); + struct input_dev *input = priv->input; + struct imx_sc_msg_key msg; + struct imx_sc_rpc_msg *hdr = &msg.hdr; + bool state; + int error; + + hdr->ver = IMX_SC_RPC_VERSION; + hdr->svc = IMX_SC_RPC_SVC_MISC; + hdr->func = IMX_SC_MISC_FUNC_GET_BUTTON_STATUS; + hdr->size = 1; + + error = imx_scu_call_rpc(priv->key_ipc_handle, &msg, true); + if (error) { + dev_err(&input->dev, "read imx sc key failed, error %d\n", error); + return; + } + + /* + * The response data from SCU firmware is 4 bytes, + * but ONLY the first byte is the key state, other + * 3 bytes could be some dirty data, so we should + * ONLY take the first byte as key state. + */ + state = (bool)(msg.state & 0xff); + + if (state ^ priv->keystate) { + priv->keystate = state; + input_event(input, EV_KEY, priv->keycode, state); + input_sync(input); + if (!priv->keystate) + pm_relax(priv->input->dev.parent); + } + + if (state) + schedule_delayed_work(&priv->check_work, + msecs_to_jiffies(REPEAT_INTERVAL)); +} + +static int imx_sc_key_probe(struct platform_device *pdev) +{ + struct imx_key_drv_data *priv; + struct input_dev *input; + int error; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + error = imx_scu_get_handle(&priv->key_ipc_handle); + if (error) + return error; + + if (device_property_read_u32(&pdev->dev, "linux,keycodes", + &priv->keycode)) { + dev_err(&pdev->dev, "missing linux,keycodes property\n"); + return -EINVAL; + } + + INIT_DELAYED_WORK(&priv->check_work, imx_sc_check_for_events); + + input = devm_input_allocate_device(&pdev->dev); + if (!input) { + dev_err(&pdev->dev, "failed to allocate the input device\n"); + return -ENOMEM; + } + + input->name = pdev->name; + input->phys = "imx-sc-key/input0"; + input->id.bustype = BUS_HOST; + + input_set_capability(input, EV_KEY, priv->keycode); + + error = input_register_device(input); + if (error) { + dev_err(&pdev->dev, "failed to register input device\n"); + return error; + } + + priv->input = input; + platform_set_drvdata(pdev, priv); + + error = imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, + true); + if (error) { + dev_err(&pdev->dev, "failed to enable scu group irq\n"); + return error; + } + + priv->key_notifier.notifier_call = imx_sc_key_notify; + error = imx_scu_irq_register_notifier(&priv->key_notifier); + if (error) { + imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, + false); + dev_err(&pdev->dev, "failed to register scu notifier\n"); + return error; + } + + return 0; +} + +static int imx_sc_key_remove(struct platform_device *pdev) +{ + struct imx_key_drv_data *priv = platform_get_drvdata(pdev); + + imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, false); + imx_scu_irq_unregister_notifier(&priv->key_notifier); + cancel_delayed_work_sync(&priv->check_work); + + return 0; +} + +static const struct of_device_id imx_sc_key_ids[] = { + { .compatible = "fsl,imx-sc-key" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx_sc_key_ids); + +static struct platform_driver imx_sc_key_driver = { + .driver = { + .name = "imx-sc-key", + .of_match_table = imx_sc_key_ids, + }, + .probe = imx_sc_key_probe, + .remove = imx_sc_key_remove, +}; +module_platform_driver(imx_sc_key_driver); + +MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>"); +MODULE_DESCRIPTION("i.MX System Controller Key Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 4232aa876d2e..7e35081393be 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c @@ -15,7 +15,6 @@ #include <linux/device.h> #include <linux/input.h> -#include <linux/input-polldev.h> #include <linux/interrupt.h> #include <linux/jiffies.h> #include <linux/kernel.h> @@ -64,7 +63,7 @@ static const unsigned short jornada_scancodes[] = { #define JORNADA_SCAN_SIZE 18 struct jornadakbd { - struct input_polled_dev *poll_dev; + struct input_dev *input; unsigned short keymap[ARRAY_SIZE(jornada_scancodes)]; unsigned char length; unsigned char old_scan[JORNADA_SCAN_SIZE]; @@ -73,7 +72,7 @@ struct jornadakbd { static void jornada_parse_kbd(struct jornadakbd *jornadakbd) { - struct input_dev *input_dev = jornadakbd->poll_dev->input; + struct input_dev *input_dev = jornadakbd->input; unsigned short *keymap = jornadakbd->keymap; unsigned int sync_me = 0; unsigned int i, j; @@ -167,9 +166,9 @@ static void jornada_scan_keyb(unsigned char *s) *s++ = __raw_readb(PHDR); } -static void jornadakbd680_poll(struct input_polled_dev *dev) +static void jornadakbd680_poll(struct input_dev *input) { - struct jornadakbd *jornadakbd = dev->private; + struct jornadakbd *jornadakbd = input_get_drvdata(input); jornada_scan_keyb(jornadakbd->new_scan); jornada_parse_kbd(jornadakbd); @@ -179,7 +178,6 @@ static void jornadakbd680_poll(struct input_polled_dev *dev) static int jornada680kbd_probe(struct platform_device *pdev) { struct jornadakbd *jornadakbd; - struct input_polled_dev *poll_dev; struct input_dev *input_dev; int i, error; @@ -188,29 +186,24 @@ static int jornada680kbd_probe(struct platform_device *pdev) if (!jornadakbd) return -ENOMEM; - poll_dev = devm_input_allocate_polled_device(&pdev->dev); - if (!poll_dev) { - dev_err(&pdev->dev, "failed to allocate polled input device\n"); + input_dev = devm_input_allocate_device(&pdev->dev); + if (!input_dev) { + dev_err(&pdev->dev, "failed to allocate input device\n"); return -ENOMEM; } - jornadakbd->poll_dev = poll_dev; + jornadakbd->input = input_dev; memcpy(jornadakbd->keymap, jornada_scancodes, sizeof(jornadakbd->keymap)); - poll_dev->private = jornadakbd; - poll_dev->poll = jornadakbd680_poll; - poll_dev->poll_interval = 50; /* msec */ - - input_dev = poll_dev->input; + input_set_drvdata(input_dev, jornadakbd); input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->name = "HP Jornada 680 keyboard"; input_dev->phys = "jornadakbd/input0"; input_dev->keycode = jornadakbd->keymap; input_dev->keycodesize = sizeof(unsigned short); input_dev->keycodemax = ARRAY_SIZE(jornada_scancodes); - input_dev->dev.parent = &pdev->dev; input_dev->id.bustype = BUS_HOST; for (i = 0; i < 128; i++) @@ -220,9 +213,17 @@ static int jornada680kbd_probe(struct platform_device *pdev) input_set_capability(input_dev, EV_MSC, MSC_SCAN); - error = input_register_polled_device(jornadakbd->poll_dev); + error = input_setup_polling(input_dev, jornadakbd680_poll); + if (error) { + dev_err(&pdev->dev, "failed to set up polling\n"); + return error; + } + + input_set_poll_interval(input_dev, 50 /* msec */); + + error = input_register_device(input_dev); if (error) { - dev_err(&pdev->dev, "failed to register polled input device\n"); + dev_err(&pdev->dev, "failed to register input device\n"); return error; } diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c index a34e3271b0c9..348af2aeb5de 100644 --- a/drivers/input/keyboard/lpc32xx-keys.c +++ b/drivers/input/keyboard/lpc32xx-keys.c @@ -172,10 +172,8 @@ static int lpc32xx_kscan_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get platform irq\n"); + if (irq < 0) return -EINVAL; - } kscandat = devm_kzalloc(&pdev->dev, sizeof(*kscandat), GFP_KERNEL); diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index e9ceaa16b46a..40d6e5087cde 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -54,6 +54,9 @@ /* MPR121 has 12 keys */ #define MPR121_MAX_KEY_COUNT 12 +#define MPR121_MIN_POLL_INTERVAL 10 +#define MPR121_MAX_POLL_INTERVAL 200 + struct mpr121_touchkey { struct i2c_client *client; struct input_dev *input_dev; @@ -115,11 +118,11 @@ static struct regulator *mpr121_vdd_supply_init(struct device *dev) return vdd_supply; } -static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) +static void mpr_touchkey_report(struct input_dev *dev) { - struct mpr121_touchkey *mpr121 = dev_id; - struct i2c_client *client = mpr121->client; + struct mpr121_touchkey *mpr121 = input_get_drvdata(dev); struct input_dev *input = mpr121->input_dev; + struct i2c_client *client = mpr121->client; unsigned long bit_changed; unsigned int key_num; int reg; @@ -127,14 +130,14 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR); if (reg < 0) { dev_err(&client->dev, "i2c read error [%d]\n", reg); - goto out; + return; } reg <<= 8; reg |= i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_0_ADDR); if (reg < 0) { dev_err(&client->dev, "i2c read error [%d]\n", reg); - goto out; + return; } reg &= TOUCH_STATUS_MASK; @@ -155,8 +158,14 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) } input_sync(input); +} + +static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) +{ + struct mpr121_touchkey *mpr121 = dev_id; + + mpr_touchkey_report(mpr121->input_dev); -out: return IRQ_HANDLED; } @@ -229,14 +238,10 @@ static int mpr_touchkey_probe(struct i2c_client *client, int vdd_uv; struct mpr121_touchkey *mpr121; struct input_dev *input_dev; + u32 poll_interval = 0; int error; int i; - if (!client->irq) { - dev_err(dev, "irq number should not be zero\n"); - return -EINVAL; - } - vdd_supply = mpr121_vdd_supply_init(dev); if (IS_ERR(vdd_supply)) return PTR_ERR(vdd_supply); @@ -253,8 +258,7 @@ static int mpr_touchkey_probe(struct i2c_client *client, mpr121->client = client; mpr121->input_dev = input_dev; - mpr121->keycount = device_property_read_u32_array(dev, "linux,keycodes", - NULL, 0); + mpr121->keycount = device_property_count_u32(dev, "linux,keycodes"); if (mpr121->keycount > MPR121_MAX_KEY_COUNT) { dev_err(dev, "too many keys defined (%d)\n", mpr121->keycount); return -EINVAL; @@ -275,6 +279,7 @@ static int mpr_touchkey_probe(struct i2c_client *client, if (device_property_read_bool(dev, "autorepeat")) __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); + input_set_drvdata(input_dev, mpr121); input_dev->keycode = mpr121->keycodes; input_dev->keycodesize = sizeof(mpr121->keycodes[0]); @@ -289,13 +294,40 @@ static int mpr_touchkey_probe(struct i2c_client *client, return error; } - error = devm_request_threaded_irq(dev, client->irq, NULL, - mpr_touchkey_interrupt, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - dev->driver->name, mpr121); - if (error) { - dev_err(dev, "Failed to register interrupt\n"); - return error; + device_property_read_u32(dev, "poll-interval", &poll_interval); + + if (client->irq) { + error = devm_request_threaded_irq(dev, client->irq, NULL, + mpr_touchkey_interrupt, + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + dev->driver->name, mpr121); + if (error) { + dev_err(dev, "Failed to register interrupt\n"); + return error; + } + } else if (poll_interval) { + if (poll_interval < MPR121_MIN_POLL_INTERVAL) + return -EINVAL; + + if (poll_interval > MPR121_MAX_POLL_INTERVAL) + return -EINVAL; + + error = input_setup_polling(input_dev, mpr_touchkey_report); + if (error) { + dev_err(dev, "Failed to setup polling\n"); + return error; + } + + input_set_poll_interval(input_dev, poll_interval); + input_set_min_poll_interval(input_dev, + MPR121_MIN_POLL_INTERVAL); + input_set_max_poll_interval(input_dev, + MPR121_MAX_POLL_INTERVAL); + } else { + dev_err(dev, + "invalid IRQ number and polling not configured\n"); + return -EINVAL; } error = input_register_device(input_dev); diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index fa265fdce2c4..608446e14614 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -235,10 +235,8 @@ static int __init ske_keypad_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get keypad irq\n"); + if (irq < 0) return -EINVAL; - } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { diff --git a/drivers/input/keyboard/nspire-keypad.c b/drivers/input/keyboard/nspire-keypad.c index 57eac91ecd76..63d5e488137d 100644 --- a/drivers/input/keyboard/nspire-keypad.c +++ b/drivers/input/keyboard/nspire-keypad.c @@ -165,10 +165,8 @@ static int nspire_keypad_probe(struct platform_device *pdev) int error; irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get keypad irq\n"); + if (irq < 0) return -EINVAL; - } keypad = devm_kzalloc(&pdev->dev, sizeof(struct nspire_keypad), GFP_KERNEL); diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c index 159346cb4060..b0ea387414c1 100644 --- a/drivers/input/keyboard/opencores-kbd.c +++ b/drivers/input/keyboard/opencores-kbd.c @@ -49,10 +49,8 @@ static int opencores_kbd_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "missing board IRQ resource\n"); + if (irq < 0) return -EINVAL; - } opencores_kbd = devm_kzalloc(&pdev->dev, sizeof(*opencores_kbd), GFP_KERNEL); diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index d529768a1d06..91d5811d6f0e 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c @@ -544,16 +544,12 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev) } kp->key_sense_irq = platform_get_irq(pdev, 0); - if (kp->key_sense_irq < 0) { - dev_err(&pdev->dev, "unable to get keypad sense irq\n"); + if (kp->key_sense_irq < 0) return kp->key_sense_irq; - } kp->key_stuck_irq = platform_get_irq(pdev, 1); - if (kp->key_stuck_irq < 0) { - dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); + if (kp->key_stuck_irq < 0) return kp->key_stuck_irq; - } kp->input->name = "PMIC8XXX keypad"; kp->input->phys = "pmic8xxx_keypad/input0"; diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 39023664d2f2..7e65708b25a4 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -727,10 +727,8 @@ static int pxa27x_keypad_probe(struct platform_device *pdev) return -EINVAL; irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get keypad irq\n"); + if (irq < 0) return -ENXIO; - } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c index 585e7765cbf0..2fe9dcfe0a6f 100644 --- a/drivers/input/keyboard/pxa930_rotary.c +++ b/drivers/input/keyboard/pxa930_rotary.c @@ -89,10 +89,8 @@ static int pxa930_rotary_probe(struct platform_device *pdev) int err; irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "no irq for rotary controller\n"); + if (irq < 0) return -ENXIO; - } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { @@ -109,7 +107,7 @@ static int pxa930_rotary_probe(struct platform_device *pdev) if (!r) return -ENOMEM; - r->mmio_base = ioremap_nocache(res->start, resource_size(res)); + r->mmio_base = ioremap(res->start, resource_size(res)); if (r->mmio_base == NULL) { dev_err(&pdev->dev, "failed to remap IO memory\n"); err = -ENXIO; diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 08ba41a81f14..c155adebf96e 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -181,10 +181,8 @@ static int sh_keysc_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get irq\n"); + if (irq < 0) goto err0; - } priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (priv == NULL) { @@ -197,7 +195,7 @@ static int sh_keysc_probe(struct platform_device *pdev) memcpy(&priv->pdata, dev_get_platdata(&pdev->dev), sizeof(priv->pdata)); pdata = &priv->pdata; - priv->iomem_base = ioremap_nocache(res->start, resource_size(res)); + priv->iomem_base = ioremap(res->start, resource_size(res)); if (priv->iomem_base == NULL) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); error = -ENXIO; diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c index 5342d8d45f81..2f5e3ab5ed63 100644 --- a/drivers/input/keyboard/snvs_pwrkey.c +++ b/drivers/input/keyboard/snvs_pwrkey.c @@ -19,15 +19,16 @@ #include <linux/mfd/syscon.h> #include <linux/regmap.h> -#define SNVS_LPSR_REG 0x4C /* LP Status Register */ -#define SNVS_LPCR_REG 0x38 /* LP Control Register */ -#define SNVS_HPSR_REG 0x14 -#define SNVS_HPSR_BTN BIT(6) -#define SNVS_LPSR_SPO BIT(18) -#define SNVS_LPCR_DEP_EN BIT(5) +#define SNVS_HPVIDR1_REG 0xF8 +#define SNVS_LPSR_REG 0x4C /* LP Status Register */ +#define SNVS_LPCR_REG 0x38 /* LP Control Register */ +#define SNVS_HPSR_REG 0x14 +#define SNVS_HPSR_BTN BIT(6) +#define SNVS_LPSR_SPO BIT(18) +#define SNVS_LPCR_DEP_EN BIT(5) -#define DEBOUNCE_TIME 30 -#define REPEAT_INTERVAL 60 +#define DEBOUNCE_TIME 30 +#define REPEAT_INTERVAL 60 struct pwrkey_drv_data { struct regmap *snvs; @@ -37,6 +38,7 @@ struct pwrkey_drv_data { int wakeup; struct timer_list check_timer; struct input_dev *input; + u8 minor_rev; }; static void imx_imx_snvs_check_for_events(struct timer_list *t) @@ -67,13 +69,29 @@ static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id) { struct platform_device *pdev = dev_id; struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev); + struct input_dev *input = pdata->input; u32 lp_status; - pm_wakeup_event(pdata->input->dev.parent, 0); + pm_wakeup_event(input->dev.parent, 0); regmap_read(pdata->snvs, SNVS_LPSR_REG, &lp_status); - if (lp_status & SNVS_LPSR_SPO) - mod_timer(&pdata->check_timer, jiffies + msecs_to_jiffies(DEBOUNCE_TIME)); + if (lp_status & SNVS_LPSR_SPO) { + if (pdata->minor_rev == 0) { + /* + * The first generation i.MX6 SoCs only sends an + * interrupt on button release. To mimic power-key + * usage, we'll prepend a press event. + */ + input_report_key(input, pdata->keycode, 1); + input_sync(input); + input_report_key(input, pdata->keycode, 0); + input_sync(input); + pm_relax(input->dev.parent); + } else { + mod_timer(&pdata->check_timer, + jiffies + msecs_to_jiffies(DEBOUNCE_TIME)); + } + } /* clear SPO status */ regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO); @@ -90,10 +108,11 @@ static void imx_snvs_pwrkey_act(void *pdata) static int imx_snvs_pwrkey_probe(struct platform_device *pdev) { - struct pwrkey_drv_data *pdata = NULL; - struct input_dev *input = NULL; + struct pwrkey_drv_data *pdata; + struct input_dev *input; struct device_node *np; int error; + u32 vid; /* Get SNVS register Page */ np = pdev->dev.of_node; @@ -118,10 +137,11 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev) pdata->wakeup = of_property_read_bool(np, "wakeup-source"); pdata->irq = platform_get_irq(pdev, 0); - if (pdata->irq < 0) { - dev_err(&pdev->dev, "no irq defined in platform data\n"); + if (pdata->irq < 0) return -EINVAL; - } + + regmap_read(pdata->snvs, SNVS_HPVIDR1_REG, &vid); + pdata->minor_rev = vid & 0xff; regmap_update_bits(pdata->snvs, SNVS_LPCR_REG, SNVS_LPCR_DEP_EN, SNVS_LPCR_DEP_EN); diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 7d25fa338ab4..9b8d78f87253 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -191,10 +191,8 @@ static int spear_kbd_probe(struct platform_device *pdev) int error; irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "not able to get irq for the device\n"); + if (irq < 0) return irq; - } kbd = devm_kzalloc(&pdev->dev, sizeof(*kbd), GFP_KERNEL); if (!kbd) { diff --git a/drivers/input/keyboard/st-keyscan.c b/drivers/input/keyboard/st-keyscan.c index f097128b93fe..27562cd67fb6 100644 --- a/drivers/input/keyboard/st-keyscan.c +++ b/drivers/input/keyboard/st-keyscan.c @@ -187,10 +187,8 @@ static int keyscan_probe(struct platform_device *pdev) keyscan_stop(keypad_data); keypad_data->irq = platform_get_irq(pdev, 0); - if (keypad_data->irq < 0) { - dev_err(&pdev->dev, "no IRQ specified\n"); + if (keypad_data->irq < 0) return -EINVAL; - } error = devm_request_irq(&pdev->dev, keypad_data->irq, keyscan_isr, 0, pdev->name, keypad_data); diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c index 2a14769de637..21758767ccf0 100644 --- a/drivers/input/keyboard/tca6416-keypad.c +++ b/drivers/input/keyboard/tca6416-keypad.c @@ -33,7 +33,7 @@ MODULE_DEVICE_TABLE(i2c, tca6416_id); struct tca6416_drv_data { struct input_dev *input; - struct tca6416_button data[0]; + struct tca6416_button data[]; }; struct tca6416_keypad_chip { @@ -48,7 +48,7 @@ struct tca6416_keypad_chip { int irqnum; u16 pinmask; bool use_polling; - struct tca6416_button buttons[0]; + struct tca6416_button buttons[]; }; static int tca6416_write_reg(struct tca6416_keypad_chip *chip, int reg, u16 val) diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index a37a7a9e9171..d34d6947960f 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -631,10 +631,8 @@ static int tegra_kbc_probe(struct platform_device *pdev) return -EINVAL; kbc->irq = platform_get_irq(pdev, 0); - if (kbc->irq < 0) { - dev_err(&pdev->dev, "failed to get keyboard IRQ\n"); + if (kbc->irq < 0) return -ENXIO; - } kbc->idev = devm_input_allocate_device(&pdev->dev); if (!kbc->idev) { diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c deleted file mode 100644 index c88d05d6108a..000000000000 --- a/drivers/input/keyboard/w90p910_keypad.c +++ /dev/null @@ -1,264 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2008-2009 Nuvoton technology corporation. - * - * Wan ZongShun <mcuos.com@gmail.com> - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/input.h> -#include <linux/device.h> -#include <linux/platform_device.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/slab.h> - -#include <linux/platform_data/keypad-w90p910.h> - -/* Keypad Interface Control Registers */ -#define KPI_CONF 0x00 -#define KPI_3KCONF 0x04 -#define KPI_LPCONF 0x08 -#define KPI_STATUS 0x0C - -#define IS1KEY (0x01 << 16) -#define INTTR (0x01 << 21) -#define KEY0R (0x0f << 3) -#define KEY0C 0x07 -#define DEBOUNCE_BIT 0x08 -#define KSIZE0 (0x01 << 16) -#define KSIZE1 (0x01 << 17) -#define KPSEL (0x01 << 19) -#define ENKP (0x01 << 18) - -#define KGET_RAW(n) (((n) & KEY0R) >> 3) -#define KGET_COLUMN(n) ((n) & KEY0C) - -#define W90P910_NUM_ROWS 8 -#define W90P910_NUM_COLS 8 -#define W90P910_ROW_SHIFT 3 - -struct w90p910_keypad { - const struct w90p910_keypad_platform_data *pdata; - struct clk *clk; - struct input_dev *input_dev; - void __iomem *mmio_base; - int irq; - unsigned short keymap[W90P910_NUM_ROWS * W90P910_NUM_COLS]; -}; - -static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad, - unsigned int status) -{ - struct input_dev *input_dev = keypad->input_dev; - unsigned int row = KGET_RAW(status); - unsigned int col = KGET_COLUMN(status); - unsigned int code = MATRIX_SCAN_CODE(row, col, W90P910_ROW_SHIFT); - unsigned int key = keypad->keymap[code]; - - input_event(input_dev, EV_MSC, MSC_SCAN, code); - input_report_key(input_dev, key, 1); - input_sync(input_dev); - - input_event(input_dev, EV_MSC, MSC_SCAN, code); - input_report_key(input_dev, key, 0); - input_sync(input_dev); -} - -static irqreturn_t w90p910_keypad_irq_handler(int irq, void *dev_id) -{ - struct w90p910_keypad *keypad = dev_id; - unsigned int kstatus, val; - - kstatus = __raw_readl(keypad->mmio_base + KPI_STATUS); - - val = INTTR | IS1KEY; - - if (kstatus & val) - w90p910_keypad_scan_matrix(keypad, kstatus); - - return IRQ_HANDLED; -} - -static int w90p910_keypad_open(struct input_dev *dev) -{ - struct w90p910_keypad *keypad = input_get_drvdata(dev); - const struct w90p910_keypad_platform_data *pdata = keypad->pdata; - unsigned int val, config; - - /* Enable unit clock */ - clk_enable(keypad->clk); - - val = __raw_readl(keypad->mmio_base + KPI_CONF); - val |= (KPSEL | ENKP); - val &= ~(KSIZE0 | KSIZE1); - - config = pdata->prescale | (pdata->debounce << DEBOUNCE_BIT); - - val |= config; - - __raw_writel(val, keypad->mmio_base + KPI_CONF); - - return 0; -} - -static void w90p910_keypad_close(struct input_dev *dev) -{ - struct w90p910_keypad *keypad = input_get_drvdata(dev); - - /* Disable clock unit */ - clk_disable(keypad->clk); -} - -static int w90p910_keypad_probe(struct platform_device *pdev) -{ - const struct w90p910_keypad_platform_data *pdata = - dev_get_platdata(&pdev->dev); - const struct matrix_keymap_data *keymap_data; - struct w90p910_keypad *keypad; - struct input_dev *input_dev; - struct resource *res; - int irq; - int error; - - if (!pdata) { - dev_err(&pdev->dev, "no platform data defined\n"); - return -EINVAL; - } - - keymap_data = pdata->keymap_data; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "failed to get keypad irq\n"); - return -ENXIO; - } - - keypad = kzalloc(sizeof(struct w90p910_keypad), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!keypad || !input_dev) { - dev_err(&pdev->dev, "failed to allocate driver data\n"); - error = -ENOMEM; - goto failed_free; - } - - keypad->pdata = pdata; - keypad->input_dev = input_dev; - keypad->irq = irq; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "failed to get I/O memory\n"); - error = -ENXIO; - goto failed_free; - } - - res = request_mem_region(res->start, resource_size(res), pdev->name); - if (res == NULL) { - dev_err(&pdev->dev, "failed to request I/O memory\n"); - error = -EBUSY; - goto failed_free; - } - - keypad->mmio_base = ioremap(res->start, resource_size(res)); - if (keypad->mmio_base == NULL) { - dev_err(&pdev->dev, "failed to remap I/O memory\n"); - error = -ENXIO; - goto failed_free_res; - } - - keypad->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(keypad->clk)) { - dev_err(&pdev->dev, "failed to get keypad clock\n"); - error = PTR_ERR(keypad->clk); - goto failed_free_io; - } - - /* set multi-function pin for w90p910 kpi. */ - mfp_set_groupi(&pdev->dev); - - input_dev->name = pdev->name; - input_dev->id.bustype = BUS_HOST; - input_dev->open = w90p910_keypad_open; - input_dev->close = w90p910_keypad_close; - input_dev->dev.parent = &pdev->dev; - - error = matrix_keypad_build_keymap(keymap_data, NULL, - W90P910_NUM_ROWS, W90P910_NUM_COLS, - keypad->keymap, input_dev); - if (error) { - dev_err(&pdev->dev, "failed to build keymap\n"); - goto failed_put_clk; - } - - error = request_irq(keypad->irq, w90p910_keypad_irq_handler, - 0, pdev->name, keypad); - if (error) { - dev_err(&pdev->dev, "failed to request IRQ\n"); - goto failed_put_clk; - } - - __set_bit(EV_REP, input_dev->evbit); - input_set_capability(input_dev, EV_MSC, MSC_SCAN); - input_set_drvdata(input_dev, keypad); - - /* Register the input device */ - error = input_register_device(input_dev); - if (error) { - dev_err(&pdev->dev, "failed to register input device\n"); - goto failed_free_irq; - } - - platform_set_drvdata(pdev, keypad); - return 0; - -failed_free_irq: - free_irq(irq, keypad); -failed_put_clk: - clk_put(keypad->clk); -failed_free_io: - iounmap(keypad->mmio_base); -failed_free_res: - release_mem_region(res->start, resource_size(res)); -failed_free: - input_free_device(input_dev); - kfree(keypad); - return error; -} - -static int w90p910_keypad_remove(struct platform_device *pdev) -{ - struct w90p910_keypad *keypad = platform_get_drvdata(pdev); - struct resource *res; - - free_irq(keypad->irq, keypad); - - clk_put(keypad->clk); - - input_unregister_device(keypad->input_dev); - - iounmap(keypad->mmio_base); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); - - kfree(keypad); - - return 0; -} - -static struct platform_driver w90p910_keypad_driver = { - .probe = w90p910_keypad_probe, - .remove = w90p910_keypad_remove, - .driver = { - .name = "nuc900-kpi", - }, -}; -module_platform_driver(w90p910_keypad_driver); - -MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); -MODULE_DESCRIPTION("w90p910 keypad driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:nuc900-keypad"); |