From c4834f4ad7fdc9002e7d3424bd7aed7a63f070be Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 25 Jun 2023 18:27:55 +0200 Subject: Input: gpio-vibra - simplify with dev_err_probe() Common pattern of handling deferred probe can be simplified with dev_err_probe(). Less code and also it prints the error value. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20230625162817.100397-3-krzysztof.kozlowski@linaro.org Signed-off-by: Dmitry Torokhov --- drivers/input/misc/gpio-vibra.c | 20 ++++++-------------- drivers/input/misc/pwm-beeper.c | 19 +++++-------------- 2 files changed, 11 insertions(+), 28 deletions(-) (limited to 'drivers/input/misc') diff --git a/drivers/input/misc/gpio-vibra.c b/drivers/input/misc/gpio-vibra.c index 134a1309ba92..c1c3ba5960dd 100644 --- a/drivers/input/misc/gpio-vibra.c +++ b/drivers/input/misc/gpio-vibra.c @@ -113,22 +113,14 @@ static int gpio_vibrator_probe(struct platform_device *pdev) return -ENOMEM; vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc"); - err = PTR_ERR_OR_ZERO(vibrator->vcc); - if (err) { - if (err != -EPROBE_DEFER) - dev_err(&pdev->dev, "Failed to request regulator: %d\n", - err); - return err; - } + if (IS_ERR(vibrator->vcc)) + return dev_err_probe(&pdev->dev, PTR_ERR(vibrator->vcc), + "Failed to request regulator\n"); vibrator->gpio = devm_gpiod_get(&pdev->dev, "enable", GPIOD_OUT_LOW); - err = PTR_ERR_OR_ZERO(vibrator->gpio); - if (err) { - if (err != -EPROBE_DEFER) - dev_err(&pdev->dev, "Failed to request main gpio: %d\n", - err); - return err; - } + if (IS_ERR(vibrator->gpio)) + return dev_err_probe(&pdev->dev, PTR_ERR(vibrator->gpio), + "Failed to request main gpio\n"); INIT_WORK(&vibrator->play_work, gpio_vibrator_play_work); diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index 3cf1812384e6..1e731d8397c6 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c @@ -132,13 +132,8 @@ static int pwm_beeper_probe(struct platform_device *pdev) return -ENOMEM; beeper->pwm = devm_pwm_get(dev, NULL); - if (IS_ERR(beeper->pwm)) { - error = PTR_ERR(beeper->pwm); - if (error != -EPROBE_DEFER) - dev_err(dev, "Failed to request PWM device: %d\n", - error); - return error; - } + if (IS_ERR(beeper->pwm)) + return dev_err_probe(dev, PTR_ERR(beeper->pwm), "Failed to request PWM device\n"); /* Sync up PWM state and ensure it is off. */ pwm_init_state(beeper->pwm, &state); @@ -151,13 +146,9 @@ static int pwm_beeper_probe(struct platform_device *pdev) } beeper->amplifier = devm_regulator_get(dev, "amp"); - if (IS_ERR(beeper->amplifier)) { - error = PTR_ERR(beeper->amplifier); - if (error != -EPROBE_DEFER) - dev_err(dev, "Failed to get 'amp' regulator: %d\n", - error); - return error; - } + if (IS_ERR(beeper->amplifier)) + return dev_err_probe(dev, PTR_ERR(beeper->amplifier), + "Failed to get 'amp' regulator\n"); INIT_WORK(&beeper->work, pwm_beeper_work); -- cgit v1.2.3 From a07e68dff58bd536f9e909b007875726eade5c0e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 25 Jun 2023 18:27:56 +0200 Subject: Input: pwm-vibra - simplify with dev_err_probe() Common pattern of handling deferred probe can be simplified with dev_err_probe(). Less code and also it prints the error value. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230625162817.100397-4-krzysztof.kozlowski@linaro.org Signed-off-by: Dmitry Torokhov --- drivers/input/misc/pwm-vibra.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) (limited to 'drivers/input/misc') diff --git a/drivers/input/misc/pwm-vibra.c b/drivers/input/misc/pwm-vibra.c index 2ba035299db8..a3cde30ee8d2 100644 --- a/drivers/input/misc/pwm-vibra.c +++ b/drivers/input/misc/pwm-vibra.c @@ -140,32 +140,20 @@ static int pwm_vibrator_probe(struct platform_device *pdev) return -ENOMEM; vibrator->vcc = devm_regulator_get(&pdev->dev, "vcc"); - err = PTR_ERR_OR_ZERO(vibrator->vcc); - if (err) { - if (err != -EPROBE_DEFER) - dev_err(&pdev->dev, "Failed to request regulator: %d\n", - err); - return err; - } + if (IS_ERR(vibrator->vcc)) + return dev_err_probe(&pdev->dev, PTR_ERR(vibrator->vcc), + "Failed to request regulator\n"); vibrator->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", GPIOD_OUT_LOW); - err = PTR_ERR_OR_ZERO(vibrator->enable_gpio); - if (err) { - if (err != -EPROBE_DEFER) - dev_err(&pdev->dev, "Failed to request enable gpio: %d\n", - err); - return err; - } + if (IS_ERR(vibrator->enable_gpio)) + return dev_err_probe(&pdev->dev, PTR_ERR(vibrator->enable_gpio), + "Failed to request enable gpio\n"); vibrator->pwm = devm_pwm_get(&pdev->dev, "enable"); - err = PTR_ERR_OR_ZERO(vibrator->pwm); - if (err) { - if (err != -EPROBE_DEFER) - dev_err(&pdev->dev, "Failed to request main pwm: %d\n", - err); - return err; - } + if (IS_ERR(vibrator->pwm)) + return dev_err_probe(&pdev->dev, PTR_ERR(vibrator->pwm), + "Failed to request main pwm\n"); INIT_WORK(&vibrator->play_work, pwm_vibrator_play_work); -- cgit v1.2.3 From 1e402a15bc00201c1068596445ebfe98d60d1c58 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 25 Jun 2023 18:27:57 +0200 Subject: Input: rotary_encoder - simplify with dev_err_probe() Common pattern of handling deferred probe can be simplified with dev_err_probe(). Less code and also it prints the error value. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230625162817.100397-5-krzysztof.kozlowski@linaro.org Signed-off-by: Dmitry Torokhov --- drivers/input/misc/rotary_encoder.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/input/misc') diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 22ec62083065..fb3a34f8eccd 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -236,12 +236,8 @@ static int rotary_encoder_probe(struct platform_device *pdev) device_property_read_bool(dev, "rotary-encoder,relative-axis"); encoder->gpios = devm_gpiod_get_array(dev, NULL, GPIOD_IN); - if (IS_ERR(encoder->gpios)) { - err = PTR_ERR(encoder->gpios); - if (err != -EPROBE_DEFER) - dev_err(dev, "unable to get gpios: %d\n", err); - return err; - } + if (IS_ERR(encoder->gpios)) + return dev_err_probe(dev, PTR_ERR(encoder->gpios), "unable to get gpios\n"); if (encoder->gpios->ndescs < 2) { dev_err(dev, "not enough gpios found\n"); return -EINVAL; -- cgit v1.2.3 From 2e00b8bf5624767f6be7427b6eb532524793463e Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Sun, 9 Jul 2023 12:06:37 -0500 Subject: Input: iqs7222 - configure power mode before triggering ATI If the device drops into ultra-low-power mode before being placed into normal-power mode as part of ATI being triggered, the device does not assert any interrupts until the ATI routine is restarted two seconds later. Solve this problem by adopting the vendor's recommendation, which calls for the device to be placed into normal-power mode prior to being configured and ATI being triggered. The original implementation followed this sequence, but the order was inadvertently changed as part of the resolution of a separate erratum. Fixes: 1e4189d8af27 ("Input: iqs7222 - protect volatile registers") Signed-off-by: Jeff LaBundy Link: https://lore.kernel.org/r/ZKrpHc2Ji9qR25r2@nixie71 Signed-off-by: Dmitry Torokhov --- drivers/input/misc/iqs7222.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/input/misc') diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c index 096b0925f41b..acb95048e823 100644 --- a/drivers/input/misc/iqs7222.c +++ b/drivers/input/misc/iqs7222.c @@ -1381,9 +1381,6 @@ static int iqs7222_ati_trigger(struct iqs7222_private *iqs7222) if (error) return error; - sys_setup &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK; - sys_setup &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK; - for (i = 0; i < IQS7222_NUM_RETRIES; i++) { /* * Trigger ATI from streaming and normal-power modes so that @@ -1561,8 +1558,11 @@ static int iqs7222_dev_init(struct iqs7222_private *iqs7222, int dir) return error; } - if (dir == READ) + if (dir == READ) { + iqs7222->sys_setup[0] &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK; + iqs7222->sys_setup[0] &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK; return 0; + } return iqs7222_ati_trigger(iqs7222); } -- cgit v1.2.3 From dd24e202ac722b3fea1fadb7f6c0b2db61086e78 Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Sun, 9 Jul 2023 12:07:18 -0500 Subject: Input: iqs7222 - add support for Azoteq IQS7222D The vendor has introduced a new variant of silicon which is highly similar to the existing IQS7222A, but with its independent sliders essentially replaced with a single-contact trackpad. Update the common driver to support this new device's register map and report trackpad events. As with the IQS7222A, the new IQS7222D can report both raw coordinates as well as gestures. Signed-off-by: Jeff LaBundy Link: https://lore.kernel.org/r/ZKrpRh6RT6+6KrMQ@nixie71 Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 4 +- drivers/input/misc/iqs7222.c | 468 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 461 insertions(+), 11 deletions(-) (limited to 'drivers/input/misc') diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 81a54a59e13c..c47eecc6f83b 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -791,10 +791,10 @@ config INPUT_IQS626A module will be called iqs626a. config INPUT_IQS7222 - tristate "Azoteq IQS7222A/B/C capacitive touch controller" + tristate "Azoteq IQS7222A/B/C/D capacitive touch controller" depends on I2C help - Say Y to enable support for the Azoteq IQS7222A/B/C family + Say Y to enable support for the Azoteq IQS7222A/B/C/D family of capacitive touch controllers. To compile this driver as a module, choose M here: the diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c index acb95048e823..a9c1dba1e8c1 100644 --- a/drivers/input/misc/iqs7222.c +++ b/drivers/input/misc/iqs7222.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * Azoteq IQS7222A/B/C Capacitive Touch Controller + * Azoteq IQS7222A/B/C/D Capacitive Touch Controller * * Copyright (C) 2022 Jeff LaBundy */ @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #define IQS7222_PROD_NUM_A 840 #define IQS7222_PROD_NUM_B 698 #define IQS7222_PROD_NUM_C 863 +#define IQS7222_PROD_NUM_D 1046 #define IQS7222_SYS_STATUS 0x10 #define IQS7222_SYS_STATUS_RESET BIT(3) @@ -54,6 +56,7 @@ #define IQS7222_EVENT_MASK_ATI BIT(12) #define IQS7222_EVENT_MASK_SLDR BIT(10) +#define IQS7222_EVENT_MASK_TPAD IQS7222_EVENT_MASK_SLDR #define IQS7222_EVENT_MASK_TOUCH BIT(1) #define IQS7222_EVENT_MASK_PROX BIT(0) @@ -71,6 +74,7 @@ #define IQS7222_MAX_COLS_CHAN 6 #define IQS7222_MAX_COLS_FILT 2 #define IQS7222_MAX_COLS_SLDR 11 +#define IQS7222_MAX_COLS_TPAD 24 #define IQS7222_MAX_COLS_GPIO 3 #define IQS7222_MAX_COLS_SYS 13 @@ -102,16 +106,18 @@ enum iqs7222_reg_grp_id { IQS7222_REG_GRP_BTN, IQS7222_REG_GRP_CHAN, IQS7222_REG_GRP_SLDR, + IQS7222_REG_GRP_TPAD, IQS7222_REG_GRP_GPIO, IQS7222_REG_GRP_SYS, IQS7222_NUM_REG_GRPS }; static const char * const iqs7222_reg_grp_names[IQS7222_NUM_REG_GRPS] = { - [IQS7222_REG_GRP_CYCLE] = "cycle", - [IQS7222_REG_GRP_CHAN] = "channel", - [IQS7222_REG_GRP_SLDR] = "slider", - [IQS7222_REG_GRP_GPIO] = "gpio", + [IQS7222_REG_GRP_CYCLE] = "cycle-%d", + [IQS7222_REG_GRP_CHAN] = "channel-%d", + [IQS7222_REG_GRP_SLDR] = "slider-%d", + [IQS7222_REG_GRP_TPAD] = "trackpad", + [IQS7222_REG_GRP_GPIO] = "gpio-%d", }; static const unsigned int iqs7222_max_cols[IQS7222_NUM_REG_GRPS] = { @@ -122,6 +128,7 @@ static const unsigned int iqs7222_max_cols[IQS7222_NUM_REG_GRPS] = { [IQS7222_REG_GRP_CHAN] = IQS7222_MAX_COLS_CHAN, [IQS7222_REG_GRP_FILT] = IQS7222_MAX_COLS_FILT, [IQS7222_REG_GRP_SLDR] = IQS7222_MAX_COLS_SLDR, + [IQS7222_REG_GRP_TPAD] = IQS7222_MAX_COLS_TPAD, [IQS7222_REG_GRP_GPIO] = IQS7222_MAX_COLS_GPIO, [IQS7222_REG_GRP_SYS] = IQS7222_MAX_COLS_SYS, }; @@ -130,8 +137,10 @@ static const unsigned int iqs7222_gpio_links[] = { 2, 5, 6, }; struct iqs7222_event_desc { const char *name; + u16 link; u16 mask; u16 val; + u16 strict; u16 enable; enum iqs7222_reg_key_id reg_key; }; @@ -188,6 +197,93 @@ static const struct iqs7222_event_desc iqs7222_sl_events[] = { }, }; +static const struct iqs7222_event_desc iqs7222_tp_events[] = { + { + .name = "event-press", + .link = BIT(7), + }, + { + .name = "event-tap", + .link = BIT(0), + .mask = BIT(0), + .val = BIT(0), + .enable = BIT(0), + .reg_key = IQS7222_REG_KEY_TAP, + }, + { + .name = "event-swipe-x-pos", + .link = BIT(2), + .mask = BIT(2) | BIT(1), + .val = BIT(2), + .strict = BIT(4), + .enable = BIT(1), + .reg_key = IQS7222_REG_KEY_AXIAL, + }, + { + .name = "event-swipe-y-pos", + .link = BIT(3), + .mask = BIT(3) | BIT(1), + .val = BIT(3), + .strict = BIT(3), + .enable = BIT(1), + .reg_key = IQS7222_REG_KEY_AXIAL, + }, + { + .name = "event-swipe-x-neg", + .link = BIT(4), + .mask = BIT(4) | BIT(1), + .val = BIT(4), + .strict = BIT(4), + .enable = BIT(1), + .reg_key = IQS7222_REG_KEY_AXIAL, + }, + { + .name = "event-swipe-y-neg", + .link = BIT(5), + .mask = BIT(5) | BIT(1), + .val = BIT(5), + .strict = BIT(3), + .enable = BIT(1), + .reg_key = IQS7222_REG_KEY_AXIAL, + }, + { + .name = "event-flick-x-pos", + .link = BIT(2), + .mask = BIT(2) | BIT(1), + .val = BIT(2) | BIT(1), + .strict = BIT(4), + .enable = BIT(2), + .reg_key = IQS7222_REG_KEY_AXIAL, + }, + { + .name = "event-flick-y-pos", + .link = BIT(3), + .mask = BIT(3) | BIT(1), + .val = BIT(3) | BIT(1), + .strict = BIT(3), + .enable = BIT(2), + .reg_key = IQS7222_REG_KEY_AXIAL, + }, + { + .name = "event-flick-x-neg", + .link = BIT(4), + .mask = BIT(4) | BIT(1), + .val = BIT(4) | BIT(1), + .strict = BIT(4), + .enable = BIT(2), + .reg_key = IQS7222_REG_KEY_AXIAL, + }, + { + .name = "event-flick-y-neg", + .link = BIT(5), + .mask = BIT(5) | BIT(1), + .val = BIT(5) | BIT(1), + .strict = BIT(3), + .enable = BIT(2), + .reg_key = IQS7222_REG_KEY_AXIAL, + }, +}; + struct iqs7222_reg_grp_desc { u16 base; int num_row; @@ -524,6 +620,62 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = { }, }, }, + { + .prod_num = IQS7222_PROD_NUM_D, + .fw_major = 0, + .fw_minor = 37, + .touch_link = 1770, + .allow_offset = 9, + .event_offset = 10, + .comms_offset = 11, + .reg_grps = { + [IQS7222_REG_GRP_STAT] = { + .base = IQS7222_SYS_STATUS, + .num_row = 1, + .num_col = 7, + }, + [IQS7222_REG_GRP_CYCLE] = { + .base = 0x8000, + .num_row = 7, + .num_col = 2, + }, + [IQS7222_REG_GRP_GLBL] = { + .base = 0x8700, + .num_row = 1, + .num_col = 3, + }, + [IQS7222_REG_GRP_BTN] = { + .base = 0x9000, + .num_row = 14, + .num_col = 3, + }, + [IQS7222_REG_GRP_CHAN] = { + .base = 0xA000, + .num_row = 14, + .num_col = 4, + }, + [IQS7222_REG_GRP_FILT] = { + .base = 0xAE00, + .num_row = 1, + .num_col = 2, + }, + [IQS7222_REG_GRP_TPAD] = { + .base = 0xB000, + .num_row = 1, + .num_col = 24, + }, + [IQS7222_REG_GRP_GPIO] = { + .base = 0xC000, + .num_row = 3, + .num_col = 3, + }, + [IQS7222_REG_GRP_SYS] = { + .base = IQS7222_SYS_SETUP, + .num_row = 1, + .num_col = 12, + }, + }, + }, }; struct iqs7222_prop_desc { @@ -1008,6 +1160,123 @@ static const struct iqs7222_prop_desc iqs7222_props[] = { .val_pitch = 4, .label = "maximum gesture time", }, + { + .name = "azoteq,num-rows", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_offset = 0, + .reg_shift = 4, + .reg_width = 4, + .val_min = 1, + .val_max = 12, + .label = "number of rows", + }, + { + .name = "azoteq,num-cols", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_offset = 0, + .reg_shift = 0, + .reg_width = 4, + .val_min = 1, + .val_max = 12, + .label = "number of columns", + }, + { + .name = "azoteq,lower-cal-y", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_offset = 1, + .reg_shift = 8, + .reg_width = 8, + .label = "lower vertical calibration", + }, + { + .name = "azoteq,lower-cal-x", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_offset = 1, + .reg_shift = 0, + .reg_width = 8, + .label = "lower horizontal calibration", + }, + { + .name = "azoteq,upper-cal-y", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_offset = 2, + .reg_shift = 8, + .reg_width = 8, + .label = "upper vertical calibration", + }, + { + .name = "azoteq,upper-cal-x", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_offset = 2, + .reg_shift = 0, + .reg_width = 8, + .label = "upper horizontal calibration", + }, + { + .name = "azoteq,top-speed", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_offset = 3, + .reg_shift = 8, + .reg_width = 8, + .val_pitch = 4, + .label = "top speed", + }, + { + .name = "azoteq,bottom-speed", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_offset = 3, + .reg_shift = 0, + .reg_width = 8, + .label = "bottom speed", + }, + { + .name = "azoteq,gesture-min-ms", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_key = IQS7222_REG_KEY_TAP, + .reg_offset = 20, + .reg_shift = 8, + .reg_width = 8, + .val_pitch = 16, + .label = "minimum gesture time", + }, + { + .name = "azoteq,gesture-max-ms", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_key = IQS7222_REG_KEY_AXIAL, + .reg_offset = 21, + .reg_shift = 8, + .reg_width = 8, + .val_pitch = 16, + .label = "maximum gesture time", + }, + { + .name = "azoteq,gesture-max-ms", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_key = IQS7222_REG_KEY_TAP, + .reg_offset = 21, + .reg_shift = 0, + .reg_width = 8, + .val_pitch = 16, + .label = "maximum gesture time", + }, + { + .name = "azoteq,gesture-dist", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_key = IQS7222_REG_KEY_TAP, + .reg_offset = 22, + .reg_shift = 0, + .reg_width = 16, + .label = "gesture distance", + }, + { + .name = "azoteq,gesture-dist", + .reg_grp = IQS7222_REG_GRP_TPAD, + .reg_key = IQS7222_REG_KEY_AXIAL, + .reg_offset = 23, + .reg_shift = 0, + .reg_width = 16, + .label = "gesture distance", + }, { .name = "drive-open-drain", .reg_grp = IQS7222_REG_GRP_GPIO, @@ -1091,16 +1360,19 @@ struct iqs7222_private { struct gpio_desc *irq_gpio; struct i2c_client *client; struct input_dev *keypad; + struct touchscreen_properties prop; unsigned int kp_type[IQS7222_MAX_CHAN][ARRAY_SIZE(iqs7222_kp_events)]; unsigned int kp_code[IQS7222_MAX_CHAN][ARRAY_SIZE(iqs7222_kp_events)]; unsigned int sl_code[IQS7222_MAX_SLDR][ARRAY_SIZE(iqs7222_sl_events)]; unsigned int sl_axis[IQS7222_MAX_SLDR]; + unsigned int tp_code[ARRAY_SIZE(iqs7222_tp_events)]; u16 cycle_setup[IQS7222_MAX_CHAN / 2][IQS7222_MAX_COLS_CYCLE]; u16 glbl_setup[IQS7222_MAX_COLS_GLBL]; u16 btn_setup[IQS7222_MAX_CHAN][IQS7222_MAX_COLS_BTN]; u16 chan_setup[IQS7222_MAX_CHAN][IQS7222_MAX_COLS_CHAN]; u16 filt_setup[IQS7222_MAX_COLS_FILT]; u16 sldr_setup[IQS7222_MAX_SLDR][IQS7222_MAX_COLS_SLDR]; + u16 tpad_setup[IQS7222_MAX_COLS_TPAD]; u16 gpio_setup[ARRAY_SIZE(iqs7222_gpio_links)][IQS7222_MAX_COLS_GPIO]; u16 sys_setup[IQS7222_MAX_COLS_SYS]; }; @@ -1127,6 +1399,9 @@ static u16 *iqs7222_setup(struct iqs7222_private *iqs7222, case IQS7222_REG_GRP_SLDR: return iqs7222->sldr_setup[row]; + case IQS7222_REG_GRP_TPAD: + return iqs7222->tpad_setup; + case IQS7222_REG_GRP_GPIO: return iqs7222->gpio_setup[row]; @@ -1936,6 +2211,14 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, ref_setup[4] = dev_desc->touch_link; if (fwnode_property_present(chan_node, "azoteq,use-prox")) ref_setup[4] -= 2; + } else if (dev_desc->reg_grps[IQS7222_REG_GRP_TPAD].num_row && + fwnode_property_present(chan_node, + "azoteq,counts-filt-enable")) { + /* + * In the case of IQS7222D, however, the reference mode field + * is partially repurposed as a counts filter enable control. + */ + chan_setup[0] |= IQS7222_CHAN_SETUP_0_REF_MODE_REF; } if (fwnode_property_present(chan_node, "azoteq,rx-enable")) { @@ -2278,6 +2561,136 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, IQS7222_REG_KEY_NO_WHEEL); } +static int iqs7222_parse_tpad(struct iqs7222_private *iqs7222, + struct fwnode_handle *tpad_node, int tpad_index) +{ + const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc; + struct touchscreen_properties *prop = &iqs7222->prop; + struct i2c_client *client = iqs7222->client; + int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row; + int count, error, i; + u16 *event_mask = &iqs7222->sys_setup[dev_desc->event_offset]; + u16 *tpad_setup = iqs7222->tpad_setup; + unsigned int chan_sel[12]; + + error = iqs7222_parse_props(iqs7222, tpad_node, tpad_index, + IQS7222_REG_GRP_TPAD, + IQS7222_REG_KEY_NONE); + if (error) + return error; + + count = fwnode_property_count_u32(tpad_node, "azoteq,channel-select"); + if (count < 0) { + dev_err(&client->dev, "Failed to count %s channels: %d\n", + fwnode_get_name(tpad_node), count); + return count; + } else if (!count || count > ARRAY_SIZE(chan_sel)) { + dev_err(&client->dev, "Invalid number of %s channels\n", + fwnode_get_name(tpad_node)); + return -EINVAL; + } + + error = fwnode_property_read_u32_array(tpad_node, + "azoteq,channel-select", + chan_sel, count); + if (error) { + dev_err(&client->dev, "Failed to read %s channels: %d\n", + fwnode_get_name(tpad_node), error); + return error; + } + + tpad_setup[6] &= ~GENMASK(num_chan - 1, 0); + + for (i = 0; i < ARRAY_SIZE(chan_sel); i++) { + tpad_setup[8 + i] = 0; + if (i >= count || chan_sel[i] == U8_MAX) + continue; + + if (chan_sel[i] >= num_chan) { + dev_err(&client->dev, "Invalid %s channel: %u\n", + fwnode_get_name(tpad_node), chan_sel[i]); + return -EINVAL; + } + + /* + * The following fields indicate which channels participate in + * the trackpad, as well as each channel's relative placement. + */ + tpad_setup[6] |= BIT(chan_sel[i]); + tpad_setup[8 + i] = chan_sel[i] * 34 + 1072; + } + + tpad_setup[7] = dev_desc->touch_link; + if (fwnode_property_present(tpad_node, "azoteq,use-prox")) + tpad_setup[7] -= 2; + + for (i = 0; i < ARRAY_SIZE(iqs7222_tp_events); i++) + tpad_setup[20] &= ~(iqs7222_tp_events[i].strict | + iqs7222_tp_events[i].enable); + + for (i = 0; i < ARRAY_SIZE(iqs7222_tp_events); i++) { + const char *event_name = iqs7222_tp_events[i].name; + struct fwnode_handle *event_node; + + event_node = fwnode_get_named_child_node(tpad_node, event_name); + if (!event_node) + continue; + + if (fwnode_property_present(event_node, + "azoteq,gesture-angle-tighten")) + tpad_setup[20] |= iqs7222_tp_events[i].strict; + + tpad_setup[20] |= iqs7222_tp_events[i].enable; + + error = iqs7222_parse_event(iqs7222, event_node, tpad_index, + IQS7222_REG_GRP_TPAD, + iqs7222_tp_events[i].reg_key, + iqs7222_tp_events[i].link, 1566, + NULL, + &iqs7222->tp_code[i]); + fwnode_handle_put(event_node); + if (error) + return error; + + if (!dev_desc->event_offset) + continue; + + /* + * The press/release event is determined based on whether the + * coordinate fields report 0xFFFF and solely relies on touch + * or proximity interrupts to be unmasked. + */ + if (i) + *event_mask |= IQS7222_EVENT_MASK_TPAD; + else if (tpad_setup[7] == dev_desc->touch_link) + *event_mask |= IQS7222_EVENT_MASK_TOUCH; + else + *event_mask |= IQS7222_EVENT_MASK_PROX; + } + + if (!iqs7222->tp_code[0]) + return 0; + + input_set_abs_params(iqs7222->keypad, ABS_X, + 0, (tpad_setup[4] ? : 1) - 1, 0, 0); + + input_set_abs_params(iqs7222->keypad, ABS_Y, + 0, (tpad_setup[5] ? : 1) - 1, 0, 0); + + touchscreen_parse_properties(iqs7222->keypad, false, prop); + + if (prop->max_x >= U16_MAX || prop->max_y >= U16_MAX) { + dev_err(&client->dev, "Invalid trackpad size: %u*%u\n", + prop->max_x, prop->max_y); + return -EINVAL; + } + + tpad_setup[4] = prop->max_x + 1; + tpad_setup[5] = prop->max_y + 1; + + return 0; +} + static int (*iqs7222_parse_extra[IQS7222_NUM_REG_GRPS]) (struct iqs7222_private *iqs7222, struct fwnode_handle *reg_grp_node, @@ -2285,6 +2698,7 @@ static int (*iqs7222_parse_extra[IQS7222_NUM_REG_GRPS]) [IQS7222_REG_GRP_CYCLE] = iqs7222_parse_cycle, [IQS7222_REG_GRP_CHAN] = iqs7222_parse_chan, [IQS7222_REG_GRP_SLDR] = iqs7222_parse_sldr, + [IQS7222_REG_GRP_TPAD] = iqs7222_parse_tpad, }; static int iqs7222_parse_reg_grp(struct iqs7222_private *iqs7222, @@ -2298,7 +2712,7 @@ static int iqs7222_parse_reg_grp(struct iqs7222_private *iqs7222, if (iqs7222_reg_grp_names[reg_grp]) { char reg_grp_name[16]; - snprintf(reg_grp_name, sizeof(reg_grp_name), "%s-%d", + snprintf(reg_grp_name, sizeof(reg_grp_name), iqs7222_reg_grp_names[reg_grp], reg_grp_index); reg_grp_node = device_get_named_child_node(&client->dev, @@ -2346,8 +2760,8 @@ static int iqs7222_parse_all(struct iqs7222_private *iqs7222) continue; /* - * The IQS7222C exposes multiple GPIO and must be informed - * as to which GPIO this group represents. + * The IQS7222C and IQS7222D expose multiple GPIO and must be + * informed as to which GPIO this group represents. */ for (j = 0; j < ARRAY_SIZE(iqs7222_gpio_links); j++) gpio_setup[0] &= ~BIT(iqs7222_gpio_links[j]); @@ -2480,6 +2894,41 @@ static int iqs7222_report(struct iqs7222_private *iqs7222) iqs7222->sl_code[i][j], 0); } + for (i = 0; i < dev_desc->reg_grps[IQS7222_REG_GRP_TPAD].num_row; i++) { + u16 tpad_pos_x = le16_to_cpu(status[4]); + u16 tpad_pos_y = le16_to_cpu(status[5]); + u16 state = le16_to_cpu(status[6]); + + input_report_key(iqs7222->keypad, iqs7222->tp_code[0], + tpad_pos_x < U16_MAX); + + if (tpad_pos_x < U16_MAX) + touchscreen_report_pos(iqs7222->keypad, &iqs7222->prop, + tpad_pos_x, tpad_pos_y, false); + + if (!(le16_to_cpu(status[1]) & IQS7222_EVENT_MASK_TPAD)) + continue; + + /* + * Skip the press/release event, as it does not have separate + * status fields and is handled separately. + */ + for (j = 1; j < ARRAY_SIZE(iqs7222_tp_events); j++) { + u16 mask = iqs7222_tp_events[j].mask; + u16 val = iqs7222_tp_events[j].val; + + input_report_key(iqs7222->keypad, + iqs7222->tp_code[j], + (state & mask) == val); + } + + input_sync(iqs7222->keypad); + + for (j = 1; j < ARRAY_SIZE(iqs7222_tp_events); j++) + input_report_key(iqs7222->keypad, + iqs7222->tp_code[j], 0); + } + input_sync(iqs7222->keypad); return 0; @@ -2584,6 +3033,7 @@ static const struct of_device_id iqs7222_of_match[] = { { .compatible = "azoteq,iqs7222a" }, { .compatible = "azoteq,iqs7222b" }, { .compatible = "azoteq,iqs7222c" }, + { .compatible = "azoteq,iqs7222d" }, { } }; MODULE_DEVICE_TABLE(of, iqs7222_of_match); @@ -2598,5 +3048,5 @@ static struct i2c_driver iqs7222_i2c_driver = { module_i2c_driver(iqs7222_i2c_driver); MODULE_AUTHOR("Jeff LaBundy "); -MODULE_DESCRIPTION("Azoteq IQS7222A/B/C Capacitive Touch Controller"); +MODULE_DESCRIPTION("Azoteq IQS7222A/B/C/D Capacitive Touch Controller"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 0859c1764c77dd61adf46e3d0c440145118d9e0e Mon Sep 17 00:00:00 2001 From: Roi L Date: Wed, 12 Jul 2023 14:09:06 -0700 Subject: Input: rotary_encoder - don't double assign input->dev.parent devm_input_allocate_device() already assigns the @dev.parent field of the input device/structure, so there's no need to reassign input->dev.parent to dev. Signed-off-by: Roi L Link: https://lore.kernel.org/r/PH0P220MB0460B69CA018F5515F5FACDDDD53A@PH0P220MB0460.NAMP220.PROD.OUTLOOK.COM Signed-off-by: Dmitry Torokhov --- drivers/input/misc/rotary_encoder.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/misc') diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index fb3a34f8eccd..e94cab8133be 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -251,7 +251,6 @@ static int rotary_encoder_probe(struct platform_device *pdev) input->name = pdev->name; input->id.bustype = BUS_HOST; - input->dev.parent = dev; if (encoder->relative_axis) input_set_capability(input, EV_REL, encoder->axis); -- cgit v1.2.3 From dbce1a7d5dce7318d8465b1e0d052ef1d2202237 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 17 Jul 2023 09:03:47 -0700 Subject: Input: Explicitly include correct DT includes The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20230714174633.4058096-1-robh@kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/sun4i-lradc-keys.c | 3 ++- drivers/input/keyboard/tm2-touchkey.c | 1 - drivers/input/misc/gpio-vibra.c | 2 +- drivers/input/misc/iqs269a.c | 2 +- drivers/input/misc/iqs626a.c | 2 +- drivers/input/misc/iqs7222.c | 2 +- drivers/input/misc/mma8450.c | 2 +- drivers/input/misc/pm8941-pwrkey.c | 1 - drivers/input/misc/pm8xxx-vibrator.c | 1 - drivers/input/misc/pmic8xxx-pwrkey.c | 1 - drivers/input/misc/pwm-vibra.c | 2 +- drivers/input/misc/sparcspkr.c | 3 ++- drivers/input/serio/apbps2.c | 2 +- drivers/input/serio/i8042-sparcio.h | 4 +++- drivers/input/serio/xilinx_ps2.c | 4 ++-- drivers/input/touchscreen/cyttsp5.c | 2 +- drivers/input/touchscreen/ili210x.c | 2 +- drivers/input/touchscreen/iqs5xx.c | 2 +- drivers/input/touchscreen/mms114.c | 1 - drivers/input/touchscreen/pixcir_i2c_ts.c | 2 +- drivers/input/touchscreen/ti_am335x_tsc.c | 1 - 21 files changed, 20 insertions(+), 22 deletions(-) (limited to 'drivers/input/misc') diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c index 95d927cc8b7e..f304cab0ebdb 100644 --- a/drivers/input/keyboard/sun4i-lradc-keys.c +++ b/drivers/input/keyboard/sun4i-lradc-keys.c @@ -21,10 +21,11 @@ #include #include #include -#include +#include #include #include #include +#include #include #include #include diff --git a/drivers/input/keyboard/tm2-touchkey.c b/drivers/input/keyboard/tm2-touchkey.c index 75bd3ea51194..0fd761ae052f 100644 --- a/drivers/input/keyboard/tm2-touchkey.c +++ b/drivers/input/keyboard/tm2-touchkey.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/drivers/input/misc/gpio-vibra.c b/drivers/input/misc/gpio-vibra.c index c1c3ba5960dd..ad44b4d18a2a 100644 --- a/drivers/input/misc/gpio-vibra.c +++ b/drivers/input/misc/gpio-vibra.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c index 1272ef7b5794..c0a085639870 100644 --- a/drivers/input/misc/iqs269a.c +++ b/drivers/input/misc/iqs269a.c @@ -17,9 +17,9 @@ #include #include #include +#include #include #include -#include #include #include #include diff --git a/drivers/input/misc/iqs626a.c b/drivers/input/misc/iqs626a.c index 50035c25c3f7..0dab54d3a060 100644 --- a/drivers/input/misc/iqs626a.c +++ b/drivers/input/misc/iqs626a.c @@ -19,8 +19,8 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c index a9c1dba1e8c1..36aeeae77611 100644 --- a/drivers/input/misc/iqs7222.c +++ b/drivers/input/misc/iqs7222.c @@ -16,8 +16,8 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c index 76a190b2220b..662b436d765b 100644 --- a/drivers/input/misc/mma8450.c +++ b/drivers/input/misc/mma8450.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #define MMA8450_DRV_NAME "mma8450" diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c index 74d77d8aaeff..ba747c5b2b5f 100644 --- a/drivers/input/misc/pm8941-pwrkey.c +++ b/drivers/input/misc/pm8941-pwrkey.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/misc/pm8xxx-vibrator.c b/drivers/input/misc/pm8xxx-vibrator.c index 04cb87efd799..5c288fe7accf 100644 --- a/drivers/input/misc/pm8xxx-vibrator.c +++ b/drivers/input/misc/pm8xxx-vibrator.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c index 89fb137e3715..c406a1cca5c4 100644 --- a/drivers/input/misc/pmic8xxx-pwrkey.c +++ b/drivers/input/misc/pmic8xxx-pwrkey.c @@ -12,7 +12,6 @@ #include #include #include -#include #define PON_CNTL_1 0x1C #define PON_CNTL_PULL_UP BIT(7) diff --git a/drivers/input/misc/pwm-vibra.c b/drivers/input/misc/pwm-vibra.c index a3cde30ee8d2..acac79c488aa 100644 --- a/drivers/input/misc/pwm-vibra.c +++ b/drivers/input/misc/pwm-vibra.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index cdcb7737c46a..e5dd84725c6e 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -9,7 +9,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/input/serio/apbps2.c b/drivers/input/serio/apbps2.c index 513d96e40e0e..3f6866d39b86 100644 --- a/drivers/input/serio/apbps2.c +++ b/drivers/input/serio/apbps2.c @@ -14,11 +14,11 @@ * Contributors: Daniel Hellstrom */ #include -#include #include #include #include #include +#include #include #include #include diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h index c712c1fe0605..b68793bf05c8 100644 --- a/drivers/input/serio/i8042-sparcio.h +++ b/drivers/input/serio/i8042-sparcio.h @@ -2,7 +2,9 @@ #ifndef _I8042_SPARCIO_H #define _I8042_SPARCIO_H -#include +#include +#include +#include #include #include diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 960d7601fbc8..f3d28da70b75 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -14,10 +14,10 @@ #include #include #include +#include #include -#include #include -#include +#include #define DRIVER_NAME "xilinx_ps2" diff --git a/drivers/input/touchscreen/cyttsp5.c b/drivers/input/touchscreen/cyttsp5.c index b461ded946fc..db5a885ecd72 100644 --- a/drivers/input/touchscreen/cyttsp5.c +++ b/drivers/input/touchscreen/cyttsp5.c @@ -18,8 +18,8 @@ #include #include #include +#include #include -#include #include #include diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index f7cd773f7292..ad6828e4f2e2 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -8,8 +8,8 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/drivers/input/touchscreen/iqs5xx.c b/drivers/input/touchscreen/iqs5xx.c index 0aa9d6492df8..b4768b66eb10 100644 --- a/drivers/input/touchscreen/iqs5xx.c +++ b/drivers/input/touchscreen/iqs5xx.c @@ -23,8 +23,8 @@ #include #include #include +#include #include -#include #include #include diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index ac12494c7930..6109cf7e779a 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index 0b4576091dac..4ede0687beb0 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -13,8 +13,8 @@ #include #include #include -#include #include +#include #include #define PIXCIR_MAX_SLOTS 5 /* Max fingers supported by driver */ diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index decf2d24a115..9aa4e35fb4f5 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From d7781232b5b2d049e654d5ead9921dc49090d214 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Mon, 17 Jul 2023 12:20:03 -0700 Subject: Input: da9063 - add wakeup support Mark the IRQ as a wake IRQ so it will be enabled during system suspend. Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20230717192004.1304287-1-samuel.holland@sifive.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/da9063_onkey.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/input/misc') diff --git a/drivers/input/misc/da9063_onkey.c b/drivers/input/misc/da9063_onkey.c index b14a389600c9..74808bae326a 100644 --- a/drivers/input/misc/da9063_onkey.c +++ b/drivers/input/misc/da9063_onkey.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -251,6 +252,14 @@ static int da9063_onkey_probe(struct platform_device *pdev) return error; } + error = dev_pm_set_wake_irq(&pdev->dev, irq); + if (error) + dev_warn(&pdev->dev, + "Failed to set IRQ %d as a wake IRQ: %d\n", + irq, error); + else + device_init_wakeup(&pdev->dev, true); + error = input_register_device(onkey->input); if (error) { dev_err(&pdev->dev, -- cgit v1.2.3