Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'input-for-v6.4-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input updates from Dmitry Torokhov:

- a new driver for Novatek touch controllers

- a new driver for power button for NXP BBNSM

- a skeleton KUnit tests for the input core

- improvements to Xpad game controller driver to support more devices

- improvements to edt-ft5x06, hideep and other drivers

* tag 'input-for-v6.4-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (42 commits)
Revert "Input: xpad - fix support for some third-party controllers"
dt-bindings: input: pwm-beeper: convert to dt schema
Input: xpad - fix PowerA EnWired Controller guide button
Input: xpad - add constants for GIP interface numbers
Input: synaptics-rmi4 - fix function name in kerneldoc
Input: raspberrypi-ts - fix refcount leak in rpi_ts_probe
Input: edt-ft5x06 - select REGMAP_I2C
Input: melfas_mip4 - report palm touches
Input: cma3000_d0x - remove unneeded code
Input: edt-ft5x06 - calculate points data length only once
Input: edt-ft5x06 - unify the crc check
Input: edt-ft5x06 - convert to use regmap API
Input: edt-ft5x06 - don't print error messages with dev_dbg()
Input: edt-ft5x06 - remove code duplication
Input: edt-ft5x06 - don't recalculate the CRC
Input: edt-ft5x06 - add spaces to ensure format specification
Input: edt-ft5x06 - remove unnecessary blank lines
Input: edt-ft5x06 - fix indentation
Input: tsc2007 - enable cansleep pendown GPIO
Input: Add KUnit tests for some of the input core helper functions
...

