diff options
Diffstat (limited to 'drivers/input')
33 files changed, 638 insertions, 77 deletions
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index ff8037798779..c5992cd195a1 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -16,7 +16,7 @@ config INPUT Say N here if you have a headless (no monitor, no keyboard) system. - More information is available: <file:Documentation/input/input.txt> + More information is available: <file:Documentation/input/input.rst> If unsure, say Y. @@ -144,7 +144,7 @@ config INPUT_JOYDEV If unsure, say Y. - More information is available: <file:Documentation/input/joystick.txt> + More information is available: <file:Documentation/input/joydev/joystick.rst> To compile this driver as a module, choose M here: the module will be called joydev. diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c index 5f04b2d94635..99cc784e1264 100644 --- a/drivers/input/input-leds.c +++ b/drivers/input/input-leds.c @@ -98,8 +98,7 @@ static int input_leds_connect(struct input_handler *handler, if (!num_leds) return -ENXIO; - leds = kzalloc(sizeof(*leds) + num_leds * sizeof(*leds->leds), - GFP_KERNEL); + leds = kzalloc(struct_size(leds, leds, num_leds), GFP_KERNEL); if (!leds) return -ENOMEM; diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 4a69716e5461..6c7326c93721 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -49,7 +49,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, if (mt) return mt->num_slots != num_slots ? -EINVAL : 0; - mt = kzalloc(sizeof(*mt) + num_slots * sizeof(*mt->slots), GFP_KERNEL); + mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL); if (!mt) goto err_mem; diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index 9591fc04a8ab..d8f9c6e1fc08 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig @@ -9,7 +9,7 @@ menuconfig INPUT_JOYSTICK and the list of supported devices will be displayed. This option doesn't affect the kernel. - Please read the file <file:Documentation/input/joystick.txt> which + Please read the file <file:Documentation/input/joydev/joystick.rst> which contains more information. if INPUT_JOYSTICK @@ -25,7 +25,7 @@ config JOYSTICK_ANALOG Flightstick Pro, ThrustMaster FCS, 6 and 8 button gamepads, or Saitek Cyborg joysticks. - Please read the file <file:Documentation/input/joystick.txt> which + Please read the file <file:Documentation/input/joydev/joystick.rst> which contains more information. To compile this driver as a module, choose M here: the @@ -214,7 +214,7 @@ config JOYSTICK_DB9 gamepad, Sega Saturn gamepad, or a Multisystem -- Atari, Amiga, Commodore, Amstrad CPC joystick connected to your parallel port. For more information on how to use the driver please read - <file:Documentation/input/joystick-parport.txt>. + <file:Documentation/input/devices/joystick-parport.rst>. To compile this driver as a module, choose M here: the module will be called db9. @@ -229,7 +229,7 @@ config JOYSTICK_GAMECON Sony PlayStation gamepad or a Multisystem -- Atari, Amiga, Commodore, Amstrad CPC joystick connected to your parallel port. For more information on how to use the driver please read - <file:Documentation/input/joystick-parport.txt>. + <file:Documentation/input/devices/joystick-parport.rst>. To compile this driver as a module, choose M here: the module will be called gamecon. @@ -241,7 +241,7 @@ config JOYSTICK_TURBOGRAFX Say Y here if you have the TurboGraFX interface by Steffen Schwenke, and want to use it with Multisystem -- Atari, Amiga, Commodore, Amstrad CPC joystick. For more information on how to use the driver - please read <file:Documentation/input/joystick-parport.txt>. + please read <file:Documentation/input/devices/joystick-parport.rst>. To compile this driver as a module, choose M here: the module will be called turbografx. @@ -287,7 +287,7 @@ config JOYSTICK_XPAD and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well. For information about how to connect the X-Box pad to USB, see - <file:Documentation/input/xpad.txt>. + <file:Documentation/input/devices/xpad.rst>. To compile this driver as a module, choose M here: the module will be called xpad. @@ -313,7 +313,7 @@ config JOYSTICK_WALKERA0701 Say Y or M here if you have a Walkera WK-0701 transmitter which is supplied with a ready to fly Walkera helicopters such as HM36, HM37, HM60 and want to use it via parport as a joystick. More - information is available: <file:Documentation/input/walkera0701.txt> + information is available: <file:Documentation/input/devices/walkera0701.rst> To compile this driver as a module, choose M here: the module will be called walkera0701. diff --git a/drivers/input/joystick/iforce/Kconfig b/drivers/input/joystick/iforce/Kconfig index 8fde22a021b3..ab4dbcbcbf50 100644 --- a/drivers/input/joystick/iforce/Kconfig +++ b/drivers/input/joystick/iforce/Kconfig @@ -27,6 +27,6 @@ config JOYSTICK_IFORCE_232 connected to your serial (COM) port. You will need an additional utility called inputattach, see - <file:Documentation/input/joystick.txt> - and <file:Documentation/input/ff.txt>. + <file:Documentation/input/joydev/joystick.rst> + and <file:Documentation/input/ff.rst>. diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c index 2ea05ade4d4e..344ab44ff581 100644 --- a/drivers/input/joystick/joydump.c +++ b/drivers/input/joystick/joydump.c @@ -76,7 +76,7 @@ static int joydump_connect(struct gameport *gameport, struct gameport_driver *dr timeout = gameport_time(gameport, 10000); /* 10 ms */ - buf = kmalloc(BUF_SIZE * sizeof(struct joydump), GFP_KERNEL); + buf = kmalloc_array(BUF_SIZE, sizeof(struct joydump), GFP_KERNEL); if (!buf) { printk(KERN_INFO "joydump: no memory for testing\n"); goto jd_end; diff --git a/drivers/input/joystick/walkera0701.c b/drivers/input/joystick/walkera0701.c index 36a5b93156ed..dce313dc260a 100644 --- a/drivers/input/joystick/walkera0701.c +++ b/drivers/input/joystick/walkera0701.c @@ -3,7 +3,7 @@ * * Copyright (c) 2008 Peter Popovec * - * More about driver: <file:Documentation/input/walkera0701.txt> + * More about driver: <file:Documentation/input/devices/walkera0701.rst> */ /* diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 2b469cc47a78..6bd97ffee761 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -747,4 +747,13 @@ config KEYBOARD_BCM To compile this driver as a module, choose M here: the module will be called bcm-keypad. +config KEYBOARD_MTK_PMIC + tristate "MediaTek PMIC keys support" + depends on MFD_MT6397 + help + Say Y here if you want to use the pmic keys (powerkey/homekey). + + To compile this driver as a module, choose M here: the + module will be called pmic-keys. + endif diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 8fab920afa58..182e92985dbf 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o +obj-$(CONFIG_KEYBOARD_MTK_PMIC) += mtk-pmic-keys.o obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o obj-$(CONFIG_KEYBOARD_NSPIRE) += nspire-keypad.o diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c index 1a1eacae3ea1..312916f99597 100644 --- a/drivers/input/keyboard/cap11xx.c +++ b/drivers/input/keyboard/cap11xx.c @@ -357,8 +357,7 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, } priv = devm_kzalloc(dev, - sizeof(*priv) + - cap->num_channels * sizeof(priv->keycodes[0]), + struct_size(priv, keycodes, cap->num_channels), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/input/keyboard/clps711x-keypad.c b/drivers/input/keyboard/clps711x-keypad.c index 997e3e97f573..e319f745771a 100644 --- a/drivers/input/keyboard/clps711x-keypad.c +++ b/drivers/input/keyboard/clps711x-keypad.c @@ -109,8 +109,8 @@ static int clps711x_keypad_probe(struct platform_device *pdev) if (priv->row_count < 1) return -EINVAL; - priv->gpio_data = devm_kzalloc(dev, - sizeof(*priv->gpio_data) * priv->row_count, + priv->gpio_data = devm_kcalloc(dev, + priv->row_count, sizeof(*priv->gpio_data), GFP_KERNEL); if (!priv->gpio_data) return -ENOMEM; diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index a4e404aaf64b..5c7afdec192c 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c @@ -57,8 +57,8 @@ MODULE_LICENSE("GPL v2"); #define HIL_DATA 0x1 #define HIL_CMD 0x3 #define HIL_IRQ 2 - #define hil_readb(p) readb(p) - #define hil_writeb(v,p) writeb((v),(p)) + #define hil_readb(p) readb((const volatile void __iomem *)(p)) + #define hil_writeb(v, p) writeb((v), (volatile void __iomem *)(p)) #else #error "HIL is not supported on this platform" diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 41614c185918..f51ae09596ef 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -443,9 +443,9 @@ matrix_keypad_parse_dt(struct device *dev) of_property_read_u32(np, "col-scan-delay-us", &pdata->col_scan_delay_us); - gpios = devm_kzalloc(dev, - sizeof(unsigned int) * - (pdata->num_row_gpios + pdata->num_col_gpios), + gpios = devm_kcalloc(dev, + pdata->num_row_gpios + pdata->num_col_gpios, + sizeof(unsigned int), GFP_KERNEL); if (!gpios) { dev_err(dev, "could not allocate memory for gpios\n"); diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c new file mode 100644 index 000000000000..02c67a1749fc --- /dev/null +++ b/drivers/input/keyboard/mtk-pmic-keys.c @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2017 MediaTek, Inc. + * + * Author: Chen Zhong <chen.zhong@mediatek.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/regmap.h> +#include <linux/mfd/mt6323/registers.h> +#include <linux/mfd/mt6397/registers.h> +#include <linux/mfd/mt6397/core.h> + +#define MTK_PMIC_PWRKEY_RST_EN_MASK 0x1 +#define MTK_PMIC_PWRKEY_RST_EN_SHIFT 6 +#define MTK_PMIC_HOMEKEY_RST_EN_MASK 0x1 +#define MTK_PMIC_HOMEKEY_RST_EN_SHIFT 5 +#define MTK_PMIC_RST_DU_MASK 0x3 +#define MTK_PMIC_RST_DU_SHIFT 8 + +#define MTK_PMIC_PWRKEY_RST \ + (MTK_PMIC_PWRKEY_RST_EN_MASK << MTK_PMIC_PWRKEY_RST_EN_SHIFT) +#define MTK_PMIC_HOMEKEY_RST \ + (MTK_PMIC_HOMEKEY_RST_EN_MASK << MTK_PMIC_HOMEKEY_RST_EN_SHIFT) + +#define MTK_PMIC_PWRKEY_INDEX 0 +#define MTK_PMIC_HOMEKEY_INDEX 1 +#define MTK_PMIC_MAX_KEY_COUNT 2 + +struct mtk_pmic_keys_regs { + u32 deb_reg; + u32 deb_mask; + u32 intsel_reg; + u32 intsel_mask; +}; + +#define MTK_PMIC_KEYS_REGS(_deb_reg, _deb_mask, \ + _intsel_reg, _intsel_mask) \ +{ \ + .deb_reg = _deb_reg, \ + .deb_mask = _deb_mask, \ + .intsel_reg = _intsel_reg, \ + .intsel_mask = _intsel_mask, \ +} + +struct mtk_pmic_regs { + const struct mtk_pmic_keys_regs keys_regs[MTK_PMIC_MAX_KEY_COUNT]; + u32 pmic_rst_reg; +}; + +static const struct mtk_pmic_regs mt6397_regs = { + .keys_regs[MTK_PMIC_PWRKEY_INDEX] = + MTK_PMIC_KEYS_REGS(MT6397_CHRSTATUS, + 0x8, MT6397_INT_RSV, 0x10), + .keys_regs[MTK_PMIC_HOMEKEY_INDEX] = + MTK_PMIC_KEYS_REGS(MT6397_OCSTATUS2, + 0x10, MT6397_INT_RSV, 0x8), + .pmic_rst_reg = MT6397_TOP_RST_MISC, +}; + +static const struct mtk_pmic_regs mt6323_regs = { + .keys_regs[MTK_PMIC_PWRKEY_INDEX] = + MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS, + 0x2, MT6323_INT_MISC_CON, 0x10), + .keys_regs[MTK_PMIC_HOMEKEY_INDEX] = + MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS, + 0x4, MT6323_INT_MISC_CON, 0x8), + .pmic_rst_reg = MT6323_TOP_RST_MISC, +}; + +struct mtk_pmic_keys_info { + struct mtk_pmic_keys *keys; + const struct mtk_pmic_keys_regs *regs; + unsigned int keycode; + int irq; + bool wakeup:1; +}; + +struct mtk_pmic_keys { + struct input_dev *input_dev; + struct device *dev; + struct regmap *regmap; + struct mtk_pmic_keys_info keys[MTK_PMIC_MAX_KEY_COUNT]; +}; + +enum mtk_pmic_keys_lp_mode { + LP_DISABLE, + LP_ONEKEY, + LP_TWOKEY, +}; + +static void mtk_pmic_keys_lp_reset_setup(struct mtk_pmic_keys *keys, + u32 pmic_rst_reg) +{ + int ret; + u32 long_press_mode, long_press_debounce; + + ret = of_property_read_u32(keys->dev->of_node, + "power-off-time-sec", &long_press_debounce); + if (ret) + long_press_debounce = 0; + + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_RST_DU_MASK << MTK_PMIC_RST_DU_SHIFT, + long_press_debounce << MTK_PMIC_RST_DU_SHIFT); + + ret = of_property_read_u32(keys->dev->of_node, + "mediatek,long-press-mode", &long_press_mode); + if (ret) + long_press_mode = LP_DISABLE; + + switch (long_press_mode) { + case LP_ONEKEY: + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_PWRKEY_RST, + MTK_PMIC_PWRKEY_RST); + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_HOMEKEY_RST, + 0); + break; + case LP_TWOKEY: + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_PWRKEY_RST, + MTK_PMIC_PWRKEY_RST); + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_HOMEKEY_RST, + MTK_PMIC_HOMEKEY_RST); + break; + case LP_DISABLE: + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_PWRKEY_RST, + 0); + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_HOMEKEY_RST, + 0); + break; + default: + break; + } +} + +static irqreturn_t mtk_pmic_keys_irq_handler_thread(int irq, void *data) +{ + struct mtk_pmic_keys_info *info = data; + u32 key_deb, pressed; + + regmap_read(info->keys->regmap, info->regs->deb_reg, &key_deb); + + key_deb &= info->regs->deb_mask; + + pressed = !key_deb; + + input_report_key(info->keys->input_dev, info->keycode, pressed); + input_sync(info->keys->input_dev); + + dev_dbg(info->keys->dev, "(%s) key =%d using PMIC\n", + pressed ? "pressed" : "released", info->keycode); + + return IRQ_HANDLED; +} + +static int mtk_pmic_key_setup(struct mtk_pmic_keys *keys, + struct mtk_pmic_keys_info *info) +{ + int ret; + + info->keys = keys; + + ret = regmap_update_bits(keys->regmap, info->regs->intsel_reg, + info->regs->intsel_mask, + info->regs->intsel_mask); + if (ret < 0) + return ret; + + ret = devm_request_threaded_irq(keys->dev, info->irq, NULL, + mtk_pmic_keys_irq_handler_thread, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, + "mtk-pmic-keys", info); + if (ret) { + dev_err(keys->dev, "Failed to request IRQ: %d: %d\n", + info->irq, ret); + return ret; + } + + input_set_capability(keys->input_dev, EV_KEY, info->keycode); + + return 0; +} + +static int __maybe_unused mtk_pmic_keys_suspend(struct device *dev) +{ + struct mtk_pmic_keys *keys = dev_get_drvdata(dev); + int index; + + for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) { + if (keys->keys[index].wakeup) + enable_irq_wake(keys->keys[index].irq); + } + + return 0; +} + +static int __maybe_unused mtk_pmic_keys_resume(struct device *dev) +{ + struct mtk_pmic_keys *keys = dev_get_drvdata(dev); + int index; + + for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) { + if (keys->keys[index].wakeup) + disable_irq_wake(keys->keys[index].irq); + } + + return 0; +} + +static SIMPLE_DEV_PM_OPS(mtk_pmic_keys_pm_ops, mtk_pmic_keys_suspend, + mtk_pmic_keys_resume); + +static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = { + { + .compatible = "mediatek,mt6397-keys", + .data = &mt6397_regs, + }, { + .compatible = "mediatek,mt6323-keys", + .data = &mt6323_regs, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, of_mtk_pmic_keys_match_tbl); + +static int mtk_pmic_keys_probe(struct platform_device *pdev) +{ + int error, index = 0; + unsigned int keycount; + struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent); + struct device_node *node = pdev->dev.of_node, *child; + struct mtk_pmic_keys *keys; + const struct mtk_pmic_regs *mtk_pmic_regs; + struct input_dev *input_dev; + const struct of_device_id *of_id = + of_match_device(of_mtk_pmic_keys_match_tbl, &pdev->dev); + + keys = devm_kzalloc(&pdev->dev, sizeof(*keys), GFP_KERNEL); + if (!keys) + return -ENOMEM; + + keys->dev = &pdev->dev; + keys->regmap = pmic_chip->regmap; + mtk_pmic_regs = of_id->data; + + keys->input_dev = input_dev = devm_input_allocate_device(keys->dev); + if (!input_dev) { + dev_err(keys->dev, "input allocate device fail.\n"); + return -ENOMEM; + } + + input_dev->name = "mtk-pmic-keys"; + input_dev->id.bustype = BUS_HOST; + input_dev->id.vendor = 0x0001; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0001; + + keycount = of_get_available_child_count(node); + if (keycount > MTK_PMIC_MAX_KEY_COUNT) { + dev_err(keys->dev, "too many keys defined (%d)\n", keycount); + return -EINVAL; + } + + for_each_child_of_node(node, child) { + keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index]; + + keys->keys[index].irq = platform_get_irq(pdev, index); + if (keys->keys[index].irq < 0) + return keys->keys[index].irq; + + error = of_property_read_u32(child, + "linux,keycodes", &keys->keys[index].keycode); + if (error) { + dev_err(keys->dev, + "failed to read key:%d linux,keycode property: %d\n", + index, error); + return error; + } + + if (of_property_read_bool(child, "wakeup-source")) + keys->keys[index].wakeup = true; + + error = mtk_pmic_key_setup(keys, &keys->keys[index]); + if (error) + return error; + + index++; + } + + error = input_register_device(input_dev); + if (error) { + dev_err(&pdev->dev, + "register input device failed (%d)\n", error); + return error; + } + + mtk_pmic_keys_lp_reset_setup(keys, mtk_pmic_regs->pmic_rst_reg); + + platform_set_drvdata(pdev, keys); + + return 0; +} + +static struct platform_driver pmic_keys_pdrv = { + .probe = mtk_pmic_keys_probe, + .driver = { + .name = "mtk-pmic-keys", + .of_match_table = of_mtk_pmic_keys_match_tbl, + .pm = &mtk_pmic_keys_pm_ops, + }, +}; + +module_platform_driver(pmic_keys_pdrv); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>"); +MODULE_DESCRIPTION("MTK pmic-keys driver v0.1"); diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 940d38b08e6b..46406345742b 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -337,7 +337,8 @@ static int omap4_keypad_probe(struct platform_device *pdev) keypad_data->row_shift = get_count_order(keypad_data->cols); max_keys = keypad_data->rows << keypad_data->row_shift; - keypad_data->keymap = kzalloc(max_keys * sizeof(keypad_data->keymap[0]), + keypad_data->keymap = kcalloc(max_keys, + sizeof(keypad_data->keymap[0]), GFP_KERNEL); if (!keypad_data->keymap) { dev_err(&pdev->dev, "Not enough memory for keymap\n"); diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 316414465c77..1fe1aa2adf85 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -281,7 +281,7 @@ samsung_keypad_parse_dt(struct device *dev) key_count = of_get_child_count(np); keymap_data->keymap_size = key_count; - keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL); + keymap = devm_kcalloc(dev, key_count, sizeof(uint32_t), GFP_KERNEL); if (!keymap) { dev_err(dev, "could not allocate memory for keymap\n"); return ERR_PTR(-ENOMEM); diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c index 8ccefc15c7a4..8b3a5758451e 100644 --- a/drivers/input/matrix-keymap.c +++ b/drivers/input/matrix-keymap.c @@ -170,8 +170,8 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, return -EINVAL; if (!keymap) { - keymap = devm_kzalloc(input_dev->dev.parent, - max_keys * sizeof(*keymap), + keymap = devm_kcalloc(input_dev->dev.parent, + max_keys, sizeof(*keymap), GFP_KERNEL); if (!keymap) { dev_err(input_dev->dev.parent, diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index c761c0c4f2b8..ca59a2be9bc5 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -411,7 +411,7 @@ config INPUT_YEALINK usb sound driver, so you might want to enable that as well. For information about how to use these additional functions, see - <file:Documentation/input/yealink.txt>. + <file:Documentation/input/devices/yealink.rst>. To compile this driver as a module, choose M here: the module will be called yealink. @@ -595,7 +595,7 @@ config INPUT_GPIO_ROTARY_ENCODER depends on GPIOLIB || COMPILE_TEST help Say Y here to add support for rotary encoders connected to GPIO lines. - Check file:Documentation/input/rotary-encoder.txt for more + Check file:Documentation/input/devices/rotary-encoder.rst for more information. To compile this driver as a module, choose M here: the diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index 49b34de0aed4..47eb8ca729fe 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c @@ -509,18 +509,6 @@ static int hp_sdc_rtc_proc_show(struct seq_file *m, void *v) #undef NY } -static int hp_sdc_rtc_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, hp_sdc_rtc_proc_show, NULL); -} - -static const struct file_operations hp_sdc_rtc_proc_fops = { - .open = hp_sdc_rtc_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static int hp_sdc_rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -713,7 +701,7 @@ static int __init hp_sdc_rtc_init(void) if (misc_register(&hp_sdc_rtc_dev) != 0) printk(KERN_INFO "Could not register misc. dev for i8042 rtc\n"); - proc_create("driver/rtc", 0, NULL, &hp_sdc_rtc_proc_fops); + proc_create_single("driver/rtc", 0, NULL, hp_sdc_rtc_proc_show); printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded " "(RTC v " RTC_VERSION ")\n"); diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 1588aecafff7..30ec77ad32c6 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -7,7 +7,7 @@ * state machine code inspired by code from Tim Ruetz * * A generic driver for rotary encoders connected to GPIO lines. - * See file:Documentation/input/rotary-encoder.txt for more information + * See file:Documentation/input/devices/rotary-encoder.rst for more information * * 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 @@ -283,8 +283,8 @@ static int rotary_encoder_probe(struct platform_device *pdev) } encoder->irq = - devm_kzalloc(dev, - sizeof(*encoder->irq) * encoder->gpios->ndescs, + devm_kcalloc(dev, + encoder->gpios->ndescs, sizeof(*encoder->irq), GFP_KERNEL); if (!encoder->irq) return -ENOMEM; diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index f27f23f2d99a..566a1e3aa504 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -129,7 +129,7 @@ config MOUSE_PS2_ELANTECH This driver exposes some configuration registers via sysfs entries. For further information, - see <file:Documentation/input/elantech.txt>. + see <file:Documentation/input/devices/elantech.rst>. If unsure, say N. @@ -228,7 +228,7 @@ config MOUSE_APPLETOUCH scrolling in X11. For further information, see - <file:Documentation/input/appletouch.txt>. + <file:Documentation/input/devices/appletouch.rst>. To compile this driver as a module, choose M here: the module will be called appletouch. @@ -251,7 +251,7 @@ config MOUSE_BCM5974 The interface is currently identical to the appletouch interface, for further information, see - <file:Documentation/input/appletouch.txt>. + <file:Documentation/input/devices/appletouch.rst>. To compile this driver as a module, choose M here: the module will be called bcm5974. diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index cb5579716dba..0a6f7ca883e7 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -212,7 +212,7 @@ static void alps_set_abs_params_v7(struct alps_data *priv, static void alps_set_abs_params_ss4_v2(struct alps_data *priv, struct input_dev *dev1); -/* Packet formats are described in Documentation/input/alps.txt */ +/* Packet formats are described in Documentation/input/devices/alps.rst */ static bool alps_is_valid_first_byte(struct alps_data *priv, unsigned char data) diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index cb6d983e8033..fc3ab93b7aea 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -612,9 +612,10 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr, rdesc->num_registers = bitmap_weight(rdesc->presense_map, RMI_REG_DESC_PRESENSE_BITS); - rdesc->registers = devm_kzalloc(&d->dev, rdesc->num_registers * - sizeof(struct rmi_register_desc_item), - GFP_KERNEL); + rdesc->registers = devm_kcalloc(&d->dev, + rdesc->num_registers, + sizeof(struct rmi_register_desc_item), + GFP_KERNEL); if (!rdesc->registers) return -ENOMEM; @@ -1050,7 +1051,7 @@ int rmi_probe_interrupts(struct rmi_driver_data *data) data->num_of_irq_regs = (data->irq_count + 7) / 8; size = BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long); - data->irq_memory = devm_kzalloc(dev, size * 4, GFP_KERNEL); + data->irq_memory = devm_kcalloc(dev, size, 4, GFP_KERNEL); if (!data->irq_memory) { dev_err(dev, "Failed to allocate memory for irq masks.\n"); return -ENOMEM; diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c index 5f2e1ef5accc..df64d6aed4f7 100644 --- a/drivers/input/rmi4/rmi_f11.c +++ b/drivers/input/rmi4/rmi_f11.c @@ -1180,14 +1180,15 @@ static int rmi_f11_initialize(struct rmi_function *fn) f11->sensor.attn_size += f11->sensor.nbr_fingers * 2; /* allocate the in-kernel tracking buffers */ - sensor->tracking_pos = devm_kzalloc(&fn->dev, - sizeof(struct input_mt_pos) * sensor->nbr_fingers, + sensor->tracking_pos = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, sizeof(struct input_mt_pos), + GFP_KERNEL); + sensor->tracking_slots = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, sizeof(int), GFP_KERNEL); + sensor->objs = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, + sizeof(struct rmi_2d_sensor_abs_object), GFP_KERNEL); - sensor->tracking_slots = devm_kzalloc(&fn->dev, - sizeof(int) * sensor->nbr_fingers, GFP_KERNEL); - sensor->objs = devm_kzalloc(&fn->dev, - sizeof(struct rmi_2d_sensor_abs_object) - * sensor->nbr_fingers, GFP_KERNEL); if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs) return -ENOMEM; diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c index e226def74d82..5c7f48915779 100644 --- a/drivers/input/rmi4/rmi_f12.c +++ b/drivers/input/rmi4/rmi_f12.c @@ -502,14 +502,15 @@ static int rmi_f12_probe(struct rmi_function *fn) } /* allocate the in-kernel tracking buffers */ - sensor->tracking_pos = devm_kzalloc(&fn->dev, - sizeof(struct input_mt_pos) * sensor->nbr_fingers, + sensor->tracking_pos = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, sizeof(struct input_mt_pos), + GFP_KERNEL); + sensor->tracking_slots = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, sizeof(int), GFP_KERNEL); + sensor->objs = devm_kcalloc(&fn->dev, + sensor->nbr_fingers, + sizeof(struct rmi_2d_sensor_abs_object), GFP_KERNEL); - sensor->tracking_slots = devm_kzalloc(&fn->dev, - sizeof(int) * sensor->nbr_fingers, GFP_KERNEL); - sensor->objs = devm_kzalloc(&fn->dev, - sizeof(struct rmi_2d_sensor_abs_object) - * sensor->nbr_fingers, GFP_KERNEL); if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs) return -ENOMEM; diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c index 98a935efec8e..a6f515bcab22 100644 --- a/drivers/input/rmi4/rmi_f54.c +++ b/drivers/input/rmi4/rmi_f54.c @@ -680,7 +680,7 @@ static int rmi_f54_probe(struct rmi_function *fn) rx = f54->num_rx_electrodes; tx = f54->num_tx_electrodes; f54->report_data = devm_kzalloc(&fn->dev, - sizeof(u16) * tx * rx, + array3_size(tx, rx, sizeof(u16)), GFP_KERNEL); if (f54->report_data == NULL) return -ENOMEM; diff --git a/drivers/input/rmi4/rmi_spi.c b/drivers/input/rmi4/rmi_spi.c index 082defc329a8..33b8c6e7ac0a 100644 --- a/drivers/input/rmi4/rmi_spi.c +++ b/drivers/input/rmi4/rmi_spi.c @@ -69,7 +69,7 @@ static int rmi_spi_manage_pools(struct rmi_spi_xport *rmi_spi, int len) buf_size = RMI_SPI_XFER_SIZE_LIMIT; tmp = rmi_spi->rx_buf; - buf = devm_kzalloc(&spi->dev, buf_size * 2, + buf = devm_kcalloc(&spi->dev, buf_size, 2, GFP_KERNEL | GFP_DMA); if (!buf) return -ENOMEM; @@ -96,9 +96,10 @@ static int rmi_spi_manage_pools(struct rmi_spi_xport *rmi_spi, int len) * per byte delays. */ tmp = rmi_spi->rx_xfers; - xfer_buf = devm_kzalloc(&spi->dev, - (rmi_spi->rx_xfer_count + rmi_spi->tx_xfer_count) - * sizeof(struct spi_transfer), GFP_KERNEL); + xfer_buf = devm_kcalloc(&spi->dev, + rmi_spi->rx_xfer_count + rmi_spi->tx_xfer_count, + sizeof(struct spi_transfer), + GFP_KERNEL); if (!xfer_buf) return -ENOMEM; diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index ca4530eb3378..d90d9f1098ff 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -47,7 +47,7 @@ config SERIO_SERPORT Say Y here if you plan to use an input device (mouse, joystick, tablet, 6dof) that communicates over the RS232 serial (COM) port. - More information is available: <file:Documentation/input/input.txt> + More information is available: <file:Documentation/input/input.rst> If unsure, say Y. @@ -78,7 +78,7 @@ config SERIO_PARKBD Say Y here if you built a simple parallel port adapter to attach an additional AT keyboard, XT keyboard or PS/2 mouse. - More information is available: <file:Documentation/input/input.txt> + More information is available: <file:Documentation/input/input.rst> If unsure, say N. diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c index 25151d9214e0..47a0e81a2989 100644 --- a/drivers/input/serio/hyperv-keyboard.c +++ b/drivers/input/serio/hyperv-keyboard.c @@ -424,6 +424,9 @@ static struct hv_driver hv_kbd_drv = { .id_table = id_table, .probe = hv_kbd_probe, .remove = hv_kbd_remove, + .driver = { + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, }; static int __init hv_kbd_init(void) diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 5374bd573e66..2a80675cfd94 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -92,6 +92,19 @@ config TOUCHSCREEN_AD7879_SPI To compile this driver as a module, choose M here: the module will be called ad7879-spi. +config TOUCHSCREEN_ADC + tristate "Generic ADC based resistive touchscreen" + depends on IIO + select IIO_BUFFER_CB + help + Say Y here if you want to use the generic ADC + resistive touchscreen driver. + + If unsure, say N (but it's safe to say "Y"). + + To compile this driver as a module, choose M here: the + module will be called resistive-adc-touch.ko. + config TOUCHSCREEN_AR1021_I2C tristate "Microchip AR1020/1021 i2c touchscreen" depends on I2C && OF diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index c2175163152d..5911a4190cd2 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o +obj-$(CONFIG_TOUCHSCREEN_ADC) += resistive-adc-touch.o obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C) += ar1021_i2c.o obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o diff --git a/drivers/input/touchscreen/resistive-adc-touch.c b/drivers/input/touchscreen/resistive-adc-touch.c new file mode 100644 index 000000000000..cfc8bb4553f7 --- /dev/null +++ b/drivers/input/touchscreen/resistive-adc-touch.c @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ADC generic resistive touchscreen (GRTS) + * This is a generic input driver that connects to an ADC + * given the channels in device tree, and reports events to the input + * subsystem. + * + * Copyright (C) 2017,2018 Microchip Technology, + * Author: Eugen Hristev <eugen.hristev@microchip.com> + * + */ +#include <linux/input.h> +#include <linux/input/touchscreen.h> +#include <linux/iio/consumer.h> +#include <linux/iio/iio.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +#define DRIVER_NAME "resistive-adc-touch" +#define GRTS_DEFAULT_PRESSURE_MIN 50000 +#define GRTS_MAX_POS_MASK GENMASK(11, 0) + +/** + * grts_state - generic resistive touch screen information struct + * @pressure_min: number representing the minimum for the pressure + * @pressure: are we getting pressure info or not + * @iio_chans: list of channels acquired + * @iio_cb: iio_callback buffer for the data + * @input: the input device structure that we register + * @prop: touchscreen properties struct + */ +struct grts_state { + u32 pressure_min; + bool pressure; + struct iio_channel *iio_chans; + struct iio_cb_buffer *iio_cb; + struct input_dev *input; + struct touchscreen_properties prop; +}; + +static int grts_cb(const void *data, void *private) +{ + const u16 *touch_info = data; + struct grts_state *st = private; + unsigned int x, y, press = 0x0; + + /* channel data coming in buffer in the order below */ + x = touch_info[0]; + y = touch_info[1]; + if (st->pressure) + press = touch_info[2]; + + if ((!x && !y) || (st->pressure && (press < st->pressure_min))) { + /* report end of touch */ + input_report_key(st->input, BTN_TOUCH, 0); + input_sync(st->input); + return 0; + } + + /* report proper touch to subsystem*/ + touchscreen_report_pos(st->input, &st->prop, x, y, false); + if (st->pressure) + input_report_abs(st->input, ABS_PRESSURE, press); + input_report_key(st->input, BTN_TOUCH, 1); + input_sync(st->input); + + return 0; +} + +static int grts_open(struct input_dev *dev) +{ + int error; + struct grts_state *st = input_get_drvdata(dev); + + error = iio_channel_start_all_cb(st->iio_cb); + if (error) { + dev_err(dev->dev.parent, "failed to start callback buffer.\n"); + return error; + } + return 0; +} + +static void grts_close(struct input_dev *dev) +{ + struct grts_state *st = input_get_drvdata(dev); + + iio_channel_stop_all_cb(st->iio_cb); +} + +static void grts_disable(void *data) +{ + iio_channel_release_all_cb(data); +} + +static int grts_probe(struct platform_device *pdev) +{ + struct grts_state *st; + struct input_dev *input; + struct device *dev = &pdev->dev; + struct iio_channel *chan; + int error; + + st = devm_kzalloc(dev, sizeof(struct grts_state), GFP_KERNEL); + if (!st) + return -ENOMEM; + + /* get the channels from IIO device */ + st->iio_chans = devm_iio_channel_get_all(dev); + if (IS_ERR(st->iio_chans)) { + error = PTR_ERR(st->iio_chans); + if (error != -EPROBE_DEFER) + dev_err(dev, "can't get iio channels.\n"); + return error; + } + + chan = &st->iio_chans[0]; + st->pressure = false; + while (chan && chan->indio_dev) { + if (!strcmp(chan->channel->datasheet_name, "pressure")) + st->pressure = true; + chan++; + } + + if (st->pressure) { + error = device_property_read_u32(dev, + "touchscreen-min-pressure", + &st->pressure_min); + if (error) { + dev_dbg(dev, "can't get touchscreen-min-pressure property.\n"); + st->pressure_min = GRTS_DEFAULT_PRESSURE_MIN; + } + } + + input = devm_input_allocate_device(dev); + if (!input) { + dev_err(dev, "failed to allocate input device.\n"); + return -ENOMEM; + } + + input->name = DRIVER_NAME; + input->id.bustype = BUS_HOST; + input->open = grts_open; + input->close = grts_close; + + input_set_abs_params(input, ABS_X, 0, GRTS_MAX_POS_MASK - 1, 0, 0); + input_set_abs_params(input, ABS_Y, 0, GRTS_MAX_POS_MASK - 1, 0, 0); + if (st->pressure) + input_set_abs_params(input, ABS_PRESSURE, st->pressure_min, + 0xffff, 0, 0); + + input_set_capability(input, EV_KEY, BTN_TOUCH); + + /* parse optional device tree properties */ + touchscreen_parse_properties(input, false, &st->prop); + + st->input = input; + input_set_drvdata(input, st); + + error = input_register_device(input); + if (error) { + dev_err(dev, "failed to register input device."); + return error; + } + + st->iio_cb = iio_channel_get_all_cb(dev, grts_cb, st); + if (IS_ERR(st->iio_cb)) { + dev_err(dev, "failed to allocate callback buffer.\n"); + return PTR_ERR(st->iio_cb); + } + + error = devm_add_action_or_reset(dev, grts_disable, st->iio_cb); + if (error) { + dev_err(dev, "failed to add disable action.\n"); + return error; + } + + return 0; +} + +static const struct of_device_id grts_of_match[] = { + { + .compatible = "resistive-adc-touch", + }, { + /* sentinel */ + }, +}; + +MODULE_DEVICE_TABLE(of, grts_of_match); + +static struct platform_driver grts_driver = { + .probe = grts_probe, + .driver = { + .name = DRIVER_NAME, + .of_match_table = of_match_ptr(grts_of_match), + }, +}; + +module_platform_driver(grts_driver); + +MODULE_AUTHOR("Eugen Hristev <eugen.hristev@microchip.com>"); +MODULE_DESCRIPTION("Generic ADC Resistive Touch Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index fd714ee881f7..2566b4d8b342 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c @@ -68,7 +68,7 @@ * The default values correspond to Mainstone II in QVGA mode * * Please read - * Documentation/input/input-programming.txt for more details. + * Documentation/input/input-programming.rst for more details. */ static int abs_x[3] = {150, 4000, 5}; |