From 92a37438ced77a8acb380457e0a28970f1ae9472 Mon Sep 17 00:00:00 2001 From: Jeffrey Lin Date: Thu, 4 Jan 2018 21:35:23 -0800 Subject: Input: raydium_i2c_ts - include hardware version in firmware name Add hardware version to the firmware file name to handle scenarios where single system image supports variety of devices. Signed-off-by: Jeffrey Lin Patchwork-Id: 10127677 Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/raydium_i2c_ts.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c index 100538d64fff..d1c09e6a2cb6 100644 --- a/drivers/input/touchscreen/raydium_i2c_ts.c +++ b/drivers/input/touchscreen/raydium_i2c_ts.c @@ -752,13 +752,20 @@ static int raydium_i2c_fw_update(struct raydium_data *ts) { struct i2c_client *client = ts->client; const struct firmware *fw = NULL; - const char *fw_file = "raydium.fw"; + char *fw_file; int error; + fw_file = kasprintf(GFP_KERNEL, "raydium_%#04x.fw", + le32_to_cpu(ts->info.hw_ver)); + if (!fw_file) + return -ENOMEM; + + dev_dbg(&client->dev, "firmware name: %s\n", fw_file); + error = request_firmware(&fw, fw_file, &client->dev); if (error) { dev_err(&client->dev, "Unable to open firmware %s\n", fw_file); - return error; + goto out_free_fw_file; } disable_irq(client->irq); @@ -787,6 +794,9 @@ out_enable_irq: release_firmware(fw); +out_free_fw_file: + kfree(fw_file); + return error; } -- cgit v1.2.3-59-g8ed1b From eca3be9b95ac7cf9442654a54962859d74f8e38a Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 9 Jan 2018 11:34:15 -0800 Subject: Input: silead - add support for capactive home button found on some x86 tablets On some x86 tablets with a silead touchscreen the windows logo on the front is a capacitive home button. Touching this button results in a touch with bits 12-15 of the Y coordinates set, while normally only the lower 12 are used. Detect this and report a KEY_LEFTMETA press when this happens. Note for now we only respond to the Y coordinate bits 12-15 containing 0x01, on some tablets *without* a capacative button I've noticed these bits containing 0x04 when crossing the edges of the screen. Acked-by: Rob Herring Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/silead_gsl1680.txt | 2 + drivers/input/touchscreen/silead.c | 46 ++++++++++++++++------ 2 files changed, 37 insertions(+), 11 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt b/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt index 6aa625e0cb8d..84752de12412 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/silead_gsl1680.txt @@ -23,6 +23,8 @@ Optional properties: - touchscreen-inverted-y : See touchscreen.txt - touchscreen-swapped-x-y : See touchscreen.txt - silead,max-fingers : maximum number of fingers the touchscreen can detect +- silead,home-button : Boolean, set to true on devices which have a + capacitive home-button build into the touchscreen - vddio-supply : regulator phandle for controller VDDIO - avdd-supply : regulator phandle for controller AVDD diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c index 0dbcf105f7db..646b1e768e6b 100644 --- a/drivers/input/touchscreen/silead.c +++ b/drivers/input/touchscreen/silead.c @@ -56,7 +56,7 @@ #define SILEAD_POINT_Y_MSB_OFF 0x01 #define SILEAD_POINT_X_OFF 0x02 #define SILEAD_POINT_X_MSB_OFF 0x03 -#define SILEAD_TOUCH_ID_MASK 0xF0 +#define SILEAD_EXTRA_DATA_MASK 0xF0 #define SILEAD_CMD_SLEEP_MIN 10000 #define SILEAD_CMD_SLEEP_MAX 20000 @@ -109,6 +109,9 @@ static int silead_ts_request_input_dev(struct silead_ts_data *data) INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); + if (device_property_read_bool(dev, "silead,home-button")) + input_set_capability(data->input, EV_KEY, KEY_LEFTMETA); + data->input->name = SILEAD_TS_NAME; data->input->phys = "input/ts"; data->input->id.bustype = BUS_I2C; @@ -139,7 +142,8 @@ static void silead_ts_read_data(struct i2c_client *client) struct input_dev *input = data->input; struct device *dev = &client->dev; u8 *bufp, buf[SILEAD_TS_DATA_LEN]; - int touch_nr, error, i; + int touch_nr, softbutton, error, i; + bool softbutton_pressed = false; error = i2c_smbus_read_i2c_block_data(client, SILEAD_REG_DATA, SILEAD_TS_DATA_LEN, buf); @@ -148,21 +152,40 @@ static void silead_ts_read_data(struct i2c_client *client) return; } - touch_nr = buf[0]; - if (touch_nr > data->max_fingers) { + if (buf[0] > data->max_fingers) { dev_warn(dev, "More touches reported then supported %d > %d\n", - touch_nr, data->max_fingers); - touch_nr = data->max_fingers; + buf[0], data->max_fingers); + buf[0] = data->max_fingers; } + touch_nr = 0; bufp = buf + SILEAD_POINT_DATA_LEN; - for (i = 0; i < touch_nr; i++, bufp += SILEAD_POINT_DATA_LEN) { - /* Bits 4-7 are the touch id */ - data->id[i] = (bufp[SILEAD_POINT_X_MSB_OFF] & - SILEAD_TOUCH_ID_MASK) >> 4; - touchscreen_set_mt_pos(&data->pos[i], &data->prop, + for (i = 0; i < buf[0]; i++, bufp += SILEAD_POINT_DATA_LEN) { + softbutton = (bufp[SILEAD_POINT_Y_MSB_OFF] & + SILEAD_EXTRA_DATA_MASK) >> 4; + + if (softbutton) { + /* + * For now only respond to softbutton == 0x01, some + * tablets *without* a capacative button send 0x04 + * when crossing the edges of the screen. + */ + if (softbutton == 0x01) + softbutton_pressed = true; + + continue; + } + + /* + * Bits 4-7 are the touch id, note not all models have + * hardware touch ids so atm we don't use these. + */ + data->id[touch_nr] = (bufp[SILEAD_POINT_X_MSB_OFF] & + SILEAD_EXTRA_DATA_MASK) >> 4; + touchscreen_set_mt_pos(&data->pos[touch_nr], &data->prop, get_unaligned_le16(&bufp[SILEAD_POINT_X_OFF]) & 0xfff, get_unaligned_le16(&bufp[SILEAD_POINT_Y_OFF]) & 0xfff); + touch_nr++; } input_mt_assign_slots(input, data->slots, data->pos, touch_nr, 0); @@ -178,6 +201,7 @@ static void silead_ts_read_data(struct i2c_client *client) } input_mt_sync_frame(input); + input_report_key(input, KEY_LEFTMETA, softbutton_pressed); input_sync(input); } -- cgit v1.2.3-59-g8ed1b From faec44b6838312484d63e82286087cf2d5ebb891 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 12 Jan 2018 00:36:48 -0800 Subject: Input: goodix - disable IRQs while suspended We should not try to do any i2c transfers before the controller is resumed (which happens before our resume method gets called). So we need to disable our IRQ while suspended to enforce this. The code paths for devices with GPIOs for the int and reset pins already disable the IRQ the through goodix_free_irq(). This commit also disables the IRQ while suspended for devices without GPIOs for the int and reset pins. This fixes the i2c bus sometimes getting stuck after a suspend/resume causing the touchscreen to sometimes not work after a suspend/resume. This has been tested on a GPD pocked device. BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10 BugLink: https://www.reddit.com/r/GPDPocket/comments/7niut2/fix_for_broken_touch_after_resume_all_linux/ Tested-by: Hans de Goede Signed-off-by: Hans de Goede Reviewed-by: Bastien Nocera Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 69d0b8cbc71f..ecec8eb17f28 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -878,8 +878,10 @@ static int __maybe_unused goodix_suspend(struct device *dev) int error; /* We need gpio pins to suspend/resume */ - if (!ts->gpiod_int || !ts->gpiod_rst) + if (!ts->gpiod_int || !ts->gpiod_rst) { + disable_irq(client->irq); return 0; + } wait_for_completion(&ts->firmware_loading_complete); @@ -919,8 +921,10 @@ static int __maybe_unused goodix_resume(struct device *dev) struct goodix_ts_data *ts = i2c_get_clientdata(client); int error; - if (!ts->gpiod_int || !ts->gpiod_rst) + if (!ts->gpiod_int || !ts->gpiod_rst) { + enable_irq(client->irq); return 0; + } /* * Exit sleep mode by outputting HIGH level to INT pin -- cgit v1.2.3-59-g8ed1b From 4f7fc9b561eab242152f928ff6be1d03e7259e84 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 16 Jan 2018 16:43:00 -0800 Subject: Input: remove unneeded MODULE_VERSION() usage in touchscreen drivers MODULE_VERSION is useless for in-kernel drivers, so just remove all usage of it in the touchscreen drivers. Along with this, some DRV_VERSION macros were removed as they are also pointless. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/colibri-vf50-ts.c | 2 -- drivers/input/touchscreen/elants_i2c.c | 2 -- drivers/input/touchscreen/melfas_mip4.c | 1 - drivers/input/touchscreen/wdt87xx_i2c.c | 2 -- 4 files changed, 7 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/colibri-vf50-ts.c b/drivers/input/touchscreen/colibri-vf50-ts.c index 69c08acae264..82ca5ab65cec 100644 --- a/drivers/input/touchscreen/colibri-vf50-ts.c +++ b/drivers/input/touchscreen/colibri-vf50-ts.c @@ -28,7 +28,6 @@ #include #define DRIVER_NAME "colibri-vf50-ts" -#define DRV_VERSION "1.0" #define VF_ADC_MAX ((1 << 12) - 1) @@ -382,4 +381,3 @@ module_platform_driver(vf50_touch_driver); MODULE_AUTHOR("Sanchayan Maity"); MODULE_DESCRIPTION("Colibri VF50 Touchscreen driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c index e102d7764bc2..a174b8c79ef5 100644 --- a/drivers/input/touchscreen/elants_i2c.c +++ b/drivers/input/touchscreen/elants_i2c.c @@ -44,7 +44,6 @@ /* Device, Driver information */ #define DEVICE_NAME "elants_i2c" -#define DRV_VERSION "1.0.9" /* Convert from rows or columns into resolution */ #define ELAN_TS_RESOLUTION(n, m) (((n) - 1) * (m)) @@ -1402,5 +1401,4 @@ module_i2c_driver(elants_i2c_driver); MODULE_AUTHOR("Scott Liu "); MODULE_DESCRIPTION("Elan I2c Touchscreen driver"); -MODULE_VERSION(DRV_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c index 6892f0e28918..430a2bc5f7ca 100644 --- a/drivers/input/touchscreen/melfas_mip4.c +++ b/drivers/input/touchscreen/melfas_mip4.c @@ -1611,6 +1611,5 @@ static struct i2c_driver mip4_driver = { module_i2c_driver(mip4_driver); MODULE_DESCRIPTION("MELFAS MIP4 Touchscreen"); -MODULE_VERSION("2016.10.31"); MODULE_AUTHOR("Sangwon Jee "); MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/wdt87xx_i2c.c b/drivers/input/touchscreen/wdt87xx_i2c.c index d351efd18f89..20f7f3902757 100644 --- a/drivers/input/touchscreen/wdt87xx_i2c.c +++ b/drivers/input/touchscreen/wdt87xx_i2c.c @@ -23,7 +23,6 @@ #include #define WDT87XX_NAME "wdt87xx_i2c" -#define WDT87XX_DRV_VER "0.9.8" #define WDT87XX_FW_NAME "wdt87xx_fw.bin" #define WDT87XX_CFG_NAME "wdt87xx_cfg.bin" @@ -1183,5 +1182,4 @@ module_i2c_driver(wdt87xx_driver); MODULE_AUTHOR("HN Chen "); MODULE_DESCRIPTION("WeidaHiTech WDT87XX Touchscreen driver"); -MODULE_VERSION(WDT87XX_DRV_VER); MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From 698c03b4745006e14eccb8270f714d52fac1c97e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 16 Jan 2018 16:56:54 -0800 Subject: Input: inline macros for MODULE_LICENSE, etc Inline macro for MODULE_LICENSE to make the license information easy to find, eg with grep. Inline the other module-related macros at the same time. A simplified version of the semantic patch for the MODULE_LICENSE case is as follows: (http://coccinelle.lip6.fr/) // @s@ identifier i; expression e; @@ @@ declarer name MODULE_LICENSE; identifier s.i; expression s.e; @@ MODULE_LICENSE( - i + e ); // Signed-off-by: Julia Lawall [dtor: added a couple of drivers missed by the script, removed a few unused DRIVER_VERSION macros] Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 7 ++----- drivers/input/misc/keyspan_remote.c | 8 ++------ drivers/input/misc/yealink.c | 6 ++---- drivers/input/tablet/acecad.c | 11 ++--------- drivers/input/tablet/aiptek.c | 11 ++--------- drivers/input/tablet/hanwang.c | 7 ++----- drivers/input/tablet/kbtab.c | 14 +++----------- drivers/input/touchscreen/usbtouchscreen.c | 9 ++------- 8 files changed, 17 insertions(+), 56 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index d86e59515b9c..0434a1369188 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -84,9 +84,6 @@ #include #include -#define DRIVER_AUTHOR "Marko Friedemann " -#define DRIVER_DESC "X-Box pad driver" - #define XPAD_PKT_LEN 64 /* xbox d-pads should map to buttons, as is required for DDR pads @@ -1924,6 +1921,6 @@ static struct usb_driver xpad_driver = { module_usb_driver(xpad_driver); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Marko Friedemann "); +MODULE_DESCRIPTION("X-Box pad driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c index 4f13b2f7bf4f..67482b248b2d 100644 --- a/drivers/input/misc/keyspan_remote.c +++ b/drivers/input/misc/keyspan_remote.c @@ -17,10 +17,6 @@ #include #include -#define DRIVER_VERSION "v0.1" -#define DRIVER_AUTHOR "Michael Downey " -#define DRIVER_DESC "Driver for the USB Keyspan remote control." - /* Parameters that can be passed to the driver. */ static int debug; module_param(debug, int, 0444); @@ -589,6 +585,6 @@ static struct usb_driver keyspan_driver = module_usb_driver(keyspan_driver); MODULE_DEVICE_TABLE(usb, keyspan_table); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Michael Downey "); +MODULE_DESCRIPTION("Driver for the USB Keyspan remote control."); MODULE_LICENSE("GPL"); diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c index a1e0ff59d2f2..f0c9bf87b4e3 100644 --- a/drivers/input/misc/yealink.c +++ b/drivers/input/misc/yealink.c @@ -56,8 +56,6 @@ #include "yealink.h" #define DRIVER_VERSION "yld-20051230" -#define DRIVER_AUTHOR "Henk Vergonet" -#define DRIVER_DESC "Yealink phone driver" #define YEALINK_POLLING_FREQUENCY 10 /* in [Hz] */ @@ -1006,6 +1004,6 @@ module_usb_driver(yealink_driver); MODULE_DEVICE_TABLE (usb, usb_table); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Henk Vergonet"); +MODULE_DESCRIPTION("Yealink phone driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index fcb67c7cd86b..a86255d08a6b 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c @@ -30,15 +30,8 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "v3.2" -#define DRIVER_DESC "USB Acecad Flair tablet driver" -#define DRIVER_AUTHOR "Edouard TISSERANT " - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Edouard TISSERANT "); +MODULE_DESCRIPTION("USB Acecad Flair tablet driver"); MODULE_LICENSE("GPL"); #define USB_VENDOR_ID_ACECAD 0x0460 diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 0b55e1f375b3..545fa6e89035 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -78,13 +78,6 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "v2.3 (May 2, 2007)" -#define DRIVER_AUTHOR "Bryan W. Headley/Chris Atenasio/Cedric Brun/Rene van Paassen" -#define DRIVER_DESC "Aiptek HyperPen USB Tablet Driver (Linux 2.6.x)" - /* * Aiptek status packet: * @@ -1941,8 +1934,8 @@ static struct usb_driver aiptek_driver = { module_usb_driver(aiptek_driver); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Bryan W. Headley/Chris Atenasio/Cedric Brun/Rene van Paassen"); +MODULE_DESCRIPTION("Aiptek HyperPen USB Tablet Driver"); MODULE_LICENSE("GPL"); module_param(programmableDelay, int, 0); diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c index 70cb26bbfe1d..4042c41160f4 100644 --- a/drivers/input/tablet/hanwang.c +++ b/drivers/input/tablet/hanwang.c @@ -28,11 +28,8 @@ #include #include -#define DRIVER_AUTHOR "Xing Wei " -#define DRIVER_DESC "USB Hanwang tablet driver" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Xing Wei "); +MODULE_DESCRIPTION("USB Hanwang tablet driver"); MODULE_LICENSE("GPL"); #define USB_VENDOR_ID_HANWANG 0x0b57 diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c index bee18e33e261..75b500651e4e 100644 --- a/drivers/input/tablet/kbtab.c +++ b/drivers/input/tablet/kbtab.c @@ -5,19 +5,11 @@ #include /* - * Version Information - * v0.0.1 - Original, extremely basic version, 2.4.xx only - * v0.0.2 - Updated, works with 2.5.62 and 2.4.20; - * - added pressure-threshold modules param code from - * Alex Perry + * Pressure-threshold modules param code from Alex Perry */ -#define DRIVER_VERSION "v0.0.2" -#define DRIVER_AUTHOR "Josh Myer " -#define DRIVER_DESC "USB KB Gear JamStudio Tablet driver" - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Josh Myer "); +MODULE_DESCRIPTION("USB KB Gear JamStudio Tablet driver"); MODULE_LICENSE("GPL"); #define USB_VENDOR_ID_KBGEAR 0x084e diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 2c41107240de..aa77d243b786 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -55,11 +55,6 @@ #include #include - -#define DRIVER_VERSION "v0.6" -#define DRIVER_AUTHOR "Daniel Ritz " -#define DRIVER_DESC "USB Touchscreen Driver" - static bool swap_xy; module_param(swap_xy, bool, 0644); MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); @@ -1763,8 +1758,8 @@ static struct usb_driver usbtouch_driver = { module_usb_driver(usbtouch_driver); -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Daniel Ritz "); +MODULE_DESCRIPTION("USB Touchscreen Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("touchkitusb"); -- cgit v1.2.3-59-g8ed1b From 082dc4dcc35f9e1695f0050ea6475f9a56df2c0a Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Fri, 19 Jan 2018 09:29:28 -0800 Subject: Input: remove atmel-wm97xx touchscreen driver Since AVR32 arch is gone, atmel-wm97xx driver is useless. In theory it could have been rewritten to work with AT91 devices, but the driver is from the platform data era, and a bit hard coded to work on AVR32 hardware variant of the AC97C peripheral, so let's remove it. Signed-off-by: Corentin Labbe Acked-by: Hans-Christian Noren Egtvedt Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 15 -- drivers/input/touchscreen/Makefile | 1 - drivers/input/touchscreen/atmel-wm97xx.c | 436 ------------------------------- 3 files changed, 452 deletions(-) delete mode 100644 drivers/input/touchscreen/atmel-wm97xx.c (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 0cfdb7cb610e..5fac4ef3ae7b 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -795,21 +795,6 @@ config TOUCHSCREEN_WM9713 Say Y here to enable support for the Wolfson Microelectronics WM9713 touchscreen controller. -config TOUCHSCREEN_WM97XX_ATMEL - tristate "WM97xx Atmel accelerated touch" - depends on TOUCHSCREEN_WM97XX && AVR32 - help - Say Y here for support for streaming mode with WM97xx touchscreens - on Atmel AT91 or AVR32 systems with an AC97C module. - - Be aware that this will use channel B in the controller for - streaming data, this must not conflict with other AC97C drivers. - - If unsure, say N. - - To compile this driver as a module, choose M here: the module will - be called atmel-wm97xx. - config TOUCHSCREEN_WM97XX_MAINSTONE tristate "WM97xx Mainstone/Palm accelerated touch" depends on TOUCHSCREEN_WM97XX && ARCH_PXA diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index d2a2b3b7af27..dddae7973436 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -97,7 +97,6 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o -obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c deleted file mode 100644 index 9140a43cfe20..000000000000 --- a/drivers/input/touchscreen/atmel-wm97xx.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Atmel AT91 and AVR32 continuous touch screen driver for Wolfson WM97xx AC97 - * codecs. - * - * Copyright (C) 2008 - 2009 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define AC97C_ICA 0x10 -#define AC97C_CBRHR 0x30 -#define AC97C_CBSR 0x38 -#define AC97C_CBMR 0x3c -#define AC97C_IER 0x54 -#define AC97C_IDR 0x58 - -#define AC97C_RXRDY (1 << 4) -#define AC97C_OVRUN (1 << 5) - -#define AC97C_CMR_SIZE_20 (0 << 16) -#define AC97C_CMR_SIZE_18 (1 << 16) -#define AC97C_CMR_SIZE_16 (2 << 16) -#define AC97C_CMR_SIZE_10 (3 << 16) -#define AC97C_CMR_CEM_LITTLE (1 << 18) -#define AC97C_CMR_CEM_BIG (0 << 18) -#define AC97C_CMR_CENA (1 << 21) - -#define AC97C_INT_CBEVT (1 << 4) - -#define AC97C_SR_CAEVT (1 << 3) - -#define AC97C_CH_MASK(slot) \ - (0x7 << (3 * (slot - 3))) -#define AC97C_CH_ASSIGN(slot, channel) \ - (AC97C_CHANNEL_##channel << (3 * (slot - 3))) -#define AC97C_CHANNEL_NONE 0x0 -#define AC97C_CHANNEL_B 0x2 - -#define ac97c_writel(chip, reg, val) \ - __raw_writel((val), (chip)->regs + AC97C_##reg) -#define ac97c_readl(chip, reg) \ - __raw_readl((chip)->regs + AC97C_##reg) - -#ifdef CONFIG_CPU_AT32AP700X -#define ATMEL_WM97XX_AC97C_IOMEM (0xfff02800) -#define ATMEL_WM97XX_AC97C_IRQ (29) -#define ATMEL_WM97XX_GPIO_DEFAULT (32+16) /* Pin 16 on port B. */ -#else -#error Unknown CPU, this driver only supports AT32AP700X CPUs. -#endif - -struct continuous { - u16 id; /* codec id */ - u8 code; /* continuous code */ - u8 reads; /* number of coord reads per read cycle */ - u32 speed; /* number of coords per second */ -}; - -#define WM_READS(sp) ((sp / HZ) + 1) - -static const struct continuous cinfo[] = { - {WM9705_ID2, 0, WM_READS(94), 94}, - {WM9705_ID2, 1, WM_READS(188), 188}, - {WM9705_ID2, 2, WM_READS(375), 375}, - {WM9705_ID2, 3, WM_READS(750), 750}, - {WM9712_ID2, 0, WM_READS(94), 94}, - {WM9712_ID2, 1, WM_READS(188), 188}, - {WM9712_ID2, 2, WM_READS(375), 375}, - {WM9712_ID2, 3, WM_READS(750), 750}, - {WM9713_ID2, 0, WM_READS(94), 94}, - {WM9713_ID2, 1, WM_READS(120), 120}, - {WM9713_ID2, 2, WM_READS(154), 154}, - {WM9713_ID2, 3, WM_READS(188), 188}, -}; - -/* Continuous speed index. */ -static int sp_idx; - -/* - * Pen sampling frequency (Hz) in continuous mode. - */ -static int cont_rate = 188; -module_param(cont_rate, int, 0); -MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)"); - -/* - * Pen down detection. - * - * This driver can either poll or use an interrupt to indicate a pen down - * event. If the irq request fails then it will fall back to polling mode. - */ -static int pen_int = 1; -module_param(pen_int, int, 0); -MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)"); - -/* - * Pressure readback. - * - * Set to 1 to read back pen down pressure. - */ -static int pressure; -module_param(pressure, int, 0); -MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)"); - -/* - * AC97 touch data slot. - * - * Touch screen readback data ac97 slot. - */ -static int ac97_touch_slot = 5; -module_param(ac97_touch_slot, int, 0); -MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number"); - -/* - * GPIO line number. - * - * Set to GPIO number where the signal from the WM97xx device is hooked up. - */ -static int atmel_gpio_line = ATMEL_WM97XX_GPIO_DEFAULT; -module_param(atmel_gpio_line, int, 0); -MODULE_PARM_DESC(atmel_gpio_line, "GPIO line number connected to WM97xx"); - -struct atmel_wm97xx { - struct wm97xx *wm; - struct timer_list pen_timer; - void __iomem *regs; - unsigned long ac97c_irq; - unsigned long gpio_pen; - unsigned long gpio_irq; - unsigned short x; - unsigned short y; -}; - -static irqreturn_t atmel_wm97xx_channel_b_interrupt(int irq, void *dev_id) -{ - struct atmel_wm97xx *atmel_wm97xx = dev_id; - struct wm97xx *wm = atmel_wm97xx->wm; - int status = ac97c_readl(atmel_wm97xx, CBSR); - irqreturn_t retval = IRQ_NONE; - - if (status & AC97C_OVRUN) { - dev_dbg(&wm->touch_dev->dev, "AC97C overrun\n"); - ac97c_readl(atmel_wm97xx, CBRHR); - retval = IRQ_HANDLED; - } else if (status & AC97C_RXRDY) { - u16 data; - u16 value; - u16 source; - u16 pen_down; - - data = ac97c_readl(atmel_wm97xx, CBRHR); - value = data & 0x0fff; - source = data & WM97XX_ADCSEL_MASK; - pen_down = (data & WM97XX_PEN_DOWN) >> 8; - - if (source == WM97XX_ADCSEL_X) - atmel_wm97xx->x = value; - if (source == WM97XX_ADCSEL_Y) - atmel_wm97xx->y = value; - - if (!pressure && source == WM97XX_ADCSEL_Y) { - input_report_abs(wm->input_dev, ABS_X, atmel_wm97xx->x); - input_report_abs(wm->input_dev, ABS_Y, atmel_wm97xx->y); - input_report_key(wm->input_dev, BTN_TOUCH, pen_down); - input_sync(wm->input_dev); - } else if (pressure && source == WM97XX_ADCSEL_PRES) { - input_report_abs(wm->input_dev, ABS_X, atmel_wm97xx->x); - input_report_abs(wm->input_dev, ABS_Y, atmel_wm97xx->y); - input_report_abs(wm->input_dev, ABS_PRESSURE, value); - input_report_key(wm->input_dev, BTN_TOUCH, value); - input_sync(wm->input_dev); - } - - retval = IRQ_HANDLED; - } - - return retval; -} - -static void atmel_wm97xx_acc_pen_up(struct wm97xx *wm) -{ - struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(wm->touch_dev); - struct input_dev *input_dev = wm->input_dev; - int pen_down = gpio_get_value(atmel_wm97xx->gpio_pen); - - if (pen_down != 0) { - mod_timer(&atmel_wm97xx->pen_timer, - jiffies + msecs_to_jiffies(1)); - } else { - if (pressure) - input_report_abs(input_dev, ABS_PRESSURE, 0); - input_report_key(input_dev, BTN_TOUCH, 0); - input_sync(input_dev); - } -} - -static void atmel_wm97xx_pen_timer(struct timer_list *t) -{ - struct atmel_wm97xx *atmel_wm97xx = from_timer(atmel_wm97xx, t, - pen_timer); - - atmel_wm97xx_acc_pen_up(atmel_wm97xx->wm); -} - -static int atmel_wm97xx_acc_startup(struct wm97xx *wm) -{ - struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(wm->touch_dev); - int idx = 0; - - if (wm->ac97 == NULL) - return -ENODEV; - - for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) { - if (wm->id != cinfo[idx].id) - continue; - - sp_idx = idx; - - if (cont_rate <= cinfo[idx].speed) - break; - } - - wm->acc_rate = cinfo[sp_idx].code; - wm->acc_slot = ac97_touch_slot; - dev_info(&wm->touch_dev->dev, "atmel accelerated touchscreen driver, " - "%d samples/sec\n", cinfo[sp_idx].speed); - - if (pen_int) { - unsigned long reg; - - wm->pen_irq = atmel_wm97xx->gpio_irq; - - switch (wm->id) { - case WM9712_ID2: /* Fall through. */ - case WM9713_ID2: - /* - * Use GPIO 13 (PEN_DOWN) to assert GPIO line 3 - * (PENDOWN). - */ - wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, - WM97XX_GPIO_POL_HIGH, - WM97XX_GPIO_STICKY, - WM97XX_GPIO_WAKE); - wm97xx_config_gpio(wm, WM97XX_GPIO_3, WM97XX_GPIO_OUT, - WM97XX_GPIO_POL_HIGH, - WM97XX_GPIO_NOTSTICKY, - WM97XX_GPIO_NOWAKE); - case WM9705_ID2: /* Fall through. */ - /* - * Enable touch data slot in AC97 controller channel B. - */ - reg = ac97c_readl(atmel_wm97xx, ICA); - reg &= ~AC97C_CH_MASK(wm->acc_slot); - reg |= AC97C_CH_ASSIGN(wm->acc_slot, B); - ac97c_writel(atmel_wm97xx, ICA, reg); - - /* - * Enable channel and interrupt for RXRDY and OVERRUN. - */ - ac97c_writel(atmel_wm97xx, CBMR, AC97C_CMR_CENA - | AC97C_CMR_CEM_BIG - | AC97C_CMR_SIZE_16 - | AC97C_OVRUN - | AC97C_RXRDY); - /* Dummy read to empty RXRHR. */ - ac97c_readl(atmel_wm97xx, CBRHR); - /* - * Enable interrupt for channel B in the AC97 - * controller. - */ - ac97c_writel(atmel_wm97xx, IER, AC97C_INT_CBEVT); - break; - default: - dev_err(&wm->touch_dev->dev, "pen down irq not " - "supported on this device\n"); - pen_int = 0; - break; - } - } - - return 0; -} - -static void atmel_wm97xx_acc_shutdown(struct wm97xx *wm) -{ - if (pen_int) { - struct atmel_wm97xx *atmel_wm97xx = - platform_get_drvdata(wm->touch_dev); - unsigned long ica; - - switch (wm->id & 0xffff) { - case WM9705_ID2: /* Fall through. */ - case WM9712_ID2: /* Fall through. */ - case WM9713_ID2: - /* Disable slot and turn off channel B interrupts. */ - ica = ac97c_readl(atmel_wm97xx, ICA); - ica &= ~AC97C_CH_MASK(wm->acc_slot); - ac97c_writel(atmel_wm97xx, ICA, ica); - ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT); - ac97c_writel(atmel_wm97xx, CBMR, 0); - wm->pen_irq = 0; - break; - default: - dev_err(&wm->touch_dev->dev, "unknown codec\n"); - break; - } - } -} - -static void atmel_wm97xx_irq_enable(struct wm97xx *wm, int enable) -{ - /* Intentionally left empty. */ -} - -static struct wm97xx_mach_ops atmel_mach_ops = { - .acc_enabled = 1, - .acc_pen_up = atmel_wm97xx_acc_pen_up, - .acc_startup = atmel_wm97xx_acc_startup, - .acc_shutdown = atmel_wm97xx_acc_shutdown, - .irq_enable = atmel_wm97xx_irq_enable, - .irq_gpio = WM97XX_GPIO_3, -}; - -static int __init atmel_wm97xx_probe(struct platform_device *pdev) -{ - struct wm97xx *wm = platform_get_drvdata(pdev); - struct atmel_wm97xx *atmel_wm97xx; - int ret; - - atmel_wm97xx = kzalloc(sizeof(struct atmel_wm97xx), GFP_KERNEL); - if (!atmel_wm97xx) - return -ENOMEM; - - atmel_wm97xx->wm = wm; - atmel_wm97xx->regs = (void *)ATMEL_WM97XX_AC97C_IOMEM; - atmel_wm97xx->ac97c_irq = ATMEL_WM97XX_AC97C_IRQ; - atmel_wm97xx->gpio_pen = atmel_gpio_line; - atmel_wm97xx->gpio_irq = gpio_to_irq(atmel_wm97xx->gpio_pen); - - timer_setup(&atmel_wm97xx->pen_timer, atmel_wm97xx_pen_timer, 0); - - ret = request_irq(atmel_wm97xx->ac97c_irq, - atmel_wm97xx_channel_b_interrupt, - IRQF_SHARED, "atmel-wm97xx-ch-b", atmel_wm97xx); - if (ret) { - dev_dbg(&pdev->dev, "could not request ac97c irq\n"); - goto err; - } - - platform_set_drvdata(pdev, atmel_wm97xx); - - ret = wm97xx_register_mach_ops(wm, &atmel_mach_ops); - if (ret) - goto err_irq; - - return ret; - -err_irq: - free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx); -err: - kfree(atmel_wm97xx); - return ret; -} - -static int __exit atmel_wm97xx_remove(struct platform_device *pdev) -{ - struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev); - struct wm97xx *wm = atmel_wm97xx->wm; - - ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT); - free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx); - del_timer_sync(&atmel_wm97xx->pen_timer); - wm97xx_unregister_mach_ops(wm); - kfree(atmel_wm97xx); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int atmel_wm97xx_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev); - - ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT); - disable_irq(atmel_wm97xx->gpio_irq); - del_timer_sync(&atmel_wm97xx->pen_timer); - - return 0; -} - -static int atmel_wm97xx_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev); - struct wm97xx *wm = atmel_wm97xx->wm; - - if (wm->input_dev->users) { - enable_irq(atmel_wm97xx->gpio_irq); - ac97c_writel(atmel_wm97xx, IER, AC97C_INT_CBEVT); - } - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(atmel_wm97xx_pm_ops, - atmel_wm97xx_suspend, atmel_wm97xx_resume); - -static struct platform_driver atmel_wm97xx_driver = { - .remove = __exit_p(atmel_wm97xx_remove), - .driver = { - .name = "wm97xx-touch", - .pm = &atmel_wm97xx_pm_ops, - }, -}; - -module_platform_driver_probe(atmel_wm97xx_driver, atmel_wm97xx_probe); - -MODULE_AUTHOR("Hans-Christian Egtvedt "); -MODULE_DESCRIPTION("wm97xx continuous touch driver for Atmel AT91 and AVR32"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3-59-g8ed1b From f8c5938f6919bfe7b82ed34472bee1eb637ddbea Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Mon, 22 Jan 2018 11:23:27 -0800 Subject: Input: stmfts,s6sy671 - add SPDX identifier Replace the original license statement with the SPDX identifier. Update also the copyright owner adding myself as co-owner of the copyright. Signed-off-by: Andi Shyti Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/s6sy761.c | 15 +++++---------- drivers/input/touchscreen/stmfts.c | 15 +++++---------- 2 files changed, 10 insertions(+), 20 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/s6sy761.c b/drivers/input/touchscreen/s6sy761.c index 26b1cb8a88ec..675efa93d444 100644 --- a/drivers/input/touchscreen/s6sy761.c +++ b/drivers/input/touchscreen/s6sy761.c @@ -1,13 +1,8 @@ -/* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * Author: Andi Shyti - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Samsung S6SY761 Touchscreen device driver - */ +// SPDX-License-Identifier: GPL-2.0 +// Samsung S6SY761 Touchscreen device driver +// +// Copyright (c) 2017 Samsung Electronics Co., Ltd. +// Copyright (c) 2017 Andi Shyti #include #include diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c index c12d01899939..2a123e20a42e 100644 --- a/drivers/input/touchscreen/stmfts.c +++ b/drivers/input/touchscreen/stmfts.c @@ -1,13 +1,8 @@ -/* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * Author: Andi Shyti - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * STMicroelectronics FTS Touchscreen device driver - */ +// SPDX-License-Identifier: GPL-2.0 +// STMicroelectronics FTS Touchscreen device driver +// +// Copyright (c) 2017 Samsung Electronics Co., Ltd. +// Copyright (c) 2017 Andi Shyti #include #include -- cgit v1.2.3-59-g8ed1b From fbe6a536cf9c71ac02b763b76ad7395132d4ecbc Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Mon, 22 Jan 2018 16:08:51 -0800 Subject: Input: ad7877 - use managed resource allocations Use managed resource allocations to simplify error handling during probing failure and module exiting. With this all the goto labels in the probe function together with the cleanups in the remove function are unnecessary, therefore removed. Signed-off-by: Andi Shyti Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ad7877.c | 67 +++++++++++++------------------------- 1 file changed, 23 insertions(+), 44 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index 0381c7809d1b..5cfe477ec992 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c @@ -417,8 +417,10 @@ out: return IRQ_HANDLED; } -static void ad7877_disable(struct ad7877 *ts) +static void ad7877_disable(void *data) { + struct ad7877 *ts = data; + mutex_lock(&ts->mutex); if (!ts->disabled) { @@ -707,12 +709,17 @@ static int ad7877_probe(struct spi_device *spi) return err; } - ts = kzalloc(sizeof(struct ad7877), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!ts || !input_dev) { - err = -ENOMEM; - goto err_free_mem; - } + ts = devm_kzalloc(&spi->dev, sizeof(struct ad7877), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + input_dev = devm_input_allocate_device(&spi->dev); + if (!input_dev) + return -ENOMEM; + + err = devm_add_action_or_reset(&spi->dev, ad7877_disable, ts); + if (err) + return err; spi_set_drvdata(spi, ts); ts->spi = spi; @@ -761,11 +768,10 @@ static int ad7877_probe(struct spi_device *spi) verify = ad7877_read(spi, AD7877_REG_SEQ1); - if (verify != AD7877_MM_SEQUENCE){ + if (verify != AD7877_MM_SEQUENCE) { dev_err(&spi->dev, "%s: Failed to probe %s\n", dev_name(&spi->dev), input_dev->name); - err = -ENODEV; - goto err_free_mem; + return -ENODEV; } if (gpio3) @@ -775,47 +781,21 @@ static int ad7877_probe(struct spi_device *spi) /* Request AD7877 /DAV GPIO interrupt */ - err = request_threaded_irq(spi->irq, NULL, ad7877_irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - spi->dev.driver->name, ts); + err = devm_request_threaded_irq(&spi->dev, spi->irq, NULL, ad7877_irq, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + spi->dev.driver->name, ts); if (err) { dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); - goto err_free_mem; + return err; } - err = sysfs_create_group(&spi->dev.kobj, &ad7877_attr_group); + err = devm_device_add_group(&spi->dev, &ad7877_attr_group); if (err) - goto err_free_irq; + return err; err = input_register_device(input_dev); if (err) - goto err_remove_attr_group; - - return 0; - -err_remove_attr_group: - sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); -err_free_irq: - free_irq(spi->irq, ts); -err_free_mem: - input_free_device(input_dev); - kfree(ts); - return err; -} - -static int ad7877_remove(struct spi_device *spi) -{ - struct ad7877 *ts = spi_get_drvdata(spi); - - sysfs_remove_group(&spi->dev.kobj, &ad7877_attr_group); - - ad7877_disable(ts); - free_irq(ts->spi->irq, ts); - - input_unregister_device(ts->input); - kfree(ts); - - dev_dbg(&spi->dev, "unregistered touchscreen\n"); + return err; return 0; } @@ -846,7 +826,6 @@ static struct spi_driver ad7877_driver = { .pm = &ad7877_pm, }, .probe = ad7877_probe, - .remove = ad7877_remove, }; module_spi_driver(ad7877_driver); -- cgit v1.2.3-59-g8ed1b From aac21bbbf7d7136364c8ac2ef3e8aed2d887a760 Mon Sep 17 00:00:00 2001 From: Marcus Folkesson Date: Mon, 22 Jan 2018 09:27:37 -0800 Subject: Input: da9052_tsi - remove unused mutex Signed-off-by: Marcus Folkesson Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/da9052_tsi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/da9052_tsi.c b/drivers/input/touchscreen/da9052_tsi.c index 5a013bb7bcad..b5dfd5944cc3 100644 --- a/drivers/input/touchscreen/da9052_tsi.c +++ b/drivers/input/touchscreen/da9052_tsi.c @@ -26,7 +26,6 @@ struct da9052_tsi { struct da9052 *da9052; struct input_dev *dev; struct delayed_work ts_pen_work; - struct mutex mutex; bool stopped; bool adc_on; }; -- cgit v1.2.3-59-g8ed1b From eae7d90c9224ccbbd8a58a3f6610896242c620a0 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 22 Jan 2018 10:54:21 -0800 Subject: Input: auo-pixcir-ts - remove custom log for a failed memory allocation Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Reviewed-by: Heiko Stuebner Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/auo-pixcir-ts.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index 6592fc5d48b4..398e27c48a51 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -487,10 +487,8 @@ static struct auo_pixcir_ts_platdata *auo_pixcir_parse_dt(struct device *dev) return ERR_PTR(-ENOENT); pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - dev_err(dev, "failed to allocate platform data\n"); + if (!pdata) return ERR_PTR(-ENOMEM); - } pdata->gpio_int = of_get_gpio(np, 0); if (!gpio_is_valid(pdata->gpio_int)) { -- cgit v1.2.3-59-g8ed1b From 2cdc8749613de4e52f14cdb43f686d59173ed24e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 22 Jan 2018 10:55:30 -0800 Subject: Input: auo-pixcir-ts - delete an unnecessary return statement The script "checkpatch.pl" pointed information out like the following: WARNING: void function return statements are not generally useful Thus remove such a statement in the affected function. Signed-off-by: Markus Elfring Reviewed-by: Heiko Stuebner Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/auo-pixcir-ts.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c index 398e27c48a51..df8ca856393b 100644 --- a/drivers/input/touchscreen/auo-pixcir-ts.c +++ b/drivers/input/touchscreen/auo-pixcir-ts.c @@ -408,8 +408,6 @@ static void auo_pixcir_input_close(struct input_dev *dev) struct auo_pixcir_ts *ts = input_get_drvdata(dev); auo_pixcir_stop(ts); - - return; } static int __maybe_unused auo_pixcir_suspend(struct device *dev) -- cgit v1.2.3-59-g8ed1b From cba04cdf437d745fac85220d1d692a9ae23d7004 Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Mon, 22 Jan 2018 17:32:46 -0800 Subject: Input: stmfts - set IRQ_NOAUTOEN to the irq flag The interrupt is requested before the device is powered on and it's value in some cases cannot be reliable. It happens on some devices that an interrupt is generated as soon as requested before having the chance to disable the irq. Set the irq flag as IRQ_NOAUTOEN before requesting it. This patch mutes the error: stmfts 2-0049: failed to read events: -11 received sometimes during boot time. Signed-off-by: Andi Shyti Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/stmfts.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c index 2a123e20a42e..efdb1a75a163 100644 --- a/drivers/input/touchscreen/stmfts.c +++ b/drivers/input/touchscreen/stmfts.c @@ -682,6 +682,14 @@ static int stmfts_probe(struct i2c_client *client, input_set_drvdata(sdata->input, sdata); + /* + * stmfts_power_on expects interrupt to be disabled, but + * at this point the device is still off and I do not trust + * the status of the irq line that can generate some spurious + * interrupts. To be on the safe side it's better to not enable + * the interrupts during their request. + */ + irq_set_status_flags(client->irq, IRQ_NOAUTOEN); err = devm_request_threaded_irq(&client->dev, client->irq, NULL, stmfts_irq_handler, IRQF_ONESHOT, @@ -689,9 +697,6 @@ static int stmfts_probe(struct i2c_client *client, if (err) return err; - /* stmfts_power_on expects interrupt to be disabled */ - disable_irq(client->irq); - dev_dbg(&client->dev, "initializing ST-Microelectronics FTS...\n"); err = stmfts_power_on(sdata); -- cgit v1.2.3-59-g8ed1b From 4b3e910d7f430ab76dd37131bb75129878950163 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 23 Jan 2018 10:01:57 -0800 Subject: Input: edt-ft5x06 - fix error handling for factory mode on non-M06 When attempting enter factory mode on firmware that does not support it, we'd error out, but leave the device with interrupts disabled, and thus touch not working. Fix it by moving the check before we disable interrupts/allocate memory for debug buffers. Fixes: fd335ab04b3f ("Input: edt-ft5x06 - add support for M09 firmware version") Reviewed-by: Andi Shyti Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/edt-ft5x06.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index c53a3d7239e7..1e18ca0d1b4e 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -511,6 +511,12 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata) int ret; int error; + if (tsdata->version != EDT_M06) { + dev_err(&client->dev, + "No factory mode support for non-M06 devices\n"); + return -EINVAL; + } + disable_irq(client->irq); if (!tsdata->raw_buffer) { @@ -524,9 +530,6 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata) } /* mode register is 0x3c when in the work mode */ - if (tsdata->version != EDT_M06) - goto m09_out; - error = edt_ft5x06_register_write(tsdata, WORK_REGISTER_OPMODE, 0x03); if (error) { dev_err(&client->dev, @@ -559,11 +562,6 @@ err_out: enable_irq(client->irq); return error; - -m09_out: - dev_err(&client->dev, "No factory mode support for M09/M12/GENERIC_FT\n"); - return -EINVAL; - } static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata) -- cgit v1.2.3-59-g8ed1b From 5e703b883468f9e5c88bde82a2e5b34a89fefa96 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 23 Jan 2018 11:06:56 -0800 Subject: Input: mms114 - do not clobber interrupt trigger Rely on the platform (device tree, ACPI, etc) to properly configure interrupt trigger/polarity instead of hardcoding the falling edge. Reviewed-by: Simon Shields Tested-by: Simon Shields Reviewed-by: Andi Shyti Tested-by: Andi Shyti Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/mms114.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index e5eeb6311f7d..92f2e9da351f 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -497,9 +497,9 @@ static int mms114_probe(struct i2c_client *client, return error; } - error = devm_request_threaded_irq(&client->dev, client->irq, NULL, - mms114_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - dev_name(&client->dev), data); + error = devm_request_threaded_irq(&client->dev, client->irq, + NULL, mms114_interrupt, IRQF_ONESHOT, + dev_name(&client->dev), data); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); return error; -- cgit v1.2.3-59-g8ed1b From 477baf7e9a45538f984216acba371b8bd190d4f3 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 23 Jan 2018 11:11:09 -0800 Subject: Input: mms114 - mark as direct input device mms14 is a touchscreen and thus a direct input device; let's mark it as such. This also allows us to drop some initialization code as input_init_mt_slots() will do that for us. Also add error handling for input_mt_init_slots(). Reviewed-by: Simon Shields Tested-by: Simon Shields Reviewed-by: Andi Shyti Tested-by: Andi Shyti Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/mms114.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 92f2e9da351f..c3480db5d21e 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -462,14 +462,6 @@ static int mms114_probe(struct i2c_client *client, input_dev->open = mms114_input_open; input_dev->close = mms114_input_close; - __set_bit(EV_ABS, input_dev->evbit); - __set_bit(EV_KEY, input_dev->evbit); - __set_bit(BTN_TOUCH, input_dev->keybit); - input_set_abs_params(input_dev, ABS_X, 0, data->pdata->x_size, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, data->pdata->y_size, 0, 0); - - /* For multi touch */ - input_mt_init_slots(input_dev, MMS114_MAX_TOUCH, 0); input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, MMS114_MAX_AREA, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_X, @@ -478,6 +470,11 @@ static int mms114_probe(struct i2c_client *client, 0, data->pdata->y_size, 0, 0); input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); + error = input_mt_init_slots(input_dev, MMS114_MAX_TOUCH, + INPUT_MT_DIRECT); + if (error) + return error; + input_set_drvdata(input_dev, data); i2c_set_clientdata(client, data); -- cgit v1.2.3-59-g8ed1b From 5b0d0033f3f3a3d09178ef0dcdd0d4e1a08666b8 Mon Sep 17 00:00:00 2001 From: Simon Shields Date: Mon, 22 Jan 2018 17:45:09 -0800 Subject: Input: mms114 - drop platform data and use generic APIs The MMS114 platform data has no in-tree users, so drop it. Switch to using the standard touchscreen properties via touchscreen_parse_properties(), and move the old DT parsing code to use device_property_*() APIs. Finally, use touchscreen_report_pos to report x/y coordinates and drop the custom x/y inversion code. Signed-off-by: Simon Shields Reviewed-by: Rob Herring Reviewed-by: Andi Shyti Tested-by: Andi Shyti Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/mms114.txt | 29 ++-- drivers/input/touchscreen/mms114.c | 147 +++++++++------------ include/linux/platform_data/mms114.h | 24 ---- 3 files changed, 82 insertions(+), 118 deletions(-) delete mode 100644 include/linux/platform_data/mms114.h (limited to 'drivers/input/touchscreen') diff --git a/Documentation/devicetree/bindings/input/touchscreen/mms114.txt b/Documentation/devicetree/bindings/input/touchscreen/mms114.txt index 89d4c56c5671..8f9f9f38eff4 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/mms114.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/mms114.txt @@ -4,14 +4,18 @@ Required properties: - compatible: must be "melfas,mms114" - reg: I2C address of the chip - interrupts: interrupt to which the chip is connected -- x-size: horizontal resolution of touchscreen -- y-size: vertical resolution of touchscreen +- touchscreen-size-x: See [1] +- touchscreen-size-y: See [1] Optional properties: -- contact-threshold: -- moving-threshold: -- x-invert: invert X axis -- y-invert: invert Y axis +- touchscreen-fuzz-x: See [1] +- touchscreen-fuzz-y: See [1] +- touchscreen-fuzz-pressure: See [1] +- touchscreen-inverted-x: See [1] +- touchscreen-inverted-y: See [1] +- touchscreen-swapped-x-y: See [1] + +[1]: Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt Example: @@ -22,12 +26,13 @@ Example: compatible = "melfas,mms114"; reg = <0x48>; interrupts = <39 0>; - x-size = <720>; - y-size = <1280>; - contact-threshold = <10>; - moving-threshold = <10>; - x-invert; - y-invert; + touchscreen-size-x = <720>; + touchscreen-size-y = <1280>; + touchscreen-fuzz-x = <10>; + touchscreen-fuzz-y = <10>; + touchscreen-fuzz-pressure = <10>; + touchscreen-inverted-x; + touchscreen-inverted-y; }; /* ... */ diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index c3480db5d21e..69e4288bf8aa 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -12,8 +12,8 @@ #include #include #include +#include #include -#include #include #include @@ -55,7 +55,9 @@ struct mms114_data { struct input_dev *input_dev; struct regulator *core_reg; struct regulator *io_reg; - const struct mms114_platform_data *pdata; + struct touchscreen_properties props; + unsigned int contact_threshold; + unsigned int moving_threshold; /* Use cache data for mode control register(write only) */ u8 cache_mode_control; @@ -143,7 +145,6 @@ static int mms114_write_reg(struct mms114_data *data, unsigned int reg, static void mms114_process_mt(struct mms114_data *data, struct mms114_touch *touch) { - const struct mms114_platform_data *pdata = data->pdata; struct i2c_client *client = data->client; struct input_dev *input_dev = data->input_dev; unsigned int id; @@ -163,16 +164,6 @@ static void mms114_process_mt(struct mms114_data *data, struct mms114_touch *tou id = touch->id - 1; x = touch->x_lo | touch->x_hi << 8; y = touch->y_lo | touch->y_hi << 8; - if (x > pdata->x_size || y > pdata->y_size) { - dev_dbg(&client->dev, - "Wrong touch coordinates (%d, %d)\n", x, y); - return; - } - - if (pdata->x_invert) - x = pdata->x_size - x; - if (pdata->y_invert) - y = pdata->y_size - y; dev_dbg(&client->dev, "id: %d, type: %d, pressed: %d, x: %d, y: %d, width: %d, strength: %d\n", @@ -183,9 +174,8 @@ static void mms114_process_mt(struct mms114_data *data, struct mms114_touch *tou input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, touch->pressed); if (touch->pressed) { + touchscreen_report_pos(input_dev, &data->props, x, y, true); input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, touch->width); - input_report_abs(input_dev, ABS_MT_POSITION_X, x); - input_report_abs(input_dev, ABS_MT_POSITION_Y, y); input_report_abs(input_dev, ABS_MT_PRESSURE, touch->strength); } } @@ -263,7 +253,7 @@ static int mms114_get_version(struct mms114_data *data) static int mms114_setup_regs(struct mms114_data *data) { - const struct mms114_platform_data *pdata = data->pdata; + const struct touchscreen_properties *props = &data->props; int val; int error; @@ -275,32 +265,32 @@ static int mms114_setup_regs(struct mms114_data *data) if (error < 0) return error; - val = (pdata->x_size >> 8) & 0xf; - val |= ((pdata->y_size >> 8) & 0xf) << 4; + val = (props->max_x >> 8) & 0xf; + val |= ((props->max_y >> 8) & 0xf) << 4; error = mms114_write_reg(data, MMS114_XY_RESOLUTION_H, val); if (error < 0) return error; - val = pdata->x_size & 0xff; + val = props->max_x & 0xff; error = mms114_write_reg(data, MMS114_X_RESOLUTION, val); if (error < 0) return error; - val = pdata->y_size & 0xff; + val = props->max_x & 0xff; error = mms114_write_reg(data, MMS114_Y_RESOLUTION, val); if (error < 0) return error; - if (pdata->contact_threshold) { + if (data->contact_threshold) { error = mms114_write_reg(data, MMS114_CONTACT_THRESHOLD, - pdata->contact_threshold); + data->contact_threshold); if (error < 0) return error; } - if (pdata->moving_threshold) { + if (data->moving_threshold) { error = mms114_write_reg(data, MMS114_MOVING_THRESHOLD, - pdata->moving_threshold); + data->moving_threshold); if (error < 0) return error; } @@ -335,9 +325,6 @@ static int mms114_start(struct mms114_data *data) return error; } - if (data->pdata->cfg_pin) - data->pdata->cfg_pin(true); - enable_irq(client->irq); return 0; @@ -350,9 +337,6 @@ static void mms114_stop(struct mms114_data *data) disable_irq(client->irq); - if (data->pdata->cfg_pin) - data->pdata->cfg_pin(false); - error = regulator_disable(data->io_reg); if (error) dev_warn(&client->dev, "Failed to disable vdd: %d\n", error); @@ -376,67 +360,43 @@ static void mms114_input_close(struct input_dev *dev) mms114_stop(data); } -#ifdef CONFIG_OF -static struct mms114_platform_data *mms114_parse_dt(struct device *dev) +static int mms114_parse_legacy_bindings(struct mms114_data *data) { - struct mms114_platform_data *pdata; - struct device_node *np = dev->of_node; - - if (!np) - return NULL; + struct device *dev = &data->client->dev; + struct touchscreen_properties *props = &data->props; - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - dev_err(dev, "failed to allocate platform data\n"); - return NULL; + if (device_property_read_u32(dev, "x-size", &props->max_x)) { + dev_dbg(dev, "failed to get legacy x-size property\n"); + return -EINVAL; } - if (of_property_read_u32(np, "x-size", &pdata->x_size)) { - dev_err(dev, "failed to get x-size property\n"); - return NULL; + if (device_property_read_u32(dev, "y-size", &props->max_y)) { + dev_dbg(dev, "failed to get legacy y-size property\n"); + return -EINVAL; } - if (of_property_read_u32(np, "y-size", &pdata->y_size)) { - dev_err(dev, "failed to get y-size property\n"); - return NULL; - } + device_property_read_u32(dev, "contact-threshold", + &data->contact_threshold); + device_property_read_u32(dev, "moving-threshold", + &data->moving_threshold); - of_property_read_u32(np, "contact-threshold", - &pdata->contact_threshold); - of_property_read_u32(np, "moving-threshold", - &pdata->moving_threshold); + if (device_property_read_bool(dev, "x-invert")) + props->invert_x = true; + if (device_property_read_bool(dev, "y-invert")) + props->invert_y = true; - if (of_find_property(np, "x-invert", NULL)) - pdata->x_invert = true; - if (of_find_property(np, "y-invert", NULL)) - pdata->y_invert = true; + props->swap_x_y = false; - return pdata; -} -#else -static inline struct mms114_platform_data *mms114_parse_dt(struct device *dev) -{ - return NULL; + return 0; } -#endif static int mms114_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct mms114_platform_data *pdata; struct mms114_data *data; struct input_dev *input_dev; int error; - pdata = dev_get_platdata(&client->dev); - if (!pdata) - pdata = mms114_parse_dt(&client->dev); - - if (!pdata) { - dev_err(&client->dev, "Need platform data\n"); - return -EINVAL; - } - if (!i2c_check_functionality(client->adapter, I2C_FUNC_PROTOCOL_MANGLING)) { dev_err(&client->dev, @@ -454,7 +414,38 @@ static int mms114_probe(struct i2c_client *client, data->client = client; data->input_dev = input_dev; - data->pdata = pdata; + + input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X); + input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y); + input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, + 0, MMS114_MAX_AREA, 0, 0); + + touchscreen_parse_properties(input_dev, true, &data->props); + if (!data->props.max_x || !data->props.max_y) { + dev_dbg(&client->dev, + "missing X/Y size properties, trying legacy bindings\n"); + error = mms114_parse_legacy_bindings(data); + if (error) + return error; + + input_set_abs_params(input_dev, ABS_MT_POSITION_X, + 0, data->props.max_x, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, + 0, data->props.max_y, 0, 0); + } + + /* + * The firmware handles movement and pressure fuzz, so + * don't duplicate that in software. + */ + data->moving_threshold = input_abs_get_fuzz(input_dev, + ABS_MT_POSITION_X); + data->contact_threshold = input_abs_get_fuzz(input_dev, + ABS_MT_PRESSURE); + input_abs_set_fuzz(input_dev, ABS_MT_POSITION_X, 0); + input_abs_set_fuzz(input_dev, ABS_MT_POSITION_Y, 0); + input_abs_set_fuzz(input_dev, ABS_MT_PRESSURE, 0); input_dev->name = "MELFAS MMS114 Touchscreen"; input_dev->id.bustype = BUS_I2C; @@ -462,14 +453,6 @@ static int mms114_probe(struct i2c_client *client, input_dev->open = mms114_input_open; input_dev->close = mms114_input_close; - input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, - 0, MMS114_MAX_AREA, 0, 0); - input_set_abs_params(input_dev, ABS_MT_POSITION_X, - 0, data->pdata->x_size, 0, 0); - input_set_abs_params(input_dev, ABS_MT_POSITION_Y, - 0, data->pdata->y_size, 0, 0); - input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); - error = input_mt_init_slots(input_dev, MMS114_MAX_TOUCH, INPUT_MT_DIRECT); if (error) diff --git a/include/linux/platform_data/mms114.h b/include/linux/platform_data/mms114.h deleted file mode 100644 index 5722ebfb2738..000000000000 --- a/include/linux/platform_data/mms114.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2012 Samsung Electronics Co.Ltd - * Author: Joonyoung Shim - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundationr - */ - -#ifndef __LINUX_MMS114_H -#define __LINUX_MMS114_H - -struct mms114_platform_data { - unsigned int x_size; - unsigned int y_size; - unsigned int contact_threshold; - unsigned int moving_threshold; - bool x_invert; - bool y_invert; - - void (*cfg_pin)(bool); -}; - -#endif /* __LINUX_MMS114_H */ -- cgit v1.2.3-59-g8ed1b From 72b0c0cf9720cd139829610cfcd9ac294451a9f8 Mon Sep 17 00:00:00 2001 From: Simon Shields Date: Tue, 23 Jan 2018 12:02:39 -0800 Subject: Input: mms114 - add support for mms152 MMS152 has no configuration registers, but the packet format used in interrupts is identical to mms114. Signed-off-by: Simon Shields Reviewed-by: Andi Shyti Tested-by: Andi Shyti Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/mms114.txt | 6 +- drivers/input/touchscreen/mms114.c | 92 +++++++++++++++++----- 2 files changed, 77 insertions(+), 21 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/Documentation/devicetree/bindings/input/touchscreen/mms114.txt b/Documentation/devicetree/bindings/input/touchscreen/mms114.txt index 8f9f9f38eff4..2cd954051d29 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/mms114.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/mms114.txt @@ -1,7 +1,9 @@ -* MELFAS MMS114 touchscreen controller +* MELFAS MMS114/MMS152 touchscreen controller Required properties: -- compatible: must be "melfas,mms114" +- compatible: should be one of: + - "melfas,mms114" + - "melfas,mms152" - reg: I2C address of the chip - interrupts: interrupt to which the chip is connected - touchscreen-size-x: See [1] diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 69e4288bf8aa..c54f4afe1103 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,9 @@ #define MMS114_INFOMATION 0x10 #define MMS114_TSP_REV 0xF0 +#define MMS152_FW_REV 0xE1 +#define MMS152_COMPAT_GROUP 0xF2 + /* Minimum delay time is 50us between stop and start signal of i2c */ #define MMS114_I2C_DELAY 50 @@ -50,12 +54,18 @@ #define MMS114_TYPE_TOUCHSCREEN 1 #define MMS114_TYPE_TOUCHKEY 2 +enum mms_type { + TYPE_MMS114 = 114, + TYPE_MMS152 = 152, +}; + struct mms114_data { struct i2c_client *client; struct input_dev *input_dev; struct regulator *core_reg; struct regulator *io_reg; struct touchscreen_properties props; + enum mms_type type; unsigned int contact_threshold; unsigned int moving_threshold; @@ -239,14 +249,33 @@ static int mms114_get_version(struct mms114_data *data) { struct device *dev = &data->client->dev; u8 buf[6]; + int group; int error; - error = __mms114_read_reg(data, MMS114_TSP_REV, 6, buf); - if (error < 0) - return error; + switch (data->type) { + case TYPE_MMS152: + error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf); + if (error) + return error; + + group = i2c_smbus_read_byte_data(data->client, + MMS152_COMPAT_GROUP); + if (group < 0) + return group; + + dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x, Compat group: %c\n", + buf[0], buf[1], buf[2], group); + break; + + case TYPE_MMS114: + error = __mms114_read_reg(data, MMS114_TSP_REV, 6, buf); + if (error) + return error; - dev_info(dev, "TSP Rev: 0x%x, HW Rev: 0x%x, Firmware Ver: 0x%x\n", - buf[0], buf[1], buf[3]); + dev_info(dev, "TSP Rev: 0x%x, HW Rev: 0x%x, Firmware Ver: 0x%x\n", + buf[0], buf[1], buf[3]); + break; + } return 0; } @@ -261,6 +290,10 @@ static int mms114_setup_regs(struct mms114_data *data) if (error < 0) return error; + /* MMS152 has no configuration or power on registers */ + if (data->type == TYPE_MMS152) + return 0; + error = mms114_set_active(data, true); if (error < 0) return error; @@ -395,6 +428,7 @@ static int mms114_probe(struct i2c_client *client, { struct mms114_data *data; struct input_dev *input_dev; + const void *match_data; int error; if (!i2c_check_functionality(client->adapter, @@ -415,6 +449,13 @@ 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); + if (!match_data) + return -EINVAL; + + data->type = (enum mms_type)match_data; + input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X); input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y); input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); @@ -435,19 +476,26 @@ static int mms114_probe(struct i2c_client *client, 0, data->props.max_y, 0, 0); } - /* - * The firmware handles movement and pressure fuzz, so - * don't duplicate that in software. - */ - data->moving_threshold = input_abs_get_fuzz(input_dev, - ABS_MT_POSITION_X); - data->contact_threshold = input_abs_get_fuzz(input_dev, - ABS_MT_PRESSURE); - input_abs_set_fuzz(input_dev, ABS_MT_POSITION_X, 0); - input_abs_set_fuzz(input_dev, ABS_MT_POSITION_Y, 0); - input_abs_set_fuzz(input_dev, ABS_MT_PRESSURE, 0); - - input_dev->name = "MELFAS MMS114 Touchscreen"; + if (data->type == TYPE_MMS114) { + /* + * The firmware handles movement and pressure fuzz, so + * don't duplicate that in software. + */ + data->moving_threshold = input_abs_get_fuzz(input_dev, + ABS_MT_POSITION_X); + data->contact_threshold = input_abs_get_fuzz(input_dev, + ABS_MT_PRESSURE); + input_abs_set_fuzz(input_dev, ABS_MT_POSITION_X, 0); + input_abs_set_fuzz(input_dev, ABS_MT_POSITION_Y, 0); + input_abs_set_fuzz(input_dev, ABS_MT_PRESSURE, 0); + } + + input_dev->name = devm_kasprintf(&client->dev, GFP_KERNEL, + "MELFAS MMS%d Touchscreen", + data->type); + if (!input_dev->name) + return -ENOMEM; + input_dev->id.bustype = BUS_I2C; input_dev->dev.parent = &client->dev; input_dev->open = mms114_input_open; @@ -549,7 +597,13 @@ MODULE_DEVICE_TABLE(i2c, mms114_id); #ifdef CONFIG_OF static const struct of_device_id mms114_dt_match[] = { - { .compatible = "melfas,mms114" }, + { + .compatible = "melfas,mms114", + .data = (void *)TYPE_MMS114, + }, { + .compatible = "melfas,mms152", + .data = (void *)TYPE_MMS152, + }, { } }; MODULE_DEVICE_TABLE(of, mms114_dt_match); -- cgit v1.2.3-59-g8ed1b From a22e88fd7da44616388d366030e9bd170ab97788 Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Mon, 29 Jan 2018 11:43:52 -0800 Subject: Input: mms114 - replace mdelay with msleep 200 milliseconds is a very long time to keep the CPU busy looping. Use msleep instead. Signed-off-by: Andi Shyti Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/mms114.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index c54f4afe1103..7b1307c1374b 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -349,7 +349,7 @@ static int mms114_start(struct mms114_data *data) return error; } - mdelay(MMS114_POWERON_DELAY); + msleep(MMS114_POWERON_DELAY); error = mms114_setup_regs(data); if (error < 0) { -- cgit v1.2.3-59-g8ed1b From 7546db025f265fc0d79c754e912d5fb5fcab5b89 Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Mon, 29 Jan 2018 11:44:44 -0800 Subject: Input: mms114 - use BIT() macro instead of explicit shifting Signed-off-by: Andi Shyti Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/mms114.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 7b1307c1374b..1483af9e3d05 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -21,7 +21,7 @@ /* Write only registers */ #define MMS114_MODE_CONTROL 0x01 #define MMS114_OPERATION_MODE_MASK 0xE -#define MMS114_ACTIVE (1 << 1) +#define MMS114_ACTIVE BIT(1) #define MMS114_XY_RESOLUTION_H 0x02 #define MMS114_X_RESOLUTION 0x03 -- cgit v1.2.3-59-g8ed1b From 13e945401a8dd5098ed07d242542e90be9f1c19d Mon Sep 17 00:00:00 2001 From: Andi Shyti Date: Mon, 29 Jan 2018 11:46:02 -0800 Subject: Input: mms114 - fix typo in definition It's 'MMS114_INFORMATION', not 'MMS114_INFOMATION' Signed-off-by: Andi Shyti Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/mms114.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 1483af9e3d05..db4f6bb502e3 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -31,7 +31,7 @@ /* Read only registers */ #define MMS114_PACKET_SIZE 0x0F -#define MMS114_INFOMATION 0x10 +#define MMS114_INFORMATION 0x10 #define MMS114_TSP_REV 0xF0 #define MMS152_FW_REV 0xE1 @@ -213,7 +213,7 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id) touch_size = packet_size / MMS114_PACKET_NUM; - error = __mms114_read_reg(data, MMS114_INFOMATION, packet_size, + error = __mms114_read_reg(data, MMS114_INFORMATION, packet_size, (u8 *)touch); if (error < 0) goto out; -- cgit v1.2.3-59-g8ed1b From fafef982c7353e8982b951e40573e990ccf0ed00 Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Fri, 26 Jan 2018 11:08:59 -0800 Subject: Input: goodix - use generic touchscreen_properties Use touchscreen_properties structure instead of implementing all properties by our own. It allows us to reuse generic code for parsing device-tree properties (which was implemented manually in the driver for now). Additionally, it allows us to report events using generic touchscreen_report_pos(), which automatically handles inverted and swapped axes. This fixes the issue with the custom code incorrectly handling case where ts->inverted_x and ts->swapped_x_y were true, but ts->inverted_y was false. Assuming we have 720x1280 touch panel, ts->abs_x_max == 1279 and ts->abs_y_max == 719 (because we inverted that in goodix_read_config()). Now let's assume that we received event from (0:0) position (in touch panel original coordinates). In function goodix_ts_report_touch() we calculate input_x as 1279, but after swapping input_y takes that value (which is more that maximum 719 value reported during initialization). Note that since touchscreen coordinates are 0-indexed, we now report touchscreen range as (0:size-1). Developed and tested on custom DT-based device with gt1151 touch panel. Signed-off-by: Marcin Niestroj [dtor: fix endianness annotation reported by sparse, handle errors when initializing MT slots] Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 141 +++++++++++++++---------------------- 1 file changed, 58 insertions(+), 83 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index ecec8eb17f28..9736c83dd418 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -43,11 +44,7 @@ struct goodix_ts_data { struct i2c_client *client; struct input_dev *input_dev; const struct goodix_chip_data *chip; - int abs_x_max; - int abs_y_max; - bool swapped_x_y; - bool inverted_x; - bool inverted_y; + struct touchscreen_properties prop; unsigned int max_touch_num; unsigned int int_trigger_type; struct gpio_desc *gpiod_int; @@ -160,7 +157,7 @@ static int goodix_i2c_read(struct i2c_client *client, u16 reg, u8 *buf, int len) { struct i2c_msg msgs[2]; - u16 wbuf = cpu_to_be16(reg); + __be16 wbuf = cpu_to_be16(reg); int ret; msgs[0].flags = 0; @@ -295,18 +292,10 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) int input_y = get_unaligned_le16(&coor_data[3]); int input_w = get_unaligned_le16(&coor_data[5]); - /* Inversions have to happen before axis swapping */ - if (ts->inverted_x) - input_x = ts->abs_x_max - input_x; - if (ts->inverted_y) - input_y = ts->abs_y_max - input_y; - if (ts->swapped_x_y) - swap(input_x, input_y); - input_mt_slot(ts->input_dev, id); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y); + touchscreen_report_pos(ts->input_dev, &ts->prop, + input_x, input_y, true); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); } @@ -579,44 +568,27 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) static void goodix_read_config(struct goodix_ts_data *ts) { u8 config[GOODIX_CONFIG_MAX_LENGTH]; + int x_max, y_max; int error; error = goodix_i2c_read(ts->client, ts->chip->config_addr, config, ts->chip->config_len); if (error) { - dev_warn(&ts->client->dev, - "Error reading config (%d), using defaults\n", + dev_warn(&ts->client->dev, "Error reading config: %d\n", error); - ts->abs_x_max = GOODIX_MAX_WIDTH; - ts->abs_y_max = GOODIX_MAX_HEIGHT; - if (ts->swapped_x_y) - swap(ts->abs_x_max, ts->abs_y_max); ts->int_trigger_type = GOODIX_INT_TRIGGER; ts->max_touch_num = GOODIX_MAX_CONTACTS; return; } - ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); - ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); - if (ts->swapped_x_y) - swap(ts->abs_x_max, ts->abs_y_max); ts->int_trigger_type = config[TRIGGER_LOC] & 0x03; ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f; - if (!ts->abs_x_max || !ts->abs_y_max || !ts->max_touch_num) { - dev_err(&ts->client->dev, - "Invalid config, using defaults\n"); - ts->abs_x_max = GOODIX_MAX_WIDTH; - ts->abs_y_max = GOODIX_MAX_HEIGHT; - if (ts->swapped_x_y) - swap(ts->abs_x_max, ts->abs_y_max); - ts->max_touch_num = GOODIX_MAX_CONTACTS; - } - if (dmi_check_system(rotated_screen)) { - ts->inverted_x = true; - ts->inverted_y = true; - dev_dbg(&ts->client->dev, - "Applying '180 degrees rotated screen' quirk\n"); + x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); + y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); + if (x_max && y_max) { + input_abs_set_max(ts->input_dev, ABS_MT_POSITION_X, x_max - 1); + input_abs_set_max(ts->input_dev, ABS_MT_POSITION_Y, y_max - 1); } } @@ -676,32 +648,28 @@ static int goodix_i2c_test(struct i2c_client *client) } /** - * goodix_request_input_dev - Allocate, populate and register the input device + * goodix_configure_dev - Finish device initialization * * @ts: our goodix_ts_data pointer * - * Must be called during probe + * Must be called from probe to finish initialization of the device. + * Contains the common initialization code for both devices that + * declare gpio pins and devices that do not. It is either called + * directly from probe or from request_firmware_wait callback. */ -static int goodix_request_input_dev(struct goodix_ts_data *ts) +static int goodix_configure_dev(struct goodix_ts_data *ts) { int error; + ts->int_trigger_type = GOODIX_INT_TRIGGER; + ts->max_touch_num = GOODIX_MAX_CONTACTS; + ts->input_dev = devm_input_allocate_device(&ts->client->dev); if (!ts->input_dev) { dev_err(&ts->client->dev, "Failed to allocate input device."); return -ENOMEM; } - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, - 0, ts->abs_x_max, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, - 0, ts->abs_y_max, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); - input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); - - input_mt_init_slots(ts->input_dev, ts->max_touch_num, - INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); - ts->input_dev->name = "Goodix Capacitive TouchScreen"; ts->input_dev->phys = "input/ts"; ts->input_dev->id.bustype = BUS_I2C; @@ -712,42 +680,49 @@ static int goodix_request_input_dev(struct goodix_ts_data *ts) /* Capacitive Windows/Home button on some devices */ input_set_capability(ts->input_dev, EV_KEY, KEY_LEFTMETA); - error = input_register_device(ts->input_dev); - if (error) { - dev_err(&ts->client->dev, - "Failed to register input device: %d", error); - return error; - } + input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_X); + input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_Y); + input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); - return 0; -} + /* Read configuration and apply touchscreen parameters */ + goodix_read_config(ts); -/** - * goodix_configure_dev - Finish device initialization - * - * @ts: our goodix_ts_data pointer - * - * Must be called from probe to finish initialization of the device. - * Contains the common initialization code for both devices that - * declare gpio pins and devices that do not. It is either called - * directly from probe or from request_firmware_wait callback. - */ -static int goodix_configure_dev(struct goodix_ts_data *ts) -{ - int error; + /* Try overriding touchscreen parameters via device properties */ + touchscreen_parse_properties(ts->input_dev, true, &ts->prop); - ts->swapped_x_y = device_property_read_bool(&ts->client->dev, - "touchscreen-swapped-x-y"); - ts->inverted_x = device_property_read_bool(&ts->client->dev, - "touchscreen-inverted-x"); - ts->inverted_y = device_property_read_bool(&ts->client->dev, - "touchscreen-inverted-y"); + if (!ts->prop.max_x || !ts->prop.max_y || !ts->max_touch_num) { + dev_err(&ts->client->dev, "Invalid config, using defaults\n"); + ts->prop.max_x = GOODIX_MAX_WIDTH - 1; + ts->prop.max_y = GOODIX_MAX_HEIGHT - 1; + ts->max_touch_num = GOODIX_MAX_CONTACTS; + input_abs_set_max(ts->input_dev, + ABS_MT_POSITION_X, ts->prop.max_x); + input_abs_set_max(ts->input_dev, + ABS_MT_POSITION_Y, ts->prop.max_y); + } - goodix_read_config(ts); + if (dmi_check_system(rotated_screen)) { + ts->prop.invert_x = true; + ts->prop.invert_y = true; + dev_dbg(&ts->client->dev, + "Applying '180 degrees rotated screen' quirk\n"); + } - error = goodix_request_input_dev(ts); - if (error) + error = input_mt_init_slots(ts->input_dev, ts->max_touch_num, + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); + if (error) { + dev_err(&ts->client->dev, + "Failed to initialize MT slots: %d", error); + return error; + } + + error = input_register_device(ts->input_dev); + if (error) { + dev_err(&ts->client->dev, + "Failed to register input device: %d", error); return error; + } ts->irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; error = goodix_request_irq(ts); -- cgit v1.2.3-59-g8ed1b