+1068 -325
+1 -1
Documentation/devicetree/bindings/input/google,cros-ec-keyb.yaml
··· 45 45 when the keyboard has a custom design for the top row keys. 46 46 47 47 dependencies: 48 - function-row-phsymap: [ 'linux,keymap' ] 48 + function-row-physmap: [ 'linux,keymap' ] 49 49 google,needs-ghost-filter: [ 'linux,keymap' ] 50 50 51 51 required:
-24
Documentation/devicetree/bindings/input/pwm-beeper.txt
··· 1 - * PWM beeper device tree bindings 2 - 3 - Registers a PWM device as beeper. 4 - 5 - Required properties: 6 - - compatible: should be "pwm-beeper" 7 - - pwms: phandle to the physical PWM device 8 - 9 - Optional properties: 10 - - amp-supply: phandle to a regulator that acts as an amplifier for the beeper 11 - - beeper-hz: bell frequency in Hz 12 - 13 - Example: 14 - 15 - beeper_amp: amplifier { 16 - compatible = "fixed-regulator"; 17 - gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; 18 - }; 19 - 20 - beeper { 21 - compatible = "pwm-beeper"; 22 - pwms = <&pwm0>; 23 - amp-supply = <&beeper_amp>; 24 - };
+41
Documentation/devicetree/bindings/input/pwm-beeper.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/input/pwm-beeper.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: PWM beeper 8 + 9 + maintainers: 10 + - Sascha Hauer <s.hauer@pengutronix.de> 11 + 12 + properties: 13 + compatible: 14 + const: pwm-beeper 15 + 16 + pwms: 17 + maxItems: 1 18 + 19 + amp-supply: 20 + description: an amplifier for the beeper 21 + 22 + beeper-hz: 23 + description: bell frequency in Hz 24 + minimum: 10 25 + maximum: 10000 26 + 27 + required: 28 + - compatible 29 + - pwms 30 + 31 + unevaluatedProperties: false 32 + 33 + examples: 34 + - | 35 + #include <dt-bindings/gpio/gpio.h> 36 + beeper { 37 + compatible = "pwm-beeper"; 38 + pwms = <&pwm0>; 39 + amp-supply = <&beeper_amp>; 40 + beeper-hz = <1000>; 41 + };
+6
MAINTAINERS
··· 14877 14877 F: tools/include/nolibc/ 14878 14878 F: tools/testing/selftests/nolibc/ 14879 14879 14880 + NOVATEK NVT-TS I2C TOUCHSCREEN DRIVER 14881 + M: Hans de Goede <hdegoede@redhat.com> 14882 + L: linux-input@vger.kernel.org 14883 + S: Maintained 14884 + F: drivers/input/touchscreen/novatek-nvt-ts.c 14885 + 14880 14886 NSDEPS 14881 14887 M: Matthias Maennich <maennich@google.com> 14882 14888 S: Maintained
+1
arch/arm/mach-pxa/spitz.c
··· 25 25 #include <linux/spi/pxa2xx_spi.h> 26 26 #include <linux/mtd/sharpsl.h> 27 27 #include <linux/mtd/physmap.h> 28 + #include <linux/input-event-codes.h> 28 29 #include <linux/input/matrix_keypad.h> 29 30 #include <linux/regulator/machine.h> 30 31 #include <linux/io.h>
+10
drivers/input/Kconfig
··· 166 166 To compile this driver as a module, choose M here: the 167 167 module will be called evbug. 168 168 169 + config INPUT_KUNIT_TEST 170 + tristate "KUnit tests for Input" if !KUNIT_ALL_TESTS 171 + depends on INPUT && KUNIT=y 172 + default KUNIT_ALL_TESTS 173 + help 174 + Say Y here if you want to build the KUnit tests for the input 175 + subsystem. 176 + 177 + If in doubt, say "N". 178 + 169 179 config INPUT_APMPOWER 170 180 tristate "Input Power Event -> APM Bridge" if EXPERT 171 181 depends on INPUT && APM_EMULATION
+1
drivers/input/Makefile
··· 26 26 obj-$(CONFIG_INPUT_TABLET) += tablet/ 27 27 obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ 28 28 obj-$(CONFIG_INPUT_MISC) += misc/ 29 + obj-$(CONFIG_INPUT_KUNIT_TEST) += tests/ 29 30 30 31 obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o 31 32
+21 -2
drivers/input/joystick/xpad.c
··· 126 126 char *name; 127 127 u8 mapping; 128 128 u8 xtype; 129 - u8 packet_type; 130 129 } xpad_device[] = { 131 130 { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 }, 132 131 { 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 }, ··· 474 475 XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ 475 476 XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */ 476 477 XPAD_XBOX360_VENDOR(0x1038), /* SteelSeries Controllers */ 478 + XPAD_XBOXONE_VENDOR(0x10f5), /* Turtle Beach Controllers */ 477 479 XPAD_XBOX360_VENDOR(0x11c9), /* Nacon GC100XF */ 478 480 XPAD_XBOX360_VENDOR(0x1209), /* Ardwiino Controllers */ 479 481 XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */ ··· 493 493 XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */ 494 494 XPAD_XBOX360_VENDOR(0x2563), /* OneXPlayer Gamepad */ 495 495 XPAD_XBOX360_VENDOR(0x260d), /* Dareu H101 */ 496 + XPAD_XBOX360_VENDOR(0x2c22), /* Qanba Controllers */ 496 497 XPAD_XBOX360_VENDOR(0x2dc8), /* 8BitDo Pro 2 Wired Controller */ 497 498 XPAD_XBOXONE_VENDOR(0x2dc8), /* 8BitDo Pro 2 Wired Controller for Xbox */ 498 499 XPAD_XBOXONE_VENDOR(0x2e24), /* Hyperkin Duke X-Box One pad */ ··· 559 558 #define GIP_MOTOR_RT BIT(2) 560 559 #define GIP_MOTOR_LT BIT(3) 561 560 #define GIP_MOTOR_ALL (GIP_MOTOR_R | GIP_MOTOR_L | GIP_MOTOR_RT | GIP_MOTOR_LT) 561 + 562 + #define GIP_WIRED_INTF_DATA 0 563 + #define GIP_WIRED_INTF_AUDIO 1 562 564 563 565 /* 564 566 * This packet is required for all Xbox One pads with 2015 ··· 1396 1392 unsigned long flags; 1397 1393 int retval; 1398 1394 1395 + if (usb_ifnum_to_if(xpad->udev, GIP_WIRED_INTF_AUDIO)) { 1396 + /* 1397 + * Explicitly disable the audio interface. This is needed 1398 + * for some controllers, such as the PowerA Enhanced Wired 1399 + * Controller for Series X|S (0x20d6:0x200e) to report the 1400 + * guide button. 1401 + */ 1402 + retval = usb_set_interface(xpad->udev, 1403 + GIP_WIRED_INTF_AUDIO, 0); 1404 + if (retval) 1405 + dev_warn(&xpad->dev->dev, 1406 + "unable to disable audio interface: %d\n", 1407 + retval); 1408 + } 1409 + 1399 1410 spin_lock_irqsave(&xpad->odata_lock, flags); 1400 1411 1401 1412 /* ··· 2022 2003 } 2023 2004 2024 2005 if (xpad->xtype == XTYPE_XBOXONE && 2025 - intf->cur_altsetting->desc.bInterfaceNumber != 0) { 2006 + intf->cur_altsetting->desc.bInterfaceNumber != GIP_WIRED_INTF_DATA) { 2026 2007 /* 2027 2008 * The Xbox One controller lists three interfaces all with the 2028 2009 * same interface class, subclass and protocol. Differentiate by
+3
drivers/input/keyboard/gpio_keys.c
··· 770 770 &button->type)) 771 771 button->type = EV_KEY; 772 772 773 + fwnode_property_read_u32(child, "linux,input-value", 774 + (u32 *)&button->value); 775 + 773 776 button->wakeup = 774 777 fwnode_property_read_bool(child, "wakeup-source") || 775 778 /* legacy name */
+1 -1
drivers/input/keyboard/iqs62x-keys.c
··· 320 320 if (ret) 321 321 dev_err(&pdev->dev, "Failed to unregister notifier: %d\n", ret); 322 322 323 - return ret; 323 + return 0; 324 324 } 325 325 326 326 static struct platform_driver iqs62x_keys_platform_driver = {
+2 -4
drivers/input/keyboard/matrix_keypad.c
··· 425 425 return ERR_PTR(-EINVAL); 426 426 } 427 427 428 - if (of_get_property(np, "linux,no-autorepeat", NULL)) 429 - pdata->no_autorepeat = true; 428 + pdata->no_autorepeat = of_property_read_bool(np, "linux,no-autorepeat"); 430 429 431 430 pdata->wakeup = of_property_read_bool(np, "wakeup-source") || 432 431 of_property_read_bool(np, "linux,wakeup"); /* legacy */ 433 432 434 - if (of_get_property(np, "gpio-activelow", NULL)) 435 - pdata->active_low = true; 433 + pdata->active_low = of_property_read_bool(np, "gpio-activelow"); 436 434 437 435 pdata->drive_inactive_cols = 438 436 of_property_read_bool(np, "drive-inactive-cols");
+1 -2
drivers/input/keyboard/omap4-keypad.c
··· 274 274 if (err) 275 275 return err; 276 276 277 - if (of_get_property(np, "linux,input-no-autorepeat", NULL)) 278 - keypad_data->no_autorepeat = true; 277 + keypad_data->no_autorepeat = of_property_read_bool(np, "linux,input-no-autorepeat"); 279 278 280 279 return 0; 281 280 }
+1 -2
drivers/input/keyboard/samsung-keypad.c
··· 291 291 *keymap++ = KEY(row, col, key_code); 292 292 } 293 293 294 - if (of_get_property(np, "linux,input-no-autorepeat", NULL)) 295 - pdata->no_autorepeat = true; 294 + pdata->no_autorepeat = of_property_read_bool(np, "linux,input-no-autorepeat"); 296 295 297 296 pdata->wakeup = of_property_read_bool(np, "wakeup-source") || 298 297 /* legacy name */
+1 -1
drivers/input/keyboard/st-keyscan.c
··· 259 259 .driver = { 260 260 .name = "st-keyscan", 261 261 .pm = pm_sleep_ptr(&keyscan_dev_pm_ops), 262 - .of_match_table = of_match_ptr(keyscan_of_match), 262 + .of_match_table = keyscan_of_match, 263 263 } 264 264 }; 265 265
+1 -2
drivers/input/keyboard/tegra-kbc.c
··· 504 504 if (!of_property_read_u32(np, "nvidia,repeat-delay-ms", &prop)) 505 505 kbc->repeat_cnt = prop; 506 506 507 - if (of_find_property(np, "nvidia,needs-ghost-filter", NULL)) 508 - kbc->use_ghost_filter = true; 507 + kbc->use_ghost_filter = of_property_present(np, "nvidia,needs-ghost-filter"); 509 508 510 509 if (of_property_read_bool(np, "wakeup-source") || 511 510 of_property_read_bool(np, "nvidia,wakeup-source")) /* legacy */
+1 -1
drivers/input/keyboard/tm2-touchkey.c
··· 354 354 .driver = { 355 355 .name = TM2_TOUCHKEY_DEV_NAME, 356 356 .pm = pm_sleep_ptr(&tm2_touchkey_pm_ops), 357 - .of_match_table = of_match_ptr(tm2_touchkey_of_match), 357 + .of_match_table = tm2_touchkey_of_match, 358 358 }, 359 359 .probe_new = tm2_touchkey_probe, 360 360 .id_table = tm2_touchkey_id_table,
+11
drivers/input/misc/Kconfig
··· 119 119 To compile this driver as a module, choose M here: the 120 120 module will be called atmel_captouch. 121 121 122 + config INPUT_BBNSM_PWRKEY 123 + tristate "NXP BBNSM Power Key Driver" 124 + depends on ARCH_MXC || COMPILE_TEST 125 + depends on OF 126 + help 127 + This is the bbnsm powerkey driver for the NXP i.MX application 128 + processors. 129 + 130 + To compile this driver as a module, choose M here; the 131 + module will be called bbnsm_pwrkey. 132 + 122 133 config INPUT_BMA150 123 134 tristate "BMA150/SMB380 acceleration sensor support" 124 135 depends on I2C
+1
drivers/input/misc/Makefile
··· 21 21 obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o 22 22 obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o 23 23 obj-$(CONFIG_INPUT_ATMEL_CAPTOUCH) += atmel_captouch.o 24 + obj-$(CONFIG_INPUT_BBNSM_PWRKEY) += nxp-bbnsm-pwrkey.o 24 25 obj-$(CONFIG_INPUT_BMA150) += bma150.o 25 26 obj-$(CONFIG_INPUT_CM109) += cm109.o 26 27 obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o
-2
drivers/input/misc/cma3000_d0x.c
··· 325 325 input_dev->open = cma3000_open; 326 326 input_dev->close = cma3000_close; 327 327 328 - __set_bit(EV_ABS, input_dev->evbit); 329 - 330 328 input_set_abs_params(input_dev, ABS_X, 331 329 -data->g_range, data->g_range, pdata->fuzz_x, 0); 332 330 input_set_abs_params(input_dev, ABS_Y,
+1 -1
drivers/input/misc/hp_sdc_rtc.c
··· 265 265 return 0; 266 266 } 267 267 268 - static int hp_sdc_rtc_proc_show(struct seq_file *m, void *v) 268 + static int __maybe_unused hp_sdc_rtc_proc_show(struct seq_file *m, void *v) 269 269 { 270 270 #define YN(bit) ("no") 271 271 #define NY(bit) ("yes")
+193
drivers/input/misc/nxp-bbnsm-pwrkey.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + // 3 + // Copyright 2022 NXP. 4 + 5 + #include <linux/device.h> 6 + #include <linux/err.h> 7 + #include <linux/init.h> 8 + #include <linux/input.h> 9 + #include <linux/interrupt.h> 10 + #include <linux/io.h> 11 + #include <linux/jiffies.h> 12 + #include <linux/kernel.h> 13 + #include <linux/mfd/syscon.h> 14 + #include <linux/module.h> 15 + #include <linux/of.h> 16 + #include <linux/of_address.h> 17 + #include <linux/platform_device.h> 18 + #include <linux/pm_wakeirq.h> 19 + #include <linux/regmap.h> 20 + 21 + #define BBNSM_CTRL 0x8 22 + #define BBNSM_INT_EN 0x10 23 + #define BBNSM_EVENTS 0x14 24 + #define BBNSM_PAD_CTRL 0x24 25 + 26 + #define BBNSM_BTN_PRESSED BIT(7) 27 + #define BBNSM_PWR_ON BIT(6) 28 + #define BBNSM_BTN_OFF BIT(5) 29 + #define BBNSM_EMG_OFF BIT(4) 30 + #define BBNSM_PWRKEY_EVENTS (BBNSM_PWR_ON | BBNSM_BTN_OFF | BBNSM_EMG_OFF) 31 + #define BBNSM_DP_EN BIT(24) 32 + 33 + #define DEBOUNCE_TIME 30 34 + #define REPEAT_INTERVAL 60 35 + 36 + struct bbnsm_pwrkey { 37 + struct regmap *regmap; 38 + int irq; 39 + int keycode; 40 + int keystate; /* 1:pressed */ 41 + struct timer_list check_timer; 42 + struct input_dev *input; 43 + }; 44 + 45 + static void bbnsm_pwrkey_check_for_events(struct timer_list *t) 46 + { 47 + struct bbnsm_pwrkey *bbnsm = from_timer(bbnsm, t, check_timer); 48 + struct input_dev *input = bbnsm->input; 49 + u32 state; 50 + 51 + regmap_read(bbnsm->regmap, BBNSM_EVENTS, &state); 52 + 53 + state = state & BBNSM_BTN_PRESSED ? 1 : 0; 54 + 55 + /* only report new event if status changed */ 56 + if (state ^ bbnsm->keystate) { 57 + bbnsm->keystate = state; 58 + input_event(input, EV_KEY, bbnsm->keycode, state); 59 + input_sync(input); 60 + pm_relax(bbnsm->input->dev.parent); 61 + } 62 + 63 + /* repeat check if pressed long */ 64 + if (state) 65 + mod_timer(&bbnsm->check_timer, 66 + jiffies + msecs_to_jiffies(REPEAT_INTERVAL)); 67 + } 68 + 69 + static irqreturn_t bbnsm_pwrkey_interrupt(int irq, void *dev_id) 70 + { 71 + struct platform_device *pdev = dev_id; 72 + struct bbnsm_pwrkey *bbnsm = platform_get_drvdata(pdev); 73 + u32 event; 74 + 75 + regmap_read(bbnsm->regmap, BBNSM_EVENTS, &event); 76 + if (!(event & BBNSM_BTN_OFF)) 77 + return IRQ_NONE; 78 + 79 + pm_wakeup_event(bbnsm->input->dev.parent, 0); 80 + 81 + mod_timer(&bbnsm->check_timer, 82 + jiffies + msecs_to_jiffies(DEBOUNCE_TIME)); 83 + 84 + /* clear PWR OFF */ 85 + regmap_write(bbnsm->regmap, BBNSM_EVENTS, BBNSM_BTN_OFF); 86 + 87 + return IRQ_HANDLED; 88 + } 89 + 90 + static void bbnsm_pwrkey_act(void *pdata) 91 + { 92 + struct bbnsm_pwrkey *bbnsm = pdata; 93 + 94 + timer_shutdown_sync(&bbnsm->check_timer); 95 + } 96 + 97 + static int bbnsm_pwrkey_probe(struct platform_device *pdev) 98 + { 99 + struct bbnsm_pwrkey *bbnsm; 100 + struct input_dev *input; 101 + struct device_node *np = pdev->dev.of_node; 102 + int error; 103 + 104 + bbnsm = devm_kzalloc(&pdev->dev, sizeof(*bbnsm), GFP_KERNEL); 105 + if (!bbnsm) 106 + return -ENOMEM; 107 + 108 + bbnsm->regmap = syscon_node_to_regmap(np->parent); 109 + if (IS_ERR(bbnsm->regmap)) { 110 + dev_err(&pdev->dev, "bbnsm pwerkey get regmap failed\n"); 111 + return PTR_ERR(bbnsm->regmap); 112 + } 113 + 114 + if (device_property_read_u32(&pdev->dev, "linux,code", 115 + &bbnsm->keycode)) { 116 + bbnsm->keycode = KEY_POWER; 117 + dev_warn(&pdev->dev, "key code is not specified, using default KEY_POWER\n"); 118 + } 119 + 120 + bbnsm->irq = platform_get_irq(pdev, 0); 121 + if (bbnsm->irq < 0) 122 + return -EINVAL; 123 + 124 + /* config the BBNSM power related register */ 125 + regmap_update_bits(bbnsm->regmap, BBNSM_CTRL, BBNSM_DP_EN, BBNSM_DP_EN); 126 + 127 + /* clear the unexpected interrupt before driver ready */ 128 + regmap_write_bits(bbnsm->regmap, BBNSM_EVENTS, BBNSM_PWRKEY_EVENTS, 129 + BBNSM_PWRKEY_EVENTS); 130 + 131 + timer_setup(&bbnsm->check_timer, bbnsm_pwrkey_check_for_events, 0); 132 + 133 + input = devm_input_allocate_device(&pdev->dev); 134 + if (!input) { 135 + dev_err(&pdev->dev, "failed to allocate the input device\n"); 136 + return -ENOMEM; 137 + } 138 + 139 + input->name = pdev->name; 140 + input->phys = "bbnsm-pwrkey/input0"; 141 + input->id.bustype = BUS_HOST; 142 + 143 + input_set_capability(input, EV_KEY, bbnsm->keycode); 144 + 145 + /* input customer action to cancel release timer */ 146 + error = devm_add_action(&pdev->dev, bbnsm_pwrkey_act, bbnsm); 147 + if (error) { 148 + dev_err(&pdev->dev, "failed to register remove action\n"); 149 + return error; 150 + } 151 + 152 + bbnsm->input = input; 153 + platform_set_drvdata(pdev, bbnsm); 154 + 155 + error = devm_request_irq(&pdev->dev, bbnsm->irq, bbnsm_pwrkey_interrupt, 156 + IRQF_SHARED, pdev->name, pdev); 157 + if (error) { 158 + dev_err(&pdev->dev, "interrupt not available.\n"); 159 + return error; 160 + } 161 + 162 + error = input_register_device(input); 163 + if (error) { 164 + dev_err(&pdev->dev, "failed to register input device\n"); 165 + return error; 166 + } 167 + 168 + device_init_wakeup(&pdev->dev, true); 169 + error = dev_pm_set_wake_irq(&pdev->dev, bbnsm->irq); 170 + if (error) 171 + dev_warn(&pdev->dev, "irq wake enable failed.\n"); 172 + 173 + return 0; 174 + } 175 + 176 + static const struct of_device_id bbnsm_pwrkey_ids[] = { 177 + { .compatible = "nxp,imx93-bbnsm-pwrkey" }, 178 + { /* sentinel */ } 179 + }; 180 + MODULE_DEVICE_TABLE(of, bbnsm_pwrkey_ids); 181 + 182 + static struct platform_driver bbnsm_pwrkey_driver = { 183 + .driver = { 184 + .name = "bbnsm_pwrkey", 185 + .of_match_table = bbnsm_pwrkey_ids, 186 + }, 187 + .probe = bbnsm_pwrkey_probe, 188 + }; 189 + module_platform_driver(bbnsm_pwrkey_driver); 190 + 191 + MODULE_AUTHOR("Jacky Bai <ping.bai@nxp.com>"); 192 + MODULE_DESCRIPTION("NXP bbnsm power key Driver"); 193 + MODULE_LICENSE("GPL");
+1 -1
drivers/input/rmi4/rmi_bus.c
··· 285 285 } 286 286 287 287 /** 288 - * rmi_register_function_handler - register a handler for an RMI function 288 + * __rmi_register_function_handler - register a handler for an RMI function 289 289 * @handler: RMI handler that should be registered. 290 290 * @owner: pointer to module that implements the handler 291 291 * @mod_name: name of the module implementing the handler
+3
drivers/input/tests/.kunitconfig
··· 1 + CONFIG_KUNIT=y 2 + CONFIG_INPUT=y 3 + CONFIG_INPUT_KUNIT_TEST=y
+3
drivers/input/tests/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + obj-$(CONFIG_INPUT_KUNIT_TEST) += input_test.o
+150
drivers/input/tests/input_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * KUnit test for the input core. 4 + * 5 + * Copyright (c) 2023 Red Hat Inc 6 + */ 7 + 8 + #include <linux/delay.h> 9 + #include <linux/input.h> 10 + 11 + #include <kunit/test.h> 12 + 13 + #define POLL_INTERVAL 100 14 + 15 + static int input_test_init(struct kunit *test) 16 + { 17 + struct input_dev *input_dev; 18 + int ret; 19 + 20 + input_dev = input_allocate_device(); 21 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, input_dev); 22 + 23 + input_dev->name = "Test input device"; 24 + input_dev->id.bustype = BUS_VIRTUAL; 25 + input_dev->id.vendor = 1; 26 + input_dev->id.product = 1; 27 + input_dev->id.version = 1; 28 + input_set_capability(input_dev, EV_KEY, BTN_LEFT); 29 + input_set_capability(input_dev, EV_KEY, BTN_RIGHT); 30 + 31 + ret = input_register_device(input_dev); 32 + if (ret) { 33 + input_free_device(input_dev); 34 + KUNIT_ASSERT_FAILURE(test, "Register device failed: %d", ret); 35 + } 36 + 37 + test->priv = input_dev; 38 + 39 + return 0; 40 + } 41 + 42 + static void input_test_exit(struct kunit *test) 43 + { 44 + struct input_dev *input_dev = test->priv; 45 + 46 + input_unregister_device(input_dev); 47 + input_free_device(input_dev); 48 + } 49 + 50 + static void input_test_poll(struct input_dev *input) { } 51 + 52 + static void input_test_polling(struct kunit *test) 53 + { 54 + struct input_dev *input_dev = test->priv; 55 + 56 + /* Must fail because a poll handler has not been set-up yet */ 57 + KUNIT_ASSERT_EQ(test, input_get_poll_interval(input_dev), -EINVAL); 58 + 59 + KUNIT_ASSERT_EQ(test, input_setup_polling(input_dev, input_test_poll), 0); 60 + 61 + input_set_poll_interval(input_dev, POLL_INTERVAL); 62 + 63 + /* Must succeed because poll handler was set-up and poll interval set */ 64 + KUNIT_ASSERT_EQ(test, input_get_poll_interval(input_dev), POLL_INTERVAL); 65 + } 66 + 67 + static void input_test_timestamp(struct kunit *test) 68 + { 69 + const ktime_t invalid_timestamp = ktime_set(0, 0); 70 + struct input_dev *input_dev = test->priv; 71 + ktime_t *timestamp, time; 72 + 73 + timestamp = input_get_timestamp(input_dev); 74 + time = timestamp[INPUT_CLK_MONO]; 75 + 76 + /* The returned timestamp must always be valid */ 77 + KUNIT_ASSERT_EQ(test, ktime_compare(time, invalid_timestamp), 1); 78 + 79 + time = ktime_get(); 80 + input_set_timestamp(input_dev, time); 81 + 82 + timestamp = input_get_timestamp(input_dev); 83 + /* The timestamp must be the same than set before */ 84 + KUNIT_ASSERT_EQ(test, ktime_compare(timestamp[INPUT_CLK_MONO], time), 0); 85 + } 86 + 87 + static void input_test_match_device_id(struct kunit *test) 88 + { 89 + struct input_dev *input_dev = test->priv; 90 + struct input_device_id id; 91 + 92 + /* 93 + * Must match when the input device bus, vendor, product, version 94 + * and events capable of handling are the same and fail to match 95 + * otherwise. 96 + */ 97 + id.flags = INPUT_DEVICE_ID_MATCH_BUS; 98 + id.bustype = BUS_VIRTUAL; 99 + KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id)); 100 + 101 + id.bustype = BUS_I2C; 102 + KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id)); 103 + 104 + id.flags = INPUT_DEVICE_ID_MATCH_VENDOR; 105 + id.vendor = 1; 106 + KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id)); 107 + 108 + id.vendor = 2; 109 + KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id)); 110 + 111 + id.flags = INPUT_DEVICE_ID_MATCH_PRODUCT; 112 + id.product = 1; 113 + KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id)); 114 + 115 + id.product = 2; 116 + KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id)); 117 + 118 + id.flags = INPUT_DEVICE_ID_MATCH_VERSION; 119 + id.version = 1; 120 + KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id)); 121 + 122 + id.version = 2; 123 + KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id)); 124 + 125 + id.flags = INPUT_DEVICE_ID_MATCH_EVBIT; 126 + __set_bit(EV_KEY, id.evbit); 127 + KUNIT_ASSERT_TRUE(test, input_match_device_id(input_dev, &id)); 128 + 129 + __set_bit(EV_ABS, id.evbit); 130 + KUNIT_ASSERT_FALSE(test, input_match_device_id(input_dev, &id)); 131 + } 132 + 133 + static struct kunit_case input_tests[] = { 134 + KUNIT_CASE(input_test_polling), 135 + KUNIT_CASE(input_test_timestamp), 136 + KUNIT_CASE(input_test_match_device_id), 137 + { /* sentinel */ } 138 + }; 139 + 140 + static struct kunit_suite input_test_suite = { 141 + .name = "input_core", 142 + .init = input_test_init, 143 + .exit = input_test_exit, 144 + .test_cases = input_tests, 145 + }; 146 + 147 + kunit_test_suite(input_test_suite); 148 + 149 + MODULE_AUTHOR("Javier Martinez Canillas <javierm@redhat.com>"); 150 + MODULE_LICENSE("GPL");
+11
drivers/input/touchscreen/Kconfig
··· 654 654 To compile this driver as a module, choose M here: the 655 655 module will be called mtouch. 656 656 657 + config TOUCHSCREEN_NOVATEK_NVT_TS 658 + tristate "Novatek NVT-ts touchscreen support" 659 + depends on I2C 660 + help 661 + Say Y here if you have a Novatek NVT-ts touchscreen. 662 + If unsure, say N. 663 + 664 + To compile this driver as a module, choose M here: the 665 + module will be called novatek-nvt-ts. 666 + 657 667 config TOUCHSCREEN_IMAGIS 658 668 tristate "Imagis touchscreen support" 659 669 depends on I2C ··· 768 758 config TOUCHSCREEN_EDT_FT5X06 769 759 tristate "EDT FocalTech FT5x06 I2C Touchscreen support" 770 760 depends on I2C 761 + select REGMAP_I2C 771 762 help 772 763 Say Y here if you have an EDT "Polytouch" touchscreen based 773 764 on the FocalTech FT5x06 family of controllers connected to
+1
drivers/input/touchscreen/Makefile
··· 67 67 obj-$(CONFIG_TOUCHSCREEN_MSG2638) += msg2638.o 68 68 obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o 69 69 obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o 70 + obj-$(CONFIG_TOUCHSCREEN_NOVATEK_NVT_TS) += novatek-nvt-ts.o 70 71 obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o 71 72 obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o 72 73 obj-$(CONFIG_TOUCHSCREEN_IPAQ_MICRO) += ipaq-micro-ts.o
+1 -1
drivers/input/touchscreen/bcm_iproc_tsc.c
··· 511 511 .probe = iproc_ts_probe, 512 512 .driver = { 513 513 .name = IPROC_TS_NAME, 514 - .of_match_table = of_match_ptr(iproc_ts_of_match), 514 + .of_match_table = iproc_ts_of_match, 515 515 }, 516 516 }; 517 517
+252 -246
drivers/input/touchscreen/edt-ft5x06.c
··· 3 3 * Copyright (C) 2012 Simon Budig, <simon.budig@kernelconcepts.de> 4 4 * Daniel Wagener <daniel.wagener@kernelconcepts.de> (M09 firmware support) 5 5 * Lothar Waßmann <LW@KARO-electronics.de> (DT support) 6 + * Dario Binacchi <dario.binacchi@amarulasolutions.com> (regmap support) 6 7 */ 7 8 8 9 /* ··· 27 26 #include <linux/module.h> 28 27 #include <linux/property.h> 29 28 #include <linux/ratelimit.h> 29 + #include <linux/regmap.h> 30 30 #include <linux/regulator/consumer.h> 31 31 #include <linux/slab.h> 32 32 #include <linux/uaccess.h> ··· 77 75 #define EDT_DEFAULT_NUM_X 1024 78 76 #define EDT_DEFAULT_NUM_Y 1024 79 77 78 + #define M06_REG_CMD(factory) ((factory) ? 0xf3 : 0xfc) 79 + #define M06_REG_ADDR(factory, addr) ((factory) ? (addr) & 0x7f : (addr) & 0x3f) 80 + 80 81 enum edt_pmode { 81 82 EDT_PMODE_NOT_SUPPORTED, 82 83 EDT_PMODE_HIBERNATE, ··· 117 112 struct gpio_desc *reset_gpio; 118 113 struct gpio_desc *wake_gpio; 119 114 115 + struct regmap *regmap; 116 + 120 117 #if defined(CONFIG_DEBUG_FS) 121 118 struct dentry *debug_dir; 122 119 u8 *raw_buffer; ··· 135 128 int offset_y; 136 129 int report_rate; 137 130 int max_support_points; 131 + int point_len; 132 + u8 tdata_cmd; 133 + int tdata_len; 134 + int tdata_offset; 138 135 139 136 char name[EDT_NAME_LEN]; 140 137 char fw_version[EDT_NAME_LEN]; ··· 153 142 int max_support_points; 154 143 }; 155 144 156 - static int edt_ft5x06_ts_readwrite(struct i2c_client *client, 157 - u16 wr_len, u8 *wr_buf, 158 - u16 rd_len, u8 *rd_buf) 159 - { 160 - struct i2c_msg wrmsg[2]; 161 - int i = 0; 162 - int ret; 163 - 164 - if (wr_len) { 165 - wrmsg[i].addr = client->addr; 166 - wrmsg[i].flags = 0; 167 - wrmsg[i].len = wr_len; 168 - wrmsg[i].buf = wr_buf; 169 - i++; 170 - } 171 - if (rd_len) { 172 - wrmsg[i].addr = client->addr; 173 - wrmsg[i].flags = I2C_M_RD; 174 - wrmsg[i].len = rd_len; 175 - wrmsg[i].buf = rd_buf; 176 - i++; 177 - } 178 - 179 - ret = i2c_transfer(client->adapter, wrmsg, i); 180 - if (ret < 0) 181 - return ret; 182 - if (ret != i) 183 - return -EIO; 184 - 185 - return 0; 186 - } 145 + static const struct regmap_config edt_ft5x06_i2c_regmap_config = { 146 + .reg_bits = 8, 147 + .val_bits = 8, 148 + }; 187 149 188 150 static bool edt_ft5x06_ts_check_crc(struct edt_ft5x06_ts_data *tsdata, 189 151 u8 *buf, int buflen) ··· 167 183 for (i = 0; i < buflen - 1; i++) 168 184 crc ^= buf[i]; 169 185 170 - if (crc != buf[buflen-1]) { 186 + if (crc != buf[buflen - 1]) { 171 187 tsdata->crc_errors++; 172 188 dev_err_ratelimited(&tsdata->client->dev, 173 189 "crc error: 0x%02x expected, got 0x%02x\n", 174 - crc, buf[buflen-1]); 190 + crc, buf[buflen - 1]); 175 191 return false; 176 192 } 177 193 178 194 return true; 179 195 } 180 196 197 + static int edt_M06_i2c_read(void *context, const void *reg_buf, size_t reg_size, 198 + void *val_buf, size_t val_size) 199 + { 200 + struct device *dev = context; 201 + struct i2c_client *i2c = to_i2c_client(dev); 202 + struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(i2c); 203 + struct i2c_msg xfer[2]; 204 + bool reg_read = false; 205 + u8 addr; 206 + u8 wlen; 207 + u8 wbuf[4], rbuf[3]; 208 + int ret; 209 + 210 + addr = *((u8 *)reg_buf); 211 + wbuf[0] = addr; 212 + switch (addr) { 213 + case 0xf5: 214 + wlen = 3; 215 + wbuf[0] = 0xf5; 216 + wbuf[1] = 0xe; 217 + wbuf[2] = *((u8 *)val_buf); 218 + break; 219 + case 0xf9: 220 + wlen = 1; 221 + break; 222 + default: 223 + wlen = 2; 224 + reg_read = true; 225 + wbuf[0] = M06_REG_CMD(tsdata->factory_mode); 226 + wbuf[1] = M06_REG_ADDR(tsdata->factory_mode, addr); 227 + wbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40; 228 + } 229 + 230 + xfer[0].addr = i2c->addr; 231 + xfer[0].flags = 0; 232 + xfer[0].len = wlen; 233 + xfer[0].buf = wbuf; 234 + 235 + xfer[1].addr = i2c->addr; 236 + xfer[1].flags = I2C_M_RD; 237 + xfer[1].len = reg_read ? 2 : val_size; 238 + xfer[1].buf = reg_read ? rbuf : val_buf; 239 + 240 + ret = i2c_transfer(i2c->adapter, xfer, 2); 241 + if (ret != 2) { 242 + if (ret < 0) 243 + return ret; 244 + 245 + return -EIO; 246 + } 247 + 248 + if (addr == 0xf9) { 249 + u8 *buf = (u8 *)val_buf; 250 + 251 + if (buf[0] != 0xaa || buf[1] != 0xaa || 252 + buf[2] != val_size) { 253 + tsdata->header_errors++; 254 + dev_err_ratelimited(dev, 255 + "Unexpected header: %02x%02x%02x\n", 256 + buf[0], buf[1], buf[2]); 257 + return -EIO; 258 + } 259 + 260 + if (!edt_ft5x06_ts_check_crc(tsdata, val_buf, val_size)) 261 + return -EIO; 262 + } else if (reg_read) { 263 + wbuf[2] = rbuf[0]; 264 + wbuf[3] = rbuf[1]; 265 + if (!edt_ft5x06_ts_check_crc(tsdata, wbuf, 4)) 266 + return -EIO; 267 + 268 + *((u8 *)val_buf) = rbuf[0]; 269 + } 270 + 271 + return 0; 272 + } 273 + 274 + static int edt_M06_i2c_write(void *context, const void *data, size_t count) 275 + { 276 + struct device *dev = context; 277 + struct i2c_client *i2c = to_i2c_client(dev); 278 + struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(i2c); 279 + u8 addr, val; 280 + u8 wbuf[4]; 281 + struct i2c_msg xfer; 282 + int ret; 283 + 284 + addr = *((u8 *)data); 285 + val = *((u8 *)data + 1); 286 + 287 + wbuf[0] = M06_REG_CMD(tsdata->factory_mode); 288 + wbuf[1] = M06_REG_ADDR(tsdata->factory_mode, addr); 289 + wbuf[2] = val; 290 + wbuf[3] = wbuf[0] ^ wbuf[1] ^ wbuf[2]; 291 + 292 + xfer.addr = i2c->addr; 293 + xfer.flags = 0; 294 + xfer.len = 4; 295 + xfer.buf = wbuf; 296 + 297 + ret = i2c_transfer(i2c->adapter, &xfer, 1); 298 + if (ret != 1) { 299 + if (ret < 0) 300 + return ret; 301 + 302 + return -EIO; 303 + } 304 + 305 + return 0; 306 + } 307 + 308 + static const struct regmap_config edt_M06_i2c_regmap_config = { 309 + .reg_bits = 8, 310 + .val_bits = 8, 311 + .read = edt_M06_i2c_read, 312 + .write = edt_M06_i2c_write, 313 + }; 314 + 181 315 static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id) 182 316 { 183 317 struct edt_ft5x06_ts_data *tsdata = dev_id; 184 318 struct device *dev = &tsdata->client->dev; 185 - u8 cmd; 186 319 u8 rdbuf[63]; 187 320 int i, type, x, y, id; 188 - int offset, tplen, datalen, crclen; 189 321 int error; 190 322 191 - switch (tsdata->version) { 192 - case EDT_M06: 193 - cmd = 0xf9; /* tell the controller to send touch data */ 194 - offset = 5; /* where the actual touch data starts */ 195 - tplen = 4; /* data comes in so called frames */ 196 - crclen = 1; /* length of the crc data */ 197 - break; 198 - 199 - case EDT_M09: 200 - case EDT_M12: 201 - case EV_FT: 202 - case GENERIC_FT: 203 - cmd = 0x0; 204 - offset = 3; 205 - tplen = 6; 206 - crclen = 0; 207 - break; 208 - 209 - default: 210 - goto out; 211 - } 212 - 213 323 memset(rdbuf, 0, sizeof(rdbuf)); 214 - datalen = tplen * tsdata->max_support_points + offset + crclen; 215 - 216 - error = edt_ft5x06_ts_readwrite(tsdata->client, 217 - sizeof(cmd), &cmd, 218 - datalen, rdbuf); 324 + error = regmap_bulk_read(tsdata->regmap, tsdata->tdata_cmd, rdbuf, 325 + tsdata->tdata_len); 219 326 if (error) { 220 327 dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n", 221 328 error); 222 329 goto out; 223 330 } 224 331 225 - /* M09/M12 does not send header or CRC */ 226 - if (tsdata->version == EDT_M06) { 227 - if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa || 228 - rdbuf[2] != datalen) { 229 - tsdata->header_errors++; 230 - dev_err_ratelimited(dev, 231 - "Unexpected header: %02x%02x%02x!\n", 232 - rdbuf[0], rdbuf[1], rdbuf[2]); 233 - goto out; 234 - } 235 - 236 - if (!edt_ft5x06_ts_check_crc(tsdata, rdbuf, datalen)) 237 - goto out; 238 - } 239 - 240 332 for (i = 0; i < tsdata->max_support_points; i++) { 241 - u8 *buf = &rdbuf[i * tplen + offset]; 333 + u8 *buf = &rdbuf[i * tsdata->point_len + tsdata->tdata_offset]; 242 334 243 335 type = buf[0] >> 6; 244 336 /* ignore Reserved events */ ··· 345 285 346 286 out: 347 287 return IRQ_HANDLED; 348 - } 349 - 350 - static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata, 351 - u8 addr, u8 value) 352 - { 353 - u8 wrbuf[4]; 354 - 355 - switch (tsdata->version) { 356 - case EDT_M06: 357 - wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc; 358 - wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; 359 - wrbuf[2] = value; 360 - wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2]; 361 - return edt_ft5x06_ts_readwrite(tsdata->client, 4, 362 - wrbuf, 0, NULL); 363 - 364 - case EDT_M09: 365 - case EDT_M12: 366 - case EV_FT: 367 - case GENERIC_FT: 368 - wrbuf[0] = addr; 369 - wrbuf[1] = value; 370 - 371 - return edt_ft5x06_ts_readwrite(tsdata->client, 2, 372 - wrbuf, 0, NULL); 373 - 374 - default: 375 - return -EINVAL; 376 - } 377 - } 378 - 379 - static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata, 380 - u8 addr) 381 - { 382 - u8 wrbuf[2], rdbuf[2]; 383 - int error; 384 - 385 - switch (tsdata->version) { 386 - case EDT_M06: 387 - wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc; 388 - wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; 389 - wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40; 390 - 391 - error = edt_ft5x06_ts_readwrite(tsdata->client, 2, wrbuf, 2, 392 - rdbuf); 393 - if (error) 394 - return error; 395 - 396 - if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) { 397 - dev_err(&tsdata->client->dev, 398 - "crc error: 0x%02x expected, got 0x%02x\n", 399 - wrbuf[0] ^ wrbuf[1] ^ rdbuf[0], 400 - rdbuf[1]); 401 - return -EIO; 402 - } 403 - break; 404 - 405 - case EDT_M09: 406 - case EDT_M12: 407 - case EV_FT: 408 - case GENERIC_FT: 409 - wrbuf[0] = addr; 410 - error = edt_ft5x06_ts_readwrite(tsdata->client, 1, 411 - wrbuf, 1, rdbuf); 412 - if (error) 413 - return error; 414 - break; 415 - 416 - default: 417 - return -EINVAL; 418 - } 419 - 420 - return rdbuf[0]; 421 288 } 422 289 423 290 struct edt_ft5x06_attribute { ··· 380 393 struct edt_ft5x06_attribute *attr = 381 394 container_of(dattr, struct edt_ft5x06_attribute, dattr); 382 395 u8 *field = (u8 *)tsdata + attr->field_offset; 383 - int val; 396 + unsigned int val; 384 397 size_t count = 0; 385 398 int error = 0; 386 399 u8 addr; ··· 413 426 } 414 427 415 428 if (addr != NO_REGISTER) { 416 - val = edt_ft5x06_register_read(tsdata, addr); 417 - if (val < 0) { 418 - error = val; 429 + error = regmap_read(tsdata->regmap, addr, &val); 430 + if (error) { 419 431 dev_err(&tsdata->client->dev, 420 432 "Failed to fetch attribute %s, error %d\n", 421 433 dattr->attr.name, error); ··· 487 501 } 488 502 489 503 if (addr != NO_REGISTER) { 490 - error = edt_ft5x06_register_write(tsdata, addr, val); 504 + error = regmap_write(tsdata->regmap, addr, val); 491 505 if (error) { 492 506 dev_err(&tsdata->client->dev, 493 507 "Failed to update attribute %s, error: %d\n", ··· 588 602 static void edt_ft5x06_restore_reg_parameters(struct edt_ft5x06_ts_data *tsdata) 589 603 { 590 604 struct edt_reg_addr *reg_addr = &tsdata->reg_addr; 605 + struct regmap *regmap = tsdata->regmap; 591 606 592 - edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold, 593 - tsdata->threshold); 594 - edt_ft5x06_register_write(tsdata, reg_addr->reg_gain, 595 - tsdata->gain); 607 + regmap_write(regmap, reg_addr->reg_threshold, tsdata->threshold); 608 + regmap_write(regmap, reg_addr->reg_gain, tsdata->gain); 596 609 if (reg_addr->reg_offset != NO_REGISTER) 597 - edt_ft5x06_register_write(tsdata, reg_addr->reg_offset, 598 - tsdata->offset); 610 + regmap_write(regmap, reg_addr->reg_offset, tsdata->offset); 599 611 if (reg_addr->reg_offset_x != NO_REGISTER) 600 - edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_x, 601 - tsdata->offset_x); 612 + regmap_write(regmap, reg_addr->reg_offset_x, tsdata->offset_x); 602 613 if (reg_addr->reg_offset_y != NO_REGISTER) 603 - edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_y, 604 - tsdata->offset_y); 614 + regmap_write(regmap, reg_addr->reg_offset_y, tsdata->offset_y); 605 615 if (reg_addr->reg_report_rate != NO_REGISTER) 606 - edt_ft5x06_register_write(tsdata, reg_addr->reg_report_rate, 607 - tsdata->report_rate); 608 - 616 + regmap_write(regmap, reg_addr->reg_report_rate, 617 + tsdata->report_rate); 609 618 } 610 619 611 620 #ifdef CONFIG_DEBUG_FS ··· 608 627 { 609 628 struct i2c_client *client = tsdata->client; 610 629 int retries = EDT_SWITCH_MODE_RETRIES; 611 - int ret; 630 + unsigned int val; 612 631 int error; 613 632 614 633 if (tsdata->version != EDT_M06) { ··· 630 649 } 631 650 632 651 /* mode register is 0x3c when in the work mode */ 633 - error = edt_ft5x06_register_write(tsdata, WORK_REGISTER_OPMODE, 0x03); 652 + error = regmap_write(tsdata->regmap, WORK_REGISTER_OPMODE, 0x03); 634 653 if (error) { 635 654 dev_err(&client->dev, 636 655 "failed to switch to factory mode, error %d\n", error); ··· 641 660 do { 642 661 mdelay(EDT_SWITCH_MODE_DELAY); 643 662 /* mode register is 0x01 when in factory mode */ 644 - ret = edt_ft5x06_register_read(tsdata, FACTORY_REGISTER_OPMODE); 645 - if (ret == 0x03) 663 + error = regmap_read(tsdata->regmap, FACTORY_REGISTER_OPMODE, 664 + &val); 665 + if (!error && val == 0x03) 646 666 break; 647 667 } while (--retries > 0); 648 668 ··· 669 687 { 670 688 struct i2c_client *client = tsdata->client; 671 689 int retries = EDT_SWITCH_MODE_RETRIES; 672 - int ret; 690 + unsigned int val; 673 691 int error; 674 692 675 693 /* mode register is 0x01 when in the factory mode */ 676 - error = edt_ft5x06_register_write(tsdata, FACTORY_REGISTER_OPMODE, 0x1); 694 + error = regmap_write(tsdata->regmap, FACTORY_REGISTER_OPMODE, 0x1); 677 695 if (error) { 678 696 dev_err(&client->dev, 679 697 "failed to switch to work mode, error: %d\n", error); ··· 685 703 do { 686 704 mdelay(EDT_SWITCH_MODE_DELAY); 687 705 /* mode register is 0x01 when in factory mode */ 688 - ret = edt_ft5x06_register_read(tsdata, WORK_REGISTER_OPMODE); 689 - if (ret == 0x01) 706 + error = regmap_read(tsdata->regmap, WORK_REGISTER_OPMODE, &val); 707 + if (!error && val == 0x01) 690 708 break; 691 709 } while (--retries > 0); 692 710 ··· 739 757 edt_ft5x06_debugfs_mode_set, "%llu\n"); 740 758 741 759 static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file, 742 - char __user *buf, size_t count, loff_t *off) 760 + char __user *buf, size_t count, 761 + loff_t *off) 743 762 { 744 763 struct edt_ft5x06_ts_data *tsdata = file->private_data; 745 764 struct i2c_client *client = tsdata->client; 746 765 int retries = EDT_RAW_DATA_RETRIES; 747 - int val, i, error; 766 + unsigned int val; 767 + int i, error; 748 768 size_t read = 0; 749 769 int colbytes; 750 - char wrbuf[3]; 751 770 u8 *rdbuf; 752 771 753 772 if (*off < 0 || *off >= tsdata->raw_bufsize) ··· 761 778 goto out; 762 779 } 763 780 764 - error = edt_ft5x06_register_write(tsdata, 0x08, 0x01); 781 + error = regmap_write(tsdata->regmap, 0x08, 0x01); 765 782 if (error) { 766 - dev_dbg(&client->dev, 783 + dev_err(&client->dev, 767 784 "failed to write 0x08 register, error %d\n", error); 768 785 goto out; 769 786 } 770 787 771 788 do { 772 789 usleep_range(EDT_RAW_DATA_DELAY, EDT_RAW_DATA_DELAY + 100); 773 - val = edt_ft5x06_register_read(tsdata, 0x08); 774 - if (val < 1) 790 + error = regmap_read(tsdata->regmap, 0x08, &val); 791 + if (error) { 792 + dev_err(&client->dev, 793 + "failed to read 0x08 register, error %d\n", 794 + error); 795 + goto out; 796 + } 797 + 798 + if (val == 1) 775 799 break; 776 800 } while (--retries > 0); 777 801 778 - if (val < 0) { 779 - error = val; 780 - dev_dbg(&client->dev, 781 - "failed to read 0x08 register, error %d\n", error); 782 - goto out; 783 - } 784 - 785 802 if (retries == 0) { 786 - dev_dbg(&client->dev, 803 + dev_err(&client->dev, 787 804 "timed out waiting for register to settle\n"); 788 805 error = -ETIMEDOUT; 789 806 goto out; ··· 792 809 rdbuf = tsdata->raw_buffer; 793 810 colbytes = tsdata->num_y * sizeof(u16); 794 811 795 - wrbuf[0] = 0xf5; 796 - wrbuf[1] = 0x0e; 797 812 for (i = 0; i < tsdata->num_x; i++) { 798 - wrbuf[2] = i; /* column index */ 799 - error = edt_ft5x06_ts_readwrite(tsdata->client, 800 - sizeof(wrbuf), wrbuf, 801 - colbytes, rdbuf); 813 + rdbuf[0] = i; /* column index */ 814 + error = regmap_bulk_read(tsdata->regmap, 0xf5, rdbuf, colbytes); 802 815 if (error) 803 816 goto out; 804 817 ··· 870 891 * to have garbage in there 871 892 */ 872 893 memset(rdbuf, 0, sizeof(rdbuf)); 873 - error = edt_ft5x06_ts_readwrite(client, 1, "\xBB", 874 - EDT_NAME_LEN - 1, rdbuf); 894 + error = regmap_bulk_read(tsdata->regmap, 0xBB, rdbuf, EDT_NAME_LEN - 1); 875 895 if (error) 876 896 return error; 877 897 ··· 892 914 *p++ = '\0'; 893 915 strscpy(model_name, rdbuf + 1, EDT_NAME_LEN); 894 916 strscpy(fw_version, p ? p : "", EDT_NAME_LEN); 917 + 918 + regmap_exit(tsdata->regmap); 919 + tsdata->regmap = regmap_init_i2c(client, 920 + &edt_M06_i2c_regmap_config); 921 + if (IS_ERR(tsdata->regmap)) { 922 + dev_err(&client->dev, "regmap allocation failed\n"); 923 + return PTR_ERR(tsdata->regmap); 924 + } 895 925 } else if (!strncasecmp(rdbuf, "EP0", 3)) { 896 926 tsdata->version = EDT_M12; 897 927 ··· 926 940 */ 927 941 tsdata->version = GENERIC_FT; 928 942 929 - error = edt_ft5x06_ts_readwrite(client, 1, "\xA6", 930 - 2, rdbuf); 943 + error = regmap_bulk_read(tsdata->regmap, 0xA6, rdbuf, 2); 931 944 if (error) 932 945 return error; 933 946 934 947 strscpy(fw_version, rdbuf, 2); 935 948 936 - error = edt_ft5x06_ts_readwrite(client, 1, "\xA8", 937 - 1, rdbuf); 949 + error = regmap_bulk_read(tsdata->regmap, 0xA8, rdbuf, 1); 938 950 if (error) 939 951 return error; 940 952 ··· 949 965 case 0x70: /* EDT EP0700M09 */ 950 966 tsdata->version = EDT_M09; 951 967 snprintf(model_name, EDT_NAME_LEN, "EP0%i%i0M09", 952 - rdbuf[0] >> 4, rdbuf[0] & 0x0F); 968 + rdbuf[0] >> 4, rdbuf[0] & 0x0F); 953 969 break; 954 970 case 0xa1: /* EDT EP1010ML00 */ 955 971 tsdata->version = EDT_M09; 956 972 snprintf(model_name, EDT_NAME_LEN, "EP%i%i0ML00", 957 - rdbuf[0] >> 4, rdbuf[0] & 0x0F); 973 + rdbuf[0] >> 4, rdbuf[0] & 0x0F); 958 974 break; 959 975 case 0x5a: /* Solomon Goldentek Display */ 960 976 snprintf(model_name, EDT_NAME_LEN, "GKTW50SCED1R0"); 961 977 break; 962 978 case 0x59: /* Evervision Display with FT5xx6 TS */ 963 979 tsdata->version = EV_FT; 964 - error = edt_ft5x06_ts_readwrite(client, 1, "\x53", 965 - 1, rdbuf); 980 + error = regmap_bulk_read(tsdata->regmap, 0x53, rdbuf, 1); 966 981 if (error) 967 982 return error; 968 983 strscpy(fw_version, rdbuf, 1); ··· 983 1000 struct edt_ft5x06_ts_data *tsdata) 984 1001 { 985 1002 struct edt_reg_addr *reg_addr = &tsdata->reg_addr; 1003 + struct regmap *regmap = tsdata->regmap; 986 1004 u32 val; 987 1005 int error; 988 1006 989 1007 error = device_property_read_u32(dev, "threshold", &val); 990 1008 if (!error) { 991 - edt_ft5x06_register_write(tsdata, reg_addr->reg_threshold, val); 1009 + regmap_write(regmap, reg_addr->reg_threshold, val); 992 1010 tsdata->threshold = val; 993 1011 } 994 1012 995 1013 error = device_property_read_u32(dev, "gain", &val); 996 1014 if (!error) { 997 - edt_ft5x06_register_write(tsdata, reg_addr->reg_gain, val); 1015 + regmap_write(regmap, reg_addr->reg_gain, val); 998 1016 tsdata->gain = val; 999 1017 } 1000 1018 1001 1019 error = device_property_read_u32(dev, "offset", &val); 1002 1020 if (!error) { 1003 1021 if (reg_addr->reg_offset != NO_REGISTER) 1004 - edt_ft5x06_register_write(tsdata, 1005 - reg_addr->reg_offset, val); 1022 + regmap_write(regmap, reg_addr->reg_offset, val); 1006 1023 tsdata->offset = val; 1007 1024 } 1008 1025 1009 1026 error = device_property_read_u32(dev, "offset-x", &val); 1010 1027 if (!error) { 1011 1028 if (reg_addr->reg_offset_x != NO_REGISTER) 1012 - edt_ft5x06_register_write(tsdata, 1013 - reg_addr->reg_offset_x, val); 1029 + regmap_write(regmap, reg_addr->reg_offset_x, val); 1014 1030 tsdata->offset_x = val; 1015 1031 } 1016 1032 1017 1033 error = device_property_read_u32(dev, "offset-y", &val); 1018 1034 if (!error) { 1019 1035 if (reg_addr->reg_offset_y != NO_REGISTER) 1020 - edt_ft5x06_register_write(tsdata, 1021 - reg_addr->reg_offset_y, val); 1036 + regmap_write(regmap, reg_addr->reg_offset_y, val); 1022 1037 tsdata->offset_y = val; 1023 1038 } 1024 1039 } ··· 1024 1043 static void edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata) 1025 1044 { 1026 1045 struct edt_reg_addr *reg_addr = &tsdata->reg_addr; 1046 + struct regmap *regmap = tsdata->regmap; 1047 + unsigned int val; 1027 1048 1028 - tsdata->threshold = edt_ft5x06_register_read(tsdata, 1029 - reg_addr->reg_threshold); 1030 - tsdata->gain = edt_ft5x06_register_read(tsdata, reg_addr->reg_gain); 1049 + regmap_read(regmap, reg_addr->reg_threshold, &tsdata->threshold); 1050 + regmap_read(regmap, reg_addr->reg_gain, &tsdata->gain); 1031 1051 if (reg_addr->reg_offset != NO_REGISTER) 1032 - tsdata->offset = 1033 - edt_ft5x06_register_read(tsdata, reg_addr->reg_offset); 1052 + regmap_read(regmap, reg_addr->reg_offset, &tsdata->offset); 1034 1053 if (reg_addr->reg_offset_x != NO_REGISTER) 1035 - tsdata->offset_x = edt_ft5x06_register_read(tsdata, 1036 - reg_addr->reg_offset_x); 1054 + regmap_read(regmap, reg_addr->reg_offset_x, &tsdata->offset_x); 1037 1055 if (reg_addr->reg_offset_y != NO_REGISTER) 1038 - tsdata->offset_y = edt_ft5x06_register_read(tsdata, 1039 - reg_addr->reg_offset_y); 1056 + regmap_read(regmap, reg_addr->reg_offset_y, &tsdata->offset_y); 1040 1057 if (reg_addr->reg_report_rate != NO_REGISTER) 1041 - tsdata->report_rate = edt_ft5x06_register_read(tsdata, 1042 - reg_addr->reg_report_rate); 1058 + regmap_read(regmap, reg_addr->reg_report_rate, 1059 + &tsdata->report_rate); 1043 1060 tsdata->num_x = EDT_DEFAULT_NUM_X; 1044 - if (reg_addr->reg_num_x != NO_REGISTER) 1045 - tsdata->num_x = edt_ft5x06_register_read(tsdata, 1046 - reg_addr->reg_num_x); 1061 + if (reg_addr->reg_num_x != NO_REGISTER) { 1062 + if (!regmap_read(regmap, reg_addr->reg_num_x, &val)) 1063 + tsdata->num_x = val; 1064 + } 1047 1065 tsdata->num_y = EDT_DEFAULT_NUM_Y; 1048 - if (reg_addr->reg_num_y != NO_REGISTER) 1049 - tsdata->num_y = edt_ft5x06_register_read(tsdata, 1050 - reg_addr->reg_num_y); 1066 + if (reg_addr->reg_num_y != NO_REGISTER) { 1067 + if (!regmap_read(regmap, reg_addr->reg_num_y, &val)) 1068 + tsdata->num_y = val; 1069 + } 1070 + } 1071 + 1072 + static void edt_ft5x06_ts_set_tdata_parameters(struct edt_ft5x06_ts_data *tsdata) 1073 + { 1074 + int crclen; 1075 + 1076 + if (tsdata->version == EDT_M06) { 1077 + tsdata->tdata_cmd = 0xf9; 1078 + tsdata->tdata_offset = 5; 1079 + tsdata->point_len = 4; 1080 + crclen = 1; 1081 + } else { 1082 + tsdata->tdata_cmd = 0x0; 1083 + tsdata->tdata_offset = 3; 1084 + tsdata->point_len = 6; 1085 + crclen = 0; 1086 + } 1087 + 1088 + tsdata->tdata_len = tsdata->point_len * tsdata->max_support_points + 1089 + tsdata->tdata_offset + crclen; 1051 1090 } 1052 1091 1053 1092 static void edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata) ··· 1137 1136 const struct i2c_device_id *id = i2c_client_get_device_id(client); 1138 1137 const struct edt_i2c_chip_data *chip_data; 1139 1138 struct edt_ft5x06_ts_data *tsdata; 1140 - u8 buf[2] = { 0xfc, 0x00 }; 1139 + unsigned int val; 1141 1140 struct input_dev *input; 1142 1141 unsigned long irq_flags; 1143 1142 int error; ··· 1149 1148 if (!tsdata) { 1150 1149 dev_err(&client->dev, "failed to allocate driver data.\n"); 1151 1150 return -ENOMEM; 1151 + } 1152 + 1153 + tsdata->regmap = regmap_init_i2c(client, &edt_ft5x06_i2c_regmap_config); 1154 + if (IS_ERR(tsdata->regmap)) { 1155 + dev_err(&client->dev, "regmap allocation failed\n"); 1156 + return PTR_ERR(tsdata->regmap); 1152 1157 } 1153 1158 1154 1159 chip_data = device_get_match_data(&client->dev); ··· 1259 1252 tsdata->client = client; 1260 1253 tsdata->input = input; 1261 1254 tsdata->factory_mode = false; 1255 + i2c_set_clientdata(client, tsdata); 1262 1256 1263 1257 error = edt_ft5x06_ts_identify(client, tsdata); 1264 1258 if (error) { ··· 1271 1263 * Dummy read access. EP0700MLP1 returns bogus data on the first 1272 1264 * register read access and ignores writes. 1273 1265 */ 1274 - edt_ft5x06_ts_readwrite(tsdata->client, 2, buf, 2, buf); 1266 + regmap_read(tsdata->regmap, 0x00, &val); 1275 1267 1268 + edt_ft5x06_ts_set_tdata_parameters(tsdata); 1276 1269 edt_ft5x06_ts_set_regs(tsdata); 1277 1270 edt_ft5x06_ts_get_defaults(&client->dev, tsdata); 1278 1271 edt_ft5x06_ts_get_parameters(tsdata); ··· 1294 1285 if (tsdata->version == EDT_M06) 1295 1286 tsdata->report_rate /= 10; 1296 1287 1297 - edt_ft5x06_register_write(tsdata, 1298 - tsdata->reg_addr.reg_report_rate, 1299 - tsdata->report_rate); 1288 + regmap_write(tsdata->regmap, tsdata->reg_addr.reg_report_rate, 1289 + tsdata->report_rate); 1300 1290 } 1301 1291 1302 1292 dev_dbg(&client->dev, ··· 1314 1306 touchscreen_parse_properties(input, true, &tsdata->prop); 1315 1307 1316 1308 error = input_mt_init_slots(input, tsdata->max_support_points, 1317 - INPUT_MT_DIRECT); 1309 + INPUT_MT_DIRECT); 1318 1310 if (error) { 1319 1311 dev_err(&client->dev, "Unable to init MT slots.\n"); 1320 1312 return error; 1321 1313 } 1322 - 1323 - i2c_set_clientdata(client, tsdata); 1324 1314 1325 1315 irq_flags = irq_get_trigger_type(client->irq); 1326 1316 if (irq_flags == IRQF_TRIGGER_NONE) ··· 1326 1320 irq_flags |= IRQF_ONESHOT; 1327 1321 1328 1322 error = devm_request_threaded_irq(&client->dev, client->irq, 1329 - NULL, edt_ft5x06_ts_isr, irq_flags, 1330 - client->name, tsdata); 1323 + NULL, edt_ft5x06_ts_isr, irq_flags, 1324 + client->name, tsdata); 1331 1325 if (error) { 1332 1326 dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); 1333 1327 return error; ··· 1357 1351 struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client); 1358 1352 1359 1353 edt_ft5x06_ts_teardown_debugfs(tsdata); 1354 + regmap_exit(tsdata->regmap); 1360 1355 } 1361 1356 1362 1357 static int edt_ft5x06_ts_suspend(struct device *dev) ··· 1374 1367 return 0; 1375 1368 1376 1369 /* Enter hibernate mode. */ 1377 - ret = edt_ft5x06_register_write(tsdata, PMOD_REGISTER_OPMODE, 1378 - PMOD_REGISTER_HIBERNATE); 1370 + ret = regmap_write(tsdata->regmap, PMOD_REGISTER_OPMODE, 1371 + PMOD_REGISTER_HIBERNATE); 1379 1372 if (ret) 1380 1373 dev_warn(dev, "Failed to set hibernate mode\n"); 1381 1374 ··· 1461 1454 usleep_range(5000, 6000); 1462 1455 gpiod_set_value_cansleep(wake_gpio, 1); 1463 1456 } 1464 - 1465 1457 1466 1458 return ret; 1467 1459 }
+29 -4
drivers/input/touchscreen/hideep.c
··· 35 35 #define HIDEEP_EVENT_ADDR 0x240 36 36 37 37 /* command list */ 38 + #define HIDEEP_WORK_MODE 0x081e 38 39 #define HIDEEP_RESET_CMD 0x9800 39 40 40 41 /* event bit */ ··· 272 271 273 272 #define SW_RESET_IN_PGM(clk) \ 274 273 { \ 274 + __be32 data = cpu_to_be32(0x01); \ 275 275 hideep_pgm_w_reg(ts, HIDEEP_SYSCON_WDT_CNT, (clk)); \ 276 276 hideep_pgm_w_reg(ts, HIDEEP_SYSCON_WDT_CON, 0x03); \ 277 - hideep_pgm_w_reg(ts, HIDEEP_SYSCON_WDT_CON, 0x01); \ 277 + /* \ 278 + * The first write may already cause a reset, use a raw \ 279 + * write for the second write to avoid error logging. \ 280 + */ \ 281 + hideep_pgm_w_mem(ts, HIDEEP_SYSCON_WDT_CON, &data, 1); \ 278 282 } 279 283 280 284 #define SET_FLASH_PIO(ce) \ ··· 473 467 u32 addr = 0; 474 468 int error; 475 469 476 - error = hideep_nvm_unlock(ts); 477 - if (error) 478 - return error; 470 + error = hideep_nvm_unlock(ts); 471 + if (error) 472 + return error; 479 473 480 474 while (ucode_len > 0) { 481 475 xfer_len = min_t(size_t, ucode_len, HIDEEP_NVM_PAGE_SIZE); ··· 965 959 .attrs = hideep_ts_sysfs_entries, 966 960 }; 967 961 962 + static void hideep_set_work_mode(struct hideep_ts *ts) 963 + { 964 + /* 965 + * Reset touch report format to the native HiDeep 20 protocol if requested. 966 + * This is necessary to make touchscreens which come up in I2C-HID mode 967 + * work with this driver. 968 + * 969 + * Note this is a kernel internal device-property set by x86 platform code, 970 + * this MUST not be used in devicetree files without first adding it to 971 + * the DT bindings. 972 + */ 973 + if (device_property_read_bool(&ts->client->dev, "hideep,force-native-protocol")) 974 + regmap_write(ts->reg, HIDEEP_WORK_MODE, 0x00); 975 + } 976 + 968 977 static int hideep_suspend(struct device *dev) 969 978 { 970 979 struct i2c_client *client = to_i2c_client(dev); ··· 1002 981 dev_err(&client->dev, "power on failed"); 1003 982 return error; 1004 983 } 984 + 985 + hideep_set_work_mode(ts); 1005 986 1006 987 enable_irq(client->irq); 1007 988 ··· 1080 1057 dev_err(&client->dev, "failed to load dwz: %d", error); 1081 1058 return error; 1082 1059 } 1060 + 1061 + hideep_set_work_mode(ts); 1083 1062 1084 1063 error = hideep_init_input(ts); 1085 1064 if (error)
+10 -9
drivers/input/touchscreen/melfas_mip4.c
··· 466 466 { 467 467 int id; 468 468 bool __always_unused hover; 469 - bool __always_unused palm; 469 + bool palm; 470 470 bool state; 471 471 u16 x, y; 472 472 u8 __always_unused pressure_stage = 0; ··· 522 522 523 523 if (unlikely(id < 0 || id >= MIP4_MAX_FINGERS)) { 524 524 dev_err(&ts->client->dev, "Screen - invalid slot ID: %d\n", id); 525 - } else if (state) { 526 - /* Press or Move event */ 527 - input_mt_slot(ts->input, id); 528 - input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true); 525 + goto out; 526 + } 527 + 528 + input_mt_slot(ts->input, id); 529 + if (input_mt_report_slot_state(ts->input, 530 + palm ? MT_TOOL_PALM : MT_TOOL_FINGER, 531 + state)) { 529 532 input_report_abs(ts->input, ABS_MT_POSITION_X, x); 530 533 input_report_abs(ts->input, ABS_MT_POSITION_Y, y); 531 534 input_report_abs(ts->input, ABS_MT_PRESSURE, pressure); 532 535 input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, touch_major); 533 536 input_report_abs(ts->input, ABS_MT_TOUCH_MINOR, touch_minor); 534 - } else { 535 - /* Release event */ 536 - input_mt_slot(ts->input, id); 537 - input_mt_report_slot_inactive(ts->input); 538 537 } 539 538 539 + out: 540 540 input_mt_sync_frame(ts->input); 541 541 } 542 542 ··· 1483 1483 input->keycodesize = sizeof(*ts->key_code); 1484 1484 input->keycodemax = ts->key_num; 1485 1485 1486 + input_set_abs_params(input, ABS_MT_TOOL_TYPE, 0, MT_TOOL_PALM, 0, 0); 1486 1487 input_set_abs_params(input, ABS_MT_POSITION_X, 0, ts->max_x, 0, 0); 1487 1488 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ts->max_y, 0, 0); 1488 1489 input_set_abs_params(input, ABS_MT_PRESSURE,
+301
drivers/input/touchscreen/novatek-nvt-ts.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Driver for Novatek i2c touchscreen controller as found on 4 + * the Acer Iconia One 7 B1-750 tablet. The Touchscreen controller 5 + * model-number is unknown. Android calls this a "NVT-ts" touchscreen, 6 + * but that may apply to other Novatek controller models too. 7 + * 8 + * Copyright (c) 2023 Hans de Goede <hdegoede@redhat.com> 9 + */ 10 + 11 + #include <linux/delay.h> 12 + #include <linux/gpio/consumer.h> 13 + #include <linux/interrupt.h> 14 + #include <linux/i2c.h> 15 + #include <linux/input.h> 16 + #include <linux/input/mt.h> 17 + #include <linux/input/touchscreen.h> 18 + #include <linux/module.h> 19 + 20 + #include <asm/unaligned.h> 21 + 22 + #define NVT_TS_TOUCH_START 0x00 23 + #define NVT_TS_TOUCH_SIZE 6 24 + 25 + #define NVT_TS_PARAMETERS_START 0x78 26 + /* These are offsets from NVT_TS_PARAMETERS_START */ 27 + #define NVT_TS_PARAMS_WIDTH 0x04 28 + #define NVT_TS_PARAMS_HEIGHT 0x06 29 + #define NVT_TS_PARAMS_MAX_TOUCH 0x09 30 + #define NVT_TS_PARAMS_MAX_BUTTONS 0x0a 31 + #define NVT_TS_PARAMS_IRQ_TYPE 0x0b 32 + #define NVT_TS_PARAMS_WAKE_TYPE 0x0c 33 + #define NVT_TS_PARAMS_CHIP_ID 0x0e 34 + #define NVT_TS_PARAMS_SIZE 0x0f 35 + 36 + #define NVT_TS_SUPPORTED_WAKE_TYPE 0x05 37 + #define NVT_TS_SUPPORTED_CHIP_ID 0x05 38 + 39 + #define NVT_TS_MAX_TOUCHES 10 40 + #define NVT_TS_MAX_SIZE 4096 41 + 42 + #define NVT_TS_TOUCH_INVALID 0xff 43 + #define NVT_TS_TOUCH_SLOT_SHIFT 3 44 + #define NVT_TS_TOUCH_TYPE_MASK GENMASK(2, 0) 45 + #define NVT_TS_TOUCH_NEW 1 46 + #define NVT_TS_TOUCH_UPDATE 2 47 + #define NVT_TS_TOUCH_RELEASE 3 48 + 49 + static const int nvt_ts_irq_type[4] = { 50 + IRQF_TRIGGER_RISING, 51 + IRQF_TRIGGER_FALLING, 52 + IRQF_TRIGGER_LOW, 53 + IRQF_TRIGGER_HIGH 54 + }; 55 + 56 + struct nvt_ts_data { 57 + struct i2c_client *client; 58 + struct input_dev *input; 59 + struct gpio_desc *reset_gpio; 60 + struct touchscreen_properties prop; 61 + int max_touches; 62 + u8 buf[NVT_TS_TOUCH_SIZE * NVT_TS_MAX_TOUCHES]; 63 + }; 64 + 65 + static int nvt_ts_read_data(struct i2c_client *client, u8 reg, u8 *data, int count) 66 + { 67 + struct i2c_msg msg[2] = { 68 + { 69 + .addr = client->addr, 70 + .len = 1, 71 + .buf = &reg, 72 + }, 73 + { 74 + .addr = client->addr, 75 + .flags = I2C_M_RD, 76 + .len = count, 77 + .buf = data, 78 + } 79 + }; 80 + int ret; 81 + 82 + ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); 83 + if (ret != ARRAY_SIZE(msg)) { 84 + dev_err(&client->dev, "Error reading from 0x%02x: %d\n", reg, ret); 85 + return (ret < 0) ? ret : -EIO; 86 + } 87 + 88 + return 0; 89 + } 90 + 91 + static irqreturn_t nvt_ts_irq(int irq, void *dev_id) 92 + { 93 + struct nvt_ts_data *data = dev_id; 94 + struct device *dev = &data->client->dev; 95 + int i, error, slot, x, y; 96 + bool active; 97 + u8 *touch; 98 + 99 + error = nvt_ts_read_data(data->client, NVT_TS_TOUCH_START, data->buf, 100 + data->max_touches * NVT_TS_TOUCH_SIZE); 101 + if (error) 102 + return IRQ_HANDLED; 103 + 104 + for (i = 0; i < data->max_touches; i++) { 105 + touch = &data->buf[i * NVT_TS_TOUCH_SIZE]; 106 + 107 + if (touch[0] == NVT_TS_TOUCH_INVALID) 108 + continue; 109 + 110 + slot = touch[0] >> NVT_TS_TOUCH_SLOT_SHIFT; 111 + if (slot < 1 || slot > data->max_touches) { 112 + dev_warn(dev, "slot %d out of range, ignoring\n", slot); 113 + continue; 114 + } 115 + 116 + switch (touch[0] & NVT_TS_TOUCH_TYPE_MASK) { 117 + case NVT_TS_TOUCH_NEW: 118 + case NVT_TS_TOUCH_UPDATE: 119 + active = true; 120 + break; 121 + case NVT_TS_TOUCH_RELEASE: 122 + active = false; 123 + break; 124 + default: 125 + dev_warn(dev, "slot %d unknown state %d\n", slot, touch[0] & 7); 126 + continue; 127 + } 128 + 129 + slot--; 130 + x = (touch[1] << 4) | (touch[3] >> 4); 131 + y = (touch[2] << 4) | (touch[3] & 0x0f); 132 + 133 + input_mt_slot(data->input, slot); 134 + input_mt_report_slot_state(data->input, MT_TOOL_FINGER, active); 135 + touchscreen_report_pos(data->input, &data->prop, x, y, true); 136 + } 137 + 138 + input_mt_sync_frame(data->input); 139 + input_sync(data->input); 140 + 141 + return IRQ_HANDLED; 142 + } 143 + 144 + static int nvt_ts_start(struct input_dev *dev) 145 + { 146 + struct nvt_ts_data *data = input_get_drvdata(dev); 147 + 148 + enable_irq(data->client->irq); 149 + gpiod_set_value_cansleep(data->reset_gpio, 0); 150 + 151 + return 0; 152 + } 153 + 154 + static void nvt_ts_stop(struct input_dev *dev) 155 + { 156 + struct nvt_ts_data *data = input_get_drvdata(dev); 157 + 158 + disable_irq(data->client->irq); 159 + gpiod_set_value_cansleep(data->reset_gpio, 1); 160 + } 161 + 162 + static int nvt_ts_suspend(struct device *dev) 163 + { 164 + struct nvt_ts_data *data = i2c_get_clientdata(to_i2c_client(dev)); 165 + 166 + mutex_lock(&data->input->mutex); 167 + if (input_device_enabled(data->input)) 168 + nvt_ts_stop(data->input); 169 + mutex_unlock(&data->input->mutex); 170 + 171 + return 0; 172 + } 173 + 174 + static int nvt_ts_resume(struct device *dev) 175 + { 176 + struct nvt_ts_data *data = i2c_get_clientdata(to_i2c_client(dev)); 177 + 178 + mutex_lock(&data->input->mutex); 179 + if (input_device_enabled(data->input)) 180 + nvt_ts_start(data->input); 181 + mutex_unlock(&data->input->mutex); 182 + 183 + return 0; 184 + } 185 + 186 + static DEFINE_SIMPLE_DEV_PM_OPS(nvt_ts_pm_ops, nvt_ts_suspend, nvt_ts_resume); 187 + 188 + static int nvt_ts_probe(struct i2c_client *client) 189 + { 190 + struct device *dev = &client->dev; 191 + int error, width, height, irq_type; 192 + struct nvt_ts_data *data; 193 + struct input_dev *input; 194 + 195 + if (!client->irq) { 196 + dev_err(dev, "Error no irq specified\n"); 197 + return -EINVAL; 198 + } 199 + 200 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 201 + if (!data) 202 + return -ENOMEM; 203 + 204 + data->client = client; 205 + i2c_set_clientdata(client, data); 206 + 207 + data->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); 208 + error = PTR_ERR_OR_ZERO(data->reset_gpio); 209 + if (error) { 210 + dev_err(dev, "failed to request reset GPIO: %d\n", error); 211 + return error; 212 + } 213 + 214 + /* Wait for controller to come out of reset before params read */ 215 + msleep(100); 216 + error = nvt_ts_read_data(data->client, NVT_TS_PARAMETERS_START, 217 + data->buf, NVT_TS_PARAMS_SIZE); 218 + gpiod_set_value_cansleep(data->reset_gpio, 1); /* Put back in reset */ 219 + if (error) 220 + return error; 221 + 222 + width = get_unaligned_be16(&data->buf[NVT_TS_PARAMS_WIDTH]); 223 + height = get_unaligned_be16(&data->buf[NVT_TS_PARAMS_HEIGHT]); 224 + data->max_touches = data->buf[NVT_TS_PARAMS_MAX_TOUCH]; 225 + irq_type = data->buf[NVT_TS_PARAMS_IRQ_TYPE]; 226 + 227 + if (width > NVT_TS_MAX_SIZE || height >= NVT_TS_MAX_SIZE || 228 + data->max_touches > NVT_TS_MAX_TOUCHES || 229 + irq_type >= ARRAY_SIZE(nvt_ts_irq_type) || 230 + data->buf[NVT_TS_PARAMS_WAKE_TYPE] != NVT_TS_SUPPORTED_WAKE_TYPE || 231 + data->buf[NVT_TS_PARAMS_CHIP_ID] != NVT_TS_SUPPORTED_CHIP_ID) { 232 + dev_err(dev, "Unsupported touchscreen parameters: %*ph\n", 233 + NVT_TS_PARAMS_SIZE, data->buf); 234 + return -EIO; 235 + } 236 + 237 + dev_dbg(dev, "Detected %dx%d touchscreen with %d max touches\n", 238 + width, height, data->max_touches); 239 + 240 + if (data->buf[NVT_TS_PARAMS_MAX_BUTTONS]) 241 + dev_warn(dev, "Touchscreen buttons are not supported\n"); 242 + 243 + input = devm_input_allocate_device(dev); 244 + if (!input) 245 + return -ENOMEM; 246 + 247 + input->name = client->name; 248 + input->id.bustype = BUS_I2C; 249 + input->open = nvt_ts_start; 250 + input->close = nvt_ts_stop; 251 + 252 + input_set_abs_params(input, ABS_MT_POSITION_X, 0, width - 1, 0, 0); 253 + input_set_abs_params(input, ABS_MT_POSITION_Y, 0, height - 1, 0, 0); 254 + touchscreen_parse_properties(input, true, &data->prop); 255 + 256 + error = input_mt_init_slots(input, data->max_touches, 257 + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); 258 + if (error) 259 + return error; 260 + 261 + data->input = input; 262 + input_set_drvdata(input, data); 263 + 264 + error = devm_request_threaded_irq(dev, client->irq, NULL, nvt_ts_irq, 265 + IRQF_ONESHOT | IRQF_NO_AUTOEN | 266 + nvt_ts_irq_type[irq_type], 267 + client->name, data); 268 + if (error) { 269 + dev_err(dev, "failed to request irq: %d\n", error); 270 + return error; 271 + } 272 + 273 + error = input_register_device(input); 274 + if (error) { 275 + dev_err(dev, "failed to request irq: %d\n", error); 276 + return error; 277 + } 278 + 279 + return 0; 280 + } 281 + 282 + static const struct i2c_device_id nvt_ts_i2c_id[] = { 283 + { "NVT-ts" }, 284 + { } 285 + }; 286 + MODULE_DEVICE_TABLE(i2c, nvt_ts_i2c_id); 287 + 288 + static struct i2c_driver nvt_ts_driver = { 289 + .driver = { 290 + .name = "novatek-nvt-ts", 291 + .pm = pm_sleep_ptr(&nvt_ts_pm_ops), 292 + }, 293 + .probe_new = nvt_ts_probe, 294 + .id_table = nvt_ts_i2c_id, 295 + }; 296 + 297 + module_i2c_driver(nvt_ts_driver); 298 + 299 + MODULE_DESCRIPTION("Novatek NVT-ts touchscreen driver"); 300 + MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 301 + MODULE_LICENSE("GPL");
+1 -2
drivers/input/touchscreen/raspberrypi-ts.c
··· 134 134 return -ENOENT; 135 135 } 136 136 137 - fw = rpi_firmware_get(fw_node); 137 + fw = devm_rpi_firmware_get(&pdev->dev, fw_node); 138 138 of_node_put(fw_node); 139 139 if (!fw) 140 140 return -EPROBE_DEFER; ··· 160 160 touchbuf = (u32)ts->fw_regs_phys; 161 161 error = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF, 162 162 &touchbuf, sizeof(touchbuf)); 163 - rpi_firmware_put(fw); 164 163 if (error || touchbuf != 0) { 165 164 dev_warn(dev, "Failed to set touchbuf, %d\n", error); 166 165 return error;
+1 -1
drivers/input/touchscreen/sun4i-ts.c
··· 400 400 static struct platform_driver sun4i_ts_driver = { 401 401 .driver = { 402 402 .name = "sun4i-ts", 403 - .of_match_table = of_match_ptr(sun4i_ts_of_match), 403 + .of_match_table = sun4i_ts_of_match, 404 404 }, 405 405 .probe = sun4i_ts_probe, 406 406 .remove = sun4i_ts_remove,
+2 -15
drivers/input/touchscreen/tsc2007_core.c
··· 172 172 return IRQ_HANDLED; 173 173 } 174 174 175 - static irqreturn_t tsc2007_hard_irq(int irq, void *handle) 176 - { 177 - struct tsc2007 *ts = handle; 178 - 179 - if (tsc2007_is_pen_down(ts)) 180 - return IRQ_WAKE_THREAD; 181 - 182 - if (ts->clear_penirq) 183 - ts->clear_penirq(); 184 - 185 - return IRQ_HANDLED; 186 - } 187 - 188 175 static void tsc2007_stop(struct tsc2007 *ts) 189 176 { 190 177 ts->stopped = true; ··· 213 226 struct i2c_client *client = to_i2c_client(dev); 214 227 struct tsc2007 *ts = i2c_get_clientdata(client); 215 228 216 - return gpiod_get_value(ts->gpiod); 229 + return gpiod_get_value_cansleep(ts->gpiod); 217 230 } 218 231 219 232 static int tsc2007_probe_properties(struct device *dev, struct tsc2007 *ts) ··· 363 376 } 364 377 365 378 err = devm_request_threaded_irq(&client->dev, ts->irq, 366 - tsc2007_hard_irq, tsc2007_soft_irq, 379 + NULL, tsc2007_soft_irq, 367 380 IRQF_ONESHOT, 368 381 client->dev.driver->name, ts); 369 382 if (err) {
+1 -1
drivers/input/touchscreen/zinitix.c
··· 260 260 * so check if "vddo" is present and in that case use these names. 261 261 * Else use the proper supply names on the component. 262 262 */ 263 - if (of_find_property(dev->of_node, "vddo-supply", NULL)) { 263 + if (of_property_present(dev->of_node, "vddo-supply")) { 264 264 bt541->supplies[0].supply = "vdd"; 265 265 bt541->supplies[1].supply = "vddo"; 266 266 } else {
+3 -2
include/linux/input/matrix_keypad.h
··· 3 3 #define _MATRIX_KEYPAD_H 4 4 5 5 #include <linux/types.h> 6 - #include <linux/input.h> 7 - #include <linux/of.h> 6 + 7 + struct device; 8 + struct input_dev; 8 9 9 10 #define MATRIX_MAX_ROWS 32 10 11 #define MATRIX_MAX_COLS 32