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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull input updates from Dmitry Torokhov:

- a new driver for Goodix Berlin I2C and SPI touch controllers

- support for IQS7222D v1.1 and v1.2 in iqs7222 driver

- support for IST3032C and IST3038B parts in Imagis touchscreen driver

- support for touch keys for Imagis touchscreen controllers

- support for Snakebyte GAMEPADs in xpad driver

- various cleanups and conversions to yaml for device tree bindings

- assorted fixes and cleanups

- old Synaptics navpoint driver has been removed since the only board
that used it (HP iPAQ hx4700) was removed a while ago.

* tag 'input-for-v6.9-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (37 commits)
Input: xpad - add support for Snakebyte GAMEPADs
dt-bindings: input: samsung,s3c6410-keypad: convert to DT Schema
Input: imagis - add touch key support
dt-bindings: input: imagis: Document touch keys
Input: imagis - use FIELD_GET where applicable
Input: make input_class constant
dt-bindings: input: atmel,captouch: convert bindings to YAML
Input: iqs7222 - add support for IQS7222D v1.1 and v1.2
dt-bindings: input: allwinner,sun4i-a10-lrad: drop redundant type from label
Input: serio - make serio_bus const
Input: synaptics-rmi4 - make rmi_bus_type const
Input: xilinx_ps2 - fix kernel-doc for xps2_of_probe function
input/touchscreen: imagis: add support for IST3032C
dt-bindings: input/touchscreen: imagis: add compatible for IST3032C
input/touchscreen: imagis: Add support for Imagis IST3038B
dt-bindings: input/touchscreen: Add compatible for IST3038B
input/touchscreen: imagis: Correct the maximum touch area value
Input: leds - change config symbol dependency for audio mute trigger
Input: ti_am335x_tsc - remove redundant assignment to variable config
Input: xpad - sort xpad_device by vendor and product ID
...

