From 43266ad2b47db87b91f3198afa5ad61a4206c253 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 26 Jun 2019 05:52:16 -0400 Subject: media: input/touchscreen/sur40: use COLORSPACE_RAW This driver set the colorspace to SRGB, but that makes no sense for a touchscreen. Use RAW instead. This also ensures consistency with the v4l_pix_format_touch() call that's used in v4l2-ioctl.c. Signed-off-by: Hans Verkuil Acked-by: Florian Echtler Acked-by: Dmitry Torokhov Signed-off-by: Mauro Carvalho Chehab --- drivers/input/touchscreen/sur40.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c index 00cb1ba2d364..3fd3e862269b 100644 --- a/drivers/input/touchscreen/sur40.c +++ b/drivers/input/touchscreen/sur40.c @@ -186,7 +186,7 @@ static const struct v4l2_pix_format sur40_pix_format[] = { .width = SENSOR_RES_X / 2, .height = SENSOR_RES_Y / 2, .field = V4L2_FIELD_NONE, - .colorspace = V4L2_COLORSPACE_SRGB, + .colorspace = V4L2_COLORSPACE_RAW, .bytesperline = SENSOR_RES_X / 2, .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2), }, @@ -195,7 +195,7 @@ static const struct v4l2_pix_format sur40_pix_format[] = { .width = SENSOR_RES_X / 2, .height = SENSOR_RES_Y / 2, .field = V4L2_FIELD_NONE, - .colorspace = V4L2_COLORSPACE_SRGB, + .colorspace = V4L2_COLORSPACE_RAW, .bytesperline = SENSOR_RES_X / 2, .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2), } -- cgit v1.2.3-59-g8ed1b From 463fa44eec2fef50d111ed0199cf593235065c04 Mon Sep 17 00:00:00 2001 From: Evan Green Date: Wed, 2 Oct 2019 14:00:21 -0700 Subject: Input: atmel_mxt_ts - disable IRQ across suspend Across suspend and resume, we are seeing error messages like the following: atmel_mxt_ts i2c-PRP0001:00: __mxt_read_reg: i2c transfer failed (-121) atmel_mxt_ts i2c-PRP0001:00: Failed to read T44 and T5 (-121) This occurs because the driver leaves its IRQ enabled. Upon resume, there is an IRQ pending, but the interrupt is serviced before both the driver and the underlying I2C bus have been resumed. This causes EREMOTEIO errors. Disable the IRQ in suspend, and re-enable it on resume. If there are cases where the driver enters suspend with interrupts disabled, that's a bug we should fix separately. Signed-off-by: Evan Green Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/atmel_mxt_ts.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 24c4b691b1c9..ae60442efda0 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3156,6 +3156,8 @@ static int __maybe_unused mxt_suspend(struct device *dev) mutex_unlock(&input_dev->mutex); + disable_irq(data->irq); + return 0; } @@ -3168,6 +3170,8 @@ static int __maybe_unused mxt_resume(struct device *dev) if (!input_dev) return 0; + enable_irq(data->irq); + mutex_lock(&input_dev->mutex); if (input_dev->users) -- cgit v1.2.3-59-g8ed1b From bdafbb15d13b8819d75e026c0b4b61a701583a91 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 8 Oct 2019 10:13:38 -0700 Subject: Input: pixcir_i2c_ts - remove unneeded gpio.h header file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The touchscreen device is a GPIO consumer, not a GPIO controller, so there is no need to include . Remove the unneeded header file. Signed-off-by: Fabio Estevam Reviewed-by: Roger Quadros Tested-by: Michal Vokáč Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/pixcir_i2c_ts.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index e146dfa257b1..4561d65e7a1e 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 0d3c8501e32e19c9bdfc65e5d4e17e7772729332 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 8 Oct 2019 10:13:55 -0700 Subject: Input: pixcir_i2c_ts - move definitions into a single file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All the defined symbols from linux/platform_data/pixcir_i2c_ts.h are only used by the pixcir_i2c_ts driver, so move all the definitions locally and get rid of the pixcir_i2c_ts.h file. Signed-off-by: Fabio Estevam Reviewed-by: Roger Quadros Tested-by: Michal Vokáč Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/pixcir_i2c_ts.c | 60 ++++++++++++++++++++++++++- include/linux/platform_data/pixcir_i2c_ts.h | 64 ----------------------------- 2 files changed, 59 insertions(+), 65 deletions(-) delete mode 100644 include/linux/platform_data/pixcir_i2c_ts.h (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index 4561d65e7a1e..acc9504aa35b 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -15,11 +15,69 @@ #include #include #include -#include #include #define PIXCIR_MAX_SLOTS 5 /* Max fingers supported by driver */ +/* + * Register map + */ +#define PIXCIR_REG_POWER_MODE 51 +#define PIXCIR_REG_INT_MODE 52 + +/* + * Power modes: + * active: max scan speed + * idle: lower scan speed with automatic transition to active on touch + * halt: datasheet says sleep but this is more like halt as the chip + * clocks are cut and it can only be brought out of this mode + * using the RESET pin. + */ +enum pixcir_power_mode { + PIXCIR_POWER_ACTIVE, + PIXCIR_POWER_IDLE, + PIXCIR_POWER_HALT, +}; + +#define PIXCIR_POWER_MODE_MASK 0x03 +#define PIXCIR_POWER_ALLOW_IDLE (1UL << 2) + +/* + * Interrupt modes: + * periodical: interrupt is asserted periodicaly + * diff coordinates: interrupt is asserted when coordinates change + * level on touch: interrupt level asserted during touch + * pulse on touch: interrupt pulse asserted during touch + * + */ +enum pixcir_int_mode { + PIXCIR_INT_PERIODICAL, + PIXCIR_INT_DIFF_COORD, + PIXCIR_INT_LEVEL_TOUCH, + PIXCIR_INT_PULSE_TOUCH, +}; + +#define PIXCIR_INT_MODE_MASK 0x03 +#define PIXCIR_INT_ENABLE (1UL << 3) +#define PIXCIR_INT_POL_HIGH (1UL << 2) + +/** + * struct pixcir_irc_chip_data - chip related data + * @max_fingers: Max number of fingers reported simultaneously by h/w + * @has_hw_ids: Hardware supports finger tracking IDs + * + */ +struct pixcir_i2c_chip_data { + u8 max_fingers; + bool has_hw_ids; +}; + +struct pixcir_ts_platform_data { + int x_max; + int y_max; + struct pixcir_i2c_chip_data chip; +}; + struct pixcir_i2c_ts_data { struct i2c_client *client; struct input_dev *input; diff --git a/include/linux/platform_data/pixcir_i2c_ts.h b/include/linux/platform_data/pixcir_i2c_ts.h deleted file mode 100644 index 4ab3cd6f1cc2..000000000000 --- a/include/linux/platform_data/pixcir_i2c_ts.h +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _PIXCIR_I2C_TS_H -#define _PIXCIR_I2C_TS_H - -/* - * Register map - */ -#define PIXCIR_REG_POWER_MODE 51 -#define PIXCIR_REG_INT_MODE 52 - -/* - * Power modes: - * active: max scan speed - * idle: lower scan speed with automatic transition to active on touch - * halt: datasheet says sleep but this is more like halt as the chip - * clocks are cut and it can only be brought out of this mode - * using the RESET pin. - */ -enum pixcir_power_mode { - PIXCIR_POWER_ACTIVE, - PIXCIR_POWER_IDLE, - PIXCIR_POWER_HALT, -}; - -#define PIXCIR_POWER_MODE_MASK 0x03 -#define PIXCIR_POWER_ALLOW_IDLE (1UL << 2) - -/* - * Interrupt modes: - * periodical: interrupt is asserted periodicaly - * diff coordinates: interrupt is asserted when coordinates change - * level on touch: interrupt level asserted during touch - * pulse on touch: interrupt pulse asserted druing touch - * - */ -enum pixcir_int_mode { - PIXCIR_INT_PERIODICAL, - PIXCIR_INT_DIFF_COORD, - PIXCIR_INT_LEVEL_TOUCH, - PIXCIR_INT_PULSE_TOUCH, -}; - -#define PIXCIR_INT_MODE_MASK 0x03 -#define PIXCIR_INT_ENABLE (1UL << 3) -#define PIXCIR_INT_POL_HIGH (1UL << 2) - -/** - * struct pixcir_irc_chip_data - chip related data - * @max_fingers: Max number of fingers reported simultaneously by h/w - * @has_hw_ids: Hardware supports finger tracking IDs - * - */ -struct pixcir_i2c_chip_data { - u8 max_fingers; - bool has_hw_ids; -}; - -struct pixcir_ts_platform_data { - int x_max; - int y_max; - struct pixcir_i2c_chip_data chip; -}; - -#endif -- cgit v1.2.3-59-g8ed1b From 12e7425a69fd97785f6d6835c2de0e72a9a48918 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 8 Oct 2019 10:14:41 -0700 Subject: Input: pixcir_i2c_ts - keep header files sorted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep the header files in alphabetical order to keep it more organized. Signed-off-by: Fabio Estevam Reviewed-by: Roger Quadros Tested-by: Michal Vokáč Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/pixcir_i2c_ts.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index acc9504aa35b..f22b2e7be2be 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -5,17 +5,17 @@ * Copyright (C) 2010-2011 Pixcir, Inc. */ +#include #include -#include -#include -#include +#include #include #include #include #include -#include +#include #include -#include +#include +#include #define PIXCIR_MAX_SLOTS 5 /* Max fingers supported by driver */ -- cgit v1.2.3-59-g8ed1b From 13fb9cf593c35073d707c1dabbef9f0cff772695 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 8 Oct 2019 10:15:01 -0700 Subject: Input: pixcir_i2c_ts - print register address in decimal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pixcir datasheet lists the registers addresses in decimal and so are PIXCIR_REG_POWER_MODE and PIXCIR_REG_INT_MODE defined in decimal. Change the error messages to print the register addresses in decimal instead of hexadecimal for better readability. Signed-off-by: Fabio Estevam Reviewed-by: Roger Quadros Tested-by: Michal Vokáč Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/pixcir_i2c_ts.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index f22b2e7be2be..5f2a3dc353c8 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -249,7 +249,7 @@ static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts, ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_POWER_MODE); if (ret < 0) { - dev_err(dev, "%s: can't read reg 0x%x : %d\n", + dev_err(dev, "%s: can't read reg %d : %d\n", __func__, PIXCIR_REG_POWER_MODE, ret); return ret; } @@ -262,7 +262,7 @@ static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts, ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_POWER_MODE, ret); if (ret < 0) { - dev_err(dev, "%s: can't write reg 0x%x : %d\n", + dev_err(dev, "%s: can't write reg %d : %d\n", __func__, PIXCIR_REG_POWER_MODE, ret); return ret; } @@ -288,7 +288,7 @@ static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts, ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE); if (ret < 0) { - dev_err(dev, "%s: can't read reg 0x%x : %d\n", + dev_err(dev, "%s: can't read reg %d : %d\n", __func__, PIXCIR_REG_INT_MODE, ret); return ret; } @@ -303,7 +303,7 @@ static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts, ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret); if (ret < 0) { - dev_err(dev, "%s: can't write reg 0x%x : %d\n", + dev_err(dev, "%s: can't write reg %d : %d\n", __func__, PIXCIR_REG_INT_MODE, ret); return ret; } @@ -321,7 +321,7 @@ static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable) ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE); if (ret < 0) { - dev_err(dev, "%s: can't read reg 0x%x : %d\n", + dev_err(dev, "%s: can't read reg %d : %d\n", __func__, PIXCIR_REG_INT_MODE, ret); return ret; } @@ -333,7 +333,7 @@ static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable) ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret); if (ret < 0) { - dev_err(dev, "%s: can't write reg 0x%x : %d\n", + dev_err(dev, "%s: can't write reg %d : %d\n", __func__, PIXCIR_REG_INT_MODE, ret); return ret; } -- cgit v1.2.3-59-g8ed1b From 71a8f3455cbf50f96d521c5a4c972c4709affd80 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 8 Oct 2019 10:15:12 -0700 Subject: Input: pixcir_i2c_ts - do not print error on defer probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the case of defer probe we should not print an error message. This also aligns with how defer probe is handled in the other GPIOs used by this driver. Signed-off-by: Fabio Estevam Reviewed-by: Roger Quadros Tested-by: Michal Vokáč Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/pixcir_i2c_ts.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index 5f2a3dc353c8..ec768ab6148e 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -567,7 +567,9 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, tsdata->gpio_attb = devm_gpiod_get(dev, "attb", GPIOD_IN); if (IS_ERR(tsdata->gpio_attb)) { error = PTR_ERR(tsdata->gpio_attb); - dev_err(dev, "Failed to request ATTB gpio: %d\n", error); + if (error != -EPROBE_DEFER) + dev_err(dev, "Failed to request ATTB gpio: %d\n", + error); return error; } @@ -575,7 +577,9 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, GPIOD_OUT_LOW); if (IS_ERR(tsdata->gpio_reset)) { error = PTR_ERR(tsdata->gpio_reset); - dev_err(dev, "Failed to request RESET gpio: %d\n", error); + if (error != -EPROBE_DEFER) + dev_err(dev, "Failed to request RESET gpio: %d\n", + error); return error; } -- cgit v1.2.3-59-g8ed1b From 792e154c4814abb1ec2b18c418b44a303cf6ead9 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 8 Oct 2019 11:38:04 -0700 Subject: Input: pixcir_i2c_ts - remove platform data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous change moved platform data definition into the driver, making it unusable for users. Given that we want to move away from custom platform data structures, and always use device properties (DT, ACPI or static) to configure devices, let's complete the removal. Tested-by: Fabio Estevam Tested-by: Michal Vokáč Reviewed-by: Roger Quadros Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/pixcir_i2c_ts.c | 100 ++++++++---------------------- 1 file changed, 25 insertions(+), 75 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index ec768ab6148e..9aa098577350 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -62,7 +62,7 @@ enum pixcir_int_mode { #define PIXCIR_INT_POL_HIGH (1UL << 2) /** - * struct pixcir_irc_chip_data - chip related data + * struct pixcir_i2c_chip_data - chip related data * @max_fingers: Max number of fingers reported simultaneously by h/w * @has_hw_ids: Hardware supports finger tracking IDs * @@ -72,12 +72,6 @@ struct pixcir_i2c_chip_data { bool has_hw_ids; }; -struct pixcir_ts_platform_data { - int x_max; - int y_max; - struct pixcir_i2c_chip_data chip; -}; - struct pixcir_i2c_ts_data { struct i2c_client *client; struct input_dev *input; @@ -87,7 +81,6 @@ struct pixcir_i2c_ts_data { struct gpio_desc *gpio_wake; const struct pixcir_i2c_chip_data *chip; struct touchscreen_properties prop; - int max_fingers; /* Max fingers supported in this instance */ bool running; }; @@ -111,7 +104,7 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata, memset(report, 0, sizeof(struct pixcir_report_data)); i = chip->has_hw_ids ? 1 : 0; - readsize = 2 + tsdata->max_fingers * (4 + i); + readsize = 2 + tsdata->chip->max_fingers * (4 + i); if (readsize > sizeof(rdbuf)) readsize = sizeof(rdbuf); @@ -132,8 +125,8 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata, } touch = rdbuf[0] & 0x7; - if (touch > tsdata->max_fingers) - touch = tsdata->max_fingers; + if (touch > tsdata->chip->max_fingers) + touch = tsdata->chip->max_fingers; report->num_touches = touch; bufptr = &rdbuf[2]; @@ -469,31 +462,9 @@ unlock: static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops, pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume); -#ifdef CONFIG_OF -static const struct of_device_id pixcir_of_match[]; - -static int pixcir_parse_dt(struct device *dev, - struct pixcir_i2c_ts_data *tsdata) -{ - tsdata->chip = of_device_get_match_data(dev); - if (!tsdata->chip) - return -EINVAL; - - return 0; -} -#else -static int pixcir_parse_dt(struct device *dev, - struct pixcir_i2c_ts_data *tsdata) -{ - return -EINVAL; -} -#endif - static int pixcir_i2c_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct pixcir_ts_platform_data *pdata = - dev_get_platdata(&client->dev); struct device *dev = &client->dev; struct pixcir_i2c_ts_data *tsdata; struct input_dev *input; @@ -503,19 +474,11 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, if (!tsdata) return -ENOMEM; - if (pdata) { - tsdata->chip = &pdata->chip; - } else if (dev->of_node) { - error = pixcir_parse_dt(dev, tsdata); - if (error) - return error; - } else { - dev_err(dev, "platform data not defined\n"); - return -EINVAL; - } - - if (!tsdata->chip->max_fingers) { - dev_err(dev, "Invalid max_fingers in chip data\n"); + tsdata->chip = device_get_match_data(dev); + if (!tsdata->chip && id) + tsdata->chip = (const void *)id->driver_data; + if (!tsdata->chip) { + dev_err(dev, "can't locate chip data\n"); return -EINVAL; } @@ -532,30 +495,17 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, input->id.bustype = BUS_I2C; input->open = pixcir_input_open; input->close = pixcir_input_close; - input->dev.parent = dev; - - if (pdata) { - input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0); - input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0); - } else { - input_set_capability(input, EV_ABS, ABS_MT_POSITION_X); - input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y); - touchscreen_parse_properties(input, true, &tsdata->prop); - if (!input_abs_get_max(input, ABS_MT_POSITION_X) || - !input_abs_get_max(input, ABS_MT_POSITION_Y)) { - dev_err(dev, "Touchscreen size is not specified\n"); - return -EINVAL; - } - } - tsdata->max_fingers = tsdata->chip->max_fingers; - if (tsdata->max_fingers > PIXCIR_MAX_SLOTS) { - tsdata->max_fingers = PIXCIR_MAX_SLOTS; - dev_info(dev, "Limiting maximum fingers to %d\n", - tsdata->max_fingers); + input_set_capability(input, EV_ABS, ABS_MT_POSITION_X); + input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y); + touchscreen_parse_properties(input, true, &tsdata->prop); + if (!input_abs_get_max(input, ABS_MT_POSITION_X) || + !input_abs_get_max(input, ABS_MT_POSITION_Y)) { + dev_err(dev, "Touchscreen size is not specified\n"); + return -EINVAL; } - error = input_mt_init_slots(input, tsdata->max_fingers, + error = input_mt_init_slots(input, tsdata->chip->max_fingers, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); if (error) { dev_err(dev, "Error initializing Multi-Touch slots\n"); @@ -635,14 +585,6 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, return 0; } -static const struct i2c_device_id pixcir_i2c_ts_id[] = { - { "pixcir_ts", 0 }, - { "pixcir_tangoc", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id); - -#ifdef CONFIG_OF static const struct pixcir_i2c_chip_data pixcir_ts_data = { .max_fingers = 2, /* no hw id support */ @@ -653,6 +595,14 @@ static const struct pixcir_i2c_chip_data pixcir_tangoc_data = { .has_hw_ids = true, }; +static const struct i2c_device_id pixcir_i2c_ts_id[] = { + { "pixcir_ts", (unsigned long) &pixcir_ts_data }, + { "pixcir_tangoc", (unsigned long) &pixcir_tangoc_data }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id); + +#ifdef CONFIG_OF static const struct of_device_id pixcir_of_match[] = { { .compatible = "pixcir,pixcir_ts", .data = &pixcir_ts_data }, { .compatible = "pixcir,pixcir_tangoc", .data = &pixcir_tangoc_data }, -- cgit v1.2.3-59-g8ed1b From d34a069e1c63ddc20e2c3c8bfdec2510682b15f3 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 27 Oct 2019 10:35:21 -0700 Subject: Input: colibri-vf50-ts - remove unneeded gpio.h header file The touchscreen device is a GPIO consumer, not a GPIO controller, so there is no need to include . Remove the unneeded header file. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20191026185958.24158-1-festevam@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/colibri-vf50-ts.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/colibri-vf50-ts.c b/drivers/input/touchscreen/colibri-vf50-ts.c index 0e40897949bb..aa829725ded7 100644 --- a/drivers/input/touchscreen/colibri-vf50-ts.c +++ b/drivers/input/touchscreen/colibri-vf50-ts.c @@ -9,7 +9,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 2fd61f796875b78469f35101cc2124ffed6343e5 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 27 Oct 2019 10:35:31 -0700 Subject: Input: s3c2410_ts - remove unneeded gpio.h header file There is no gpio functions used in the driver that is exported by the gpio.h header, so remove this unneeded header. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20191026185958.24158-2-festevam@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/s3c2410_ts.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index b346e7cafd62..82920ff46f72 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3-59-g8ed1b From 78e45917bf7a066fffbeb3d87f4031109df6da55 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 27 Oct 2019 10:35:41 -0700 Subject: Input: wacom_i2c - remove unneeded gpio.h header file There is no gpio functions used in the driver that is exported by the gpio.h header, so remove this unneeded header. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20191026185958.24158-3-festevam@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_i2c.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/wacom_i2c.c b/drivers/input/touchscreen/wacom_i2c.c index f017af8c2aa3..1afc6bde2891 100644 --- a/drivers/input/touchscreen/wacom_i2c.c +++ b/drivers/input/touchscreen/wacom_i2c.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #define WACOM_CMD_QUERY0 0x04 -- cgit v1.2.3-59-g8ed1b From 95c9ea96adb3c7be6295d017c7e2f594f0871c16 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 Oct 2019 10:11:23 -0700 Subject: Input: st1232 - simplify parsing of read buffer Avoid complex 2-variable loop when parsing touchscreen data to make the code clearer. Acked-by: Martin Kepplinger Tested-by: Matthias Fend Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 50 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 1139714e72e2..47033ef3749a 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -57,38 +57,38 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts) { struct st1232_ts_finger *finger = ts->finger; struct i2c_client *client = ts->client; - struct i2c_msg msg[2]; - int error; - int i, y; u8 start_reg = ts->chip_info->start_reg; - u8 *buf = ts->read_buf; - - /* read touchscreen data */ - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &start_reg; - - msg[1].addr = ts->client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = ts->read_buf_len; - msg[1].buf = buf; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .len = sizeof(start_reg), + .buf = &start_reg, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = ts->read_buf_len, + .buf = ts->read_buf, + } + }; + int ret; + int i; + u8 *buf; - error = i2c_transfer(client->adapter, msg, 2); - if (error < 0) - return error; + ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); + if (ret != ARRAY_SIZE(msg)) + return ret < 0 ? ret : -EIO; - for (i = 0, y = 0; i < ts->chip_info->max_fingers; i++, y += 3) { - finger[i].is_valid = buf[i + y] >> 7; + for (i = 0; i < ts->chip_info->max_fingers; i++) { + buf = &ts->read_buf[i * 4]; + finger[i].is_valid = buf[0] >> 7; if (finger[i].is_valid) { - finger[i].x = ((buf[i + y] & 0x0070) << 4) | - buf[i + y + 1]; - finger[i].y = ((buf[i + y] & 0x0007) << 8) | - buf[i + y + 2]; + finger[i].x = ((buf[0] & 0x70) << 4) | buf[1]; + finger[i].y = ((buf[0] & 0x07) << 8) | buf[2]; /* st1232 includes a z-axis / touch strength */ if (ts->chip_info->have_z) - finger[i].t = buf[i + 6]; + finger[i].t = ts->read_buf[i + 6]; } } -- cgit v1.2.3-59-g8ed1b From 16dc7c5c13f1482ac32b8ac7cbc1ad8ab13b0f5d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 Oct 2019 10:55:56 -0700 Subject: Input: st1232 - do not unconditionally configure as wakeup source Do not unconditionally configure the touchscreen as wakeup source but rather rely on I2C core to do that when requested (either via "wakeup-source" device property, or when creating a client with I2C_CLIENT_WAKE flag). Tested-by: Matthias Fend Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 47033ef3749a..f1b97075aa9b 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -266,7 +266,6 @@ static int st1232_ts_probe(struct i2c_client *client, } i2c_set_clientdata(client, ts); - device_init_wakeup(&client->dev, 1); return 0; } -- cgit v1.2.3-59-g8ed1b From 95dc58a9a02f9267cc08199e059329463cfe938c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 Oct 2019 11:00:21 -0700 Subject: Input: st1232 - rely on I2C core to configure wakeup interrupt When I2C client is created with I2C_CLIENT_WAKE flag (which happens either because we have "wakeup-source" device property or the flag was passed in when creating an I2C client manually), I2C core will take care of configuring interrupt as wakeup source on suspend. Tested-by: Matthias Fend Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index f1b97075aa9b..bb116f41f1c0 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -284,12 +284,10 @@ static int __maybe_unused st1232_ts_suspend(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct st1232_ts_data *ts = i2c_get_clientdata(client); - if (device_may_wakeup(&client->dev)) { - enable_irq_wake(client->irq); - } else { - disable_irq(client->irq); + disable_irq(client->irq); + + if (!device_may_wakeup(&client->dev)) st1232_ts_power(ts, false); - } return 0; } @@ -299,12 +297,10 @@ static int __maybe_unused st1232_ts_resume(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct st1232_ts_data *ts = i2c_get_clientdata(client); - if (device_may_wakeup(&client->dev)) { - disable_irq_wake(client->irq); - } else { + if (!device_may_wakeup(&client->dev)) st1232_ts_power(ts, true); - enable_irq(client->irq); - } + + enable_irq(client->irq); return 0; } -- cgit v1.2.3-59-g8ed1b From efd7bb08a762d4f6322054c6824bd942971ac563 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 Oct 2019 11:02:33 -0700 Subject: Input: st1232 - do not reset the chip too early We should not be putting the chip into reset while interrupts are enabled and ISR may be running. Fix this by installing a custom devm action and powering off the device/resetting GPIO line from there. This ensures proper ordering. Tested-by: Matthias Fend Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index bb116f41f1c0..bfea02202ded 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -149,6 +149,11 @@ static void st1232_ts_power(struct st1232_ts_data *ts, bool poweron) gpiod_set_value_cansleep(ts->reset_gpio, !poweron); } +static void st1232_ts_power_off(void *data) +{ + st1232_ts_power(data, false); +} + static const struct st_chip_info st1232_chip_info = { .have_z = true, .max_x = 0x31f, /* 800 - 1 */ @@ -229,6 +234,13 @@ static int st1232_ts_probe(struct i2c_client *client, st1232_ts_power(ts, true); + error = devm_add_action_or_reset(&client->dev, st1232_ts_power_off, ts); + if (error) { + dev_err(&client->dev, + "Failed to install power off action: %d\n", error); + return error; + } + input_dev->name = "st1232-touchscreen"; input_dev->id.bustype = BUS_I2C; input_dev->dev.parent = &client->dev; @@ -270,15 +282,6 @@ static int st1232_ts_probe(struct i2c_client *client, return 0; } -static int st1232_ts_remove(struct i2c_client *client) -{ - struct st1232_ts_data *ts = i2c_get_clientdata(client); - - st1232_ts_power(ts, false); - - return 0; -} - static int __maybe_unused st1232_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -324,7 +327,6 @@ MODULE_DEVICE_TABLE(of, st1232_ts_dt_ids); static struct i2c_driver st1232_ts_driver = { .probe = st1232_ts_probe, - .remove = st1232_ts_remove, .id_table = st1232_ts_id, .driver = { .name = ST1232_TS_NAME, -- cgit v1.2.3-59-g8ed1b From ac6b31797925b6f89885987c81d908bad90dea60 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 Oct 2019 20:49:19 -0700 Subject: Input: st1232 - do not allocate fingers data separately The finger structure size is quite small and allocating it together with the main driver structure will not increase likelyhood of allocation failing, but reduces number of objects needing to be tracked by the allocator and devm. Tested-by: Matthias Fend Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index bfea02202ded..dfc0c6cb0213 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -50,12 +50,12 @@ struct st1232_ts_data { const struct st_chip_info *chip_info; int read_buf_len; u8 *read_buf; - struct st1232_ts_finger *finger; + struct st1232_ts_finger fingers[]; }; static int st1232_ts_read_data(struct st1232_ts_data *ts) { - struct st1232_ts_finger *finger = ts->finger; + struct st1232_ts_finger *finger = ts->fingers; struct i2c_client *client = ts->client; u8 start_reg = ts->chip_info->start_reg; struct i2c_msg msg[] = { @@ -98,7 +98,7 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts) static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id) { struct st1232_ts_data *ts = dev_id; - struct st1232_ts_finger *finger = ts->finger; + struct st1232_ts_finger *finger = ts->fingers; struct input_dev *input_dev = ts->input_dev; int count = 0; int i, ret; @@ -177,7 +177,6 @@ static int st1232_ts_probe(struct i2c_client *client, { const struct st_chip_info *match; struct st1232_ts_data *ts; - struct st1232_ts_finger *finger; struct input_dev *input_dev; int error; @@ -199,16 +198,13 @@ static int st1232_ts_probe(struct i2c_client *client, return -EINVAL; } - ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); + ts = devm_kzalloc(&client->dev, + struct_size(ts, fingers, match->max_fingers), + GFP_KERNEL); if (!ts) return -ENOMEM; ts->chip_info = match; - ts->finger = devm_kcalloc(&client->dev, - ts->chip_info->max_fingers, sizeof(*finger), - GFP_KERNEL); - if (!ts->finger) - return -ENOMEM; /* allocate a buffer according to the number of registers to read */ ts->read_buf_len = ts->chip_info->max_fingers * 4; -- cgit v1.2.3-59-g8ed1b From b67b6f598c5d6efe58f202b1f95cd0503583b728 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 21 Oct 2019 20:50:37 -0700 Subject: Input: st1232 - do not set parent device explicitly devm_input_allocate_device() already sets parent device for us. Tested-by: Matthias Fend Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index dfc0c6cb0213..0aee330731c9 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -239,7 +239,6 @@ static int st1232_ts_probe(struct i2c_client *client, input_dev->name = "st1232-touchscreen"; input_dev->id.bustype = BUS_I2C; - input_dev->dev.parent = &client->dev; __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); __set_bit(EV_SYN, input_dev->evbit); -- cgit v1.2.3-59-g8ed1b From 833c2c083856ef3077b51c908ec401fa0a130d57 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 22 Oct 2019 09:34:59 -0700 Subject: Input: st1232 - note that the receive buffer is DMA-safe The receiving buffer is allocated separately from the main driver data structure, and is naturally DMA-safe, so mark it as such when building I2C transfer message. Tested-by: Matthias Fend Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 0aee330731c9..a4a3b82ee69d 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -66,7 +66,7 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts) }, { .addr = client->addr, - .flags = I2C_M_RD, + .flags = I2C_M_RD | I2C_M_DMA_SAFE, .len = ts->read_buf_len, .buf = ts->read_buf, } -- cgit v1.2.3-59-g8ed1b From a1b92973fba47ceaeb0e337132876aba078fa8b7 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 22 Oct 2019 10:31:16 -0700 Subject: Input: st1232 - switch to using MT-B protocol Switch the driver to the slotted variant of multitouch protocol (MT-B) with in-kernel tracking of the contacts. Tested-by: Matthias Fend Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 110 +++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 54 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index a4a3b82ee69d..63b29c7279e2 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -14,23 +14,19 @@ #include #include #include +#include +#include #include #include #include #include #include #include -#include #define ST1232_TS_NAME "st1232-ts" #define ST1633_TS_NAME "st1633-ts" -struct st1232_ts_finger { - u16 x; - u16 y; - u8 t; - bool is_valid; -}; +#define ST_TS_MAX_FINGERS 10 struct st_chip_info { bool have_z; @@ -50,12 +46,10 @@ struct st1232_ts_data { const struct st_chip_info *chip_info; int read_buf_len; u8 *read_buf; - struct st1232_ts_finger fingers[]; }; static int st1232_ts_read_data(struct st1232_ts_data *ts) { - struct st1232_ts_finger *finger = ts->fingers; struct i2c_client *client = ts->client; u8 start_reg = ts->chip_info->start_reg; struct i2c_msg msg[] = { @@ -72,59 +66,69 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts) } }; int ret; - int i; - u8 *buf; ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); if (ret != ARRAY_SIZE(msg)) return ret < 0 ? ret : -EIO; + return 0; +} + +static int st1232_ts_parse_and_report(struct st1232_ts_data *ts) +{ + struct input_dev *input = ts->input_dev; + struct input_mt_pos pos[ST_TS_MAX_FINGERS]; + u8 z[ST_TS_MAX_FINGERS]; + int slots[ST_TS_MAX_FINGERS]; + int n_contacts = 0; + int i; + for (i = 0; i < ts->chip_info->max_fingers; i++) { - buf = &ts->read_buf[i * 4]; - finger[i].is_valid = buf[0] >> 7; - if (finger[i].is_valid) { - finger[i].x = ((buf[0] & 0x70) << 4) | buf[1]; - finger[i].y = ((buf[0] & 0x07) << 8) | buf[2]; + u8 *buf = &ts->read_buf[i * 4]; + + if (buf[0] & BIT(7)) { + unsigned int x = ((buf[0] & 0x70) << 4) | buf[1]; + unsigned int y = ((buf[0] & 0x07) << 8) | buf[2]; + + touchscreen_set_mt_pos(&pos[n_contacts], + &ts->prop, x, y); /* st1232 includes a z-axis / touch strength */ if (ts->chip_info->have_z) - finger[i].t = ts->read_buf[i + 6]; + z[n_contacts] = ts->read_buf[i + 6]; + + n_contacts++; } } - return 0; + input_mt_assign_slots(input, slots, pos, n_contacts, 0); + for (i = 0; i < n_contacts; i++) { + input_mt_slot(input, slots[i]); + input_mt_report_slot_state(input, MT_TOOL_FINGER, true); + input_report_abs(input, ABS_MT_POSITION_X, pos[i].x); + input_report_abs(input, ABS_MT_POSITION_Y, pos[i].y); + if (ts->chip_info->have_z) + input_report_abs(input, ABS_MT_TOUCH_MAJOR, z[i]); + } + + input_mt_sync_frame(input); + input_sync(input); + + return n_contacts; } static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id) { struct st1232_ts_data *ts = dev_id; - struct st1232_ts_finger *finger = ts->fingers; - struct input_dev *input_dev = ts->input_dev; - int count = 0; - int i, ret; - - ret = st1232_ts_read_data(ts); - if (ret < 0) - goto end; - - /* multi touch protocol */ - for (i = 0; i < ts->chip_info->max_fingers; i++) { - if (!finger[i].is_valid) - continue; + int count; + int error; - if (ts->chip_info->have_z) - input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, - finger[i].t); + error = st1232_ts_read_data(ts); + if (error) + goto out; - touchscreen_report_pos(input_dev, &ts->prop, - finger[i].x, finger[i].y, true); - input_mt_sync(input_dev); - count++; - } - - /* SYN_MT_REPORT only if no contact */ + count = st1232_ts_parse_and_report(ts); if (!count) { - input_mt_sync(input_dev); if (ts->low_latency_req.dev) { dev_pm_qos_remove_request(&ts->low_latency_req); ts->low_latency_req.dev = NULL; @@ -136,10 +140,7 @@ static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id) DEV_PM_QOS_RESUME_LATENCY, 100); } - /* SYN_REPORT */ - input_sync(input_dev); - -end: +out: return IRQ_HANDLED; } @@ -198,9 +199,7 @@ static int st1232_ts_probe(struct i2c_client *client, return -EINVAL; } - ts = devm_kzalloc(&client->dev, - struct_size(ts, fingers, match->max_fingers), - GFP_KERNEL); + ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); if (!ts) return -ENOMEM; @@ -240,11 +239,6 @@ static int st1232_ts_probe(struct i2c_client *client, input_dev->name = "st1232-touchscreen"; input_dev->id.bustype = BUS_I2C; - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - __set_bit(EV_SYN, input_dev->evbit); - __set_bit(EV_KEY, input_dev->evbit); - __set_bit(EV_ABS, input_dev->evbit); - if (ts->chip_info->have_z) input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, ts->chip_info->max_area, 0, 0); @@ -256,6 +250,14 @@ static int st1232_ts_probe(struct i2c_client *client, touchscreen_parse_properties(input_dev, true, &ts->prop); + error = input_mt_init_slots(input_dev, ts->chip_info->max_fingers, + INPUT_MT_DIRECT | INPUT_MT_TRACK | + INPUT_MT_DROP_UNUSED); + if (error) { + dev_err(&client->dev, "failed to initialize MT slots\n"); + return error; + } + error = devm_request_threaded_irq(&client->dev, client->irq, NULL, st1232_ts_irq_handler, IRQF_ONESHOT, -- cgit v1.2.3-59-g8ed1b From 7448bfec6bf5e3e4a5abdd21b125a95c29a5952f Mon Sep 17 00:00:00 2001 From: Mylène Josserand Date: Mon, 28 Oct 2019 20:56:23 -0700 Subject: Input: edt-ft5x06 - add support for regulator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the support for enabling optional regulator that may be used as VCC source. Signed-off-by: Mylène Josserand Signed-off-by: Ondrej Jirman Reviewed-by: Rob Herring # bindings Link: https://lore.kernel.org/r/20191029005806.3577376-2-megous@megous.com Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/edt-ft5x06.txt | 1 + drivers/input/touchscreen/edt-ft5x06.c | 30 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'drivers/input/touchscreen') diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt index 870b8c5cce9b..0f6950073d6f 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt @@ -30,6 +30,7 @@ Required properties: Optional properties: - reset-gpios: GPIO specification for the RESET input - wake-gpios: GPIO specification for the WAKE input + - vcc-supply: Regulator that supplies the touchscreen - pinctrl-names: should be "default" - pinctrl-0: a phandle pointing to the pin settings for the diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 5525f1fb1526..d61731c0037d 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -28,6 +28,7 @@ #include #include #include +#include #define WORK_REGISTER_THRESHOLD 0x00 #define WORK_REGISTER_REPORT_RATE 0x08 @@ -88,6 +89,7 @@ struct edt_ft5x06_ts_data { struct touchscreen_properties prop; u16 num_x; u16 num_y; + struct regulator *vcc; struct gpio_desc *reset_gpio; struct gpio_desc *wake_gpio; @@ -1036,6 +1038,13 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata) } } +static void edt_ft5x06_disable_regulator(void *arg) +{ + struct edt_ft5x06_ts_data *data = arg; + + regulator_disable(data->vcc); +} + static int edt_ft5x06_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1064,6 +1073,27 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, tsdata->max_support_points = chip_data->max_support_points; + tsdata->vcc = devm_regulator_get(&client->dev, "vcc"); + if (IS_ERR(tsdata->vcc)) { + error = PTR_ERR(tsdata->vcc); + if (error != -EPROBE_DEFER) + dev_err(&client->dev, + "failed to request regulator: %d\n", error); + return error; + } + + error = regulator_enable(tsdata->vcc); + if (error < 0) { + dev_err(&client->dev, "failed to enable vcc: %d\n", error); + return error; + } + + error = devm_add_action_or_reset(&client->dev, + edt_ft5x06_disable_regulator, + tsdata); + if (error) + return error; + tsdata->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(tsdata->reset_gpio)) { -- cgit v1.2.3-59-g8ed1b From bd88ce25335d23a9967e6d3d1efdc320dbd0a3a4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 29 Oct 2019 16:41:57 -0700 Subject: Input: raspberrypi-ts - switch to using polled mode of input devices We have added polled mode to the normal input devices with the intent of retiring input_polled_dev. This converts raspberrypi-ts driver to use the polling mode of standard input devices and removes dependency on INPUT_POLLDEV. Link: https://lore.kernel.org/r/20191017204217.106453-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 1 - drivers/input/touchscreen/raspberrypi-ts.c | 38 ++++++++++++++++-------------- 2 files changed, 20 insertions(+), 19 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 46ad9090493b..00e7a9f218bc 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -700,7 +700,6 @@ config TOUCHSCREEN_EDT_FT5X06 config TOUCHSCREEN_RASPBERRYPI_FW tristate "Raspberry Pi's firmware base touch screen support" depends on RASPBERRYPI_FIRMWARE || (RASPBERRYPI_FIRMWARE=n && COMPILE_TEST) - select INPUT_POLLDEV help Say Y here if you have the official Raspberry Pi 7 inch screen on your system. diff --git a/drivers/input/touchscreen/raspberrypi-ts.c b/drivers/input/touchscreen/raspberrypi-ts.c index 69881265d121..0e2e08f3f433 100644 --- a/drivers/input/touchscreen/raspberrypi-ts.c +++ b/drivers/input/touchscreen/raspberrypi-ts.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -34,7 +33,7 @@ struct rpi_ts { struct platform_device *pdev; - struct input_polled_dev *poll_dev; + struct input_dev *input; struct touchscreen_properties prop; void __iomem *fw_regs_va; @@ -57,10 +56,9 @@ struct rpi_ts_regs { } point[RPI_TS_MAX_SUPPORTED_POINTS]; }; -static void rpi_ts_poll(struct input_polled_dev *dev) +static void rpi_ts_poll(struct input_dev *input) { - struct input_dev *input = dev->input; - struct rpi_ts *ts = dev->private; + struct rpi_ts *ts = input_get_drvdata(input); struct rpi_ts_regs regs; int modified_ids = 0; long released_ids; @@ -123,10 +121,9 @@ static int rpi_ts_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; - struct input_polled_dev *poll_dev; + struct input_dev *input; struct device_node *fw_node; struct rpi_firmware *fw; - struct input_dev *input; struct rpi_ts *ts; u32 touchbuf; int error; @@ -160,7 +157,6 @@ static int rpi_ts_probe(struct platform_device *pdev) return error; } - touchbuf = (u32)ts->fw_regs_phys; error = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF, &touchbuf, sizeof(touchbuf)); @@ -170,19 +166,17 @@ static int rpi_ts_probe(struct platform_device *pdev) 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; } - ts->poll_dev = poll_dev; - input = poll_dev->input; + + ts->input = input; + input_set_drvdata(input, ts); input->name = "raspberrypi-ts"; input->id.bustype = BUS_HOST; - poll_dev->poll_interval = RPI_TS_POLL_INTERVAL; - poll_dev->poll = rpi_ts_poll; - poll_dev->private = ts; input_set_abs_params(input, ABS_MT_POSITION_X, 0, RPI_TS_DEFAULT_WIDTH, 0, 0); @@ -197,7 +191,15 @@ static int rpi_ts_probe(struct platform_device *pdev) return error; } - error = input_register_polled_device(poll_dev); + error = input_setup_polling(input, rpi_ts_poll); + if (error) { + dev_err(dev, "could not set up polling mode, %d\n", error); + return error; + } + + input_set_poll_interval(input, RPI_TS_POLL_INTERVAL); + + error = input_register_device(input); if (error) { dev_err(dev, "could not register input device, %d\n", error); return error; @@ -214,10 +216,10 @@ MODULE_DEVICE_TABLE(of, rpi_ts_match); static struct platform_driver rpi_ts_driver = { .driver = { - .name = "raspberrypi-ts", + .name = "raspberrypi-ts", .of_match_table = rpi_ts_match, }, - .probe = rpi_ts_probe, + .probe = rpi_ts_probe, }; module_platform_driver(rpi_ts_driver); -- cgit v1.2.3-59-g8ed1b From 08b936012964dd9261c600e998e47321c92ca83f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 29 Oct 2019 16:42:30 -0700 Subject: Input: sur40 - switch to using polled mode of input devices We have added polled mode to the normal input devices with the intent of retiring input_polled_dev. This converts sur40 driver to use the polling mode of standard input devices and removes dependency on INPUT_POLLDEV. Link: https://lore.kernel.org/r/20191017204217.106453-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 1 - drivers/input/touchscreen/sur40.c | 92 ++++++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 40 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 00e7a9f218bc..df9cb92166c3 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1209,7 +1209,6 @@ config TOUCHSCREEN_SUR40 tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen" depends on USB && MEDIA_USB_SUPPORT && HAS_DMA depends on VIDEO_V4L2 - select INPUT_POLLDEV select VIDEOBUF2_DMA_SG help Say Y here if you want support for the Samsung SUR40 touchscreen diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c index 3fd3e862269b..1dd47dda71cd 100644 --- a/drivers/input/touchscreen/sur40.c +++ b/drivers/input/touchscreen/sur40.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -206,7 +206,7 @@ struct sur40_state { struct usb_device *usbdev; struct device *dev; - struct input_polled_dev *input; + struct input_dev *input; struct v4l2_device v4l2; struct video_device vdev; @@ -370,6 +370,10 @@ static int sur40_init(struct sur40_state *dev) goto error; result = sur40_command(dev, SUR40_GET_VERSION, 0x03, buffer, 12); + if (result < 0) + goto error; + + result = 0; /* * Discard the result buffer - no known data inside except @@ -381,22 +385,22 @@ error: } /* - * Callback routines from input_polled_dev + * Callback routines from input_dev */ /* Enable the device, polling will now start. */ -static void sur40_open(struct input_polled_dev *polldev) +static int sur40_open(struct input_dev *input) { - struct sur40_state *sur40 = polldev->private; + struct sur40_state *sur40 = input_get_drvdata(input); dev_dbg(sur40->dev, "open\n"); - sur40_init(sur40); + return sur40_init(sur40); } /* Disable device, polling has stopped. */ -static void sur40_close(struct input_polled_dev *polldev) +static void sur40_close(struct input_dev *input) { - struct sur40_state *sur40 = polldev->private; + struct sur40_state *sur40 = input_get_drvdata(input); dev_dbg(sur40->dev, "close\n"); /* @@ -448,10 +452,9 @@ static void sur40_report_blob(struct sur40_blob *blob, struct input_dev *input) } /* core function: poll for new input data */ -static void sur40_poll(struct input_polled_dev *polldev) +static void sur40_poll(struct input_dev *input) { - struct sur40_state *sur40 = polldev->private; - struct input_dev *input = polldev->input; + struct sur40_state *sur40 = input_get_drvdata(input); int result, bulk_read, need_blobs, packet_blobs, i; u32 uninitialized_var(packet_id); @@ -613,10 +616,9 @@ err_poll: } /* Initialize input device parameters. */ -static void sur40_input_setup(struct input_dev *input_dev) +static int sur40_input_setup_events(struct input_dev *input_dev) { - __set_bit(EV_KEY, input_dev->evbit); - __set_bit(EV_ABS, input_dev->evbit); + int error; input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, SENSOR_RES_X, 0, 0); @@ -637,8 +639,14 @@ static void sur40_input_setup(struct input_dev *input_dev) input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); - input_mt_init_slots(input_dev, MAX_CONTACTS, - INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); + error = input_mt_init_slots(input_dev, MAX_CONTACTS, + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); + if (error) { + dev_err(input_dev->dev.parent, "failed to set up slots\n"); + return error; + } + + return 0; } /* Check candidate USB interface. */ @@ -649,7 +657,7 @@ static int sur40_probe(struct usb_interface *interface, struct sur40_state *sur40; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; - struct input_polled_dev *poll_dev; + struct input_dev *input; int error; /* Check if we really have the right interface. */ @@ -670,8 +678,8 @@ static int sur40_probe(struct usb_interface *interface, if (!sur40) return -ENOMEM; - poll_dev = input_allocate_polled_device(); - if (!poll_dev) { + input = input_allocate_device(); + if (!input) { error = -ENOMEM; goto err_free_dev; } @@ -681,26 +689,33 @@ static int sur40_probe(struct usb_interface *interface, spin_lock_init(&sur40->qlock); mutex_init(&sur40->lock); - /* Set up polled input device control structure */ - poll_dev->private = sur40; - poll_dev->poll_interval = POLL_INTERVAL; - poll_dev->open = sur40_open; - poll_dev->poll = sur40_poll; - poll_dev->close = sur40_close; - /* Set up regular input device structure */ - sur40_input_setup(poll_dev->input); - - poll_dev->input->name = DRIVER_LONG; - usb_to_input_id(usbdev, &poll_dev->input->id); + input->name = DRIVER_LONG; + usb_to_input_id(usbdev, &input->id); usb_make_path(usbdev, sur40->phys, sizeof(sur40->phys)); strlcat(sur40->phys, "/input0", sizeof(sur40->phys)); - poll_dev->input->phys = sur40->phys; - poll_dev->input->dev.parent = &interface->dev; + input->phys = sur40->phys; + input->dev.parent = &interface->dev; + + input->open = sur40_open; + input->close = sur40_close; + + error = sur40_input_setup_events(input); + if (error) + goto err_free_input; + + input_set_drvdata(input, sur40); + error = input_setup_polling(input, sur40_poll); + if (error) { + dev_err(&interface->dev, "failed to set up polling"); + goto err_free_input; + } + + input_set_poll_interval(input, POLL_INTERVAL); sur40->usbdev = usbdev; sur40->dev = &interface->dev; - sur40->input = poll_dev; + sur40->input = input; /* use the bulk-in endpoint tested above */ sur40->bulk_in_size = usb_endpoint_maxp(endpoint); @@ -709,11 +724,11 @@ static int sur40_probe(struct usb_interface *interface, if (!sur40->bulk_in_buffer) { dev_err(&interface->dev, "Unable to allocate input buffer."); error = -ENOMEM; - goto err_free_polldev; + goto err_free_input; } /* register the polled input device */ - error = input_register_polled_device(poll_dev); + error = input_register_device(input); if (error) { dev_err(&interface->dev, "Unable to register polled input device."); @@ -796,8 +811,8 @@ err_unreg_v4l2: v4l2_device_unregister(&sur40->v4l2); err_free_buffer: kfree(sur40->bulk_in_buffer); -err_free_polldev: - input_free_polled_device(sur40->input); +err_free_input: + input_free_device(input); err_free_dev: kfree(sur40); @@ -813,8 +828,7 @@ static void sur40_disconnect(struct usb_interface *interface) video_unregister_device(&sur40->vdev); v4l2_device_unregister(&sur40->v4l2); - input_unregister_polled_device(sur40->input); - input_free_polled_device(sur40->input); + input_unregister_device(sur40->input); kfree(sur40->bulk_in_buffer); kfree(sur40); -- cgit v1.2.3-59-g8ed1b From 9b587815ddd8f092c5a87f764e30b39fe8748c4d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 29 Oct 2019 16:50:20 -0700 Subject: Input: ts4800-ts - switch to using polled mode of input devices We have added polled mode to the normal input devices with the intent of retiring input_polled_dev. This converts ts4800-ts driver to use the polling mode of standard input devices and removes dependency on INPUT_POLLDEV. Link: https://lore.kernel.org/r/20191017204217.106453-4-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 1 - drivers/input/touchscreen/ts4800-ts.c | 68 +++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 31 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index df9cb92166c3..2c00232b2506 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1037,7 +1037,6 @@ config TOUCHSCREEN_TS4800 depends on HAS_IOMEM && OF depends on SOC_IMX51 || COMPILE_TEST select MFD_SYSCON - select INPUT_POLLDEV help Say Y here if you have a touchscreen on a TS-4800 board. diff --git a/drivers/input/touchscreen/ts4800-ts.c b/drivers/input/touchscreen/ts4800-ts.c index 5b4f5362c67b..6cf66aadc10e 100644 --- a/drivers/input/touchscreen/ts4800-ts.c +++ b/drivers/input/touchscreen/ts4800-ts.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -33,7 +32,7 @@ #define Y_OFFSET 0x2 struct ts4800_ts { - struct input_polled_dev *poll_dev; + struct input_dev *input; struct device *dev; char phys[32]; @@ -46,22 +45,26 @@ struct ts4800_ts { int debounce; }; -static void ts4800_ts_open(struct input_polled_dev *dev) +static int ts4800_ts_open(struct input_dev *input_dev) { - struct ts4800_ts *ts = dev->private; - int ret; + struct ts4800_ts *ts = input_get_drvdata(input_dev); + int error; ts->pendown = false; ts->debounce = DEBOUNCE_COUNT; - ret = regmap_update_bits(ts->regmap, ts->reg, ts->bit, ts->bit); - if (ret) - dev_warn(ts->dev, "Failed to enable touchscreen\n"); + error = regmap_update_bits(ts->regmap, ts->reg, ts->bit, ts->bit); + if (error) { + dev_warn(ts->dev, "Failed to enable touchscreen: %d\n", error); + return error; + } + + return 0; } -static void ts4800_ts_close(struct input_polled_dev *dev) +static void ts4800_ts_close(struct input_dev *input_dev) { - struct ts4800_ts *ts = dev->private; + struct ts4800_ts *ts = input_get_drvdata(input_dev); int ret; ret = regmap_update_bits(ts->regmap, ts->reg, ts->bit, 0); @@ -70,10 +73,9 @@ static void ts4800_ts_close(struct input_polled_dev *dev) } -static void ts4800_ts_poll(struct input_polled_dev *dev) +static void ts4800_ts_poll(struct input_dev *input_dev) { - struct input_dev *input_dev = dev->input; - struct ts4800_ts *ts = dev->private; + struct ts4800_ts *ts = input_get_drvdata(input_dev); u16 last_x = readw(ts->base + X_OFFSET); u16 last_y = readw(ts->base + Y_OFFSET); bool pendown = last_x & PENDOWN_MASK; @@ -146,7 +148,7 @@ static int ts4800_parse_dt(struct platform_device *pdev, static int ts4800_ts_probe(struct platform_device *pdev) { - struct input_polled_dev *poll_dev; + struct input_dev *input_dev; struct ts4800_ts *ts; int error; @@ -162,32 +164,38 @@ static int ts4800_ts_probe(struct platform_device *pdev) if (IS_ERR(ts->base)) return PTR_ERR(ts->base); - poll_dev = devm_input_allocate_polled_device(&pdev->dev); - if (!poll_dev) + input_dev = devm_input_allocate_device(&pdev->dev); + if (!input_dev) return -ENOMEM; snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&pdev->dev)); - ts->poll_dev = poll_dev; + ts->input = input_dev; ts->dev = &pdev->dev; - poll_dev->private = ts; - poll_dev->poll_interval = POLL_INTERVAL; - poll_dev->open = ts4800_ts_open; - poll_dev->close = ts4800_ts_close; - poll_dev->poll = ts4800_ts_poll; + input_set_drvdata(input_dev, ts); + + input_dev->name = "TS-4800 Touchscreen"; + input_dev->phys = ts->phys; + + input_dev->open = ts4800_ts_open; + input_dev->close = ts4800_ts_close; + + input_set_capability(input_dev, EV_KEY, BTN_TOUCH); + input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); - poll_dev->input->name = "TS-4800 Touchscreen"; - poll_dev->input->phys = ts->phys; + error = input_setup_polling(input_dev, ts4800_ts_poll); + if (error) { + dev_err(&pdev->dev, "Unable to set up polling: %d\n", error); + return error; + } - input_set_capability(poll_dev->input, EV_KEY, BTN_TOUCH); - input_set_abs_params(poll_dev->input, ABS_X, 0, MAX_12BIT, 0, 0); - input_set_abs_params(poll_dev->input, ABS_Y, 0, MAX_12BIT, 0, 0); + input_set_poll_interval(input_dev, POLL_INTERVAL); - error = input_register_polled_device(poll_dev); + error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, - "Unabled to register polled input device (%d)\n", - error); + "Unable to register input device: %d\n", error); return error; } -- cgit v1.2.3-59-g8ed1b From 7cca5a342ecd78ee163eaf352dc3995291b55406 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 29 Oct 2019 16:50:47 -0700 Subject: Input: tsc6507x-ts - switch to using polled mode of input devices We have added polled mode to the normal input devices with the intent of retiring input_polled_dev. This converts tsc6507x-ts driver to use the polling mode of standard input devices and removes dependency on INPUT_POLLDEV. Link: https://lore.kernel.org/r/20191017204217.106453-5-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 1 - drivers/input/touchscreen/tps6507x-ts.c | 36 ++++++++++++++++----------------- 2 files changed, 17 insertions(+), 20 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 2c00232b2506..40bfc551ce30 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1243,7 +1243,6 @@ config TOUCHSCREEN_SX8654 config TOUCHSCREEN_TPS6507X tristate "TPS6507x based touchscreens" depends on I2C - select INPUT_POLLDEV help Say Y here if you have a TPS6507x based touchscreen controller. diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c index 75170a7439b1..357a3108f2e5 100644 --- a/drivers/input/touchscreen/tps6507x-ts.c +++ b/drivers/input/touchscreen/tps6507x-ts.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -40,7 +39,7 @@ struct ts_event { struct tps6507x_ts { struct device *dev; - struct input_polled_dev *poll_dev; + struct input_dev *input; struct tps6507x_dev *mfd; char phys[32]; struct ts_event tc; @@ -148,10 +147,9 @@ static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc) return ret; } -static void tps6507x_ts_poll(struct input_polled_dev *poll_dev) +static void tps6507x_ts_poll(struct input_dev *input_dev) { - struct tps6507x_ts *tsc = poll_dev->private; - struct input_dev *input_dev = poll_dev->input; + struct tps6507x_ts *tsc = input_get_drvdata(input_dev); bool pendown; s32 ret; @@ -205,7 +203,6 @@ static int tps6507x_ts_probe(struct platform_device *pdev) const struct tps6507x_board *tps_board; const struct touchscreen_init_data *init_data; struct tps6507x_ts *tsc; - struct input_polled_dev *poll_dev; struct input_dev *input_dev; int error; @@ -240,23 +237,16 @@ static int tps6507x_ts_probe(struct platform_device *pdev) snprintf(tsc->phys, sizeof(tsc->phys), "%s/input0", dev_name(tsc->dev)); - poll_dev = devm_input_allocate_polled_device(&pdev->dev); - if (!poll_dev) { + input_dev = devm_input_allocate_device(&pdev->dev); + if (!input_dev) { dev_err(tsc->dev, "Failed to allocate polled input device.\n"); return -ENOMEM; } - tsc->poll_dev = poll_dev; - - poll_dev->private = tsc; - poll_dev->poll = tps6507x_ts_poll; - poll_dev->poll_interval = init_data ? - init_data->poll_period : TSC_DEFAULT_POLL_PERIOD; - - input_dev = poll_dev->input; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + tsc->input = input_dev; + input_set_drvdata(input_dev, tsc); + input_set_capability(input_dev, EV_KEY, BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, 0, MAX_10BIT, 0, 0); input_set_abs_params(input_dev, ABS_Y, 0, MAX_10BIT, 0, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0); @@ -275,7 +265,15 @@ static int tps6507x_ts_probe(struct platform_device *pdev) if (error) return error; - error = input_register_polled_device(poll_dev); + error = input_setup_polling(input_dev, tps6507x_ts_poll); + if (error) + return error; + + input_set_poll_interval(input_dev, + init_data ? init_data->poll_period : + TSC_DEFAULT_POLL_PERIOD); + + error = input_register_device(input_dev); if (error) return error; -- cgit v1.2.3-59-g8ed1b From ee85fbe14fd62a30df76f0a8dcee590d9c759703 Mon Sep 17 00:00:00 2001 From: Flavio Suligoi Date: Mon, 11 Nov 2019 10:20:03 -0800 Subject: Input: ar1021 - fix typo in preprocessor macro name Fix spelling mistake. Signed-off-by: Flavio Suligoi Link: https://lore.kernel.org/r/1573211947-660-1-git-send-email-f.suligoi@asem.it Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ar1021_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/ar1021_i2c.c b/drivers/input/touchscreen/ar1021_i2c.c index 28644f372bd8..c0d5c2413356 100644 --- a/drivers/input/touchscreen/ar1021_i2c.c +++ b/drivers/input/touchscreen/ar1021_i2c.c @@ -13,7 +13,7 @@ #include #include -#define AR1021_TOCUH_PKG_SIZE 5 +#define AR1021_TOUCH_PKG_SIZE 5 #define AR1021_MAX_X 4095 #define AR1021_MAX_Y 4095 @@ -25,7 +25,7 @@ struct ar1021_i2c { struct i2c_client *client; struct input_dev *input; - u8 data[AR1021_TOCUH_PKG_SIZE]; + u8 data[AR1021_TOUCH_PKG_SIZE]; }; static irqreturn_t ar1021_i2c_irq(int irq, void *dev_id) -- cgit v1.2.3-59-g8ed1b From eb91ecc9fc43fbefdfdfe1ea8b3f136ccbc02f66 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 11 Aug 2019 09:16:37 -0700 Subject: Input: ili210x - add ILI2117 support Add support for ILI2117 touch controller. This controller is similar to the ILI210x and ILI251x, except for the following differences: - Reading out of touch data must happen at most 300 mS after the interrupt line was asserted. No command must be sent, the data are returned upon pure I2C read of 43 bytes long. - Supports 10 simultaneous touch inputs. - Touch data format is slightly different. Signed-off-by: Marek Vasut Reviewed-by: Rob Herring # for DT binding Tested-by: Adam Ford #imx6q-logicpd Tested-by: Sven Van Asbroeck # ILI2118A variant Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/ilitek,ili2xxx.txt | 3 +- drivers/input/touchscreen/ili210x.c | 46 +++++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt b/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt index b2a76301e632..dc194b2c151a 100644 --- a/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt +++ b/Documentation/devicetree/bindings/input/ilitek,ili2xxx.txt @@ -1,8 +1,9 @@ -Ilitek ILI210x/ILI251x touchscreen controller +Ilitek ILI210x/ILI2117/ILI251x touchscreen controller Required properties: - compatible: ilitek,ili210x for ILI210x + ilitek,ili2117 for ILI2117 ilitek,ili251x for ILI251x - reg: The I2C address of the device diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index e9006407c9bc..36491d8ff990 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -13,6 +13,7 @@ #include #define ILI210X_TOUCHES 2 +#define ILI211X_TOUCHES 10 #define ILI251X_TOUCHES 10 #define DEFAULT_POLL_PERIOD 20 @@ -30,6 +31,7 @@ struct firmware_version { enum ili2xxx_model { MODEL_ILI210X, + MODEL_ILI211X, MODEL_ILI251X, }; @@ -118,6 +120,27 @@ static bool ili210x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, return true; } +static bool ili211x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, + unsigned int finger, + unsigned int *x, unsigned int *y) +{ + u32 data; + + if (finger >= ILI211X_TOUCHES) + return false; + + data = get_unaligned_be32(touchdata + 1 + (finger * 4) + 0); + if (data == 0xffffffff) /* Finger up */ + return false; + + *x = ((touchdata[1 + (finger * 4) + 0] & 0xf0) << 4) | + touchdata[1 + (finger * 4) + 1]; + *y = ((touchdata[1 + (finger * 4) + 0] & 0x0f) << 8) | + touchdata[1 + (finger * 4) + 2]; + + return true; +} + static bool ili251x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, unsigned int finger, unsigned int *x, unsigned int *y) @@ -146,6 +169,9 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata) if (priv->model == MODEL_ILI210X) { touch = ili210x_touchdata_to_coords(priv, touchdata, i, &x, &y); + } else if (priv->model == MODEL_ILI211X) { + touch = ili211x_touchdata_to_coords(priv, touchdata, + i, &x, &y); } else if (priv->model == MODEL_ILI251X) { touch = ili251x_touchdata_to_coords(priv, touchdata, i, &x, &y); @@ -176,12 +202,26 @@ static void ili210x_work(struct work_struct *work) dwork.work); struct i2c_client *client = priv->client; u8 touchdata[64] = { 0 }; + s16 sum = 0; bool touch; - int error = -EINVAL; + int i, error = -EINVAL; if (priv->model == MODEL_ILI210X) { error = ili210x_read_reg(client, REG_TOUCHDATA, touchdata, sizeof(touchdata)); + } else if (priv->model == MODEL_ILI211X) { + error = ili210x_read(client, touchdata, 43); + if (!error) { + /* This chip uses custom checksum at the end of data */ + for (i = 0; i <= 41; i++) + sum = (sum + touchdata[i]) & 0xff; + if ((-sum & 0xff) != touchdata[42]) { + dev_err(&client->dev, + "CRC error (crc=0x%02x expected=0x%02x)\n", + sum, touchdata[42]); + return; + } + } } else if (priv->model == MODEL_ILI251X) { error = ili210x_read_reg(client, REG_TOUCHDATA, touchdata, 31); @@ -311,6 +351,8 @@ static int ili210x_i2c_probe(struct i2c_client *client, priv->model = model; if (model == MODEL_ILI210X) priv->max_touches = ILI210X_TOUCHES; + if (model == MODEL_ILI211X) + priv->max_touches = ILI211X_TOUCHES; if (model == MODEL_ILI251X) priv->max_touches = ILI251X_TOUCHES; @@ -395,6 +437,7 @@ static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm, static const struct i2c_device_id ili210x_i2c_id[] = { { "ili210x", MODEL_ILI210X }, + { "ili2117", MODEL_ILI211X }, { "ili251x", MODEL_ILI251X }, { } }; @@ -402,6 +445,7 @@ MODULE_DEVICE_TABLE(i2c, ili210x_i2c_id); static const struct of_device_id ili210x_dt_ids[] = { { .compatible = "ilitek,ili210x", .data = (void *)MODEL_ILI210X }, + { .compatible = "ilitek,ili2117", .data = (void *)MODEL_ILI211X }, { .compatible = "ilitek,ili251x", .data = (void *)MODEL_ILI251X }, { }, }; -- cgit v1.2.3-59-g8ed1b From 71f8e38ae635d92e553eec8d7359cb88b539b306 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 10 Aug 2019 23:19:24 -0700 Subject: Input: ili210x - switch to using threaded IRQ Let's switch the driver to using threaded IRQ so that we do not need to manage the interrupt and work separately, and we do not acknowledge interrupt until we finished handling it completely. Tested-by: Adam Ford #imx6q-logicpd Tested-by: Sven Van Asbroeck # ILI2118A variant Tested-by: Marek Vasut # ILI2117 Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 117 +++++++++++++++++------------------- 1 file changed, 56 insertions(+), 61 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 36491d8ff990..6985ca8b6565 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -1,21 +1,21 @@ // SPDX-License-Identifier: GPL-2.0-only -#include +#include +#include #include -#include -#include #include #include #include -#include -#include -#include +#include +#include #include +#include #include #define ILI210X_TOUCHES 2 #define ILI211X_TOUCHES 10 #define ILI251X_TOUCHES 10 -#define DEFAULT_POLL_PERIOD 20 + +#define ILI2XXX_POLL_PERIOD 20 /* Touchscreen commands */ #define REG_TOUCHDATA 0x10 @@ -38,12 +38,11 @@ enum ili2xxx_model { struct ili210x { struct i2c_client *client; struct input_dev *input; - unsigned int poll_period; - struct delayed_work dwork; struct gpio_desc *reset_gpio; struct touchscreen_properties prop; enum ili2xxx_model model; unsigned int max_touches; + bool stop; }; static int ili210x_read_reg(struct i2c_client *client, u8 reg, void *buf, @@ -196,57 +195,54 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata) return contact; } -static void ili210x_work(struct work_struct *work) +static irqreturn_t ili210x_irq(int irq, void *irq_data) { - struct ili210x *priv = container_of(work, struct ili210x, - dwork.work); + struct ili210x *priv = irq_data; struct i2c_client *client = priv->client; u8 touchdata[64] = { 0 }; s16 sum = 0; bool touch; - int i, error = -EINVAL; - - if (priv->model == MODEL_ILI210X) { - error = ili210x_read_reg(client, REG_TOUCHDATA, - touchdata, sizeof(touchdata)); - } else if (priv->model == MODEL_ILI211X) { - error = ili210x_read(client, touchdata, 43); - if (!error) { - /* This chip uses custom checksum at the end of data */ - for (i = 0; i <= 41; i++) - sum = (sum + touchdata[i]) & 0xff; - if ((-sum & 0xff) != touchdata[42]) { - dev_err(&client->dev, - "CRC error (crc=0x%02x expected=0x%02x)\n", - sum, touchdata[42]); - return; + int i; + int error; + + do { + if (priv->model == MODEL_ILI210X) { + error = ili210x_read_reg(client, REG_TOUCHDATA, + touchdata, sizeof(touchdata)); + } else if (priv->model == MODEL_ILI211X) { + error = ili210x_read(client, touchdata, 43); + if (!error) { + /* + * This chip uses custom checksum at the end + * of data. + */ + for (i = 0; i <= 41; i++) + sum = (sum + touchdata[i]) & 0xff; + if ((-sum & 0xff) != touchdata[42]) { + dev_err(&client->dev, + "CRC error (crc=0x%02x expected=0x%02x)\n", + sum, touchdata[42]); + break; + } } + } else if (priv->model == MODEL_ILI251X) { + error = ili210x_read_reg(client, REG_TOUCHDATA, + touchdata, 31); + if (!error && touchdata[0] == 2) + error = ili210x_read(client, + &touchdata[31], 20); } - } else if (priv->model == MODEL_ILI251X) { - error = ili210x_read_reg(client, REG_TOUCHDATA, - touchdata, 31); - if (!error && touchdata[0] == 2) - error = ili210x_read(client, &touchdata[31], 20); - } - - if (error) { - dev_err(&client->dev, - "Unable to get touchdata, err = %d\n", error); - return; - } - touch = ili210x_report_events(priv, touchdata); - - if (touch) - schedule_delayed_work(&priv->dwork, - msecs_to_jiffies(priv->poll_period)); -} - -static irqreturn_t ili210x_irq(int irq, void *irq_data) -{ - struct ili210x *priv = irq_data; + if (error) { + dev_err(&client->dev, + "Unable to get touchdata, err = %d\n", error); + break; + } - schedule_delayed_work(&priv->dwork, 0); + touch = ili210x_report_events(priv, touchdata); + if (touch) + msleep(ILI2XXX_POLL_PERIOD); + } while (!priv->stop && touch); return IRQ_HANDLED; } @@ -293,11 +289,12 @@ static void ili210x_power_down(void *data) gpiod_set_value_cansleep(reset_gpio, 1); } -static void ili210x_cancel_work(void *data) +static void ili210x_stop(void *data) { struct ili210x *priv = data; - cancel_delayed_work_sync(&priv->dwork); + /* Tell ISR to quit even if there is a contact. */ + priv->stop = true; } static int ili210x_i2c_probe(struct i2c_client *client, @@ -345,8 +342,6 @@ static int ili210x_i2c_probe(struct i2c_client *client, priv->client = client; priv->input = input; - priv->poll_period = DEFAULT_POLL_PERIOD; - INIT_DELAYED_WORK(&priv->dwork, ili210x_work); priv->reset_gpio = reset_gpio; priv->model = model; if (model == MODEL_ILI210X) @@ -378,18 +373,18 @@ static int ili210x_i2c_probe(struct i2c_client *client, touchscreen_parse_properties(input, true, &priv->prop); input_mt_init_slots(input, priv->max_touches, INPUT_MT_DIRECT); - error = devm_add_action(dev, ili210x_cancel_work, priv); - if (error) - return error; - - error = devm_request_irq(dev, client->irq, ili210x_irq, 0, - client->name, priv); + error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq, + IRQF_ONESHOT, client->name, priv); if (error) { dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n", error); return error; } + error = devm_add_action_or_reset(dev, ili210x_stop, priv); + if (error) + return error; + error = devm_device_add_group(dev, &ili210x_attr_group); if (error) { dev_err(dev, "Unable to create sysfs attributes, err: %d\n", -- cgit v1.2.3-59-g8ed1b From 43f06a4c639de8ee89fc348a9a3ecd70320a04dd Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 4 Nov 2019 10:39:41 -0800 Subject: Input: ili210x - handle errors from input_mt_init_slots() input_mt_init_slots() may fail and we need to handle such failures. Tested-by: Adam Ford #imx6q-logicpd Tested-by: Sven Van Asbroeck # ILI2118A variant Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 6985ca8b6565..7dee37901b7b 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -371,7 +371,12 @@ static int ili210x_i2c_probe(struct i2c_client *client, input_set_abs_params(input, ABS_MT_POSITION_X, 0, 0xffff, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 0xffff, 0, 0); touchscreen_parse_properties(input, true, &priv->prop); - input_mt_init_slots(input, priv->max_touches, INPUT_MT_DIRECT); + + error = input_mt_init_slots(input, priv->max_touches, INPUT_MT_DIRECT); + if (error) { + dev_err(dev, "Unable to set up slots, err: %d\n", error); + return error; + } error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq, IRQF_ONESHOT, client->name, priv); -- cgit v1.2.3-59-g8ed1b From efda86a49553bc7e44b3f7254208577bff2da932 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 4 Nov 2019 15:20:47 -0800 Subject: Input: ili210x - do not set parent device explicitly We are using devm_input_allocate_device() that set's up the parent for us, no need to do it ourselves. Tested-by: Adam Ford #imx6q-logicpd Tested-by: Sven Van Asbroeck # ILI2118A variant Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 7dee37901b7b..28e2dd748c5a 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -365,7 +365,6 @@ static int ili210x_i2c_probe(struct i2c_client *client, /* Setup input device */ input->name = "ILI210x Touchscreen"; input->id.bustype = BUS_I2C; - input->dev.parent = dev; /* Multi touch */ input_set_abs_params(input, ABS_MT_POSITION_X, 0, 0xffff, 0, 0); -- cgit v1.2.3-59-g8ed1b From ef536abd3afd1e3cbddf04c724db793f12ab9c44 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Feb 2019 22:33:05 -0800 Subject: Input: ili210x - define and use chip operations structure Instead of doing if/else if/else on the chip's model number let's define chip operations structure and use it to perform indirect calls. With number of protocols supported by the driver growing, this makes it better maintainable. This change includes fixes to checks whether the driver should continue polling the controller by Sven Van Asbroeck . Tested-by: Adam Ford #imx6q-logicpd Tested-by: Sven Van Asbroeck # ILI2118A variant Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 309 ++++++++++++++++++++---------------- 1 file changed, 173 insertions(+), 136 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 28e2dd748c5a..22811df82044 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -11,12 +11,13 @@ #include #include -#define ILI210X_TOUCHES 2 -#define ILI211X_TOUCHES 10 -#define ILI251X_TOUCHES 10 - #define ILI2XXX_POLL_PERIOD 20 +#define ILI210X_DATA_SIZE 64 +#define ILI211X_DATA_SIZE 43 +#define ILI251X_DATA_SIZE1 31 +#define ILI251X_DATA_SIZE2 20 + /* Touchscreen commands */ #define REG_TOUCHDATA 0x10 #define REG_PANEL_INFO 0x20 @@ -29,10 +30,14 @@ struct firmware_version { u8 minor; } __packed; -enum ili2xxx_model { - MODEL_ILI210X, - MODEL_ILI211X, - MODEL_ILI251X, +struct ili2xxx_chip { + int (*read_reg)(struct i2c_client *client, u8 reg, + void *buf, size_t len); + int (*get_touch_data)(struct i2c_client *client, u8 *data); + bool (*parse_touch_data)(const u8 *data, unsigned int finger, + unsigned int *x, unsigned int *y); + bool (*continue_polling)(const u8 *data, bool touch); + unsigned int max_touches; }; struct ili210x { @@ -40,16 +45,14 @@ struct ili210x { struct input_dev *input; struct gpio_desc *reset_gpio; struct touchscreen_properties prop; - enum ili2xxx_model model; - unsigned int max_touches; + const struct ili2xxx_chip *chip; bool stop; }; -static int ili210x_read_reg(struct i2c_client *client, u8 reg, void *buf, - size_t len) +static int ili210x_read_reg(struct i2c_client *client, + u8 reg, void *buf, size_t len) { - struct ili210x *priv = i2c_get_clientdata(client); - struct i2c_msg msg[2] = { + struct i2c_msg msg[] = { { .addr = client->addr, .flags = 0, @@ -63,53 +66,28 @@ static int ili210x_read_reg(struct i2c_client *client, u8 reg, void *buf, .buf = buf, } }; + int error, ret; - if (priv->model == MODEL_ILI251X) { - if (i2c_transfer(client->adapter, msg, 1) != 1) { - dev_err(&client->dev, "i2c transfer failed\n"); - return -EIO; - } - - usleep_range(5000, 5500); - - if (i2c_transfer(client->adapter, msg + 1, 1) != 1) { - dev_err(&client->dev, "i2c transfer failed\n"); - return -EIO; - } - } else { - if (i2c_transfer(client->adapter, msg, 2) != 2) { - dev_err(&client->dev, "i2c transfer failed\n"); - return -EIO; - } + ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); + if (ret != ARRAY_SIZE(msg)) { + error = ret < 0 ? ret : -EIO; + dev_err(&client->dev, "%s failed: %d\n", __func__, error); + return error; } return 0; } -static int ili210x_read(struct i2c_client *client, void *buf, size_t len) +static int ili210x_read_touch_data(struct i2c_client *client, u8 *data) { - struct i2c_msg msg = { - .addr = client->addr, - .flags = I2C_M_RD, - .len = len, - .buf = buf, - }; - - if (i2c_transfer(client->adapter, &msg, 1) != 1) { - dev_err(&client->dev, "i2c transfer failed\n"); - return -EIO; - } - - return 0; + return ili210x_read_reg(client, REG_TOUCHDATA, + data, ILI210X_DATA_SIZE); } -static bool ili210x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, +static bool ili210x_touchdata_to_coords(const u8 *touchdata, unsigned int finger, unsigned int *x, unsigned int *y) { - if (finger >= ILI210X_TOUCHES) - return false; - if (touchdata[0] & BIT(finger)) return false; @@ -119,15 +97,53 @@ static bool ili210x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, return true; } -static bool ili211x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, +static bool ili210x_check_continue_polling(const u8 *data, bool touch) +{ + return data[0] & 0xf3; +} + +static const struct ili2xxx_chip ili210x_chip = { + .read_reg = ili210x_read_reg, + .get_touch_data = ili210x_read_touch_data, + .parse_touch_data = ili210x_touchdata_to_coords, + .continue_polling = ili210x_check_continue_polling, + .max_touches = 2, +}; + +static int ili211x_read_touch_data(struct i2c_client *client, u8 *data) +{ + s16 sum = 0; + int error; + int ret; + int i; + + ret = i2c_master_recv(client, data, ILI211X_DATA_SIZE); + if (ret != ILI211X_DATA_SIZE) { + error = ret < 0 ? ret : -EIO; + dev_err(&client->dev, "%s failed: %d\n", __func__, error); + return error; + } + + /* This chip uses custom checksum at the end of data */ + for (i = 0; i < ILI211X_DATA_SIZE - 1; i++) + sum = (sum + data[i]) & 0xff; + + if ((-sum & 0xff) != data[ILI211X_DATA_SIZE - 1]) { + dev_err(&client->dev, + "CRC error (crc=0x%02x expected=0x%02x)\n", + sum, data[ILI211X_DATA_SIZE - 1]); + return -EIO; + } + + return 0; +} + +static bool ili211x_touchdata_to_coords(const u8 *touchdata, unsigned int finger, unsigned int *x, unsigned int *y) { u32 data; - if (finger >= ILI211X_TOUCHES) - return false; - data = get_unaligned_be32(touchdata + 1 + (finger * 4) + 0); if (data == 0xffffffff) /* Finger up */ return false; @@ -140,58 +156,104 @@ static bool ili211x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, return true; } -static bool ili251x_touchdata_to_coords(struct ili210x *priv, u8 *touchdata, +static bool ili211x_decline_polling(const u8 *data, bool touch) +{ + return false; +} + +static const struct ili2xxx_chip ili211x_chip = { + .read_reg = ili210x_read_reg, + .get_touch_data = ili211x_read_touch_data, + .parse_touch_data = ili211x_touchdata_to_coords, + .continue_polling = ili211x_decline_polling, + .max_touches = 10, +}; + +static int ili251x_read_reg(struct i2c_client *client, + u8 reg, void *buf, size_t len) +{ + int error; + int ret; + + ret = i2c_master_send(client, ®, 1); + if (ret == 1) { + usleep_range(5000, 5500); + + ret = i2c_master_recv(client, buf, len); + if (ret == len) + return 0; + } + + error = ret < 0 ? ret : -EIO; + dev_err(&client->dev, "%s failed: %d\n", __func__, error); + return ret; +} + +static int ili251x_read_touch_data(struct i2c_client *client, u8 *data) +{ + int error; + + error = ili251x_read_reg(client, REG_TOUCHDATA, + data, ILI251X_DATA_SIZE1); + if (!error && data[0] == 2) { + error = i2c_master_recv(client, data + ILI251X_DATA_SIZE1, + ILI251X_DATA_SIZE2); + if (error >= 0 && error != ILI251X_DATA_SIZE2) + error = -EIO; + } + + return error; +} + +static bool ili251x_touchdata_to_coords(const u8 *touchdata, unsigned int finger, unsigned int *x, unsigned int *y) { - if (finger >= ILI251X_TOUCHES) - return false; + u16 val; - *x = get_unaligned_be16(touchdata + 1 + (finger * 5) + 0); - if (!(*x & BIT(15))) /* Touch indication */ + val = get_unaligned_be16(touchdata + 1 + (finger * 5) + 0); + if (!(val & BIT(15))) /* Touch indication */ return false; - *x &= 0x3fff; + *x = val & 0x3fff; *y = get_unaligned_be16(touchdata + 1 + (finger * 5) + 2); return true; } +static bool ili251x_check_continue_polling(const u8 *data, bool touch) +{ + return touch; +} + +static const struct ili2xxx_chip ili251x_chip = { + .read_reg = ili251x_read_reg, + .get_touch_data = ili251x_read_touch_data, + .parse_touch_data = ili251x_touchdata_to_coords, + .continue_polling = ili251x_check_continue_polling, + .max_touches = 10, +}; + static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata) { struct input_dev *input = priv->input; int i; - bool contact = false, touch = false; + bool contact = false, touch; unsigned int x = 0, y = 0; - for (i = 0; i < priv->max_touches; i++) { - if (priv->model == MODEL_ILI210X) { - touch = ili210x_touchdata_to_coords(priv, touchdata, - i, &x, &y); - } else if (priv->model == MODEL_ILI211X) { - touch = ili211x_touchdata_to_coords(priv, touchdata, - i, &x, &y); - } else if (priv->model == MODEL_ILI251X) { - touch = ili251x_touchdata_to_coords(priv, touchdata, - i, &x, &y); - if (touch) - contact = true; - } + for (i = 0; i < priv->chip->max_touches; i++) { + touch = priv->chip->parse_touch_data(touchdata, i, &x, &y); input_mt_slot(input, i); - input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); - if (!touch) - continue; - touchscreen_report_pos(input, &priv->prop, x, y, - true); + if (input_mt_report_slot_state(input, MT_TOOL_FINGER, touch)) { + touchscreen_report_pos(input, &priv->prop, x, y, true); + contact = true; + } } input_mt_report_pointer_emulation(input, false); input_sync(input); - if (priv->model == MODEL_ILI210X) - contact = touchdata[0] & 0xf3; - return contact; } @@ -199,50 +261,25 @@ static irqreturn_t ili210x_irq(int irq, void *irq_data) { struct ili210x *priv = irq_data; struct i2c_client *client = priv->client; - u8 touchdata[64] = { 0 }; - s16 sum = 0; + const struct ili2xxx_chip *chip = priv->chip; + u8 touchdata[ILI210X_DATA_SIZE] = { 0 }; + bool keep_polling; bool touch; - int i; int error; do { - if (priv->model == MODEL_ILI210X) { - error = ili210x_read_reg(client, REG_TOUCHDATA, - touchdata, sizeof(touchdata)); - } else if (priv->model == MODEL_ILI211X) { - error = ili210x_read(client, touchdata, 43); - if (!error) { - /* - * This chip uses custom checksum at the end - * of data. - */ - for (i = 0; i <= 41; i++) - sum = (sum + touchdata[i]) & 0xff; - if ((-sum & 0xff) != touchdata[42]) { - dev_err(&client->dev, - "CRC error (crc=0x%02x expected=0x%02x)\n", - sum, touchdata[42]); - break; - } - } - } else if (priv->model == MODEL_ILI251X) { - error = ili210x_read_reg(client, REG_TOUCHDATA, - touchdata, 31); - if (!error && touchdata[0] == 2) - error = ili210x_read(client, - &touchdata[31], 20); - } - + error = chip->get_touch_data(client, touchdata); if (error) { dev_err(&client->dev, - "Unable to get touchdata, err = %d\n", error); + "Unable to get touch data: %d\n", error); break; } touch = ili210x_report_events(priv, touchdata); - if (touch) + keep_polling = chip->continue_polling(touchdata, touch); + if (keep_polling) msleep(ILI2XXX_POLL_PERIOD); - } while (!priv->stop && touch); + } while (!priv->stop && keep_polling); return IRQ_HANDLED; } @@ -298,20 +335,26 @@ static void ili210x_stop(void *data) } static int ili210x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct device *dev = &client->dev; + const struct ili2xxx_chip *chip; struct ili210x *priv; struct gpio_desc *reset_gpio; struct input_dev *input; struct firmware_version firmware; - enum ili2xxx_model model; int error; - model = (enum ili2xxx_model)id->driver_data; - dev_dbg(dev, "Probing for ILI210X I2C Touschreen driver"); + chip = device_get_match_data(dev); + if (!chip && id) + chip = (const struct ili2xxx_chip *)id->driver_data; + if (!chip) { + dev_err(&client->dev, "unknown device model\n"); + return -ENODEV; + } + if (client->irq <= 0) { dev_err(dev, "No IRQ!\n"); return -EINVAL; @@ -343,19 +386,12 @@ static int ili210x_i2c_probe(struct i2c_client *client, priv->client = client; priv->input = input; priv->reset_gpio = reset_gpio; - priv->model = model; - if (model == MODEL_ILI210X) - priv->max_touches = ILI210X_TOUCHES; - if (model == MODEL_ILI211X) - priv->max_touches = ILI211X_TOUCHES; - if (model == MODEL_ILI251X) - priv->max_touches = ILI251X_TOUCHES; - + priv->chip = chip; i2c_set_clientdata(client, priv); /* Get firmware version */ - error = ili210x_read_reg(client, REG_FIRMWARE_VERSION, - &firmware, sizeof(firmware)); + error = chip->read_reg(client, REG_FIRMWARE_VERSION, + &firmware, sizeof(firmware)); if (error) { dev_err(dev, "Failed to get firmware version, err: %d\n", error); @@ -371,7 +407,8 @@ static int ili210x_i2c_probe(struct i2c_client *client, input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 0xffff, 0, 0); touchscreen_parse_properties(input, true, &priv->prop); - error = input_mt_init_slots(input, priv->max_touches, INPUT_MT_DIRECT); + error = input_mt_init_slots(input, priv->chip->max_touches, + INPUT_MT_DIRECT); if (error) { dev_err(dev, "Unable to set up slots, err: %d\n", error); return error; @@ -435,18 +472,18 @@ static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm, ili210x_i2c_suspend, ili210x_i2c_resume); static const struct i2c_device_id ili210x_i2c_id[] = { - { "ili210x", MODEL_ILI210X }, - { "ili2117", MODEL_ILI211X }, - { "ili251x", MODEL_ILI251X }, + { "ili210x", (long)&ili210x_chip }, + { "ili2117", (long)&ili211x_chip }, + { "ili251x", (long)&ili251x_chip }, { } }; MODULE_DEVICE_TABLE(i2c, ili210x_i2c_id); static const struct of_device_id ili210x_dt_ids[] = { - { .compatible = "ilitek,ili210x", .data = (void *)MODEL_ILI210X }, - { .compatible = "ilitek,ili2117", .data = (void *)MODEL_ILI211X }, - { .compatible = "ilitek,ili251x", .data = (void *)MODEL_ILI251X }, - { }, + { .compatible = "ilitek,ili210x", .data = &ili210x_chip }, + { .compatible = "ilitek,ili2117", .data = &ili211x_chip }, + { .compatible = "ilitek,ili251x", .data = &ili251x_chip }, + { } }; MODULE_DEVICE_TABLE(of, ili210x_dt_ids); -- cgit v1.2.3-59-g8ed1b From 172bb5f34c0dd5e94eb877edb3e8721d1ebd5c75 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 4 Nov 2019 15:27:41 -0800 Subject: Input: ili210x - do not unconditionally mark touchscreen as wakeup source I2C devices that are supposed to be wakeup sources should be instantiated with I2C_CLIENT_WAKE flag (which can be either set by in board info, or retrieved from "wakeup-source" property); individual drivers should not be marking devices as wakeup sources unconditionally. Tested-by: Adam Ford #imx6q-logicpd Tested-by: Sven Van Asbroeck # ILI2118A variant Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 22811df82044..ef0da2fc8bd3 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -439,8 +439,6 @@ static int ili210x_i2c_probe(struct i2c_client *client, return error; } - device_init_wakeup(dev, 1); - dev_dbg(dev, "ILI210x initialized (IRQ: %d), firmware version %d.%d.%d", client->irq, firmware.id, firmware.major, firmware.minor); -- cgit v1.2.3-59-g8ed1b From a5fdf7d02656e71071d1a13ab887f94e58651baf Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 4 Nov 2019 15:30:22 -0800 Subject: Input: ili210x - remove unneeded suspend and resume handlers When I2C client is instantiated with I2C_CLIENT_WAKE flag (either via "wakeup-source" device property, or via board info flag), it will mark the main IRQ line as wakeup IRQ, which will ensure that it will be enabled for wakeup when system transitions to suspend state. Since our suspend/resume handlers were only managing IRQ wakeup state, they are no longer needed, and can be removed. Tested-by: Adam Ford #imx6q-logicpd Tested-by: Sven Van Asbroeck # ILI2118A variant Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index ef0da2fc8bd3..0ed6014af6d7 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -446,29 +446,6 @@ static int ili210x_i2c_probe(struct i2c_client *client, return 0; } -static int __maybe_unused ili210x_i2c_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - - if (device_may_wakeup(&client->dev)) - enable_irq_wake(client->irq); - - return 0; -} - -static int __maybe_unused ili210x_i2c_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - - if (device_may_wakeup(&client->dev)) - disable_irq_wake(client->irq); - - return 0; -} - -static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm, - ili210x_i2c_suspend, ili210x_i2c_resume); - static const struct i2c_device_id ili210x_i2c_id[] = { { "ili210x", (long)&ili210x_chip }, { "ili2117", (long)&ili211x_chip }, @@ -488,7 +465,6 @@ MODULE_DEVICE_TABLE(of, ili210x_dt_ids); static struct i2c_driver ili210x_ts_driver = { .driver = { .name = "ili210x_i2c", - .pm = &ili210x_i2c_pm, .of_match_table = ili210x_dt_ids, }, .id_table = ili210x_i2c_id, -- cgit v1.2.3-59-g8ed1b From 8d13c7642fabb0f9fb044041ebcce23fb002d86b Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Tue, 8 Oct 2019 16:48:02 -0700 Subject: Input: mms114 - use device_get_match_data device_get_match_data is available now, so we can replace the call to of_device_get_match_data and remove the FIXME comment. Signed-off-by: Stephan Gerhold Reviewed-by: Andi Shyti Link: https://lore.kernel.org/r/20191007203343.101466-2-stephan@gerhold.net Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/mms114.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index a5ab774da4cc..69c6d559eeb0 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -446,8 +446,7 @@ static int mms114_probe(struct i2c_client *client, data->client = client; data->input_dev = input_dev; - /* FIXME: switch to device_get_match_data() when available */ - match_data = of_device_get_match_data(&client->dev); + match_data = device_get_match_data(&client->dev); if (!match_data) return -EINVAL; -- cgit v1.2.3-59-g8ed1b From c7dded5b2980de9811f47a1a576e0596a5a775ce Mon Sep 17 00:00:00 2001 From: Sven Van Asbroeck Date: Tue, 12 Nov 2019 15:40:03 -0800 Subject: Input: ili210x - do not retrieve/print chip firmware version The driver's method to retrieve the firmware version on ili2117/ ili2118 chip flavours is incorrect. The firmware version register address and layout are wrong. The firmware version is not actually used anywhere inside or outside this driver. There is a dev_dbg() print, but that is only visible when the developer explicitly compiles in debug support. Don't make the code more complicated to preserve a feature that no-one is using. Remove all code associated with chip firmware version. Signed-off-by: Sven Van Asbroeck Link: https://lore.kernel.org/r/20191112164429.11225-1-TheSven73@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 0ed6014af6d7..a6feae5ce887 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -21,15 +21,8 @@ /* Touchscreen commands */ #define REG_TOUCHDATA 0x10 #define REG_PANEL_INFO 0x20 -#define REG_FIRMWARE_VERSION 0x40 #define REG_CALIBRATE 0xcc -struct firmware_version { - u8 id; - u8 major; - u8 minor; -} __packed; - struct ili2xxx_chip { int (*read_reg)(struct i2c_client *client, u8 reg, void *buf, size_t len); @@ -342,7 +335,6 @@ static int ili210x_i2c_probe(struct i2c_client *client, struct ili210x *priv; struct gpio_desc *reset_gpio; struct input_dev *input; - struct firmware_version firmware; int error; dev_dbg(dev, "Probing for ILI210X I2C Touschreen driver"); @@ -389,15 +381,6 @@ static int ili210x_i2c_probe(struct i2c_client *client, priv->chip = chip; i2c_set_clientdata(client, priv); - /* Get firmware version */ - error = chip->read_reg(client, REG_FIRMWARE_VERSION, - &firmware, sizeof(firmware)); - if (error) { - dev_err(dev, "Failed to get firmware version, err: %d\n", - error); - return error; - } - /* Setup input device */ input->name = "ILI210x Touchscreen"; input->id.bustype = BUS_I2C; @@ -439,10 +422,6 @@ static int ili210x_i2c_probe(struct i2c_client *client, return error; } - dev_dbg(dev, - "ILI210x initialized (IRQ: %d), firmware version %d.%d.%d", - client->irq, firmware.id, firmware.major, firmware.minor); - return 0; } -- cgit v1.2.3-59-g8ed1b From b32fbeaec52d387004dd7fa15877b8adf7b396c3 Mon Sep 17 00:00:00 2001 From: Sven Van Asbroeck Date: Tue, 12 Nov 2019 15:40:48 -0800 Subject: Input: ili210x - add resolution to chip operations structure Optionally allow the touch screen resolution to be set by adding it to the chip operations structure. If it is omitted (left zero), the resolution defaults to 64K. Which is the previously hard-coded value. Set the ili2117 resolution to 2048, as indicated in its datasheet. Signed-off-by: Sven Van Asbroeck Link: https://lore.kernel.org/r/20191112210148.3535-1-TheSven73@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index a6feae5ce887..6861ac4355b2 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,7 @@ struct ili2xxx_chip { unsigned int *x, unsigned int *y); bool (*continue_polling)(const u8 *data, bool touch); unsigned int max_touches; + unsigned int resolution; }; struct ili210x { @@ -160,6 +162,7 @@ static const struct ili2xxx_chip ili211x_chip = { .parse_touch_data = ili211x_touchdata_to_coords, .continue_polling = ili211x_decline_polling, .max_touches = 10, + .resolution = 2048, }; static int ili251x_read_reg(struct i2c_client *client, @@ -336,6 +339,7 @@ static int ili210x_i2c_probe(struct i2c_client *client, struct gpio_desc *reset_gpio; struct input_dev *input; int error; + unsigned int max_xy; dev_dbg(dev, "Probing for ILI210X I2C Touschreen driver"); @@ -386,8 +390,9 @@ static int ili210x_i2c_probe(struct i2c_client *client, input->id.bustype = BUS_I2C; /* Multi touch */ - input_set_abs_params(input, ABS_MT_POSITION_X, 0, 0xffff, 0, 0); - input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 0xffff, 0, 0); + max_xy = (chip->resolution ?: SZ_64K) - 1; + input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_xy, 0, 0); + input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_xy, 0, 0); touchscreen_parse_properties(input, true, &priv->prop); error = input_mt_init_slots(input, priv->chip->max_touches, -- cgit v1.2.3-59-g8ed1b From cc12ba1872c6bf05b5f177fae5082bcbea335f2b Mon Sep 17 00:00:00 2001 From: Sven Van Asbroeck Date: Tue, 12 Nov 2019 15:44:10 -0800 Subject: Input: ili210x - optionally show calibrate sysfs attribute Only show the 'calibrate' sysfs attribute on chip flavours which support calibration by writing to a calibration register. Do this by adding a flag to the chip operations structure. Signed-off-by: Sven Van Asbroeck Link: https://lore.kernel.org/r/20191112210148.3535-2-TheSven73@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 6861ac4355b2..4a17096e83e1 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -33,6 +33,7 @@ struct ili2xxx_chip { bool (*continue_polling)(const u8 *data, bool touch); unsigned int max_touches; unsigned int resolution; + bool has_calibrate_reg; }; struct ili210x { @@ -103,6 +104,7 @@ static const struct ili2xxx_chip ili210x_chip = { .parse_touch_data = ili210x_touchdata_to_coords, .continue_polling = ili210x_check_continue_polling, .max_touches = 2, + .has_calibrate_reg = true, }; static int ili211x_read_touch_data(struct i2c_client *client, u8 *data) @@ -228,6 +230,7 @@ static const struct ili2xxx_chip ili251x_chip = { .parse_touch_data = ili251x_touchdata_to_coords, .continue_polling = ili251x_check_continue_polling, .max_touches = 10, + .has_calibrate_reg = true, }; static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata) @@ -311,8 +314,19 @@ static struct attribute *ili210x_attributes[] = { NULL, }; +static umode_t ili210x_calibrate_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = kobj_to_dev(kobj); + struct i2c_client *client = to_i2c_client(dev); + struct ili210x *priv = i2c_get_clientdata(client); + + return priv->chip->has_calibrate_reg; +} + static const struct attribute_group ili210x_attr_group = { .attrs = ili210x_attributes, + .is_visible = ili210x_calibrate_visible, }; static void ili210x_power_down(void *data) -- cgit v1.2.3-59-g8ed1b From bcf1e034d3aae39d27371b51916359ea7501db01 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 22 Nov 2019 14:49:30 -0800 Subject: Input: fix Kconfig indentation Adjust indentation from spaces to tab (+optional two spaces) as in coding style with command like: $ sed -e 's/^ /\t/' -i */Kconfig Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/1574306373-29581-1-git-send-email-krzk@kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 16 ++++++++-------- drivers/input/mouse/Kconfig | 16 ++++++++-------- drivers/input/tablet/Kconfig | 20 ++++++++++---------- drivers/input/touchscreen/Kconfig | 2 +- 4 files changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 1ddfc2413035..61f4eb63eec1 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -167,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. - - To compile this driver as a module, choose M here: - the module will be called 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. + + 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" diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index bf738d3b7fe4..d8b6a5dab190 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -92,14 +92,14 @@ config MOUSE_PS2_SYNAPTICS_SMBUS If unsure, say Y. config MOUSE_PS2_CYPRESS - bool "Cypress PS/2 mouse protocol extension" if EXPERT - default y - depends on MOUSE_PS2 - help - Say Y here if you have a Cypress PS/2 Trackpad connected to - your system. - - If unsure, say Y. + bool "Cypress PS/2 mouse protocol extension" if EXPERT + default y + depends on MOUSE_PS2 + help + Say Y here if you have a Cypress PS/2 Trackpad connected to + your system. + + If unsure, say Y. config MOUSE_PS2_LIFEBOOK bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EXPERT diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig index e4c0d9a055b9..51c339182017 100644 --- a/drivers/input/tablet/Kconfig +++ b/drivers/input/tablet/Kconfig @@ -39,16 +39,16 @@ config TABLET_USB_AIPTEK module will be called aiptek. config TABLET_USB_GTCO - tristate "GTCO CalComp/InterWrite USB Support" - depends on USB && INPUT - help - Say Y here if you want to use the USB version of the GTCO - CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support" - (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" - (CONFIG_INPUT_EVDEV) as well. - - To compile this driver as a module, choose M here: the - module will be called gtco. + tristate "GTCO CalComp/InterWrite USB Support" + depends on USB && INPUT + help + Say Y here if you want to use the USB version of the GTCO + CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support" + (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" + (CONFIG_INPUT_EVDEV) as well. + + To compile this driver as a module, choose M here: the + module will be called gtco. config TABLET_USB_HANWANG tristate "Hanwang Art Master III tablet support (USB)" diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 40bfc551ce30..c071f7c407b6 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -633,7 +633,7 @@ config TOUCHSCREEN_HP600 depends on SH_HP6XX && SH_ADC help Say Y here if you have a HP Jornada 620/660/680/690 and want to - support the built-in touchscreen. + support the built-in touchscreen. To compile this driver as a module, choose M here: the module will be called hp680_ts_input. -- cgit v1.2.3-59-g8ed1b