+1669 -671
-1
Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml
··· 49 49 $ref: input.yaml# 50 50 properties: 51 51 label: 52 - $ref: /schemas/types.yaml#/definitions/string 53 52 description: Descriptive name of the key 54 53 55 54 linux,code: true
-36
Documentation/devicetree/bindings/input/atmel,captouch.txt
··· 1 - Device tree bindings for Atmel capacitive touch device, typically 2 - an Atmel touch sensor connected to AtmegaXX MCU running firmware 3 - based on Qtouch library. 4 - 5 - The node for this device must be a child of a I2C controller node, as the 6 - device communicates via I2C. 7 - 8 - Required properties: 9 - 10 - compatible: Must be "atmel,captouch". 11 - reg: The I2C slave address of the device. 12 - interrupts: Property describing the interrupt line the device 13 - is connected to. The device only has one interrupt 14 - source. 15 - linux,keycodes: Specifies an array of numeric keycode values to 16 - be used for reporting button presses. The array can 17 - contain up to 8 entries. 18 - 19 - Optional properties: 20 - 21 - autorepeat: Enables the Linux input system's autorepeat 22 - feature on the input device. 23 - 24 - Example: 25 - 26 - atmel-captouch@51 { 27 - compatible = "atmel,captouch"; 28 - reg = <0x51>; 29 - interrupt-parent = <&tlmm>; 30 - interrupts = <67 IRQ_TYPE_EDGE_FALLING>; 31 - linux,keycodes = <BTN_0>, <BTN_1>, 32 - <BTN_2>, <BTN_3>, 33 - <BTN_4>, <BTN_5>, 34 - <BTN_6>, <BTN_7>; 35 - autorepeat; 36 - };
+59
Documentation/devicetree/bindings/input/atmel,captouch.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/atmel,captouch.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Atmel capacitive touch device 8 + 9 + maintainers: 10 + - Dharma balasubiramani <dharma.b@microchip.com> 11 + 12 + description: 13 + Atmel capacitive touch device, typically an Atmel touch sensor connected to 14 + AtmegaXX MCU running firmware based on Qtouch library. 15 + 16 + allOf: 17 + - $ref: input.yaml# 18 + 19 + properties: 20 + compatible: 21 + const: atmel,captouch 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + interrupts: 27 + maxItems: 1 28 + 29 + linux,keycodes: 30 + minItems: 1 31 + maxItems: 8 32 + 33 + required: 34 + - compatible 35 + - reg 36 + - interrupts 37 + - linux,keycodes 38 + 39 + unevaluatedProperties: false 40 + 41 + examples: 42 + - | 43 + #include <dt-bindings/interrupt-controller/irq.h> 44 + #include <dt-bindings/input/linux-event-codes.h> 45 + i2c { 46 + #address-cells = <1>; 47 + #size-cells = <0>; 48 + touch@51 { 49 + compatible = "atmel,captouch"; 50 + reg = <0x51>; 51 + interrupt-parent = <&tlmm>; 52 + interrupts = <67 IRQ_TYPE_EDGE_FALLING>; 53 + linux,keycodes = <BTN_0>, <BTN_1>, 54 + <BTN_2>, <BTN_3>, 55 + <BTN_4>, <BTN_5>, 56 + <BTN_6>, <BTN_7>; 57 + autorepeat; 58 + }; 59 + };
+121
Documentation/devicetree/bindings/input/samsung,s3c6410-keypad.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/samsung,s3c6410-keypad.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Samsung SoC series Keypad Controller 8 + 9 + description: 10 + Samsung SoC Keypad controller is used to interface a SoC with a matrix-type 11 + keypad device. The keypad controller supports multiple row and column lines. 12 + A key can be placed at each intersection of a unique row and a unique column. 13 + The keypad controller can sense a key-press and key-release and report the 14 + event using a interrupt to the cpu. 15 + 16 + maintainers: 17 + - Krzysztof Kozlowski <krzk@kernel.org> 18 + 19 + properties: 20 + compatible: 21 + enum: 22 + - samsung,s3c6410-keypad 23 + - samsung,s5pv210-keypad 24 + 25 + reg: 26 + maxItems: 1 27 + 28 + clocks: 29 + maxItems: 1 30 + 31 + clock-names: 32 + items: 33 + - const: keypad 34 + 35 + interrupts: 36 + maxItems: 1 37 + 38 + wakeup-source: true 39 + 40 + linux,input-no-autorepeat: 41 + type: boolean 42 + description: 43 + Do no enable autorepeat feature. 44 + 45 + linux,input-wakeup: 46 + type: boolean 47 + deprecated: true 48 + 49 + samsung,keypad-num-columns: 50 + $ref: /schemas/types.yaml#/definitions/uint32 51 + description: 52 + Number of column lines connected to the keypad controller. 53 + 54 + samsung,keypad-num-rows: 55 + $ref: /schemas/types.yaml#/definitions/uint32 56 + description: 57 + Number of row lines connected to the keypad controller. 58 + 59 + patternProperties: 60 + '^key-[0-9a-z]+$': 61 + type: object 62 + $ref: input.yaml# 63 + additionalProperties: false 64 + description: 65 + Each key connected to the keypad controller is represented as a child 66 + node to the keypad controller device node. 67 + 68 + properties: 69 + keypad,column: 70 + $ref: /schemas/types.yaml#/definitions/uint32 71 + description: The column number to which the key is connected. 72 + 73 + keypad,row: 74 + $ref: /schemas/types.yaml#/definitions/uint32 75 + description: The row number to which the key is connected. 76 + 77 + linux,code: true 78 + 79 + required: 80 + - keypad,column 81 + - keypad,row 82 + - linux,code 83 + 84 + required: 85 + - compatible 86 + - reg 87 + - interrupts 88 + - samsung,keypad-num-columns 89 + - samsung,keypad-num-rows 90 + 91 + additionalProperties: false 92 + 93 + examples: 94 + - | 95 + #include <dt-bindings/clock/exynos4.h> 96 + #include <dt-bindings/interrupt-controller/arm-gic.h> 97 + 98 + keypad@100a0000 { 99 + compatible = "samsung,s5pv210-keypad"; 100 + reg = <0x100a0000 0x100>; 101 + interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; 102 + clocks = <&clock CLK_KEYIF>; 103 + clock-names = "keypad"; 104 + 105 + samsung,keypad-num-rows = <2>; 106 + samsung,keypad-num-columns = <8>; 107 + linux,input-no-autorepeat; 108 + wakeup-source; 109 + 110 + key-1 { 111 + keypad,row = <0>; 112 + keypad,column = <3>; 113 + linux,code = <2>; 114 + }; 115 + 116 + key-2 { 117 + keypad,row = <0>; 118 + keypad,column = <4>; 119 + linux,code = <3>; 120 + }; 121 + };
-77
Documentation/devicetree/bindings/input/samsung-keypad.txt
··· 1 - * Samsung's Keypad Controller device tree bindings 2 - 3 - Samsung's Keypad controller is used to interface a SoC with a matrix-type 4 - keypad device. The keypad controller supports multiple row and column lines. 5 - A key can be placed at each intersection of a unique row and a unique column. 6 - The keypad controller can sense a key-press and key-release and report the 7 - event using a interrupt to the cpu. 8 - 9 - Required SoC Specific Properties: 10 - - compatible: should be one of the following 11 - - "samsung,s3c6410-keypad": For controllers compatible with s3c6410 keypad 12 - controller. 13 - - "samsung,s5pv210-keypad": For controllers compatible with s5pv210 keypad 14 - controller. 15 - 16 - - reg: physical base address of the controller and length of memory mapped 17 - region. 18 - 19 - - interrupts: The interrupt number to the cpu. 20 - 21 - Required Board Specific Properties: 22 - - samsung,keypad-num-rows: Number of row lines connected to the keypad 23 - controller. 24 - 25 - - samsung,keypad-num-columns: Number of column lines connected to the 26 - keypad controller. 27 - 28 - - Keys represented as child nodes: Each key connected to the keypad 29 - controller is represented as a child node to the keypad controller 30 - device node and should include the following properties. 31 - - keypad,row: the row number to which the key is connected. 32 - - keypad,column: the column number to which the key is connected. 33 - - linux,code: the key-code to be reported when the key is pressed 34 - and released. 35 - 36 - - pinctrl-0: Should specify pin control groups used for this controller. 37 - - pinctrl-names: Should contain only one value - "default". 38 - 39 - Optional Properties: 40 - - wakeup-source: use any event on keypad as wakeup event. 41 - (Legacy property supported: "linux,input-wakeup") 42 - 43 - Optional Properties specific to linux: 44 - - linux,keypad-no-autorepeat: do no enable autorepeat feature. 45 - 46 - 47 - Example: 48 - keypad@100a0000 { 49 - compatible = "samsung,s5pv210-keypad"; 50 - reg = <0x100A0000 0x100>; 51 - interrupts = <173>; 52 - samsung,keypad-num-rows = <2>; 53 - samsung,keypad-num-columns = <8>; 54 - linux,input-no-autorepeat; 55 - wakeup-source; 56 - 57 - pinctrl-names = "default"; 58 - pinctrl-0 = <&keypad_rows &keypad_columns>; 59 - 60 - key_1 { 61 - keypad,row = <0>; 62 - keypad,column = <3>; 63 - linux,code = <2>; 64 - }; 65 - 66 - key_2 { 67 - keypad,row = <0>; 68 - keypad,column = <4>; 69 - linux,code = <3>; 70 - }; 71 - 72 - key_3 { 73 - keypad,row = <0>; 74 - keypad,column = <5>; 75 - linux,code = <4>; 76 - }; 77 - };
+95
Documentation/devicetree/bindings/input/touchscreen/goodix,gt9916.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/touchscreen/goodix,gt9916.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Goodix Berlin series touchscreen controller 8 + 9 + description: The Goodix Berlin series of touchscreen controllers 10 + be connected to either I2C or SPI buses. 11 + 12 + maintainers: 13 + - Neil Armstrong <neil.armstrong@linaro.org> 14 + 15 + allOf: 16 + - $ref: touchscreen.yaml# 17 + - $ref: /schemas/spi/spi-peripheral-props.yaml# 18 + 19 + properties: 20 + compatible: 21 + enum: 22 + - goodix,gt9916 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + interrupts: 28 + maxItems: 1 29 + 30 + reset-gpios: 31 + maxItems: 1 32 + 33 + avdd-supply: 34 + description: Analog power supply regulator on AVDD pin 35 + 36 + vddio-supply: 37 + description: power supply regulator on VDDIO pin 38 + 39 + spi-max-frequency: true 40 + touchscreen-inverted-x: true 41 + touchscreen-inverted-y: true 42 + touchscreen-size-x: true 43 + touchscreen-size-y: true 44 + touchscreen-swapped-x-y: true 45 + 46 + additionalProperties: false 47 + 48 + required: 49 + - compatible 50 + - reg 51 + - interrupts 52 + - avdd-supply 53 + - touchscreen-size-x 54 + - touchscreen-size-y 55 + 56 + examples: 57 + - | 58 + #include <dt-bindings/interrupt-controller/irq.h> 59 + #include <dt-bindings/gpio/gpio.h> 60 + i2c { 61 + #address-cells = <1>; 62 + #size-cells = <0>; 63 + touchscreen@5d { 64 + compatible = "goodix,gt9916"; 65 + reg = <0x5d>; 66 + interrupt-parent = <&gpio>; 67 + interrupts = <25 IRQ_TYPE_LEVEL_LOW>; 68 + reset-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; 69 + avdd-supply = <&ts_avdd>; 70 + touchscreen-size-x = <1024>; 71 + touchscreen-size-y = <768>; 72 + }; 73 + }; 74 + - | 75 + #include <dt-bindings/interrupt-controller/irq.h> 76 + #include <dt-bindings/gpio/gpio.h> 77 + spi { 78 + #address-cells = <1>; 79 + #size-cells = <0>; 80 + num-cs = <1>; 81 + cs-gpios = <&gpio 2 GPIO_ACTIVE_HIGH>; 82 + touchscreen@0 { 83 + compatible = "goodix,gt9916"; 84 + reg = <0>; 85 + interrupt-parent = <&gpio>; 86 + interrupts = <25 IRQ_TYPE_LEVEL_LOW>; 87 + reset-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; 88 + avdd-supply = <&ts_avdd>; 89 + spi-max-frequency = <1000000>; 90 + touchscreen-size-x = <1024>; 91 + touchscreen-size-y = <768>; 92 + }; 93 + }; 94 + 95 + ...
+3 -2
Documentation/devicetree/bindings/input/touchscreen/goodix.yaml
··· 37 37 maxItems: 1 38 38 39 39 irq-gpios: 40 - description: GPIO pin used for IRQ. The driver uses the interrupt gpio pin 41 - as output to reset the device. 40 + description: GPIO pin used for IRQ input. Additionally, this line is 41 + sampled by the device on reset deassertion to select the I2C client 42 + address, thus it can be driven by the host during the reset sequence. 42 43 maxItems: 1 43 44 44 45 reset-gpios:
+18 -3
Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml
··· 9 9 maintainers: 10 10 - Markuss Broks <markuss.broks@gmail.com> 11 11 12 - allOf: 13 - - $ref: touchscreen.yaml# 14 - 15 12 properties: 16 13 $nodename: 17 14 pattern: "^touchscreen@[0-9a-f]+$" 18 15 19 16 compatible: 20 17 enum: 18 + - imagis,ist3032c 19 + - imagis,ist3038b 21 20 - imagis,ist3038c 22 21 23 22 reg: ··· 31 32 vddio-supply: 32 33 description: Power supply regulator for the I2C bus 33 34 35 + linux,keycodes: 36 + description: Keycodes for the touch keys 37 + maxItems: 5 38 + 34 39 touchscreen-size-x: true 35 40 touchscreen-size-y: true 36 41 touchscreen-fuzz-x: true ··· 44 41 touchscreen-swapped-x-y: true 45 42 46 43 additionalProperties: false 44 + 45 + allOf: 46 + - $ref: touchscreen.yaml# 47 + - if: 48 + not: 49 + properties: 50 + compatible: 51 + contains: 52 + const: imagis,ist3032c 53 + then: 54 + properties: 55 + linux,keycodes: false 47 56 48 57 required: 49 58 - compatible
+5 -1
Documentation/devicetree/bindings/input/touchscreen/melfas,mms114.yaml
··· 17 17 pattern: "^touchscreen(@.*)?$" 18 18 19 19 compatible: 20 - items: 20 + oneOf: 21 21 - enum: 22 22 - melfas,mms114 23 23 - melfas,mms134s 24 24 - melfas,mms136 25 25 - melfas,mms152 26 26 - melfas,mms345l 27 + - items: 28 + - enum: 29 + - melfas,mms252 30 + - const: melfas,mms114 27 31 28 32 reg: 29 33 description: I2C address
+1 -1
Documentation/devicetree/bindings/input/touchscreen/silead,gsl1680.yaml
··· 31 31 maxItems: 1 32 32 33 33 firmware-name: 34 - $ref: /schemas/types.yaml#/definitions/string 34 + maxItems: 1 35 35 description: > 36 36 File basename for board specific firmware 37 37
+1 -1
Documentation/devicetree/bindings/power/wakeup-source.txt
··· 27 27 Documentation/devicetree/bindings/mfd/tc3589x.txt 28 28 Documentation/devicetree/bindings/input/touchscreen/ads7846.txt 29 29 4. "linux,keypad-wakeup" Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt 30 - 5. "linux,input-wakeup" Documentation/devicetree/bindings/input/samsung-keypad.txt 30 + 5. "linux,input-wakeup" Documentation/devicetree/bindings/input/samsung,s3c6410-keypad.yaml 31 31 6. "nvidia,wakeup-source" Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt 32 32 33 33 Examples
+2 -2
drivers/input/gameport/gameport.c
··· 38 38 39 39 static LIST_HEAD(gameport_list); 40 40 41 - static struct bus_type gameport_bus; 41 + static const struct bus_type gameport_bus; 42 42 43 43 static void gameport_add_port(struct gameport *gameport); 44 44 static void gameport_attach_driver(struct gameport_driver *drv); ··· 813 813 return !gameport_drv->ignore; 814 814 } 815 815 816 - static struct bus_type gameport_bus = { 816 + static const struct bus_type gameport_bus = { 817 817 .name = "gameport", 818 818 .dev_groups = gameport_device_groups, 819 819 .drv_groups = gameport_driver_groups,
+7 -1
drivers/input/input-leds.c
··· 18 18 #define VT_TRIGGER(_name) .trigger = NULL 19 19 #endif 20 20 21 + #if IS_ENABLED(CONFIG_SND_CTL_LED) 22 + #define AUDIO_TRIGGER(_name) .trigger = _name 23 + #else 24 + #define AUDIO_TRIGGER(_name) .trigger = NULL 25 + #endif 26 + 21 27 static const struct { 22 28 const char *name; 23 29 const char *trigger; ··· 35 29 [LED_KANA] = { "kana", VT_TRIGGER("kbd-kanalock") }, 36 30 [LED_SLEEP] = { "sleep" } , 37 31 [LED_SUSPEND] = { "suspend" }, 38 - [LED_MUTE] = { "mute" }, 32 + [LED_MUTE] = { "mute", AUDIO_TRIGGER("audio-mute") }, 39 33 [LED_MISC] = { "misc" }, 40 34 [LED_MAIL] = { "mail" }, 41 35 [LED_CHARGING] = { "charging" },
+7 -9
drivers/input/input.c
··· 1918 1918 return kasprintf(GFP_KERNEL, "input/%s", dev_name(dev)); 1919 1919 } 1920 1920 1921 - struct class input_class = { 1921 + const struct class input_class = { 1922 1922 .name = "input", 1923 1923 .devnode = input_devnode, 1924 1924 }; ··· 2629 2629 * locking is needed here. 2630 2630 */ 2631 2631 if (legacy_base >= 0) { 2632 - int minor = ida_simple_get(&input_ida, 2633 - legacy_base, 2634 - legacy_base + legacy_num, 2635 - GFP_KERNEL); 2632 + int minor = ida_alloc_range(&input_ida, legacy_base, 2633 + legacy_base + legacy_num - 1, 2634 + GFP_KERNEL); 2636 2635 if (minor >= 0 || !allow_dynamic) 2637 2636 return minor; 2638 2637 } 2639 2638 2640 - return ida_simple_get(&input_ida, 2641 - INPUT_FIRST_DYNAMIC_DEV, INPUT_MAX_CHAR_DEVICES, 2642 - GFP_KERNEL); 2639 + return ida_alloc_range(&input_ida, INPUT_FIRST_DYNAMIC_DEV, 2640 + INPUT_MAX_CHAR_DEVICES - 1, GFP_KERNEL); 2643 2641 } 2644 2642 EXPORT_SYMBOL(input_get_new_minor); 2645 2643 ··· 2650 2652 */ 2651 2653 void input_free_minor(unsigned int minor) 2652 2654 { 2653 - ida_simple_remove(&input_ida, minor); 2655 + ida_free(&input_ida, minor); 2654 2656 } 2655 2657 EXPORT_SYMBOL(input_free_minor); 2656 2658
+11 -3
drivers/input/joystick/xpad.c
··· 127 127 u8 mapping; 128 128 u8 xtype; 129 129 } xpad_device[] = { 130 + /* Please keep this list sorted by vendor and product ID. */ 130 131 { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 }, 131 132 { 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 }, 132 133 { 0x03eb, 0xff02, "Wooting Two (Legacy)", 0, XTYPE_XBOX360 }, ··· 153 152 { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE }, 154 153 { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE }, 155 154 { 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", MAP_PADDLES, XTYPE_XBOXONE }, 156 - { 0x045e, 0x0b00, "Microsoft X-Box One Elite 2 pad", MAP_PADDLES, XTYPE_XBOXONE }, 157 155 { 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE }, 158 156 { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, 157 + { 0x045e, 0x0b00, "Microsoft X-Box One Elite 2 pad", MAP_PADDLES, XTYPE_XBOXONE }, 159 158 { 0x045e, 0x0b0a, "Microsoft X-Box Adaptive Controller", MAP_PROFILE_BUTTON, XTYPE_XBOXONE }, 160 159 { 0x045e, 0x0b12, "Microsoft Xbox Series S|X Controller", MAP_SELECT_BUTTON, XTYPE_XBOXONE }, 161 160 { 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 }, ··· 341 340 { 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE }, 342 341 { 0x20d6, 0x2009, "PowerA Enhanced Wired Controller for Xbox Series X|S", 0, XTYPE_XBOXONE }, 343 342 { 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 }, 344 - { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, 345 343 { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, 346 344 { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 }, 347 345 { 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 }, ··· 355 355 { 0x24c6, 0x5502, "Hori Fighting Stick VX Alt", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, 356 356 { 0x24c6, 0x5503, "Hori Fighting Edge", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, 357 357 { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 }, 358 - { 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, 359 358 { 0x24c6, 0x550d, "Hori GEM Xbox controller", 0, XTYPE_XBOX360 }, 360 359 { 0x24c6, 0x550e, "Hori Real Arcade Pro V Kai 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, 360 + { 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, 361 361 { 0x24c6, 0x551a, "PowerA FUSION Pro Controller", 0, XTYPE_XBOXONE }, 362 362 { 0x24c6, 0x561a, "PowerA FUSION Controller", 0, XTYPE_XBOXONE }, 363 363 { 0x24c6, 0x5b00, "ThrustMaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 }, ··· 366 366 { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 }, 367 367 { 0x24c6, 0xfafe, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, 368 368 { 0x2563, 0x058d, "OneXPlayer Gamepad", 0, XTYPE_XBOX360 }, 369 + { 0x294b, 0x3303, "Snakebyte GAMEPAD BASE X", 0, XTYPE_XBOXONE }, 370 + { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE }, 369 371 { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, 370 372 { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, 373 + { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, 371 374 { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, 372 375 { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, 373 376 { 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 }, ··· 468 465 { XPAD_XBOXONE_VENDOR_PROTOCOL((vend), 208) } 469 466 470 467 static const struct usb_device_id xpad_table[] = { 468 + /* 469 + * Please keep this list sorted by vendor ID. Note that there are 2 470 + * macros - XPAD_XBOX360_VENDOR and XPAD_XBOXONE_VENDOR. 471 + */ 471 472 { USB_INTERFACE_INFO('X', 'B', 0) }, /* Xbox USB-IF not-approved class */ 472 473 XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 controller */ 473 474 XPAD_XBOX360_VENDOR(0x03eb), /* Wooting Keyboards (Legacy) */ ··· 514 507 XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA controllers */ 515 508 XPAD_XBOX360_VENDOR(0x2563), /* OneXPlayer Gamepad */ 516 509 XPAD_XBOX360_VENDOR(0x260d), /* Dareu H101 */ 510 + XPAD_XBOXONE_VENDOR(0x294b), /* Snakebyte */ 517 511 XPAD_XBOX360_VENDOR(0x2c22), /* Qanba Controllers */ 518 512 XPAD_XBOX360_VENDOR(0x2dc8), /* 8BitDo Pro 2 Wired Controller */ 519 513 XPAD_XBOXONE_VENDOR(0x2dc8), /* 8BitDo Pro 2 Wired Controller for Xbox */
+1 -1
drivers/input/keyboard/bcm-keypad.c
··· 418 418 .probe = bcm_kp_probe, 419 419 .driver = { 420 420 .name = "bcm-keypad", 421 - .of_match_table = of_match_ptr(bcm_kp_of_match), 421 + .of_match_table = bcm_kp_of_match, 422 422 } 423 423 }; 424 424
+54 -116
drivers/input/keyboard/matrix_keypad.c
··· 28 28 struct input_dev *input_dev; 29 29 unsigned int row_shift; 30 30 31 - DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS); 31 + unsigned int row_irqs[MATRIX_MAX_ROWS]; 32 + unsigned int num_row_irqs; 33 + DECLARE_BITMAP(wakeup_enabled_irqs, MATRIX_MAX_ROWS); 32 34 33 35 uint32_t last_key_state[MATRIX_MAX_COLS]; 34 36 struct delayed_work work; ··· 87 85 88 86 static void enable_row_irqs(struct matrix_keypad *keypad) 89 87 { 90 - const struct matrix_keypad_platform_data *pdata = keypad->pdata; 91 88 int i; 92 89 93 - if (pdata->clustered_irq > 0) 94 - enable_irq(pdata->clustered_irq); 95 - else { 96 - for (i = 0; i < pdata->num_row_gpios; i++) 97 - enable_irq(gpio_to_irq(pdata->row_gpios[i])); 98 - } 90 + for (i = 0; i < keypad->num_row_irqs; i++) 91 + enable_irq(keypad->row_irqs[i]); 99 92 } 100 93 101 94 static void disable_row_irqs(struct matrix_keypad *keypad) 102 95 { 103 - const struct matrix_keypad_platform_data *pdata = keypad->pdata; 104 96 int i; 105 97 106 - if (pdata->clustered_irq > 0) 107 - disable_irq_nosync(pdata->clustered_irq); 108 - else { 109 - for (i = 0; i < pdata->num_row_gpios; i++) 110 - disable_irq_nosync(gpio_to_irq(pdata->row_gpios[i])); 111 - } 98 + for (i = 0; i < keypad->num_row_irqs; i++) 99 + disable_irq_nosync(keypad->row_irqs[i]); 112 100 } 113 101 114 102 /* ··· 224 232 225 233 static void matrix_keypad_enable_wakeup(struct matrix_keypad *keypad) 226 234 { 227 - const struct matrix_keypad_platform_data *pdata = keypad->pdata; 228 - unsigned int gpio; 229 235 int i; 230 236 231 - if (pdata->clustered_irq > 0) { 232 - if (enable_irq_wake(pdata->clustered_irq) == 0) 233 - keypad->gpio_all_disabled = true; 234 - } else { 235 - 236 - for (i = 0; i < pdata->num_row_gpios; i++) { 237 - if (!test_bit(i, keypad->disabled_gpios)) { 238 - gpio = pdata->row_gpios[i]; 239 - 240 - if (enable_irq_wake(gpio_to_irq(gpio)) == 0) 241 - __set_bit(i, keypad->disabled_gpios); 242 - } 243 - } 244 - } 237 + for_each_clear_bit(i, keypad->wakeup_enabled_irqs, keypad->num_row_irqs) 238 + if (enable_irq_wake(keypad->row_irqs[i]) == 0) 239 + __set_bit(i, keypad->wakeup_enabled_irqs); 245 240 } 246 241 247 242 static void matrix_keypad_disable_wakeup(struct matrix_keypad *keypad) 248 243 { 249 - const struct matrix_keypad_platform_data *pdata = keypad->pdata; 250 - unsigned int gpio; 251 244 int i; 252 245 253 - if (pdata->clustered_irq > 0) { 254 - if (keypad->gpio_all_disabled) { 255 - disable_irq_wake(pdata->clustered_irq); 256 - keypad->gpio_all_disabled = false; 257 - } 258 - } else { 259 - for (i = 0; i < pdata->num_row_gpios; i++) { 260 - if (test_and_clear_bit(i, keypad->disabled_gpios)) { 261 - gpio = pdata->row_gpios[i]; 262 - disable_irq_wake(gpio_to_irq(gpio)); 263 - } 264 - } 246 + for_each_set_bit(i, keypad->wakeup_enabled_irqs, keypad->num_row_irqs) { 247 + disable_irq_wake(keypad->row_irqs[i]); 248 + __clear_bit(i, keypad->wakeup_enabled_irqs); 265 249 } 266 250 } 267 251 ··· 274 306 struct matrix_keypad *keypad) 275 307 { 276 308 const struct matrix_keypad_platform_data *pdata = keypad->pdata; 277 - int i, err; 309 + int i, irq, err; 278 310 279 311 /* initialized strobe lines as outputs, activated */ 280 312 for (i = 0; i < pdata->num_col_gpios; i++) { 281 - err = gpio_request(pdata->col_gpios[i], "matrix_kbd_col"); 313 + err = devm_gpio_request(&pdev->dev, 314 + pdata->col_gpios[i], "matrix_kbd_col"); 282 315 if (err) { 283 316 dev_err(&pdev->dev, 284 317 "failed to request GPIO%d for COL%d\n", 285 318 pdata->col_gpios[i], i); 286 - goto err_free_cols; 319 + return err; 287 320 } 288 321 289 322 gpio_direction_output(pdata->col_gpios[i], !pdata->active_low); 290 323 } 291 324 292 325 for (i = 0; i < pdata->num_row_gpios; i++) { 293 - err = gpio_request(pdata->row_gpios[i], "matrix_kbd_row"); 326 + err = devm_gpio_request(&pdev->dev, 327 + pdata->row_gpios[i], "matrix_kbd_row"); 294 328 if (err) { 295 329 dev_err(&pdev->dev, 296 330 "failed to request GPIO%d for ROW%d\n", 297 331 pdata->row_gpios[i], i); 298 - goto err_free_rows; 332 + return err; 299 333 } 300 334 301 335 gpio_direction_input(pdata->row_gpios[i]); 302 336 } 303 337 304 338 if (pdata->clustered_irq > 0) { 305 - err = request_any_context_irq(pdata->clustered_irq, 339 + err = devm_request_any_context_irq(&pdev->dev, 340 + pdata->clustered_irq, 306 341 matrix_keypad_interrupt, 307 342 pdata->clustered_irq_flags, 308 343 "matrix-keypad", keypad); 309 344 if (err < 0) { 310 345 dev_err(&pdev->dev, 311 346 "Unable to acquire clustered interrupt\n"); 312 - goto err_free_rows; 347 + return err; 313 348 } 349 + 350 + keypad->row_irqs[0] = pdata->clustered_irq; 351 + keypad->num_row_irqs = 1; 314 352 } else { 315 353 for (i = 0; i < pdata->num_row_gpios; i++) { 316 - err = request_any_context_irq( 317 - gpio_to_irq(pdata->row_gpios[i]), 354 + irq = gpio_to_irq(pdata->row_gpios[i]); 355 + if (irq < 0) { 356 + err = irq; 357 + dev_err(&pdev->dev, 358 + "Unable to convert GPIO line %i to irq: %d\n", 359 + pdata->row_gpios[i], err); 360 + return err; 361 + } 362 + 363 + err = devm_request_any_context_irq(&pdev->dev, 364 + irq, 318 365 matrix_keypad_interrupt, 319 366 IRQF_TRIGGER_RISING | 320 - IRQF_TRIGGER_FALLING, 367 + IRQF_TRIGGER_FALLING, 321 368 "matrix-keypad", keypad); 322 369 if (err < 0) { 323 370 dev_err(&pdev->dev, 324 371 "Unable to acquire interrupt for GPIO line %i\n", 325 372 pdata->row_gpios[i]); 326 - goto err_free_irqs; 373 + return err; 327 374 } 375 + 376 + keypad->row_irqs[i] = irq; 328 377 } 378 + 379 + keypad->num_row_irqs = pdata->num_row_gpios; 329 380 } 330 381 331 382 /* initialized as disabled - enabled by input->open */ 332 383 disable_row_irqs(keypad); 384 + 333 385 return 0; 334 - 335 - err_free_irqs: 336 - while (--i >= 0) 337 - free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); 338 - i = pdata->num_row_gpios; 339 - err_free_rows: 340 - while (--i >= 0) 341 - gpio_free(pdata->row_gpios[i]); 342 - i = pdata->num_col_gpios; 343 - err_free_cols: 344 - while (--i >= 0) 345 - gpio_free(pdata->col_gpios[i]); 346 - 347 - return err; 348 - } 349 - 350 - static void matrix_keypad_free_gpio(struct matrix_keypad *keypad) 351 - { 352 - const struct matrix_keypad_platform_data *pdata = keypad->pdata; 353 - int i; 354 - 355 - if (pdata->clustered_irq > 0) { 356 - free_irq(pdata->clustered_irq, keypad); 357 - } else { 358 - for (i = 0; i < pdata->num_row_gpios; i++) 359 - free_irq(gpio_to_irq(pdata->row_gpios[i]), keypad); 360 - } 361 - 362 - for (i = 0; i < pdata->num_row_gpios; i++) 363 - gpio_free(pdata->row_gpios[i]); 364 - 365 - for (i = 0; i < pdata->num_col_gpios; i++) 366 - gpio_free(pdata->col_gpios[i]); 367 386 } 368 387 369 388 #ifdef CONFIG_OF ··· 449 494 return -EINVAL; 450 495 } 451 496 452 - keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL); 453 - input_dev = input_allocate_device(); 454 - if (!keypad || !input_dev) { 455 - err = -ENOMEM; 456 - goto err_free_mem; 457 - } 497 + keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL); 498 + if (!keypad) 499 + return -ENOMEM; 500 + 501 + input_dev = devm_input_allocate_device(&pdev->dev); 502 + if (!input_dev) 503 + return -ENOMEM; 458 504 459 505 keypad->input_dev = input_dev; 460 506 keypad->pdata = pdata; ··· 466 510 467 511 input_dev->name = pdev->name; 468 512 input_dev->id.bustype = BUS_HOST; 469 - input_dev->dev.parent = &pdev->dev; 470 513 input_dev->open = matrix_keypad_start; 471 514 input_dev->close = matrix_keypad_stop; 472 515 ··· 475 520 NULL, input_dev); 476 521 if (err) { 477 522 dev_err(&pdev->dev, "failed to build keymap\n"); 478 - goto err_free_mem; 523 + return -ENOMEM; 479 524 } 480 525 481 526 if (!pdata->no_autorepeat) ··· 485 530 486 531 err = matrix_keypad_init_gpio(pdev, keypad); 487 532 if (err) 488 - goto err_free_mem; 533 + return err; 489 534 490 535 err = input_register_device(keypad->input_dev); 491 536 if (err) 492 - goto err_free_gpio; 537 + return err; 493 538 494 539 device_init_wakeup(&pdev->dev, pdata->wakeup); 495 540 platform_set_drvdata(pdev, keypad); 496 541 497 542 return 0; 498 - 499 - err_free_gpio: 500 - matrix_keypad_free_gpio(keypad); 501 - err_free_mem: 502 - input_free_device(input_dev); 503 - kfree(keypad); 504 - return err; 505 - } 506 - 507 - static void matrix_keypad_remove(struct platform_device *pdev) 508 - { 509 - struct matrix_keypad *keypad = platform_get_drvdata(pdev); 510 - 511 - matrix_keypad_free_gpio(keypad); 512 - input_unregister_device(keypad->input_dev); 513 - kfree(keypad); 514 543 } 515 544 516 545 #ifdef CONFIG_OF ··· 507 568 508 569 static struct platform_driver matrix_keypad_driver = { 509 570 .probe = matrix_keypad_probe, 510 - .remove_new = matrix_keypad_remove, 511 571 .driver = { 512 572 .name = "matrix-keypad", 513 573 .pm = pm_sleep_ptr(&matrix_keypad_pm_ops),
+1 -13
drivers/input/misc/88pm80x_onkey.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * Marvell 88PM80x ONKEY driver 3 4 * 4 5 * Copyright (C) 2012 Marvell International Ltd. 5 6 * Haojian Zhuang <haojian.zhuang@marvell.com> 6 7 * Qiao Zhou <zhouqiao@marvell.com> 7 - * 8 - * This file is subject to the terms and conditions of the GNU General 9 - * Public License. See the file "COPYING" in the main directory of this 10 - * archive for more details. 11 - * 12 - * This program is distributed in the hope that it will be useful, 13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - * GNU General Public License for more details. 16 - * 17 - * You should have received a copy of the GNU General Public License 18 - * along with this program; if not, write to the Free Software 19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 8 */ 21 9 22 10 #include <linux/kernel.h>
+112
drivers/input/misc/iqs7222.c
··· 622 622 }, 623 623 { 624 624 .prod_num = IQS7222_PROD_NUM_D, 625 + .fw_major = 1, 626 + .fw_minor = 2, 627 + .touch_link = 1770, 628 + .allow_offset = 9, 629 + .event_offset = 10, 630 + .comms_offset = 11, 631 + .reg_grps = { 632 + [IQS7222_REG_GRP_STAT] = { 633 + .base = IQS7222_SYS_STATUS, 634 + .num_row = 1, 635 + .num_col = 7, 636 + }, 637 + [IQS7222_REG_GRP_CYCLE] = { 638 + .base = 0x8000, 639 + .num_row = 7, 640 + .num_col = 2, 641 + }, 642 + [IQS7222_REG_GRP_GLBL] = { 643 + .base = 0x8700, 644 + .num_row = 1, 645 + .num_col = 3, 646 + }, 647 + [IQS7222_REG_GRP_BTN] = { 648 + .base = 0x9000, 649 + .num_row = 14, 650 + .num_col = 3, 651 + }, 652 + [IQS7222_REG_GRP_CHAN] = { 653 + .base = 0xA000, 654 + .num_row = 14, 655 + .num_col = 4, 656 + }, 657 + [IQS7222_REG_GRP_FILT] = { 658 + .base = 0xAE00, 659 + .num_row = 1, 660 + .num_col = 2, 661 + }, 662 + [IQS7222_REG_GRP_TPAD] = { 663 + .base = 0xB000, 664 + .num_row = 1, 665 + .num_col = 24, 666 + }, 667 + [IQS7222_REG_GRP_GPIO] = { 668 + .base = 0xC000, 669 + .num_row = 3, 670 + .num_col = 3, 671 + }, 672 + [IQS7222_REG_GRP_SYS] = { 673 + .base = IQS7222_SYS_SETUP, 674 + .num_row = 1, 675 + .num_col = 12, 676 + }, 677 + }, 678 + }, 679 + { 680 + .prod_num = IQS7222_PROD_NUM_D, 681 + .fw_major = 1, 682 + .fw_minor = 1, 683 + .touch_link = 1774, 684 + .allow_offset = 9, 685 + .event_offset = 10, 686 + .comms_offset = 11, 687 + .reg_grps = { 688 + [IQS7222_REG_GRP_STAT] = { 689 + .base = IQS7222_SYS_STATUS, 690 + .num_row = 1, 691 + .num_col = 7, 692 + }, 693 + [IQS7222_REG_GRP_CYCLE] = { 694 + .base = 0x8000, 695 + .num_row = 7, 696 + .num_col = 2, 697 + }, 698 + [IQS7222_REG_GRP_GLBL] = { 699 + .base = 0x8700, 700 + .num_row = 1, 701 + .num_col = 3, 702 + }, 703 + [IQS7222_REG_GRP_BTN] = { 704 + .base = 0x9000, 705 + .num_row = 14, 706 + .num_col = 3, 707 + }, 708 + [IQS7222_REG_GRP_CHAN] = { 709 + .base = 0xA000, 710 + .num_row = 14, 711 + .num_col = 4, 712 + }, 713 + [IQS7222_REG_GRP_FILT] = { 714 + .base = 0xAE00, 715 + .num_row = 1, 716 + .num_col = 2, 717 + }, 718 + [IQS7222_REG_GRP_TPAD] = { 719 + .base = 0xB000, 720 + .num_row = 1, 721 + .num_col = 24, 722 + }, 723 + [IQS7222_REG_GRP_GPIO] = { 724 + .base = 0xC000, 725 + .num_row = 3, 726 + .num_col = 3, 727 + }, 728 + [IQS7222_REG_GRP_SYS] = { 729 + .base = IQS7222_SYS_SETUP, 730 + .num_row = 1, 731 + .num_col = 12, 732 + }, 733 + }, 734 + }, 735 + { 736 + .prod_num = IQS7222_PROD_NUM_D, 625 737 .fw_major = 0, 626 738 .fw_minor = 37, 627 739 .touch_link = 1770,
-12
drivers/input/mouse/Kconfig
··· 439 439 To compile this driver as a module, choose M here: the 440 440 module will be called synaptics_usb. 441 441 442 - config MOUSE_NAVPOINT_PXA27x 443 - tristate "Synaptics NavPoint (PXA27x SSP/SPI)" 444 - depends on PXA27x && PXA_SSP 445 - help 446 - This driver adds support for the Synaptics NavPoint touchpad connected 447 - to a PXA27x SSP port in SPI slave mode. The device emulates a mouse; 448 - a tap or tap-and-a-half drag gesture emulates the left mouse button. 449 - For example, use the xf86-input-evdev driver for an X pointing device. 450 - 451 - To compile this driver as a module, choose M here: the 452 - module will be called navpoint. 453 - 454 442 endif
-1
drivers/input/mouse/Makefile
··· 15 15 obj-$(CONFIG_MOUSE_INPORT) += inport.o 16 16 obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o 17 17 obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o 18 - obj-$(CONFIG_MOUSE_NAVPOINT_PXA27x) += navpoint.o 19 18 obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o 20 19 obj-$(CONFIG_MOUSE_PS2) += psmouse.o 21 20 obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o
-350
drivers/input/mouse/navpoint.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Synaptics NavPoint (PXA27x SSP/SPI) driver. 4 - * 5 - * Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com> 6 - */ 7 - 8 - #include <linux/kernel.h> 9 - #include <linux/module.h> 10 - #include <linux/platform_device.h> 11 - #include <linux/clk.h> 12 - #include <linux/delay.h> 13 - #include <linux/gpio/consumer.h> 14 - #include <linux/input.h> 15 - #include <linux/input/navpoint.h> 16 - #include <linux/interrupt.h> 17 - #include <linux/mutex.h> 18 - #include <linux/pxa2xx_ssp.h> 19 - #include <linux/slab.h> 20 - 21 - /* 22 - * Synaptics Modular Embedded Protocol: Module Packet Format. 23 - * Module header byte 2:0 = Length (# bytes that follow) 24 - * Module header byte 4:3 = Control 25 - * Module header byte 7:5 = Module Address 26 - */ 27 - #define HEADER_LENGTH(byte) ((byte) & 0x07) 28 - #define HEADER_CONTROL(byte) (((byte) >> 3) & 0x03) 29 - #define HEADER_ADDRESS(byte) ((byte) >> 5) 30 - 31 - struct navpoint { 32 - struct ssp_device *ssp; 33 - struct input_dev *input; 34 - struct device *dev; 35 - struct gpio_desc *gpiod; 36 - int index; 37 - u8 data[1 + HEADER_LENGTH(0xff)]; 38 - }; 39 - 40 - /* 41 - * Initialization values for SSCR0_x, SSCR1_x, SSSR_x. 42 - */ 43 - static const u32 sscr0 = 0 44 - | SSCR0_TUM /* TIM = 1; No TUR interrupts */ 45 - | SSCR0_RIM /* RIM = 1; No ROR interrupts */ 46 - | SSCR0_SSE /* SSE = 1; SSP enabled */ 47 - | SSCR0_Motorola /* FRF = 0; Motorola SPI */ 48 - | SSCR0_DataSize(16) /* DSS = 15; Data size = 16-bit */ 49 - ; 50 - static const u32 sscr1 = 0 51 - | SSCR1_SCFR /* SCFR = 1; SSPSCLK only during transfers */ 52 - | SSCR1_SCLKDIR /* SCLKDIR = 1; Slave mode */ 53 - | SSCR1_SFRMDIR /* SFRMDIR = 1; Slave mode */ 54 - | SSCR1_RWOT /* RWOT = 1; Receive without transmit mode */ 55 - | SSCR1_RxTresh(1) /* RFT = 0; Receive FIFO threshold = 1 */ 56 - | SSCR1_SPH /* SPH = 1; SSPSCLK inactive 0.5 + 1 cycles */ 57 - | SSCR1_RIE /* RIE = 1; Receive FIFO interrupt enabled */ 58 - ; 59 - static const u32 sssr = 0 60 - | SSSR_BCE /* BCE = 1; Clear BCE */ 61 - | SSSR_TUR /* TUR = 1; Clear TUR */ 62 - | SSSR_EOC /* EOC = 1; Clear EOC */ 63 - | SSSR_TINT /* TINT = 1; Clear TINT */ 64 - | SSSR_PINT /* PINT = 1; Clear PINT */ 65 - | SSSR_ROR /* ROR = 1; Clear ROR */ 66 - ; 67 - 68 - /* 69 - * MEP Query $22: Touchpad Coordinate Range Query is not supported by 70 - * the NavPoint module, so sampled values provide the default limits. 71 - */ 72 - #define NAVPOINT_X_MIN 1278 73 - #define NAVPOINT_X_MAX 5340 74 - #define NAVPOINT_Y_MIN 1572 75 - #define NAVPOINT_Y_MAX 4396 76 - #define NAVPOINT_PRESSURE_MIN 0 77 - #define NAVPOINT_PRESSURE_MAX 255 78 - 79 - static void navpoint_packet(struct navpoint *navpoint) 80 - { 81 - int finger; 82 - int gesture; 83 - int x, y, z; 84 - 85 - switch (navpoint->data[0]) { 86 - case 0xff: /* Garbage (packet?) between reset and Hello packet */ 87 - case 0x00: /* Module 0, NULL packet */ 88 - break; 89 - 90 - case 0x0e: /* Module 0, Absolute packet */ 91 - finger = (navpoint->data[1] & 0x01); 92 - gesture = (navpoint->data[1] & 0x02); 93 - x = ((navpoint->data[2] & 0x1f) << 8) | navpoint->data[3]; 94 - y = ((navpoint->data[4] & 0x1f) << 8) | navpoint->data[5]; 95 - z = navpoint->data[6]; 96 - input_report_key(navpoint->input, BTN_TOUCH, finger); 97 - input_report_abs(navpoint->input, ABS_X, x); 98 - input_report_abs(navpoint->input, ABS_Y, y); 99 - input_report_abs(navpoint->input, ABS_PRESSURE, z); 100 - input_report_key(navpoint->input, BTN_TOOL_FINGER, finger); 101 - input_report_key(navpoint->input, BTN_LEFT, gesture); 102 - input_sync(navpoint->input); 103 - break; 104 - 105 - case 0x19: /* Module 0, Hello packet */ 106 - if ((navpoint->data[1] & 0xf0) == 0x10) 107 - break; 108 - fallthrough; 109 - default: 110 - dev_warn(navpoint->dev, 111 - "spurious packet: data=0x%02x,0x%02x,...\n", 112 - navpoint->data[0], navpoint->data[1]); 113 - break; 114 - } 115 - } 116 - 117 - static irqreturn_t navpoint_irq(int irq, void *dev_id) 118 - { 119 - struct navpoint *navpoint = dev_id; 120 - struct ssp_device *ssp = navpoint->ssp; 121 - irqreturn_t ret = IRQ_NONE; 122 - u32 status; 123 - 124 - status = pxa_ssp_read_reg(ssp, SSSR); 125 - if (status & sssr) { 126 - dev_warn(navpoint->dev, 127 - "unexpected interrupt: status=0x%08x\n", status); 128 - pxa_ssp_write_reg(ssp, SSSR, (status & sssr)); 129 - ret = IRQ_HANDLED; 130 - } 131 - 132 - while (status & SSSR_RNE) { 133 - u32 data; 134 - 135 - data = pxa_ssp_read_reg(ssp, SSDR); 136 - navpoint->data[navpoint->index + 0] = (data >> 8); 137 - navpoint->data[navpoint->index + 1] = data; 138 - navpoint->index += 2; 139 - if (HEADER_LENGTH(navpoint->data[0]) < navpoint->index) { 140 - navpoint_packet(navpoint); 141 - navpoint->index = 0; 142 - } 143 - status = pxa_ssp_read_reg(ssp, SSSR); 144 - ret = IRQ_HANDLED; 145 - } 146 - 147 - return ret; 148 - } 149 - 150 - static void navpoint_up(struct navpoint *navpoint) 151 - { 152 - struct ssp_device *ssp = navpoint->ssp; 153 - int timeout; 154 - 155 - clk_prepare_enable(ssp->clk); 156 - 157 - pxa_ssp_write_reg(ssp, SSCR1, sscr1); 158 - pxa_ssp_write_reg(ssp, SSSR, sssr); 159 - pxa_ssp_write_reg(ssp, SSTO, 0); 160 - pxa_ssp_write_reg(ssp, SSCR0, sscr0); /* SSCR0_SSE written last */ 161 - 162 - /* Wait until SSP port is ready for slave clock operations */ 163 - for (timeout = 100; timeout != 0; --timeout) { 164 - if (!(pxa_ssp_read_reg(ssp, SSSR) & SSSR_CSS)) 165 - break; 166 - msleep(1); 167 - } 168 - 169 - if (timeout == 0) 170 - dev_err(navpoint->dev, 171 - "timeout waiting for SSSR[CSS] to clear\n"); 172 - 173 - gpiod_set_value(navpoint->gpiod, 1); 174 - } 175 - 176 - static void navpoint_down(struct navpoint *navpoint) 177 - { 178 - struct ssp_device *ssp = navpoint->ssp; 179 - 180 - gpiod_set_value(navpoint->gpiod, 0); 181 - 182 - pxa_ssp_write_reg(ssp, SSCR0, 0); 183 - 184 - clk_disable_unprepare(ssp->clk); 185 - } 186 - 187 - static int navpoint_open(struct input_dev *input) 188 - { 189 - struct navpoint *navpoint = input_get_drvdata(input); 190 - 191 - navpoint_up(navpoint); 192 - 193 - return 0; 194 - } 195 - 196 - static void navpoint_close(struct input_dev *input) 197 - { 198 - struct navpoint *navpoint = input_get_drvdata(input); 199 - 200 - navpoint_down(navpoint); 201 - } 202 - 203 - static int navpoint_probe(struct platform_device *pdev) 204 - { 205 - const struct navpoint_platform_data *pdata = 206 - dev_get_platdata(&pdev->dev); 207 - struct ssp_device *ssp; 208 - struct input_dev *input; 209 - struct navpoint *navpoint; 210 - int error; 211 - 212 - if (!pdata) { 213 - dev_err(&pdev->dev, "no platform data\n"); 214 - return -EINVAL; 215 - } 216 - 217 - ssp = pxa_ssp_request(pdata->port, pdev->name); 218 - if (!ssp) 219 - return -ENODEV; 220 - 221 - /* HaRET does not disable devices before jumping into Linux */ 222 - if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { 223 - pxa_ssp_write_reg(ssp, SSCR0, 0); 224 - dev_warn(&pdev->dev, "ssp%d already enabled\n", pdata->port); 225 - } 226 - 227 - navpoint = kzalloc(sizeof(*navpoint), GFP_KERNEL); 228 - input = input_allocate_device(); 229 - if (!navpoint || !input) { 230 - error = -ENOMEM; 231 - goto err_free_mem; 232 - } 233 - 234 - navpoint->gpiod = gpiod_get_optional(&pdev->dev, 235 - NULL, GPIOD_OUT_LOW); 236 - if (IS_ERR(navpoint->gpiod)) { 237 - error = PTR_ERR(navpoint->gpiod); 238 - dev_err(&pdev->dev, "error getting GPIO\n"); 239 - goto err_free_mem; 240 - } 241 - gpiod_set_consumer_name(navpoint->gpiod, "SYNAPTICS_ON"); 242 - 243 - navpoint->ssp = ssp; 244 - navpoint->input = input; 245 - navpoint->dev = &pdev->dev; 246 - 247 - input->name = pdev->name; 248 - input->dev.parent = &pdev->dev; 249 - 250 - __set_bit(EV_KEY, input->evbit); 251 - __set_bit(EV_ABS, input->evbit); 252 - __set_bit(BTN_LEFT, input->keybit); 253 - __set_bit(BTN_TOUCH, input->keybit); 254 - __set_bit(BTN_TOOL_FINGER, input->keybit); 255 - 256 - input_set_abs_params(input, ABS_X, 257 - NAVPOINT_X_MIN, NAVPOINT_X_MAX, 0, 0); 258 - input_set_abs_params(input, ABS_Y, 259 - NAVPOINT_Y_MIN, NAVPOINT_Y_MAX, 0, 0); 260 - input_set_abs_params(input, ABS_PRESSURE, 261 - NAVPOINT_PRESSURE_MIN, NAVPOINT_PRESSURE_MAX, 262 - 0, 0); 263 - 264 - input->open = navpoint_open; 265 - input->close = navpoint_close; 266 - 267 - input_set_drvdata(input, navpoint); 268 - 269 - error = request_irq(ssp->irq, navpoint_irq, 0, pdev->name, navpoint); 270 - if (error) 271 - goto err_free_mem; 272 - 273 - error = input_register_device(input); 274 - if (error) 275 - goto err_free_irq; 276 - 277 - platform_set_drvdata(pdev, navpoint); 278 - dev_dbg(&pdev->dev, "ssp%d, irq %d\n", pdata->port, ssp->irq); 279 - 280 - return 0; 281 - 282 - err_free_irq: 283 - free_irq(ssp->irq, navpoint); 284 - err_free_mem: 285 - input_free_device(input); 286 - kfree(navpoint); 287 - pxa_ssp_free(ssp); 288 - 289 - return error; 290 - } 291 - 292 - static void navpoint_remove(struct platform_device *pdev) 293 - { 294 - struct navpoint *navpoint = platform_get_drvdata(pdev); 295 - struct ssp_device *ssp = navpoint->ssp; 296 - 297 - free_irq(ssp->irq, navpoint); 298 - 299 - input_unregister_device(navpoint->input); 300 - kfree(navpoint); 301 - 302 - pxa_ssp_free(ssp); 303 - } 304 - 305 - static int navpoint_suspend(struct device *dev) 306 - { 307 - struct platform_device *pdev = to_platform_device(dev); 308 - struct navpoint *navpoint = platform_get_drvdata(pdev); 309 - struct input_dev *input = navpoint->input; 310 - 311 - mutex_lock(&input->mutex); 312 - if (input_device_enabled(input)) 313 - navpoint_down(navpoint); 314 - mutex_unlock(&input->mutex); 315 - 316 - return 0; 317 - } 318 - 319 - static int navpoint_resume(struct device *dev) 320 - { 321 - struct platform_device *pdev = to_platform_device(dev); 322 - struct navpoint *navpoint = platform_get_drvdata(pdev); 323 - struct input_dev *input = navpoint->input; 324 - 325 - mutex_lock(&input->mutex); 326 - if (input_device_enabled(input)) 327 - navpoint_up(navpoint); 328 - mutex_unlock(&input->mutex); 329 - 330 - return 0; 331 - } 332 - 333 - static DEFINE_SIMPLE_DEV_PM_OPS(navpoint_pm_ops, 334 - navpoint_suspend, navpoint_resume); 335 - 336 - static struct platform_driver navpoint_driver = { 337 - .probe = navpoint_probe, 338 - .remove_new = navpoint_remove, 339 - .driver = { 340 - .name = "navpoint", 341 - .pm = pm_sleep_ptr(&navpoint_pm_ops), 342 - }, 343 - }; 344 - 345 - module_platform_driver(navpoint_driver); 346 - 347 - MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>"); 348 - MODULE_DESCRIPTION("Synaptics NavPoint (PXA27x SSP/SPI) driver"); 349 - MODULE_LICENSE("GPL"); 350 - MODULE_ALIAS("platform:navpoint");
+1 -1
drivers/input/rmi4/rmi_bus.c
··· 344 344 return physical || rmi_function_match(dev, drv); 345 345 } 346 346 347 - struct bus_type rmi_bus_type = { 347 + const struct bus_type rmi_bus_type = { 348 348 .match = rmi_bus_match, 349 349 .name = "rmi4", 350 350 };
+1 -1
drivers/input/rmi4/rmi_bus.h
··· 185 185 186 186 int rmi_for_each_dev(void *data, int (*func)(struct device *dev, void *data)); 187 187 188 - extern struct bus_type rmi_bus_type; 188 + extern const struct bus_type rmi_bus_type; 189 189 190 190 int rmi_of_property_read_u32(struct device *dev, u32 *result, 191 191 const char *prop, bool optional);
+5 -1
drivers/input/rmi4/rmi_driver.c
··· 1196 1196 } 1197 1197 rmi_driver_set_input_params(rmi_dev, data->input); 1198 1198 data->input->phys = devm_kasprintf(dev, GFP_KERNEL, 1199 - "%s/input0", dev_name(dev)); 1199 + "%s/input0", dev_name(dev)); 1200 + if (!data->input->phys) { 1201 + retval = -ENOMEM; 1202 + goto err; 1203 + } 1200 1204 } 1201 1205 1202 1206 retval = rmi_init_functions(data);
+1 -1
drivers/input/serio/serio.c
··· 1007 1007 } 1008 1008 EXPORT_SYMBOL(serio_interrupt); 1009 1009 1010 - struct bus_type serio_bus = { 1010 + const struct bus_type serio_bus = { 1011 1011 .name = "serio", 1012 1012 .drv_groups = serio_driver_groups, 1013 1013 .match = serio_bus_match,
+1 -2
drivers/input/serio/xilinx_ps2.c
··· 219 219 220 220 /** 221 221 * xps2_of_probe - probe method for the PS/2 device. 222 - * @of_dev: pointer to OF device structure 223 - * @match: pointer to the structure used for matching a device 222 + * @ofdev: pointer to OF device structure 224 223 * 225 224 * This function probes the PS/2 device in the device tree. 226 225 * It initializes the driver data structure and the hardware.
+31
drivers/input/touchscreen/Kconfig
··· 416 416 To compile this driver as a module, choose M here: the 417 417 module will be called goodix. 418 418 419 + config TOUCHSCREEN_GOODIX_BERLIN_CORE 420 + tristate 421 + 422 + config TOUCHSCREEN_GOODIX_BERLIN_I2C 423 + tristate "Goodix Berlin I2C touchscreen" 424 + depends on I2C 425 + select REGMAP_I2C 426 + select TOUCHSCREEN_GOODIX_BERLIN_CORE 427 + help 428 + Say Y here if you have a Goodix Berlin IC connected to 429 + your system via I2C. 430 + 431 + If unsure, say N. 432 + 433 + To compile this driver as a module, choose M here: the 434 + module will be called goodix_berlin_i2c. 435 + 436 + config TOUCHSCREEN_GOODIX_BERLIN_SPI 437 + tristate "Goodix Berlin SPI touchscreen" 438 + depends on SPI_MASTER 439 + select REGMAP 440 + select TOUCHSCREEN_GOODIX_BERLIN_CORE 441 + help 442 + Say Y here if you have a Goodix Berlin IC connected to 443 + your system via SPI. 444 + 445 + If unsure, say N. 446 + 447 + To compile this driver as a module, choose M here: the 448 + module will be called goodix_berlin_spi. 449 + 419 450 config TOUCHSCREEN_HIDEEP 420 451 tristate "HiDeep Touch IC" 421 452 depends on I2C
+3
drivers/input/touchscreen/Makefile
··· 47 47 obj-$(CONFIG_TOUCHSCREEN_EXC3000) += exc3000.o 48 48 obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o 49 49 obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix_ts.o 50 + obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_CORE) += goodix_berlin_core.o 51 + obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_I2C) += goodix_berlin_i2c.o 52 + obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI) += goodix_berlin_spi.o 50 53 obj-$(CONFIG_TOUCHSCREEN_HIDEEP) += hideep.o 51 54 obj-$(CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX) += hynitron_cstxxx.o 52 55 obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
+24
drivers/input/touchscreen/goodix_berlin.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* 3 + * Goodix Touchscreen Driver 4 + * Copyright (C) 2020 - 2021 Goodix, Inc. 5 + * Copyright (C) 2023 Linaro Ltd. 6 + * 7 + * Based on goodix_berlin_berlin driver. 8 + */ 9 + 10 + #ifndef __GOODIX_BERLIN_H_ 11 + #define __GOODIX_BERLIN_H_ 12 + 13 + #include <linux/pm.h> 14 + 15 + struct device; 16 + struct input_id; 17 + struct regmap; 18 + 19 + int goodix_berlin_probe(struct device *dev, int irq, const struct input_id *id, 20 + struct regmap *regmap); 21 + 22 + extern const struct dev_pm_ops goodix_berlin_pm_ops; 23 + 24 + #endif
+755
drivers/input/touchscreen/goodix_berlin_core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Goodix "Berlin" Touchscreen IC driver 4 + * Copyright (C) 2020 - 2021 Goodix, Inc. 5 + * Copyright (C) 2023 Linaro Ltd. 6 + * 7 + * Based on goodix_ts_berlin driver. 8 + * 9 + * This driver is distinct from goodix.c since hardware interface 10 + * is different enough to require a new driver. 11 + * None of the register address or data structure are close enough 12 + * to the previous generations. 13 + * 14 + * Currently the driver only handles Multitouch events with already 15 + * programmed firmware and "config" for "Revision D" Berlin IC. 16 + * 17 + * Support is missing for: 18 + * - ESD Management 19 + * - Firmware update/flashing 20 + * - "Config" update/flashing 21 + * - Stylus Events 22 + * - Gesture Events 23 + * - Support for older revisions (A & B) 24 + */ 25 + 26 + #include <linux/bitfield.h> 27 + #include <linux/gpio/consumer.h> 28 + #include <linux/input.h> 29 + #include <linux/input/mt.h> 30 + #include <linux/input/touchscreen.h> 31 + #include <linux/regmap.h> 32 + #include <linux/regulator/consumer.h> 33 + #include <linux/sizes.h> 34 + #include <asm/unaligned.h> 35 + 36 + #include "goodix_berlin.h" 37 + 38 + #define GOODIX_BERLIN_MAX_TOUCH 10 39 + 40 + #define GOODIX_BERLIN_NORMAL_RESET_DELAY_MS 100 41 + 42 + #define GOODIX_BERLIN_TOUCH_EVENT BIT(7) 43 + #define GOODIX_BERLIN_REQUEST_EVENT BIT(6) 44 + #define GOODIX_BERLIN_TOUCH_COUNT_MASK GENMASK(3, 0) 45 + 46 + #define GOODIX_BERLIN_REQUEST_CODE_RESET 3 47 + 48 + #define GOODIX_BERLIN_POINT_TYPE_MASK GENMASK(3, 0) 49 + #define GOODIX_BERLIN_POINT_TYPE_STYLUS_HOVER 1 50 + #define GOODIX_BERLIN_POINT_TYPE_STYLUS 3 51 + 52 + #define GOODIX_BERLIN_TOUCH_ID_MASK GENMASK(7, 4) 53 + 54 + #define GOODIX_BERLIN_DEV_CONFIRM_VAL 0xAA 55 + #define GOODIX_BERLIN_BOOTOPTION_ADDR 0x10000 56 + #define GOODIX_BERLIN_FW_VERSION_INFO_ADDR 0x10014 57 + 58 + #define GOODIX_BERLIN_IC_INFO_MAX_LEN SZ_1K 59 + #define GOODIX_BERLIN_IC_INFO_ADDR 0x10070 60 + 61 + #define GOODIX_BERLIN_CHECKSUM_SIZE sizeof(u16) 62 + 63 + struct goodix_berlin_fw_version { 64 + u8 rom_pid[6]; 65 + u8 rom_vid[3]; 66 + u8 rom_vid_reserved; 67 + u8 patch_pid[8]; 68 + u8 patch_vid[4]; 69 + u8 patch_vid_reserved; 70 + u8 sensor_id; 71 + u8 reserved[2]; 72 + __le16 checksum; 73 + }; 74 + 75 + struct goodix_berlin_ic_info_version { 76 + u8 info_customer_id; 77 + u8 info_version_id; 78 + u8 ic_die_id; 79 + u8 ic_version_id; 80 + __le32 config_id; 81 + u8 config_version; 82 + u8 frame_data_customer_id; 83 + u8 frame_data_version_id; 84 + u8 touch_data_customer_id; 85 + u8 touch_data_version_id; 86 + u8 reserved[3]; 87 + } __packed; 88 + 89 + struct goodix_berlin_ic_info_feature { 90 + __le16 freqhop_feature; 91 + __le16 calibration_feature; 92 + __le16 gesture_feature; 93 + __le16 side_touch_feature; 94 + __le16 stylus_feature; 95 + } __packed; 96 + 97 + struct goodix_berlin_ic_info_misc { 98 + __le32 cmd_addr; 99 + __le16 cmd_max_len; 100 + __le32 cmd_reply_addr; 101 + __le16 cmd_reply_len; 102 + __le32 fw_state_addr; 103 + __le16 fw_state_len; 104 + __le32 fw_buffer_addr; 105 + __le16 fw_buffer_max_len; 106 + __le32 frame_data_addr; 107 + __le16 frame_data_head_len; 108 + __le16 fw_attr_len; 109 + __le16 fw_log_len; 110 + u8 pack_max_num; 111 + u8 pack_compress_version; 112 + __le16 stylus_struct_len; 113 + __le16 mutual_struct_len; 114 + __le16 self_struct_len; 115 + __le16 noise_struct_len; 116 + __le32 touch_data_addr; 117 + __le16 touch_data_head_len; 118 + __le16 point_struct_len; 119 + __le16 reserved1; 120 + __le16 reserved2; 121 + __le32 mutual_rawdata_addr; 122 + __le32 mutual_diffdata_addr; 123 + __le32 mutual_refdata_addr; 124 + __le32 self_rawdata_addr; 125 + __le32 self_diffdata_addr; 126 + __le32 self_refdata_addr; 127 + __le32 iq_rawdata_addr; 128 + __le32 iq_refdata_addr; 129 + __le32 im_rawdata_addr; 130 + __le16 im_readata_len; 131 + __le32 noise_rawdata_addr; 132 + __le16 noise_rawdata_len; 133 + __le32 stylus_rawdata_addr; 134 + __le16 stylus_rawdata_len; 135 + __le32 noise_data_addr; 136 + __le32 esd_addr; 137 + } __packed; 138 + 139 + struct goodix_berlin_touch { 140 + u8 status; 141 + u8 reserved; 142 + __le16 x; 143 + __le16 y; 144 + __le16 w; 145 + }; 146 + #define GOODIX_BERLIN_TOUCH_SIZE sizeof(struct goodix_berlin_touch) 147 + 148 + struct goodix_berlin_header { 149 + u8 status; 150 + u8 reserved1; 151 + u8 request_type; 152 + u8 reserved2[3]; 153 + __le16 checksum; 154 + }; 155 + #define GOODIX_BERLIN_HEADER_SIZE sizeof(struct goodix_berlin_header) 156 + 157 + struct goodix_berlin_event { 158 + struct goodix_berlin_header hdr; 159 + /* The data below is u16/__le16 aligned */ 160 + u8 data[GOODIX_BERLIN_TOUCH_SIZE * GOODIX_BERLIN_MAX_TOUCH + 161 + GOODIX_BERLIN_CHECKSUM_SIZE]; 162 + }; 163 + 164 + struct goodix_berlin_core { 165 + struct device *dev; 166 + struct regmap *regmap; 167 + struct regulator *avdd; 168 + struct regulator *iovdd; 169 + struct gpio_desc *reset_gpio; 170 + struct touchscreen_properties props; 171 + struct goodix_berlin_fw_version fw_version; 172 + struct input_dev *input_dev; 173 + int irq; 174 + 175 + /* Runtime parameters extracted from IC_INFO buffer */ 176 + u32 touch_data_addr; 177 + 178 + struct goodix_berlin_event event; 179 + }; 180 + 181 + static bool goodix_berlin_checksum_valid(const u8 *data, int size) 182 + { 183 + u32 cal_checksum = 0; 184 + u16 r_checksum; 185 + int i; 186 + 187 + if (size < GOODIX_BERLIN_CHECKSUM_SIZE) 188 + return false; 189 + 190 + for (i = 0; i < size - GOODIX_BERLIN_CHECKSUM_SIZE; i++) 191 + cal_checksum += data[i]; 192 + 193 + r_checksum = get_unaligned_le16(&data[i]); 194 + 195 + return (u16)cal_checksum == r_checksum; 196 + } 197 + 198 + static bool goodix_berlin_is_dummy_data(struct goodix_berlin_core *cd, 199 + const u8 *data, int size) 200 + { 201 + int i; 202 + 203 + /* 204 + * If the device is missing or doesn't respond the buffer 205 + * could be filled with bus default line state, 0x00 or 0xff, 206 + * so declare success the first time we encounter neither. 207 + */ 208 + for (i = 0; i < size; i++) 209 + if (data[i] > 0 && data[i] < 0xff) 210 + return false; 211 + 212 + return true; 213 + } 214 + 215 + static int goodix_berlin_dev_confirm(struct goodix_berlin_core *cd) 216 + { 217 + u8 tx_buf[8], rx_buf[8]; 218 + int retry = 3; 219 + int error; 220 + 221 + memset(tx_buf, GOODIX_BERLIN_DEV_CONFIRM_VAL, sizeof(tx_buf)); 222 + while (retry--) { 223 + error = regmap_raw_write(cd->regmap, 224 + GOODIX_BERLIN_BOOTOPTION_ADDR, 225 + tx_buf, sizeof(tx_buf)); 226 + if (error) 227 + return error; 228 + 229 + error = regmap_raw_read(cd->regmap, 230 + GOODIX_BERLIN_BOOTOPTION_ADDR, 231 + rx_buf, sizeof(rx_buf)); 232 + if (error) 233 + return error; 234 + 235 + if (!memcmp(tx_buf, rx_buf, sizeof(tx_buf))) 236 + return 0; 237 + 238 + usleep_range(5000, 5100); 239 + } 240 + 241 + dev_err(cd->dev, "device confirm failed, rx_buf: %*ph\n", 242 + (int)sizeof(rx_buf), rx_buf); 243 + 244 + return -EINVAL; 245 + } 246 + 247 + static int goodix_berlin_power_on(struct goodix_berlin_core *cd) 248 + { 249 + int error; 250 + 251 + error = regulator_enable(cd->iovdd); 252 + if (error) { 253 + dev_err(cd->dev, "Failed to enable iovdd: %d\n", error); 254 + return error; 255 + } 256 + 257 + /* Vendor waits 3ms for IOVDD to settle */ 258 + usleep_range(3000, 3100); 259 + 260 + error = regulator_enable(cd->avdd); 261 + if (error) { 262 + dev_err(cd->dev, "Failed to enable avdd: %d\n", error); 263 + goto err_iovdd_disable; 264 + } 265 + 266 + /* Vendor waits 15ms for IOVDD to settle */ 267 + usleep_range(15000, 15100); 268 + 269 + gpiod_set_value_cansleep(cd->reset_gpio, 0); 270 + 271 + /* Vendor waits 4ms for Firmware to initialize */ 272 + usleep_range(4000, 4100); 273 + 274 + error = goodix_berlin_dev_confirm(cd); 275 + if (error) 276 + goto err_dev_reset; 277 + 278 + /* Vendor waits 100ms for Firmware to fully boot */ 279 + msleep(GOODIX_BERLIN_NORMAL_RESET_DELAY_MS); 280 + 281 + return 0; 282 + 283 + err_dev_reset: 284 + gpiod_set_value_cansleep(cd->reset_gpio, 1); 285 + regulator_disable(cd->avdd); 286 + err_iovdd_disable: 287 + regulator_disable(cd->iovdd); 288 + return error; 289 + } 290 + 291 + static void goodix_berlin_power_off(struct goodix_berlin_core *cd) 292 + { 293 + gpiod_set_value_cansleep(cd->reset_gpio, 1); 294 + regulator_disable(cd->avdd); 295 + regulator_disable(cd->iovdd); 296 + } 297 + 298 + static int goodix_berlin_read_version(struct goodix_berlin_core *cd) 299 + { 300 + int error; 301 + 302 + error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_FW_VERSION_INFO_ADDR, 303 + &cd->fw_version, sizeof(cd->fw_version)); 304 + if (error) { 305 + dev_err(cd->dev, "error reading fw version, %d\n", error); 306 + return error; 307 + } 308 + 309 + if (!goodix_berlin_checksum_valid((u8 *)&cd->fw_version, 310 + sizeof(cd->fw_version))) { 311 + dev_err(cd->dev, "invalid fw version: checksum error\n"); 312 + return -EINVAL; 313 + } 314 + 315 + return 0; 316 + } 317 + 318 + /* Only extract necessary data for runtime */ 319 + static int goodix_berlin_parse_ic_info(struct goodix_berlin_core *cd, 320 + const u8 *data, u16 length) 321 + { 322 + struct goodix_berlin_ic_info_misc *misc; 323 + unsigned int offset = 0; 324 + 325 + offset += sizeof(__le16); /* length */ 326 + offset += sizeof(struct goodix_berlin_ic_info_version); 327 + offset += sizeof(struct goodix_berlin_ic_info_feature); 328 + 329 + /* IC_INFO Parameters, variable width structure */ 330 + offset += 4 * sizeof(u8); /* drv_num, sen_num, button_num, force_num */ 331 + if (offset >= length) 332 + goto invalid_offset; 333 + 334 + #define ADVANCE_LE16_PARAMS() \ 335 + do { \ 336 + u8 param_num = data[offset++]; \ 337 + offset += param_num * sizeof(__le16); \ 338 + if (offset >= length) \ 339 + goto invalid_offset; \ 340 + } while (0) 341 + ADVANCE_LE16_PARAMS(); /* active_scan_rate_num */ 342 + ADVANCE_LE16_PARAMS(); /* mutual_freq_num*/ 343 + ADVANCE_LE16_PARAMS(); /* self_tx_freq_num */ 344 + ADVANCE_LE16_PARAMS(); /* self_rx_freq_num */ 345 + ADVANCE_LE16_PARAMS(); /* stylus_freq_num */ 346 + #undef ADVANCE_LE16_PARAMS 347 + 348 + misc = (struct goodix_berlin_ic_info_misc *)&data[offset]; 349 + cd->touch_data_addr = le32_to_cpu(misc->touch_data_addr); 350 + 351 + return 0; 352 + 353 + invalid_offset: 354 + dev_err(cd->dev, "ic_info length is invalid (offset %d length %d)\n", 355 + offset, length); 356 + return -EINVAL; 357 + } 358 + 359 + static int goodix_berlin_get_ic_info(struct goodix_berlin_core *cd) 360 + { 361 + u8 *afe_data __free(kfree) = NULL; 362 + __le16 length_raw; 363 + u16 length; 364 + int error; 365 + 366 + afe_data = kzalloc(GOODIX_BERLIN_IC_INFO_MAX_LEN, GFP_KERNEL); 367 + if (!afe_data) 368 + return -ENOMEM; 369 + 370 + error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_IC_INFO_ADDR, 371 + &length_raw, sizeof(length_raw)); 372 + if (error) { 373 + dev_err(cd->dev, "failed get ic info length, %d\n", error); 374 + return error; 375 + } 376 + 377 + length = le16_to_cpu(length_raw); 378 + if (length >= GOODIX_BERLIN_IC_INFO_MAX_LEN) { 379 + dev_err(cd->dev, "invalid ic info length %d\n", length); 380 + return -EINVAL; 381 + } 382 + 383 + error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_IC_INFO_ADDR, 384 + afe_data, length); 385 + if (error) { 386 + dev_err(cd->dev, "failed get ic info data, %d\n", error); 387 + return error; 388 + } 389 + 390 + /* check whether the data is valid (ex. bus default values) */ 391 + if (goodix_berlin_is_dummy_data(cd, afe_data, length)) { 392 + dev_err(cd->dev, "fw info data invalid\n"); 393 + return -EINVAL; 394 + } 395 + 396 + if (!goodix_berlin_checksum_valid(afe_data, length)) { 397 + dev_err(cd->dev, "fw info checksum error\n"); 398 + return -EINVAL; 399 + } 400 + 401 + error = goodix_berlin_parse_ic_info(cd, afe_data, length); 402 + if (error) 403 + return error; 404 + 405 + /* check some key info */ 406 + if (!cd->touch_data_addr) { 407 + dev_err(cd->dev, "touch_data_addr is null\n"); 408 + return -EINVAL; 409 + } 410 + 411 + return 0; 412 + } 413 + 414 + static int goodix_berlin_get_remaining_contacts(struct goodix_berlin_core *cd, 415 + int n) 416 + { 417 + size_t offset = 2 * GOODIX_BERLIN_TOUCH_SIZE + 418 + GOODIX_BERLIN_CHECKSUM_SIZE; 419 + u32 addr = cd->touch_data_addr + GOODIX_BERLIN_HEADER_SIZE + offset; 420 + int error; 421 + 422 + error = regmap_raw_read(cd->regmap, addr, 423 + &cd->event.data[offset], 424 + (n - 2) * GOODIX_BERLIN_TOUCH_SIZE); 425 + if (error) { 426 + dev_err_ratelimited(cd->dev, "failed to get touch data, %d\n", 427 + error); 428 + return error; 429 + } 430 + 431 + return 0; 432 + } 433 + 434 + static void goodix_berlin_report_state(struct goodix_berlin_core *cd, int n) 435 + { 436 + struct goodix_berlin_touch *touch_data = 437 + (struct goodix_berlin_touch *)cd->event.data; 438 + struct goodix_berlin_touch *t; 439 + int i; 440 + u8 type, id; 441 + 442 + for (i = 0; i < n; i++) { 443 + t = &touch_data[i]; 444 + 445 + type = FIELD_GET(GOODIX_BERLIN_POINT_TYPE_MASK, t->status); 446 + if (type == GOODIX_BERLIN_POINT_TYPE_STYLUS || 447 + type == GOODIX_BERLIN_POINT_TYPE_STYLUS_HOVER) { 448 + dev_warn_once(cd->dev, "Stylus event type not handled\n"); 449 + continue; 450 + } 451 + 452 + id = FIELD_GET(GOODIX_BERLIN_TOUCH_ID_MASK, t->status); 453 + if (id >= GOODIX_BERLIN_MAX_TOUCH) { 454 + dev_warn_ratelimited(cd->dev, "invalid finger id %d\n", id); 455 + continue; 456 + } 457 + 458 + input_mt_slot(cd->input_dev, id); 459 + input_mt_report_slot_state(cd->input_dev, MT_TOOL_FINGER, true); 460 + 461 + touchscreen_report_pos(cd->input_dev, &cd->props, 462 + __le16_to_cpu(t->x), __le16_to_cpu(t->y), 463 + true); 464 + input_report_abs(cd->input_dev, ABS_MT_TOUCH_MAJOR, 465 + __le16_to_cpu(t->w)); 466 + } 467 + 468 + input_mt_sync_frame(cd->input_dev); 469 + input_sync(cd->input_dev); 470 + } 471 + 472 + static void goodix_berlin_touch_handler(struct goodix_berlin_core *cd) 473 + { 474 + u8 touch_num; 475 + int error; 476 + 477 + touch_num = FIELD_GET(GOODIX_BERLIN_TOUCH_COUNT_MASK, 478 + cd->event.hdr.request_type); 479 + if (touch_num > GOODIX_BERLIN_MAX_TOUCH) { 480 + dev_warn(cd->dev, "invalid touch num %d\n", touch_num); 481 + return; 482 + } 483 + 484 + if (touch_num > 2) { 485 + /* read additional contact data if more than 2 touch events */ 486 + error = goodix_berlin_get_remaining_contacts(cd, touch_num); 487 + if (error) 488 + return; 489 + } 490 + 491 + if (touch_num) { 492 + int len = touch_num * GOODIX_BERLIN_TOUCH_SIZE + 493 + GOODIX_BERLIN_CHECKSUM_SIZE; 494 + if (!goodix_berlin_checksum_valid(cd->event.data, len)) { 495 + dev_err(cd->dev, "touch data checksum error: %*ph\n", 496 + len, cd->event.data); 497 + return; 498 + } 499 + } 500 + 501 + goodix_berlin_report_state(cd, touch_num); 502 + } 503 + 504 + static int goodix_berlin_request_handle_reset(struct goodix_berlin_core *cd) 505 + { 506 + gpiod_set_value_cansleep(cd->reset_gpio, 1); 507 + usleep_range(2000, 2100); 508 + gpiod_set_value_cansleep(cd->reset_gpio, 0); 509 + 510 + msleep(GOODIX_BERLIN_NORMAL_RESET_DELAY_MS); 511 + 512 + return 0; 513 + } 514 + 515 + static irqreturn_t goodix_berlin_irq(int irq, void *data) 516 + { 517 + struct goodix_berlin_core *cd = data; 518 + int error; 519 + 520 + /* 521 + * First, read buffer with space for 2 touch events: 522 + * - GOODIX_BERLIN_HEADER_SIZE = 8 bytes 523 + * - GOODIX_BERLIN_TOUCH_SIZE * 2 = 16 bytes 524 + * - GOODIX_BERLIN_CHECKLSUM_SIZE = 2 bytes 525 + * For a total of 26 bytes. 526 + * 527 + * If only a single finger is reported, we will read 8 bytes more than 528 + * needed: 529 + * - bytes 0-7: Header (GOODIX_BERLIN_HEADER_SIZE) 530 + * - bytes 8-15: Finger 0 Data 531 + * - bytes 24-25: Checksum 532 + * - bytes 18-25: Unused 8 bytes 533 + * 534 + * If 2 fingers are reported, we would have read the exact needed 535 + * amount of data and checksum would be at the end of the buffer: 536 + * - bytes 0-7: Header (GOODIX_BERLIN_HEADER_SIZE) 537 + * - bytes 8-15: Finger 0 Bytes 0-7 538 + * - bytes 16-23: Finger 1 Bytes 0-7 539 + * - bytes 24-25: Checksum 540 + * 541 + * If more than 2 fingers were reported, the "Checksum" bytes would 542 + * in fact contain part of the next finger data, and then 543 + * goodix_berlin_get_remaining_contacts() would complete the buffer 544 + * with the missing bytes, including the trailing checksum. 545 + * For example, if 3 fingers are reported, then we would do: 546 + * Read 1: 547 + * - bytes 0-7: Header (GOODIX_BERLIN_HEADER_SIZE) 548 + * - bytes 8-15: Finger 0 Bytes 0-7 549 + * - bytes 16-23: Finger 1 Bytes 0-7 550 + * - bytes 24-25: Finger 2 Bytes 0-1 551 + * Read 2 (with length of (3 - 2) * 8 = 8 bytes): 552 + * - bytes 26-31: Finger 2 Bytes 2-7 553 + * - bytes 32-33: Checksum 554 + */ 555 + error = regmap_raw_read(cd->regmap, cd->touch_data_addr, 556 + &cd->event, 557 + GOODIX_BERLIN_HEADER_SIZE + 558 + 2 * GOODIX_BERLIN_TOUCH_SIZE + 559 + GOODIX_BERLIN_CHECKSUM_SIZE); 560 + if (error) { 561 + dev_warn_ratelimited(cd->dev, 562 + "failed get event head data: %d\n", error); 563 + goto out; 564 + } 565 + 566 + if (cd->event.hdr.status == 0) 567 + goto out; 568 + 569 + if (!goodix_berlin_checksum_valid((u8 *)&cd->event.hdr, 570 + GOODIX_BERLIN_HEADER_SIZE)) { 571 + dev_warn_ratelimited(cd->dev, 572 + "touch head checksum error: %*ph\n", 573 + (int)GOODIX_BERLIN_HEADER_SIZE, 574 + &cd->event.hdr); 575 + goto out_clear; 576 + } 577 + 578 + if (cd->event.hdr.status & GOODIX_BERLIN_TOUCH_EVENT) 579 + goodix_berlin_touch_handler(cd); 580 + 581 + if (cd->event.hdr.status & GOODIX_BERLIN_REQUEST_EVENT) { 582 + switch (cd->event.hdr.request_type) { 583 + case GOODIX_BERLIN_REQUEST_CODE_RESET: 584 + if (cd->reset_gpio) 585 + goodix_berlin_request_handle_reset(cd); 586 + break; 587 + 588 + default: 589 + dev_warn(cd->dev, "unsupported request code 0x%x\n", 590 + cd->event.hdr.request_type); 591 + } 592 + } 593 + 594 + 595 + out_clear: 596 + /* Clear up status field */ 597 + regmap_write(cd->regmap, cd->touch_data_addr, 0); 598 + 599 + out: 600 + return IRQ_HANDLED; 601 + } 602 + 603 + static int goodix_berlin_input_dev_config(struct goodix_berlin_core *cd, 604 + const struct input_id *id) 605 + { 606 + struct input_dev *input_dev; 607 + int error; 608 + 609 + input_dev = devm_input_allocate_device(cd->dev); 610 + if (!input_dev) 611 + return -ENOMEM; 612 + 613 + cd->input_dev = input_dev; 614 + input_set_drvdata(input_dev, cd); 615 + 616 + input_dev->name = "Goodix Berlin Capacitive TouchScreen"; 617 + input_dev->phys = "input/ts"; 618 + 619 + input_dev->id = *id; 620 + 621 + input_set_abs_params(cd->input_dev, ABS_MT_POSITION_X, 622 + 0, SZ_64K - 1, 0, 0); 623 + input_set_abs_params(cd->input_dev, ABS_MT_POSITION_Y, 624 + 0, SZ_64K - 1, 0, 0); 625 + input_set_abs_params(cd->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); 626 + 627 + touchscreen_parse_properties(cd->input_dev, true, &cd->props); 628 + 629 + error = input_mt_init_slots(cd->input_dev, GOODIX_BERLIN_MAX_TOUCH, 630 + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); 631 + if (error) 632 + return error; 633 + 634 + error = input_register_device(cd->input_dev); 635 + if (error) 636 + return error; 637 + 638 + return 0; 639 + } 640 + 641 + static int goodix_berlin_suspend(struct device *dev) 642 + { 643 + struct goodix_berlin_core *cd = dev_get_drvdata(dev); 644 + 645 + disable_irq(cd->irq); 646 + goodix_berlin_power_off(cd); 647 + 648 + return 0; 649 + } 650 + 651 + static int goodix_berlin_resume(struct device *dev) 652 + { 653 + struct goodix_berlin_core *cd = dev_get_drvdata(dev); 654 + int error; 655 + 656 + error = goodix_berlin_power_on(cd); 657 + if (error) 658 + return error; 659 + 660 + enable_irq(cd->irq); 661 + 662 + return 0; 663 + } 664 + 665 + EXPORT_GPL_SIMPLE_DEV_PM_OPS(goodix_berlin_pm_ops, 666 + goodix_berlin_suspend, goodix_berlin_resume); 667 + 668 + static void goodix_berlin_power_off_act(void *data) 669 + { 670 + struct goodix_berlin_core *cd = data; 671 + 672 + goodix_berlin_power_off(cd); 673 + } 674 + 675 + int goodix_berlin_probe(struct device *dev, int irq, const struct input_id *id, 676 + struct regmap *regmap) 677 + { 678 + struct goodix_berlin_core *cd; 679 + int error; 680 + 681 + if (irq <= 0) { 682 + dev_err(dev, "Missing interrupt number\n"); 683 + return -EINVAL; 684 + } 685 + 686 + cd = devm_kzalloc(dev, sizeof(*cd), GFP_KERNEL); 687 + if (!cd) 688 + return -ENOMEM; 689 + 690 + cd->dev = dev; 691 + cd->regmap = regmap; 692 + cd->irq = irq; 693 + 694 + cd->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); 695 + if (IS_ERR(cd->reset_gpio)) 696 + return dev_err_probe(dev, PTR_ERR(cd->reset_gpio), 697 + "Failed to request reset gpio\n"); 698 + 699 + cd->avdd = devm_regulator_get(dev, "avdd"); 700 + if (IS_ERR(cd->avdd)) 701 + return dev_err_probe(dev, PTR_ERR(cd->avdd), 702 + "Failed to request avdd regulator\n"); 703 + 704 + cd->iovdd = devm_regulator_get(dev, "iovdd"); 705 + if (IS_ERR(cd->iovdd)) 706 + return dev_err_probe(dev, PTR_ERR(cd->iovdd), 707 + "Failed to request iovdd regulator\n"); 708 + 709 + error = goodix_berlin_power_on(cd); 710 + if (error) { 711 + dev_err(dev, "failed power on"); 712 + return error; 713 + } 714 + 715 + error = devm_add_action_or_reset(dev, goodix_berlin_power_off_act, cd); 716 + if (error) 717 + return error; 718 + 719 + error = goodix_berlin_read_version(cd); 720 + if (error) { 721 + dev_err(dev, "failed to get version info"); 722 + return error; 723 + } 724 + 725 + error = goodix_berlin_get_ic_info(cd); 726 + if (error) { 727 + dev_err(dev, "invalid ic info, abort"); 728 + return error; 729 + } 730 + 731 + error = goodix_berlin_input_dev_config(cd, id); 732 + if (error) { 733 + dev_err(dev, "failed set input device"); 734 + return error; 735 + } 736 + 737 + error = devm_request_threaded_irq(dev, cd->irq, NULL, goodix_berlin_irq, 738 + IRQF_ONESHOT, "goodix-berlin", cd); 739 + if (error) { 740 + dev_err(dev, "request threaded irq failed: %d\n", error); 741 + return error; 742 + } 743 + 744 + dev_set_drvdata(dev, cd); 745 + 746 + dev_dbg(dev, "Goodix Berlin %s Touchscreen Controller", 747 + cd->fw_version.patch_pid); 748 + 749 + return 0; 750 + } 751 + EXPORT_SYMBOL_GPL(goodix_berlin_probe); 752 + 753 + MODULE_LICENSE("GPL"); 754 + MODULE_DESCRIPTION("Goodix Berlin Core Touchscreen driver"); 755 + MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
+75
drivers/input/touchscreen/goodix_berlin_i2c.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Goodix Berlin Touchscreen Driver 4 + * 5 + * Copyright (C) 2020 - 2021 Goodix, Inc. 6 + * Copyright (C) 2023 Linaro Ltd. 7 + * 8 + * Based on goodix_ts_berlin driver. 9 + */ 10 + #include <linux/i2c.h> 11 + #include <linux/kernel.h> 12 + #include <linux/module.h> 13 + #include <linux/regmap.h> 14 + #include <linux/input.h> 15 + 16 + #include "goodix_berlin.h" 17 + 18 + #define I2C_MAX_TRANSFER_SIZE 256 19 + 20 + static const struct regmap_config goodix_berlin_i2c_regmap_conf = { 21 + .reg_bits = 32, 22 + .val_bits = 8, 23 + .max_raw_read = I2C_MAX_TRANSFER_SIZE, 24 + .max_raw_write = I2C_MAX_TRANSFER_SIZE, 25 + }; 26 + 27 + /* vendor & product left unassigned here, should probably be updated from fw info */ 28 + static const struct input_id goodix_berlin_i2c_input_id = { 29 + .bustype = BUS_I2C, 30 + }; 31 + 32 + static int goodix_berlin_i2c_probe(struct i2c_client *client) 33 + { 34 + struct regmap *regmap; 35 + int error; 36 + 37 + regmap = devm_regmap_init_i2c(client, &goodix_berlin_i2c_regmap_conf); 38 + if (IS_ERR(regmap)) 39 + return PTR_ERR(regmap); 40 + 41 + error = goodix_berlin_probe(&client->dev, client->irq, 42 + &goodix_berlin_i2c_input_id, regmap); 43 + if (error) 44 + return error; 45 + 46 + return 0; 47 + } 48 + 49 + static const struct i2c_device_id goodix_berlin_i2c_id[] = { 50 + { "gt9916", 0 }, 51 + { } 52 + }; 53 + 54 + MODULE_DEVICE_TABLE(i2c, goodix_berlin_i2c_id); 55 + 56 + static const struct of_device_id goodix_berlin_i2c_of_match[] = { 57 + { .compatible = "goodix,gt9916", }, 58 + { } 59 + }; 60 + MODULE_DEVICE_TABLE(of, goodix_berlin_i2c_of_match); 61 + 62 + static struct i2c_driver goodix_berlin_i2c_driver = { 63 + .driver = { 64 + .name = "goodix-berlin-i2c", 65 + .of_match_table = goodix_berlin_i2c_of_match, 66 + .pm = pm_sleep_ptr(&goodix_berlin_pm_ops), 67 + }, 68 + .probe = goodix_berlin_i2c_probe, 69 + .id_table = goodix_berlin_i2c_id, 70 + }; 71 + module_i2c_driver(goodix_berlin_i2c_driver); 72 + 73 + MODULE_LICENSE("GPL"); 74 + MODULE_DESCRIPTION("Goodix Berlin I2C Touchscreen driver"); 75 + MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
+178
drivers/input/touchscreen/goodix_berlin_spi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Goodix Berlin Touchscreen Driver 4 + * 5 + * Copyright (C) 2020 - 2021 Goodix, Inc. 6 + * Copyright (C) 2023 Linaro Ltd. 7 + * 8 + * Based on goodix_ts_berlin driver. 9 + */ 10 + #include <asm/unaligned.h> 11 + #include <linux/kernel.h> 12 + #include <linux/module.h> 13 + #include <linux/regmap.h> 14 + #include <linux/spi/spi.h> 15 + #include <linux/input.h> 16 + 17 + #include "goodix_berlin.h" 18 + 19 + #define GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN 1 20 + #define GOODIX_BERLIN_REGISTER_WIDTH 4 21 + #define GOODIX_BERLIN_SPI_READ_DUMMY_LEN 3 22 + #define GOODIX_BERLIN_SPI_READ_PREFIX_LEN (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \ 23 + GOODIX_BERLIN_REGISTER_WIDTH + \ 24 + GOODIX_BERLIN_SPI_READ_DUMMY_LEN) 25 + #define GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN (GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \ 26 + GOODIX_BERLIN_REGISTER_WIDTH) 27 + 28 + #define GOODIX_BERLIN_SPI_WRITE_FLAG 0xF0 29 + #define GOODIX_BERLIN_SPI_READ_FLAG 0xF1 30 + 31 + static int goodix_berlin_spi_read(void *context, const void *reg_buf, 32 + size_t reg_size, void *val_buf, 33 + size_t val_size) 34 + { 35 + struct spi_device *spi = context; 36 + struct spi_transfer xfers; 37 + struct spi_message spi_msg; 38 + const u32 *reg = reg_buf; /* reg is stored as native u32 at start of buffer */ 39 + u8 *buf; 40 + int error; 41 + 42 + if (reg_size != GOODIX_BERLIN_REGISTER_WIDTH) 43 + return -EINVAL; 44 + 45 + buf = kzalloc(GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size, GFP_KERNEL); 46 + if (!buf) 47 + return -ENOMEM; 48 + 49 + spi_message_init(&spi_msg); 50 + memset(&xfers, 0, sizeof(xfers)); 51 + 52 + /* buffer format: 0xF1 + addr(4bytes) + dummy(3bytes) + data */ 53 + buf[0] = GOODIX_BERLIN_SPI_READ_FLAG; 54 + put_unaligned_be32(*reg, buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN); 55 + memset(buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + GOODIX_BERLIN_REGISTER_WIDTH, 56 + 0xff, GOODIX_BERLIN_SPI_READ_DUMMY_LEN); 57 + 58 + xfers.tx_buf = buf; 59 + xfers.rx_buf = buf; 60 + xfers.len = GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size; 61 + xfers.cs_change = 0; 62 + spi_message_add_tail(&xfers, &spi_msg); 63 + 64 + error = spi_sync(spi, &spi_msg); 65 + if (error < 0) 66 + dev_err(&spi->dev, "spi transfer error, %d", error); 67 + else 68 + memcpy(val_buf, buf + GOODIX_BERLIN_SPI_READ_PREFIX_LEN, val_size); 69 + 70 + kfree(buf); 71 + return error; 72 + } 73 + 74 + static int goodix_berlin_spi_write(void *context, const void *data, 75 + size_t count) 76 + { 77 + unsigned int len = count - GOODIX_BERLIN_REGISTER_WIDTH; 78 + struct spi_device *spi = context; 79 + struct spi_transfer xfers; 80 + struct spi_message spi_msg; 81 + const u32 *reg = data; /* reg is stored as native u32 at start of buffer */ 82 + u8 *buf; 83 + int error; 84 + 85 + buf = kzalloc(GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len, GFP_KERNEL); 86 + if (!buf) 87 + return -ENOMEM; 88 + 89 + spi_message_init(&spi_msg); 90 + memset(&xfers, 0, sizeof(xfers)); 91 + 92 + buf[0] = GOODIX_BERLIN_SPI_WRITE_FLAG; 93 + put_unaligned_be32(*reg, buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN); 94 + memcpy(buf + GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN, 95 + data + GOODIX_BERLIN_REGISTER_WIDTH, len); 96 + 97 + xfers.tx_buf = buf; 98 + xfers.len = GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len; 99 + xfers.cs_change = 0; 100 + spi_message_add_tail(&xfers, &spi_msg); 101 + 102 + error = spi_sync(spi, &spi_msg); 103 + if (error < 0) 104 + dev_err(&spi->dev, "spi transfer error, %d", error); 105 + 106 + kfree(buf); 107 + return error; 108 + } 109 + 110 + static const struct regmap_config goodix_berlin_spi_regmap_conf = { 111 + .reg_bits = 32, 112 + .val_bits = 8, 113 + .read = goodix_berlin_spi_read, 114 + .write = goodix_berlin_spi_write, 115 + }; 116 + 117 + /* vendor & product left unassigned here, should probably be updated from fw info */ 118 + static const struct input_id goodix_berlin_spi_input_id = { 119 + .bustype = BUS_SPI, 120 + }; 121 + 122 + static int goodix_berlin_spi_probe(struct spi_device *spi) 123 + { 124 + struct regmap_config regmap_config; 125 + struct regmap *regmap; 126 + size_t max_size; 127 + int error = 0; 128 + 129 + spi->mode = SPI_MODE_0; 130 + spi->bits_per_word = 8; 131 + error = spi_setup(spi); 132 + if (error) 133 + return error; 134 + 135 + max_size = spi_max_transfer_size(spi); 136 + 137 + regmap_config = goodix_berlin_spi_regmap_conf; 138 + regmap_config.max_raw_read = max_size - GOODIX_BERLIN_SPI_READ_PREFIX_LEN; 139 + regmap_config.max_raw_write = max_size - GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN; 140 + 141 + regmap = devm_regmap_init(&spi->dev, NULL, spi, &regmap_config); 142 + if (IS_ERR(regmap)) 143 + return PTR_ERR(regmap); 144 + 145 + error = goodix_berlin_probe(&spi->dev, spi->irq, 146 + &goodix_berlin_spi_input_id, regmap); 147 + if (error) 148 + return error; 149 + 150 + return 0; 151 + } 152 + 153 + static const struct spi_device_id goodix_berlin_spi_ids[] = { 154 + { "gt9916" }, 155 + { }, 156 + }; 157 + MODULE_DEVICE_TABLE(spi, goodix_berlin_spi_ids); 158 + 159 + static const struct of_device_id goodix_berlin_spi_of_match[] = { 160 + { .compatible = "goodix,gt9916", }, 161 + { } 162 + }; 163 + MODULE_DEVICE_TABLE(of, goodix_berlin_spi_of_match); 164 + 165 + static struct spi_driver goodix_berlin_spi_driver = { 166 + .driver = { 167 + .name = "goodix-berlin-spi", 168 + .of_match_table = goodix_berlin_spi_of_match, 169 + .pm = pm_sleep_ptr(&goodix_berlin_pm_ops), 170 + }, 171 + .probe = goodix_berlin_spi_probe, 172 + .id_table = goodix_berlin_spi_ids, 173 + }; 174 + module_spi_driver(goodix_berlin_spi_driver); 175 + 176 + MODULE_LICENSE("GPL"); 177 + MODULE_DESCRIPTION("Goodix Berlin SPI Touchscreen driver"); 178 + MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
+94 -24
drivers/input/touchscreen/imagis.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 3 + #include <linux/bitfield.h> 3 4 #include <linux/bits.h> 4 5 #include <linux/delay.h> 5 6 #include <linux/i2c.h> ··· 12 11 #include <linux/property.h> 13 12 #include <linux/regulator/consumer.h> 14 13 14 + #define IST3032C_WHOAMI 0x32c 15 + 16 + #define IST3038B_REG_STATUS 0x20 17 + #define IST3038B_REG_CHIPID 0x30 18 + #define IST3038B_WHOAMI 0x30380b 19 + 15 20 #define IST3038C_HIB_ACCESS (0x800B << 16) 16 21 #define IST3038C_DIRECT_ACCESS BIT(31) 17 - #define IST3038C_REG_CHIPID 0x40001000 22 + #define IST3038C_REG_CHIPID (0x40001000 | IST3038C_DIRECT_ACCESS) 18 23 #define IST3038C_REG_HIB_BASE 0x30000100 19 24 #define IST3038C_REG_TOUCH_STATUS (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS) 20 25 #define IST3038C_REG_TOUCH_COORD (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS | 0x8) ··· 30 23 #define IST3038C_I2C_RETRY_COUNT 3 31 24 #define IST3038C_MAX_FINGER_NUM 10 32 25 #define IST3038C_X_MASK GENMASK(23, 12) 33 - #define IST3038C_X_SHIFT 12 34 26 #define IST3038C_Y_MASK GENMASK(11, 0) 35 27 #define IST3038C_AREA_MASK GENMASK(27, 24) 36 - #define IST3038C_AREA_SHIFT 24 37 28 #define IST3038C_FINGER_COUNT_MASK GENMASK(15, 12) 38 - #define IST3038C_FINGER_COUNT_SHIFT 12 39 29 #define IST3038C_FINGER_STATUS_MASK GENMASK(9, 0) 30 + #define IST3032C_KEY_STATUS_MASK GENMASK(20, 16) 31 + 32 + struct imagis_properties { 33 + unsigned int interrupt_msg_cmd; 34 + unsigned int touch_coord_cmd; 35 + unsigned int whoami_cmd; 36 + unsigned int whoami_val; 37 + bool protocol_b; 38 + bool touch_keys_supported; 39 + }; 40 40 41 41 struct imagis_ts { 42 42 struct i2c_client *client; 43 + const struct imagis_properties *tdata; 43 44 struct input_dev *input_dev; 44 45 struct touchscreen_properties prop; 45 46 struct regulator_bulk_data supplies[2]; 47 + u32 keycodes[5]; 48 + int num_keycodes; 46 49 }; 47 50 48 51 static int imagis_i2c_read_reg(struct imagis_ts *ts, ··· 97 80 { 98 81 struct imagis_ts *ts = dev_id; 99 82 u32 intr_message, finger_status; 100 - unsigned int finger_count, finger_pressed; 83 + unsigned int finger_count, finger_pressed, key_pressed; 101 84 int i; 102 85 int error; 103 86 104 - error = imagis_i2c_read_reg(ts, IST3038C_REG_INTR_MESSAGE, 105 - &intr_message); 87 + error = imagis_i2c_read_reg(ts, ts->tdata->interrupt_msg_cmd, &intr_message); 106 88 if (error) { 107 89 dev_err(&ts->client->dev, 108 90 "failed to read the interrupt message: %d\n", error); 109 91 goto out; 110 92 } 111 93 112 - finger_count = (intr_message & IST3038C_FINGER_COUNT_MASK) >> 113 - IST3038C_FINGER_COUNT_SHIFT; 94 + finger_count = FIELD_GET(IST3038C_FINGER_COUNT_MASK, intr_message); 114 95 if (finger_count > IST3038C_MAX_FINGER_NUM) { 115 96 dev_err(&ts->client->dev, 116 97 "finger count %d is more than maximum supported\n", ··· 116 101 goto out; 117 102 } 118 103 119 - finger_pressed = intr_message & IST3038C_FINGER_STATUS_MASK; 104 + finger_pressed = FIELD_GET(IST3038C_FINGER_STATUS_MASK, intr_message); 120 105 121 106 for (i = 0; i < finger_count; i++) { 122 - error = imagis_i2c_read_reg(ts, 123 - IST3038C_REG_TOUCH_COORD + (i * 4), 124 - &finger_status); 107 + if (ts->tdata->protocol_b) 108 + error = imagis_i2c_read_reg(ts, 109 + ts->tdata->touch_coord_cmd, &finger_status); 110 + else 111 + error = imagis_i2c_read_reg(ts, 112 + ts->tdata->touch_coord_cmd + (i * 4), 113 + &finger_status); 125 114 if (error) { 126 115 dev_err(&ts->client->dev, 127 116 "failed to read coordinates for finger %d: %d\n", ··· 137 118 input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 138 119 finger_pressed & BIT(i)); 139 120 touchscreen_report_pos(ts->input_dev, &ts->prop, 140 - (finger_status & IST3038C_X_MASK) >> 141 - IST3038C_X_SHIFT, 142 - finger_status & IST3038C_Y_MASK, 1); 121 + FIELD_GET(IST3038C_X_MASK, finger_status), 122 + FIELD_GET(IST3038C_Y_MASK, finger_status), 123 + true); 143 124 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 144 - (finger_status & IST3038C_AREA_MASK) >> 145 - IST3038C_AREA_SHIFT); 125 + FIELD_GET(IST3038C_AREA_MASK, finger_status)); 146 126 } 127 + 128 + key_pressed = FIELD_GET(IST3032C_KEY_STATUS_MASK, intr_message); 129 + 130 + for (int i = 0; i < ts->num_keycodes; i++) 131 + input_report_key(ts->input_dev, ts->keycodes[i], 132 + key_pressed & BIT(i)); 147 133 148 134 input_mt_sync_frame(ts->input_dev); 149 135 input_sync(ts->input_dev); ··· 234 210 235 211 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X); 236 212 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y); 237 - input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); 213 + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 16, 0, 0); 214 + if (ts->tdata->touch_keys_supported) { 215 + ts->num_keycodes = of_property_read_variable_u32_array( 216 + ts->client->dev.of_node, "linux,keycodes", 217 + ts->keycodes, 0, ARRAY_SIZE(ts->keycodes)); 218 + if (ts->num_keycodes <= 0) { 219 + ts->keycodes[0] = KEY_APPSELECT; 220 + ts->keycodes[1] = KEY_BACK; 221 + ts->num_keycodes = 2; 222 + } 223 + 224 + input_dev->keycodemax = ts->num_keycodes; 225 + input_dev->keycodesize = sizeof(ts->keycodes[0]); 226 + input_dev->keycode = ts->keycodes; 227 + } 228 + 229 + for (int i = 0; i < ts->num_keycodes; i++) 230 + input_set_capability(input_dev, EV_KEY, ts->keycodes[i]); 238 231 239 232 touchscreen_parse_properties(input_dev, true, &ts->prop); 240 233 if (!ts->prop.max_x || !ts->prop.max_y) { ··· 302 261 303 262 ts->client = i2c; 304 263 264 + ts->tdata = device_get_match_data(dev); 265 + if (!ts->tdata) { 266 + dev_err(dev, "missing chip data\n"); 267 + return -EINVAL; 268 + } 269 + 305 270 error = imagis_init_regulators(ts); 306 271 if (error) { 307 272 dev_err(dev, "regulator init error: %d\n", error); ··· 326 279 return error; 327 280 } 328 281 329 - error = imagis_i2c_read_reg(ts, 330 - IST3038C_REG_CHIPID | IST3038C_DIRECT_ACCESS, 331 - &chip_id); 282 + error = imagis_i2c_read_reg(ts, ts->tdata->whoami_cmd, &chip_id); 332 283 if (error) { 333 284 dev_err(dev, "chip ID read failure: %d\n", error); 334 285 return error; 335 286 } 336 287 337 - if (chip_id != IST3038C_WHOAMI) { 288 + if (chip_id != ts->tdata->whoami_val) { 338 289 dev_err(dev, "unknown chip ID: 0x%x\n", chip_id); 339 290 return -EINVAL; 340 291 } ··· 388 343 389 344 static DEFINE_SIMPLE_DEV_PM_OPS(imagis_pm_ops, imagis_suspend, imagis_resume); 390 345 346 + static const struct imagis_properties imagis_3032c_data = { 347 + .interrupt_msg_cmd = IST3038C_REG_INTR_MESSAGE, 348 + .touch_coord_cmd = IST3038C_REG_TOUCH_COORD, 349 + .whoami_cmd = IST3038C_REG_CHIPID, 350 + .whoami_val = IST3032C_WHOAMI, 351 + .touch_keys_supported = true, 352 + }; 353 + 354 + static const struct imagis_properties imagis_3038b_data = { 355 + .interrupt_msg_cmd = IST3038B_REG_STATUS, 356 + .touch_coord_cmd = IST3038B_REG_STATUS, 357 + .whoami_cmd = IST3038B_REG_CHIPID, 358 + .whoami_val = IST3038B_WHOAMI, 359 + .protocol_b = true, 360 + }; 361 + 362 + static const struct imagis_properties imagis_3038c_data = { 363 + .interrupt_msg_cmd = IST3038C_REG_INTR_MESSAGE, 364 + .touch_coord_cmd = IST3038C_REG_TOUCH_COORD, 365 + .whoami_cmd = IST3038C_REG_CHIPID, 366 + .whoami_val = IST3038C_WHOAMI, 367 + }; 368 + 391 369 #ifdef CONFIG_OF 392 370 static const struct of_device_id imagis_of_match[] = { 393 - { .compatible = "imagis,ist3038c", }, 371 + { .compatible = "imagis,ist3032c", .data = &imagis_3032c_data }, 372 + { .compatible = "imagis,ist3038b", .data = &imagis_3038b_data }, 373 + { .compatible = "imagis,ist3038c", .data = &imagis_3038c_data }, 394 374 { }, 395 375 }; 396 376 MODULE_DEVICE_TABLE(of, imagis_of_match);
-1
drivers/input/touchscreen/ti_am335x_tsc.c
··· 157 157 n++ == 0 ? STEPCONFIG_OPENDLY : 0); 158 158 } 159 159 160 - config = 0; 161 160 config = STEPCONFIG_MODE_HWSYNC | 162 161 STEPCONFIG_AVG_16 | ts_dev->bit_yn | 163 162 STEPCONFIG_INM_ADCREFM;
+1 -1
include/linux/input.h
··· 514 514 515 515 bool input_device_enabled(struct input_dev *dev); 516 516 517 - extern struct class input_class; 517 + extern const struct class input_class; 518 518 519 519 /** 520 520 * struct ff_device - force-feedback part of an input device
-8
include/linux/input/navpoint.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) 2012 Paul Parsons <lost.distance@yahoo.com> 4 - */ 5 - 6 - struct navpoint_platform_data { 7 - int port; /* PXA SSP port for pxa_ssp_request() */ 8 - };
+1 -1
include/linux/serio.h
··· 15 15 #include <linux/mod_devicetable.h> 16 16 #include <uapi/linux/serio.h> 17 17 18 - extern struct bus_type serio_bus; 18 + extern const struct bus_type serio_bus; 19 19 20 20 struct serio { 21 21 void *port_data;