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

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input updates from Dmitry Torokhov:

- a revert of a patch resetting extra buttons on touchpads claiming to
be buttonpads as this caused regression on certain Dell devices

- a new driver for Mediatek MT6779 keypad

- a new driver for Imagis touchscreen

- rework of Google/Chrome OS "Vivaldi" keyboard handling

- assorted driver fixes.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (31 commits)
Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads"
Input: adi - remove redundant variable z
Input: add Imagis touchscreen driver
dt-bindings: input/touchscreen: bindings for Imagis
Input: synaptics - enable InterTouch on ThinkPad T14/P14s Gen 1 AMD
Input: stmfts - fix reference leak in stmfts_input_open
Input: add bounds checking to input_set_capability()
Input: iqs5xx - use local input_dev pointer
HID: google: modify HID device groups of eel
HID: google: Add support for vivaldi to hid-hammer
HID: google: extract Vivaldi hid feature mapping for use in hid-hammer
Input: extract ChromeOS vivaldi physmap show function
HID: google: switch to devm when registering keyboard backlight LED
Input: mt6779-keypad - fix signedness bug
Input: mt6779-keypad - add MediaTek keypad driver
dt-bindings: input: Add bindings for Mediatek matrix keypad
Input: da9063 - use devm_delayed_work_autocancel()
Input: goodix - fix race on driver unbind
Input: goodix - use input_copy_abs() helper
Input: add input_copy_abs() function
...

+1364 -333
+77
Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/input/mediatek,mt6779-keypad.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Mediatek's Keypad Controller device tree bindings 8 + 9 + maintainers: 10 + - Fengping Yu <fengping.yu@mediatek.com> 11 + 12 + allOf: 13 + - $ref: "/schemas/input/matrix-keymap.yaml#" 14 + 15 + description: | 16 + Mediatek's Keypad controller is used to interface a SoC with a matrix-type 17 + keypad device. The keypad controller supports multiple row and column lines. 18 + A key can be placed at each intersection of a unique row and a unique column. 19 + The keypad controller can sense a key-press and key-release and report the 20 + event using a interrupt to the cpu. 21 + 22 + properties: 23 + compatible: 24 + oneOf: 25 + - const: mediatek,mt6779-keypad 26 + - items: 27 + - enum: 28 + - mediatek,mt6873-keypad 29 + - const: mediatek,mt6779-keypad 30 + 31 + reg: 32 + maxItems: 1 33 + 34 + interrupts: 35 + maxItems: 1 36 + 37 + clocks: 38 + maxItems: 1 39 + 40 + clock-names: 41 + items: 42 + - const: kpd 43 + 44 + wakeup-source: 45 + description: use any event on keypad as wakeup event 46 + type: boolean 47 + 48 + debounce-delay-ms: 49 + maximum: 256 50 + default: 16 51 + 52 + required: 53 + - compatible 54 + - reg 55 + - interrupts 56 + - clocks 57 + - clock-names 58 + 59 + additionalProperties: false 60 + 61 + examples: 62 + - | 63 + #include <dt-bindings/input/input.h> 64 + #include <dt-bindings/interrupt-controller/arm-gic.h> 65 + 66 + soc { 67 + #address-cells = <2>; 68 + #size-cells = <2>; 69 + 70 + keyboard@10010000 { 71 + compatible = "mediatek,mt6779-keypad"; 72 + reg = <0 0x10010000 0 0x1000>; 73 + interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_FALLING>; 74 + clocks = <&clk26m>; 75 + clock-names = "kpd"; 76 + }; 77 + };
+4 -1
Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
··· 9 9 Documentation/devicetree/bindings/mfd/mt6397.txt 10 10 11 11 Required properties: 12 - - compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys" 12 + - compatible: Should be one of: 13 + - "mediatek,mt6397-keys" 14 + - "mediatek,mt6323-keys" 15 + - "mediatek,mt6358-keys" 13 16 - linux,keycodes: See Documentation/devicetree/bindings/input/input.yaml 14 17 15 18 Optional Properties:
+74
Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.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/imagis,ist3038c.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Imagis IST30XXC family touchscreen controller bindings 8 + 9 + maintainers: 10 + - Markuss Broks <markuss.broks@gmail.com> 11 + 12 + allOf: 13 + - $ref: touchscreen.yaml# 14 + 15 + properties: 16 + $nodename: 17 + pattern: "^touchscreen@[0-9a-f]+$" 18 + 19 + compatible: 20 + enum: 21 + - imagis,ist3038c 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + interrupts: 27 + maxItems: 1 28 + 29 + vdd-supply: 30 + description: Power supply regulator for the chip 31 + 32 + vddio-supply: 33 + description: Power supply regulator for the I2C bus 34 + 35 + touchscreen-size-x: true 36 + touchscreen-size-y: true 37 + touchscreen-fuzz-x: true 38 + touchscreen-fuzz-y: true 39 + touchscreen-inverted-x: true 40 + touchscreen-inverted-y: true 41 + touchscreen-swapped-x-y: true 42 + 43 + additionalProperties: false 44 + 45 + required: 46 + - compatible 47 + - reg 48 + - interrupts 49 + - touchscreen-size-x 50 + - touchscreen-size-y 51 + 52 + examples: 53 + - | 54 + #include <dt-bindings/interrupt-controller/irq.h> 55 + i2c { 56 + #address-cells = <1>; 57 + #size-cells = <0>; 58 + touchscreen@50 { 59 + compatible = "imagis,ist3038c"; 60 + reg = <0x50>; 61 + interrupt-parent = <&gpio>; 62 + interrupts = <13 IRQ_TYPE_EDGE_FALLING>; 63 + vdd-supply = <&ldo1_reg>; 64 + vddio-supply = <&ldo2_reg>; 65 + touchscreen-size-x = <720>; 66 + touchscreen-size-y = <1280>; 67 + touchscreen-fuzz-x = <10>; 68 + touchscreen-fuzz-y = <10>; 69 + touchscreen-inverted-x; 70 + touchscreen-inverted-y; 71 + }; 72 + }; 73 + 74 + ...
+2
Documentation/devicetree/bindings/vendor-prefixes.yaml
··· 560 560 description: Ingenieurburo Fur Ic-Technologie (I/F/I) 561 561 "^ilitek,.*": 562 562 description: ILI Technology Corporation (ILITEK) 563 + "^imagis,.*": 564 + description: Imagis Technologies Co., Ltd. 563 565 "^img,.*": 564 566 description: Imagination Technologies Ltd. 565 567 "^imi,.*":
+6
MAINTAINERS
··· 9517 9517 S: Maintained 9518 9518 F: drivers/usb/atm/ueagle-atm.c 9519 9519 9520 + IMAGIS TOUCHSCREEN DRIVER 9521 + M: Markuss Broks <markuss.broks@gmail.com> 9522 + S: Maintained 9523 + F: Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml 9524 + F: drivers/input/touchscreen/imagis.c 9525 + 9520 9526 IMGTEC ASCII LCD DRIVER 9521 9527 M: Paul Burton <paulburton@kernel.org> 9522 9528 S: Maintained
+11
drivers/hid/Kconfig
··· 405 405 Say Y here if you have a Holtek On Line Grip based game controller 406 406 and want to have force feedback support for it. 407 407 408 + config HID_VIVALDI_COMMON 409 + tristate 410 + help 411 + ChromeOS Vivaldi HID parsing support library. This is a hidden 412 + option so that drivers can use common code to parse the HID 413 + descriptors for vivaldi function row keymap. 414 + 408 415 config HID_GOOGLE_HAMMER 409 416 tristate "Google Hammer Keyboard" 417 + select HID_VIVALDI_COMMON 418 + select INPUT_VIVALDIFMAP 410 419 depends on USB_HID && LEDS_CLASS && CROS_EC 411 420 help 412 421 Say Y here if you have a Google Hammer device. 413 422 414 423 config HID_VIVALDI 415 424 tristate "Vivaldi Keyboard" 425 + select HID_VIVALDI_COMMON 426 + select INPUT_VIVALDIFMAP 416 427 depends on HID 417 428 help 418 429 Say Y here if you want to enable support for Vivaldi keyboards.
+1
drivers/hid/Makefile
··· 50 50 obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o 51 51 obj-$(CONFIG_HID_GFRM) += hid-gfrm.o 52 52 obj-$(CONFIG_HID_GLORIOUS) += hid-glorious.o 53 + obj-$(CONFIG_HID_VIVALDI_COMMON) += hid-vivaldi-common.o 53 54 obj-$(CONFIG_HID_GOOGLE_HAMMER) += hid-google-hammer.o 54 55 obj-$(CONFIG_HID_VIVALDI) += hid-vivaldi.o 55 56 obj-$(CONFIG_HID_GT683R) += hid-gt683r.o
+25 -26
drivers/hid/hid-google-hammer.c
··· 15 15 16 16 #include <linux/acpi.h> 17 17 #include <linux/hid.h> 18 + #include <linux/input/vivaldi-fmap.h> 18 19 #include <linux/leds.h> 19 20 #include <linux/module.h> 20 21 #include <linux/of.h> ··· 26 25 #include <asm/unaligned.h> 27 26 28 27 #include "hid-ids.h" 28 + #include "hid-vivaldi-common.h" 29 29 30 30 /* 31 31 * C(hrome)B(ase)A(ttached)S(witch) - switch exported by Chrome EC and reporting ··· 342 340 static int hammer_register_leds(struct hid_device *hdev) 343 341 { 344 342 struct hammer_kbd_leds *kbd_backlight; 345 - int error; 346 343 347 - kbd_backlight = kzalloc(sizeof(*kbd_backlight), GFP_KERNEL); 344 + kbd_backlight = devm_kzalloc(&hdev->dev, sizeof(*kbd_backlight), 345 + GFP_KERNEL); 348 346 if (!kbd_backlight) 349 347 return -ENOMEM; 350 348 ··· 358 356 /* Set backlight to 0% initially. */ 359 357 hammer_kbd_brightness_set_blocking(&kbd_backlight->cdev, 0); 360 358 361 - error = led_classdev_register(&hdev->dev, &kbd_backlight->cdev); 362 - if (error) 363 - goto err_free_mem; 364 - 365 - hid_set_drvdata(hdev, kbd_backlight); 366 - return 0; 367 - 368 - err_free_mem: 369 - kfree(kbd_backlight); 370 - return error; 371 - } 372 - 373 - static void hammer_unregister_leds(struct hid_device *hdev) 374 - { 375 - struct hammer_kbd_leds *kbd_backlight = hid_get_drvdata(hdev); 376 - 377 - if (kbd_backlight) { 378 - led_classdev_unregister(&kbd_backlight->cdev); 379 - kfree(kbd_backlight); 380 - } 359 + return devm_led_classdev_register(&hdev->dev, &kbd_backlight->cdev); 381 360 } 382 361 383 362 #define HID_UP_GOOGLEVENDOR 0xffd10000 ··· 495 512 kfree(buf); 496 513 } 497 514 515 + static void hammer_stop(void *hdev) 516 + { 517 + hid_hw_stop(hdev); 518 + } 519 + 498 520 static int hammer_probe(struct hid_device *hdev, 499 521 const struct hid_device_id *id) 500 522 { 523 + struct vivaldi_data *vdata; 501 524 int error; 525 + 526 + vdata = devm_kzalloc(&hdev->dev, sizeof(*vdata), GFP_KERNEL); 527 + if (!vdata) 528 + return -ENOMEM; 529 + 530 + hid_set_drvdata(hdev, vdata); 502 531 503 532 error = hid_parse(hdev); 504 533 if (error) 505 534 return error; 506 535 507 536 error = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 537 + if (error) 538 + return error; 539 + 540 + error = devm_add_action(&hdev->dev, hammer_stop, hdev); 508 541 if (error) 509 542 return error; 510 543 ··· 576 577 spin_unlock_irqrestore(&cbas_ec_lock, flags); 577 578 } 578 579 579 - hammer_unregister_leds(hdev); 580 - 581 - hid_hw_stop(hdev); 580 + /* Unregistering LEDs and stopping the hardware is done via devm */ 582 581 } 583 582 584 583 static const struct hid_device_id hammer_devices[] = { 585 584 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 586 585 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_DON) }, 587 - { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 586 + { HID_DEVICE(BUS_USB, HID_GROUP_VIVALDI, 588 587 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_EEL) }, 589 588 { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 590 589 USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) }, ··· 607 610 .id_table = hammer_devices, 608 611 .probe = hammer_probe, 609 612 .remove = hammer_remove, 613 + .feature_mapping = vivaldi_feature_mapping, 614 + .input_configured = vivaldi_input_configured, 610 615 .input_mapping = hammer_input_mapping, 611 616 .event = hammer_event, 612 617 };
+140
drivers/hid/hid-vivaldi-common.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Helpers for ChromeOS HID Vivaldi keyboards 4 + * 5 + * Copyright (C) 2022 Google, Inc 6 + */ 7 + 8 + #include <linux/export.h> 9 + #include <linux/hid.h> 10 + #include <linux/input/vivaldi-fmap.h> 11 + #include <linux/kernel.h> 12 + #include <linux/module.h> 13 + #include <linux/types.h> 14 + 15 + #include "hid-vivaldi-common.h" 16 + 17 + #define MIN_FN_ROW_KEY 1 18 + #define MAX_FN_ROW_KEY VIVALDI_MAX_FUNCTION_ROW_KEYS 19 + #define HID_VD_FN_ROW_PHYSMAP 0x00000001 20 + #define HID_USAGE_FN_ROW_PHYSMAP (HID_UP_GOOGLEVENDOR | HID_VD_FN_ROW_PHYSMAP) 21 + 22 + /** 23 + * vivaldi_feature_mapping - Fill out vivaldi keymap data exposed via HID 24 + * @hdev: HID device to parse 25 + * @field: HID field to parse 26 + * @usage: HID usage to parse 27 + * 28 + * Note: this function assumes that driver data attached to @hdev contains an 29 + * instance of &struct vivaldi_data at the very beginning. 30 + */ 31 + void vivaldi_feature_mapping(struct hid_device *hdev, 32 + struct hid_field *field, struct hid_usage *usage) 33 + { 34 + struct vivaldi_data *data = hid_get_drvdata(hdev); 35 + struct hid_report *report = field->report; 36 + u8 *report_data, *buf; 37 + u32 report_len; 38 + unsigned int fn_key; 39 + int ret; 40 + 41 + if (field->logical != HID_USAGE_FN_ROW_PHYSMAP || 42 + (usage->hid & HID_USAGE_PAGE) != HID_UP_ORDINAL) 43 + return; 44 + 45 + fn_key = usage->hid & HID_USAGE; 46 + if (fn_key < MIN_FN_ROW_KEY || fn_key > MAX_FN_ROW_KEY) 47 + return; 48 + 49 + if (fn_key > data->num_function_row_keys) 50 + data->num_function_row_keys = fn_key; 51 + 52 + report_data = buf = hid_alloc_report_buf(report, GFP_KERNEL); 53 + if (!report_data) 54 + return; 55 + 56 + report_len = hid_report_len(report); 57 + if (!report->id) { 58 + /* 59 + * hid_hw_raw_request() will stuff report ID (which will be 0) 60 + * into the first byte of the buffer even for unnumbered 61 + * reports, so we need to account for this to avoid getting 62 + * -EOVERFLOW in return. 63 + * Note that hid_alloc_report_buf() adds 7 bytes to the size 64 + * so we can safely say that we have space for an extra byte. 65 + */ 66 + report_len++; 67 + } 68 + 69 + ret = hid_hw_raw_request(hdev, report->id, report_data, 70 + report_len, HID_FEATURE_REPORT, 71 + HID_REQ_GET_REPORT); 72 + if (ret < 0) { 73 + dev_warn(&hdev->dev, "failed to fetch feature %d\n", 74 + field->report->id); 75 + goto out; 76 + } 77 + 78 + if (!report->id) { 79 + /* 80 + * Undo the damage from hid_hw_raw_request() for unnumbered 81 + * reports. 82 + */ 83 + report_data++; 84 + report_len--; 85 + } 86 + 87 + ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, report_data, 88 + report_len, 0); 89 + if (ret) { 90 + dev_warn(&hdev->dev, "failed to report feature %d\n", 91 + field->report->id); 92 + goto out; 93 + } 94 + 95 + data->function_row_physmap[fn_key - MIN_FN_ROW_KEY] = 96 + field->value[usage->usage_index]; 97 + 98 + out: 99 + kfree(buf); 100 + } 101 + EXPORT_SYMBOL_GPL(vivaldi_feature_mapping); 102 + 103 + static ssize_t function_row_physmap_show(struct device *dev, 104 + struct device_attribute *attr, 105 + char *buf) 106 + { 107 + struct hid_device *hdev = to_hid_device(dev); 108 + struct vivaldi_data *data = hid_get_drvdata(hdev); 109 + 110 + return vivaldi_function_row_physmap_show(data, buf); 111 + } 112 + 113 + static DEVICE_ATTR_RO(function_row_physmap); 114 + static struct attribute *vivaldi_sysfs_attrs[] = { 115 + &dev_attr_function_row_physmap.attr, 116 + NULL 117 + }; 118 + 119 + static const struct attribute_group vivaldi_attribute_group = { 120 + .attrs = vivaldi_sysfs_attrs, 121 + }; 122 + 123 + /** 124 + * vivaldi_input_configured - Complete initialization of device using vivaldi map 125 + * @hdev: HID device to which vivaldi attributes should be attached 126 + * @hidinput: HID input device (unused) 127 + */ 128 + int vivaldi_input_configured(struct hid_device *hdev, 129 + struct hid_input *hidinput) 130 + { 131 + struct vivaldi_data *data = hid_get_drvdata(hdev); 132 + 133 + if (!data->num_function_row_keys) 134 + return 0; 135 + 136 + return devm_device_add_group(&hdev->dev, &vivaldi_attribute_group); 137 + } 138 + EXPORT_SYMBOL_GPL(vivaldi_input_configured); 139 + 140 + MODULE_LICENSE("GPL");
+16
drivers/hid/hid-vivaldi-common.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _HID_VIVALDI_COMMON_H 3 + #define _HID_VIVALDI_COMMON_H 4 + 5 + struct hid_device; 6 + struct hid_field; 7 + struct hid_input; 8 + struct hid_usage; 9 + 10 + void vivaldi_feature_mapping(struct hid_device *hdev, 11 + struct hid_field *field, struct hid_usage *usage); 12 + 13 + int vivaldi_input_configured(struct hid_device *hdev, 14 + struct hid_input *hidinput); 15 + 16 + #endif /* _HID_VIVALDI_COMMON_H */
+3 -118
drivers/hid/hid-vivaldi.c
··· 8 8 9 9 #include <linux/device.h> 10 10 #include <linux/hid.h> 11 + #include <linux/input/vivaldi-fmap.h> 11 12 #include <linux/kernel.h> 12 13 #include <linux/module.h> 13 - #include <linux/sysfs.h> 14 14 15 - #define MIN_FN_ROW_KEY 1 16 - #define MAX_FN_ROW_KEY 24 17 - #define HID_VD_FN_ROW_PHYSMAP 0x00000001 18 - #define HID_USAGE_FN_ROW_PHYSMAP (HID_UP_GOOGLEVENDOR | HID_VD_FN_ROW_PHYSMAP) 19 - 20 - struct vivaldi_data { 21 - u32 function_row_physmap[MAX_FN_ROW_KEY - MIN_FN_ROW_KEY + 1]; 22 - int max_function_row_key; 23 - }; 24 - 25 - static ssize_t function_row_physmap_show(struct device *dev, 26 - struct device_attribute *attr, 27 - char *buf) 28 - { 29 - struct hid_device *hdev = to_hid_device(dev); 30 - struct vivaldi_data *drvdata = hid_get_drvdata(hdev); 31 - ssize_t size = 0; 32 - int i; 33 - 34 - if (!drvdata->max_function_row_key) 35 - return 0; 36 - 37 - for (i = 0; i < drvdata->max_function_row_key; i++) 38 - size += sprintf(buf + size, "%02X ", 39 - drvdata->function_row_physmap[i]); 40 - size += sprintf(buf + size, "\n"); 41 - return size; 42 - } 43 - 44 - static DEVICE_ATTR_RO(function_row_physmap); 45 - static struct attribute *sysfs_attrs[] = { 46 - &dev_attr_function_row_physmap.attr, 47 - NULL 48 - }; 49 - 50 - static const struct attribute_group input_attribute_group = { 51 - .attrs = sysfs_attrs 52 - }; 15 + #include "hid-vivaldi-common.h" 53 16 54 17 static int vivaldi_probe(struct hid_device *hdev, 55 18 const struct hid_device_id *id) ··· 33 70 return hid_hw_start(hdev, HID_CONNECT_DEFAULT); 34 71 } 35 72 36 - static void vivaldi_feature_mapping(struct hid_device *hdev, 37 - struct hid_field *field, 38 - struct hid_usage *usage) 39 - { 40 - struct vivaldi_data *drvdata = hid_get_drvdata(hdev); 41 - struct hid_report *report = field->report; 42 - int fn_key; 43 - int ret; 44 - u32 report_len; 45 - u8 *report_data, *buf; 46 - 47 - if (field->logical != HID_USAGE_FN_ROW_PHYSMAP || 48 - (usage->hid & HID_USAGE_PAGE) != HID_UP_ORDINAL) 49 - return; 50 - 51 - fn_key = (usage->hid & HID_USAGE); 52 - if (fn_key < MIN_FN_ROW_KEY || fn_key > MAX_FN_ROW_KEY) 53 - return; 54 - if (fn_key > drvdata->max_function_row_key) 55 - drvdata->max_function_row_key = fn_key; 56 - 57 - report_data = buf = hid_alloc_report_buf(report, GFP_KERNEL); 58 - if (!report_data) 59 - return; 60 - 61 - report_len = hid_report_len(report); 62 - if (!report->id) { 63 - /* 64 - * hid_hw_raw_request() will stuff report ID (which will be 0) 65 - * into the first byte of the buffer even for unnumbered 66 - * reports, so we need to account for this to avoid getting 67 - * -EOVERFLOW in return. 68 - * Note that hid_alloc_report_buf() adds 7 bytes to the size 69 - * so we can safely say that we have space for an extra byte. 70 - */ 71 - report_len++; 72 - } 73 - 74 - ret = hid_hw_raw_request(hdev, report->id, report_data, 75 - report_len, HID_FEATURE_REPORT, 76 - HID_REQ_GET_REPORT); 77 - if (ret < 0) { 78 - dev_warn(&hdev->dev, "failed to fetch feature %d\n", 79 - field->report->id); 80 - goto out; 81 - } 82 - 83 - if (!report->id) { 84 - /* 85 - * Undo the damage from hid_hw_raw_request() for unnumbered 86 - * reports. 87 - */ 88 - report_data++; 89 - report_len--; 90 - } 91 - 92 - ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, report_data, 93 - report_len, 0); 94 - if (ret) { 95 - dev_warn(&hdev->dev, "failed to report feature %d\n", 96 - field->report->id); 97 - goto out; 98 - } 99 - 100 - drvdata->function_row_physmap[fn_key - MIN_FN_ROW_KEY] = 101 - field->value[usage->usage_index]; 102 - 103 - out: 104 - kfree(buf); 105 - } 106 - 107 - static int vivaldi_input_configured(struct hid_device *hdev, 108 - struct hid_input *hidinput) 109 - { 110 - return devm_device_add_group(&hdev->dev, &input_attribute_group); 111 - } 112 - 113 73 static const struct hid_device_id vivaldi_table[] = { 114 - { HID_DEVICE(HID_BUS_ANY, HID_GROUP_VIVALDI, HID_ANY_ID, 115 - HID_ANY_ID) }, 74 + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_VIVALDI, HID_ANY_ID, HID_ANY_ID) }, 116 75 { } 117 76 }; 118 77
+7
drivers/input/Kconfig
··· 77 77 To compile this driver as a module, choose M here: the 78 78 module will be called matrix-keymap. 79 79 80 + config INPUT_VIVALDIFMAP 81 + tristate 82 + help 83 + ChromeOS Vivaldi keymap support library. This is a hidden 84 + option so that drivers can use common code to parse and 85 + expose the vivaldi function row keymap. 86 + 80 87 comment "Userland interfaces" 81 88 82 89 config INPUT_MOUSEDEV
+1
drivers/input/Makefile
··· 12 12 obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o 13 13 obj-$(CONFIG_INPUT_SPARSEKMAP) += sparse-keymap.o 14 14 obj-$(CONFIG_INPUT_MATRIXKMAP) += matrix-keymap.o 15 + obj-$(CONFIG_INPUT_VIVALDIFMAP) += vivaldi-fmap.o 15 16 16 17 obj-$(CONFIG_INPUT_LEDS) += input-leds.o 17 18 obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
+58 -12
drivers/input/input.c
··· 47 47 48 48 static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 }; 49 49 50 + static const unsigned int input_max_code[EV_CNT] = { 51 + [EV_KEY] = KEY_MAX, 52 + [EV_REL] = REL_MAX, 53 + [EV_ABS] = ABS_MAX, 54 + [EV_MSC] = MSC_MAX, 55 + [EV_SW] = SW_MAX, 56 + [EV_LED] = LED_MAX, 57 + [EV_SND] = SND_MAX, 58 + [EV_FF] = FF_MAX, 59 + }; 60 + 50 61 static inline int is_event_supported(unsigned int code, 51 62 unsigned long *bm, unsigned int max) 52 63 { ··· 522 511 { 523 512 struct input_absinfo *absinfo; 524 513 514 + __set_bit(EV_ABS, dev->evbit); 515 + __set_bit(axis, dev->absbit); 516 + 525 517 input_alloc_absinfo(dev); 526 518 if (!dev->absinfo) 527 519 return; ··· 534 520 absinfo->maximum = max; 535 521 absinfo->fuzz = fuzz; 536 522 absinfo->flat = flat; 537 - 538 - __set_bit(EV_ABS, dev->evbit); 539 - __set_bit(axis, dev->absbit); 540 523 } 541 524 EXPORT_SYMBOL(input_set_abs_params); 542 525 526 + /** 527 + * input_copy_abs - Copy absinfo from one input_dev to another 528 + * @dst: Destination input device to copy the abs settings to 529 + * @dst_axis: ABS_* value selecting the destination axis 530 + * @src: Source input device to copy the abs settings from 531 + * @src_axis: ABS_* value selecting the source axis 532 + * 533 + * Set absinfo for the selected destination axis by copying it from 534 + * the specified source input device's source axis. 535 + * This is useful to e.g. setup a pen/stylus input-device for combined 536 + * touchscreen/pen hardware where the pen uses the same coordinates as 537 + * the touchscreen. 538 + */ 539 + void input_copy_abs(struct input_dev *dst, unsigned int dst_axis, 540 + const struct input_dev *src, unsigned int src_axis) 541 + { 542 + /* src must have EV_ABS and src_axis set */ 543 + if (WARN_ON(!(test_bit(EV_ABS, src->evbit) && 544 + test_bit(src_axis, src->absbit)))) 545 + return; 546 + 547 + /* 548 + * input_alloc_absinfo() may have failed for the source. Our caller is 549 + * expected to catch this when registering the input devices, which may 550 + * happen after the input_copy_abs() call. 551 + */ 552 + if (!src->absinfo) 553 + return; 554 + 555 + input_set_capability(dst, EV_ABS, dst_axis); 556 + if (!dst->absinfo) 557 + return; 558 + 559 + dst->absinfo[dst_axis] = src->absinfo[src_axis]; 560 + } 561 + EXPORT_SYMBOL(input_copy_abs); 543 562 544 563 /** 545 564 * input_grab_device - grabs device for exclusive use ··· 2121 2074 */ 2122 2075 void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code) 2123 2076 { 2077 + if (type < EV_CNT && input_max_code[type] && 2078 + code > input_max_code[type]) { 2079 + pr_err("%s: invalid code %u for type %u\n", __func__, code, 2080 + type); 2081 + dump_stack(); 2082 + return; 2083 + } 2084 + 2124 2085 switch (type) { 2125 2086 case EV_KEY: 2126 2087 __set_bit(code, dev->keybit); ··· 2140 2085 2141 2086 case EV_ABS: 2142 2087 input_alloc_absinfo(dev); 2143 - if (!dev->absinfo) 2144 - return; 2145 - 2146 2088 __set_bit(code, dev->absbit); 2147 2089 break; 2148 2090 ··· 2336 2284 2337 2285 /* KEY_RESERVED is not supposed to be transmitted to userspace. */ 2338 2286 __clear_bit(KEY_RESERVED, dev->keybit); 2339 - 2340 - /* Buttonpads should not map BTN_RIGHT and/or BTN_MIDDLE. */ 2341 - if (test_bit(INPUT_PROP_BUTTONPAD, dev->propbit)) { 2342 - __clear_bit(BTN_RIGHT, dev->keybit); 2343 - __clear_bit(BTN_MIDDLE, dev->keybit); 2344 - } 2345 2287 2346 2288 /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ 2347 2289 input_cleanse_bitmasks(dev);
+2 -2
drivers/input/joystick/adi.c
··· 123 123 { 124 124 struct adi *adi = port->adi; 125 125 struct gameport *gameport = port->gameport; 126 - unsigned char u, v, w, x, z; 126 + unsigned char u, v, w, x; 127 127 int t[2], s[2], i; 128 128 unsigned long flags; 129 129 ··· 136 136 local_irq_save(flags); 137 137 138 138 gameport_trigger(gameport); 139 - v = z = gameport_read(gameport); 139 + v = gameport_read(gameport); 140 140 141 141 do { 142 142 u = v;
+1 -1
drivers/input/joystick/xpad.c
··· 131 131 { 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", 0, XTYPE_XBOXONE }, 132 132 { 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE }, 133 133 { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, 134 - { 0x045e, 0x0b12, "Microsoft Xbox One X pad", MAP_SELECT_BUTTON, XTYPE_XBOXONE }, 134 + { 0x045e, 0x0b12, "Microsoft Xbox Series S|X Controller", MAP_SELECT_BUTTON, XTYPE_XBOXONE }, 135 135 { 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 }, 136 136 { 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 }, 137 137 { 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 },
+14
drivers/input/keyboard/Kconfig
··· 103 103 select SERIO_LIBPS2 104 104 select SERIO_I8042 if ARCH_MIGHT_HAVE_PC_SERIO 105 105 select SERIO_GSCPS2 if GSC 106 + select INPUT_VIVALDIFMAP 106 107 help 107 108 Say Y here if you want to use a standard AT or PS/2 keyboard. Usually 108 109 you'll need this, unless you have a different type keyboard (USB, ADB ··· 750 749 config KEYBOARD_CROS_EC 751 750 tristate "ChromeOS EC keyboard" 752 751 select INPUT_MATRIXKMAP 752 + select INPUT_VIVALDIFMAP 753 753 depends on CROS_EC 754 754 help 755 755 Say Y here to enable the matrix keyboard used by ChromeOS devices ··· 780 778 781 779 To compile this driver as a module, choose M here: the 782 780 module will be called bcm-keypad. 781 + 782 + config KEYBOARD_MT6779 783 + tristate "MediaTek Keypad Support" 784 + depends on ARCH_MEDIATEK || COMPILE_TEST 785 + select REGMAP_MMIO 786 + select INPUT_MATRIXKMAP 787 + help 788 + Say Y here if you want to use the keypad on MediaTek SoCs. 789 + If unsure, say N. 790 + 791 + To compile this driver as a module, choose M here: the 792 + module will be called mt6779-keypad. 783 793 784 794 config KEYBOARD_MTK_PMIC 785 795 tristate "MediaTek PMIC keys support"
+1
drivers/input/keyboard/Makefile
··· 44 44 obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o 45 45 obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o 46 46 obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o 47 + obj-$(CONFIG_KEYBOARD_MT6779) += mt6779-keypad.o 47 48 obj-$(CONFIG_KEYBOARD_MTK_PMIC) += mtk-pmic-keys.o 48 49 obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o 49 50 obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o
+8 -19
drivers/input/keyboard/atkbd.c
··· 19 19 #include <linux/interrupt.h> 20 20 #include <linux/init.h> 21 21 #include <linux/input.h> 22 + #include <linux/input/vivaldi-fmap.h> 22 23 #include <linux/serio.h> 23 24 #include <linux/workqueue.h> 24 25 #include <linux/libps2.h> ··· 64 63 static bool atkbd_terminal; 65 64 module_param_named(terminal, atkbd_terminal, bool, 0); 66 65 MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2"); 67 - 68 - #define MAX_FUNCTION_ROW_KEYS 24 69 66 70 67 #define SCANCODE(keymap) ((keymap >> 16) & 0xFFFF) 71 68 #define KEYCODE(keymap) (keymap & 0xFFFF) ··· 236 237 /* Serializes reconnect(), attr->set() and event work */ 237 238 struct mutex mutex; 238 239 239 - u32 function_row_physmap[MAX_FUNCTION_ROW_KEYS]; 240 - int num_function_row_keys; 240 + struct vivaldi_data vdata; 241 241 }; 242 242 243 243 /* ··· 306 308 307 309 static ssize_t atkbd_show_function_row_physmap(struct atkbd *atkbd, char *buf) 308 310 { 309 - ssize_t size = 0; 310 - int i; 311 - 312 - if (!atkbd->num_function_row_keys) 313 - return 0; 314 - 315 - for (i = 0; i < atkbd->num_function_row_keys; i++) 316 - size += scnprintf(buf + size, PAGE_SIZE - size, "%02X ", 317 - atkbd->function_row_physmap[i]); 318 - size += scnprintf(buf + size, PAGE_SIZE - size, "\n"); 319 - return size; 311 + return vivaldi_function_row_physmap_show(&atkbd->vdata, buf); 320 312 } 321 313 322 314 static umode_t atkbd_attr_is_visible(struct kobject *kobj, ··· 317 329 struct atkbd *atkbd = serio_get_drvdata(serio); 318 330 319 331 if (attr == &atkbd_attr_function_row_physmap.attr && 320 - !atkbd->num_function_row_keys) 332 + !atkbd->vdata.num_function_row_keys) 321 333 return 0; 322 334 323 335 return attr->mode; ··· 1194 1206 1195 1207 /* Parse "function-row-physmap" property */ 1196 1208 n = device_property_count_u32(dev, "function-row-physmap"); 1197 - if (n > 0 && n <= MAX_FUNCTION_ROW_KEYS && 1209 + if (n > 0 && n <= VIVALDI_MAX_FUNCTION_ROW_KEYS && 1198 1210 !device_property_read_u32_array(dev, "function-row-physmap", 1199 - atkbd->function_row_physmap, n)) { 1200 - atkbd->num_function_row_keys = n; 1211 + atkbd->vdata.function_row_physmap, 1212 + n)) { 1213 + atkbd->vdata.num_function_row_keys = n; 1201 1214 dev_dbg(dev, "FW reported %d function-row key locations\n", n); 1202 1215 } 1203 1216 }
+16 -27
drivers/input/keyboard/cros_ec_keyb.c
··· 15 15 #include <linux/bitops.h> 16 16 #include <linux/i2c.h> 17 17 #include <linux/input.h> 18 + #include <linux/input/vivaldi-fmap.h> 18 19 #include <linux/interrupt.h> 19 20 #include <linux/kernel.h> 20 21 #include <linux/notifier.h> ··· 27 26 #include <linux/platform_data/cros_ec_proto.h> 28 27 29 28 #include <asm/unaligned.h> 30 - 31 - #define MAX_NUM_TOP_ROW_KEYS 15 32 29 33 30 /** 34 31 * struct cros_ec_keyb - Structure representing EC keyboard device ··· 43 44 * @idev: The input device for the matrix keys. 44 45 * @bs_idev: The input device for non-matrix buttons and switches (or NULL). 45 46 * @notifier: interrupt event notifier for transport devices 46 - * @function_row_physmap: An array of the encoded rows/columns for the top 47 - * row function keys, in an order from left to right 48 - * @num_function_row_keys: The number of top row keys in a custom keyboard 47 + * @vdata: vivaldi function row data 49 48 */ 50 49 struct cros_ec_keyb { 51 50 unsigned int rows; ··· 61 64 struct input_dev *bs_idev; 62 65 struct notifier_block notifier; 63 66 64 - u16 function_row_physmap[MAX_NUM_TOP_ROW_KEYS]; 65 - size_t num_function_row_keys; 67 + struct vivaldi_data vdata; 66 68 }; 67 69 68 70 /** ··· 533 537 int err; 534 538 struct property *prop; 535 539 const __be32 *p; 536 - u16 *physmap; 540 + u32 *physmap; 537 541 u32 key_pos; 538 - int row, col; 542 + unsigned int row, col, scancode, n_physmap; 539 543 540 544 err = matrix_keypad_parse_properties(dev, &ckdev->rows, &ckdev->cols); 541 545 if (err) ··· 587 591 ckdev->idev = idev; 588 592 cros_ec_keyb_compute_valid_keys(ckdev); 589 593 590 - physmap = ckdev->function_row_physmap; 594 + physmap = ckdev->vdata.function_row_physmap; 595 + n_physmap = 0; 591 596 of_property_for_each_u32(dev->of_node, "function-row-physmap", 592 597 prop, p, key_pos) { 593 - if (ckdev->num_function_row_keys == MAX_NUM_TOP_ROW_KEYS) { 598 + if (n_physmap == VIVALDI_MAX_FUNCTION_ROW_KEYS) { 594 599 dev_warn(dev, "Only support up to %d top row keys\n", 595 - MAX_NUM_TOP_ROW_KEYS); 600 + VIVALDI_MAX_FUNCTION_ROW_KEYS); 596 601 break; 597 602 } 598 603 row = KEY_ROW(key_pos); 599 604 col = KEY_COL(key_pos); 600 - *physmap = MATRIX_SCAN_CODE(row, col, ckdev->row_shift); 601 - physmap++; 602 - ckdev->num_function_row_keys++; 605 + scancode = MATRIX_SCAN_CODE(row, col, ckdev->row_shift); 606 + physmap[n_physmap++] = scancode; 603 607 } 608 + ckdev->vdata.num_function_row_keys = n_physmap; 604 609 605 610 err = input_register_device(ckdev->idev); 606 611 if (err) { ··· 616 619 struct device_attribute *attr, 617 620 char *buf) 618 621 { 619 - ssize_t size = 0; 620 - int i; 621 - struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); 622 - u16 *physmap = ckdev->function_row_physmap; 622 + const struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); 623 + const struct vivaldi_data *data = &ckdev->vdata; 623 624 624 - for (i = 0; i < ckdev->num_function_row_keys; i++) 625 - size += scnprintf(buf + size, PAGE_SIZE - size, 626 - "%s%02X", size ? " " : "", physmap[i]); 627 - if (size) 628 - size += scnprintf(buf + size, PAGE_SIZE - size, "\n"); 629 - 630 - return size; 625 + return vivaldi_function_row_physmap_show(data, buf); 631 626 } 632 627 633 628 static DEVICE_ATTR_RO(function_row_physmap); ··· 637 648 struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); 638 649 639 650 if (attr == &dev_attr_function_row_physmap.attr && 640 - !ckdev->num_function_row_keys) 651 + !ckdev->vdata.num_function_row_keys) 641 652 return 0; 642 653 643 654 return attr->mode;
+221
drivers/input/keyboard/mt6779-keypad.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2022 MediaTek Inc. 4 + * Author Fengping Yu <fengping.yu@mediatek.com> 5 + */ 6 + #include <linux/bitops.h> 7 + #include <linux/clk.h> 8 + #include <linux/input/matrix_keypad.h> 9 + #include <linux/interrupt.h> 10 + #include <linux/module.h> 11 + #include <linux/property.h> 12 + #include <linux/platform_device.h> 13 + #include <linux/regmap.h> 14 + 15 + #define MTK_KPD_NAME "mt6779-keypad" 16 + #define MTK_KPD_MEM 0x0004 17 + #define MTK_KPD_DEBOUNCE 0x0018 18 + #define MTK_KPD_DEBOUNCE_MASK GENMASK(13, 0) 19 + #define MTK_KPD_DEBOUNCE_MAX_MS 256 20 + #define MTK_KPD_NUM_MEMS 5 21 + #define MTK_KPD_NUM_BITS 136 /* 4*32+8 MEM5 only use 8 BITS */ 22 + 23 + struct mt6779_keypad { 24 + struct regmap *regmap; 25 + struct input_dev *input_dev; 26 + struct clk *clk; 27 + void __iomem *base; 28 + u32 n_rows; 29 + u32 n_cols; 30 + DECLARE_BITMAP(keymap_state, MTK_KPD_NUM_BITS); 31 + }; 32 + 33 + static const struct regmap_config mt6779_keypad_regmap_cfg = { 34 + .reg_bits = 32, 35 + .val_bits = 32, 36 + .reg_stride = sizeof(u32), 37 + .max_register = 36, 38 + }; 39 + 40 + static irqreturn_t mt6779_keypad_irq_handler(int irq, void *dev_id) 41 + { 42 + struct mt6779_keypad *keypad = dev_id; 43 + const unsigned short *keycode = keypad->input_dev->keycode; 44 + DECLARE_BITMAP(new_state, MTK_KPD_NUM_BITS); 45 + DECLARE_BITMAP(change, MTK_KPD_NUM_BITS); 46 + unsigned int bit_nr; 47 + unsigned int row, col; 48 + unsigned int scancode; 49 + unsigned int row_shift = get_count_order(keypad->n_cols); 50 + bool pressed; 51 + 52 + regmap_bulk_read(keypad->regmap, MTK_KPD_MEM, 53 + new_state, MTK_KPD_NUM_MEMS); 54 + 55 + bitmap_xor(change, new_state, keypad->keymap_state, MTK_KPD_NUM_BITS); 56 + 57 + for_each_set_bit(bit_nr, change, MTK_KPD_NUM_BITS) { 58 + /* 59 + * Registers are 32bits, but only bits [15:0] are used to 60 + * indicate key status. 61 + */ 62 + if (bit_nr % 32 >= 16) 63 + continue; 64 + 65 + row = bit_nr / 32; 66 + col = bit_nr % 32; 67 + scancode = MATRIX_SCAN_CODE(row, col, row_shift); 68 + /* 1: not pressed, 0: pressed */ 69 + pressed = !test_bit(bit_nr, new_state); 70 + dev_dbg(&keypad->input_dev->dev, "%s", 71 + pressed ? "pressed" : "released"); 72 + 73 + input_event(keypad->input_dev, EV_MSC, MSC_SCAN, scancode); 74 + input_report_key(keypad->input_dev, keycode[scancode], pressed); 75 + input_sync(keypad->input_dev); 76 + 77 + dev_dbg(&keypad->input_dev->dev, 78 + "report Linux keycode = %d\n", keycode[scancode]); 79 + } 80 + 81 + bitmap_copy(keypad->keymap_state, new_state, MTK_KPD_NUM_BITS); 82 + 83 + return IRQ_HANDLED; 84 + } 85 + 86 + static void mt6779_keypad_clk_disable(void *data) 87 + { 88 + clk_disable_unprepare(data); 89 + } 90 + 91 + static int mt6779_keypad_pdrv_probe(struct platform_device *pdev) 92 + { 93 + struct mt6779_keypad *keypad; 94 + int irq; 95 + u32 debounce; 96 + bool wakeup; 97 + int error; 98 + 99 + keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL); 100 + if (!keypad) 101 + return -ENOMEM; 102 + 103 + keypad->base = devm_platform_ioremap_resource(pdev, 0); 104 + if (IS_ERR(keypad->base)) 105 + return PTR_ERR(keypad->base); 106 + 107 + keypad->regmap = devm_regmap_init_mmio(&pdev->dev, keypad->base, 108 + &mt6779_keypad_regmap_cfg); 109 + if (IS_ERR(keypad->regmap)) { 110 + dev_err(&pdev->dev, 111 + "regmap init failed:%pe\n", keypad->regmap); 112 + return PTR_ERR(keypad->regmap); 113 + } 114 + 115 + bitmap_fill(keypad->keymap_state, MTK_KPD_NUM_BITS); 116 + 117 + keypad->input_dev = devm_input_allocate_device(&pdev->dev); 118 + if (!keypad->input_dev) { 119 + dev_err(&pdev->dev, "Failed to allocate input dev\n"); 120 + return -ENOMEM; 121 + } 122 + 123 + keypad->input_dev->name = MTK_KPD_NAME; 124 + keypad->input_dev->id.bustype = BUS_HOST; 125 + 126 + error = matrix_keypad_parse_properties(&pdev->dev, &keypad->n_rows, 127 + &keypad->n_cols); 128 + if (error) { 129 + dev_err(&pdev->dev, "Failed to parse keypad params\n"); 130 + return error; 131 + } 132 + 133 + if (device_property_read_u32(&pdev->dev, "debounce-delay-ms", 134 + &debounce)) 135 + debounce = 16; 136 + 137 + if (debounce > MTK_KPD_DEBOUNCE_MAX_MS) { 138 + dev_err(&pdev->dev, 139 + "Debounce time exceeds the maximum allowed time %dms\n", 140 + MTK_KPD_DEBOUNCE_MAX_MS); 141 + return -EINVAL; 142 + } 143 + 144 + wakeup = device_property_read_bool(&pdev->dev, "wakeup-source"); 145 + 146 + dev_dbg(&pdev->dev, "n_row=%d n_col=%d debounce=%d\n", 147 + keypad->n_rows, keypad->n_cols, debounce); 148 + 149 + error = matrix_keypad_build_keymap(NULL, NULL, 150 + keypad->n_rows, keypad->n_cols, 151 + NULL, keypad->input_dev); 152 + if (error) { 153 + dev_err(&pdev->dev, "Failed to build keymap\n"); 154 + return error; 155 + } 156 + 157 + input_set_capability(keypad->input_dev, EV_MSC, MSC_SCAN); 158 + 159 + regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE, 160 + (debounce * (1 << 5)) & MTK_KPD_DEBOUNCE_MASK); 161 + 162 + keypad->clk = devm_clk_get(&pdev->dev, "kpd"); 163 + if (IS_ERR(keypad->clk)) 164 + return PTR_ERR(keypad->clk); 165 + 166 + error = clk_prepare_enable(keypad->clk); 167 + if (error) { 168 + dev_err(&pdev->dev, "cannot prepare/enable keypad clock\n"); 169 + return error; 170 + } 171 + 172 + error = devm_add_action_or_reset(&pdev->dev, mt6779_keypad_clk_disable, 173 + keypad->clk); 174 + if (error) 175 + return error; 176 + 177 + irq = platform_get_irq(pdev, 0); 178 + if (irq < 0) 179 + return irq; 180 + 181 + error = devm_request_threaded_irq(&pdev->dev, irq, 182 + NULL, mt6779_keypad_irq_handler, 183 + IRQF_ONESHOT, MTK_KPD_NAME, keypad); 184 + if (error) { 185 + dev_err(&pdev->dev, "Failed to request IRQ#%d: %d\n", 186 + irq, error); 187 + return error; 188 + } 189 + 190 + error = input_register_device(keypad->input_dev); 191 + if (error) { 192 + dev_err(&pdev->dev, "Failed to register device\n"); 193 + return error; 194 + } 195 + 196 + error = device_init_wakeup(&pdev->dev, wakeup); 197 + if (error) 198 + dev_warn(&pdev->dev, "device_init_wakeup() failed: %d\n", 199 + error); 200 + 201 + return 0; 202 + } 203 + 204 + static const struct of_device_id mt6779_keypad_of_match[] = { 205 + { .compatible = "mediatek,mt6779-keypad" }, 206 + { .compatible = "mediatek,mt6873-keypad" }, 207 + { /* sentinel */ } 208 + }; 209 + 210 + static struct platform_driver mt6779_keypad_pdrv = { 211 + .probe = mt6779_keypad_pdrv_probe, 212 + .driver = { 213 + .name = MTK_KPD_NAME, 214 + .of_match_table = mt6779_keypad_of_match, 215 + }, 216 + }; 217 + module_platform_driver(mt6779_keypad_pdrv); 218 + 219 + MODULE_AUTHOR("Mediatek Corporation"); 220 + MODULE_DESCRIPTION("MTK Keypad (KPD) Driver"); 221 + MODULE_LICENSE("GPL");
+51 -4
drivers/input/keyboard/mtk-pmic-keys.c
··· 9 9 #include <linux/interrupt.h> 10 10 #include <linux/kernel.h> 11 11 #include <linux/mfd/mt6323/registers.h> 12 + #include <linux/mfd/mt6358/registers.h> 12 13 #include <linux/mfd/mt6397/core.h> 13 14 #include <linux/mfd/mt6397/registers.h> 14 15 #include <linux/module.h> ··· 75 74 .pmic_rst_reg = MT6323_TOP_RST_MISC, 76 75 }; 77 76 77 + static const struct mtk_pmic_regs mt6358_regs = { 78 + .keys_regs[MTK_PMIC_PWRKEY_INDEX] = 79 + MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS, 80 + 0x2, MT6358_PSC_TOP_INT_CON0, 0x5), 81 + .keys_regs[MTK_PMIC_HOMEKEY_INDEX] = 82 + MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS, 83 + 0x8, MT6358_PSC_TOP_INT_CON0, 0xa), 84 + .pmic_rst_reg = MT6358_TOP_RST_MISC, 85 + }; 86 + 78 87 struct mtk_pmic_keys_info { 79 88 struct mtk_pmic_keys *keys; 80 89 const struct mtk_pmic_keys_regs *regs; 81 90 unsigned int keycode; 82 91 int irq; 92 + int irq_r; /* optional: release irq if different */ 83 93 bool wakeup:1; 84 94 }; 85 95 ··· 200 188 return ret; 201 189 } 202 190 191 + if (info->irq_r > 0) { 192 + ret = devm_request_threaded_irq(keys->dev, info->irq_r, NULL, 193 + mtk_pmic_keys_irq_handler_thread, 194 + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, 195 + "mtk-pmic-keys", info); 196 + if (ret) { 197 + dev_err(keys->dev, "Failed to request IRQ_r: %d: %d\n", 198 + info->irq, ret); 199 + return ret; 200 + } 201 + } 202 + 203 203 input_set_capability(keys->input_dev, EV_KEY, info->keycode); 204 204 205 205 return 0; ··· 223 199 int index; 224 200 225 201 for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) { 226 - if (keys->keys[index].wakeup) 202 + if (keys->keys[index].wakeup) { 227 203 enable_irq_wake(keys->keys[index].irq); 204 + if (keys->keys[index].irq_r > 0) 205 + enable_irq_wake(keys->keys[index].irq_r); 206 + } 228 207 } 229 208 230 209 return 0; ··· 239 212 int index; 240 213 241 214 for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) { 242 - if (keys->keys[index].wakeup) 215 + if (keys->keys[index].wakeup) { 243 216 disable_irq_wake(keys->keys[index].irq); 217 + if (keys->keys[index].irq_r > 0) 218 + disable_irq_wake(keys->keys[index].irq_r); 219 + } 244 220 } 245 221 246 222 return 0; ··· 260 230 .compatible = "mediatek,mt6323-keys", 261 231 .data = &mt6323_regs, 262 232 }, { 233 + .compatible = "mediatek,mt6358-keys", 234 + .data = &mt6358_regs, 235 + }, { 263 236 /* sentinel */ 264 237 } 265 238 }; ··· 274 241 unsigned int keycount; 275 242 struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent); 276 243 struct device_node *node = pdev->dev.of_node, *child; 244 + static const char *const irqnames[] = { "powerkey", "homekey" }; 245 + static const char *const irqnames_r[] = { "powerkey_r", "homekey_r" }; 277 246 struct mtk_pmic_keys *keys; 278 247 const struct mtk_pmic_regs *mtk_pmic_regs; 279 248 struct input_dev *input_dev; ··· 303 268 input_dev->id.version = 0x0001; 304 269 305 270 keycount = of_get_available_child_count(node); 306 - if (keycount > MTK_PMIC_MAX_KEY_COUNT) { 271 + if (keycount > MTK_PMIC_MAX_KEY_COUNT || 272 + keycount > ARRAY_SIZE(irqnames)) { 307 273 dev_err(keys->dev, "too many keys defined (%d)\n", keycount); 308 274 return -EINVAL; 309 275 } ··· 312 276 for_each_child_of_node(node, child) { 313 277 keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index]; 314 278 315 - keys->keys[index].irq = platform_get_irq(pdev, index); 279 + keys->keys[index].irq = 280 + platform_get_irq_byname(pdev, irqnames[index]); 316 281 if (keys->keys[index].irq < 0) { 317 282 of_node_put(child); 318 283 return keys->keys[index].irq; 284 + } 285 + 286 + if (of_device_is_compatible(node, "mediatek,mt6358-keys")) { 287 + keys->keys[index].irq_r = platform_get_irq_byname(pdev, 288 + irqnames_r[index]); 289 + 290 + if (keys->keys[index].irq_r < 0) { 291 + of_node_put(child); 292 + return keys->keys[index].irq_r; 293 + } 319 294 } 320 295 321 296 error = of_property_read_u32(child,
+3 -10
drivers/input/misc/da9063_onkey.c
··· 4 4 * Copyright (C) 2015 Dialog Semiconductor Ltd. 5 5 */ 6 6 7 + #include <linux/devm-helpers.h> 7 8 #include <linux/module.h> 8 9 #include <linux/errno.h> 9 10 #include <linux/input.h> ··· 183 182 return IRQ_HANDLED; 184 183 } 185 184 186 - static void da9063_cancel_poll(void *data) 187 - { 188 - struct da9063_onkey *onkey = data; 189 - 190 - cancel_delayed_work_sync(&onkey->work); 191 - } 192 - 193 185 static int da9063_onkey_probe(struct platform_device *pdev) 194 186 { 195 187 struct da9063_onkey *onkey; ··· 228 234 229 235 input_set_capability(onkey->input, EV_KEY, KEY_POWER); 230 236 231 - INIT_DELAYED_WORK(&onkey->work, da9063_poll_on); 232 - 233 - error = devm_add_action(&pdev->dev, da9063_cancel_poll, onkey); 237 + error = devm_delayed_work_autocancel(&pdev->dev, &onkey->work, 238 + da9063_poll_on); 234 239 if (error) { 235 240 dev_err(&pdev->dev, 236 241 "Failed to add cancel poll action: %d\n",
+1
drivers/input/mouse/synaptics.c
··· 186 186 "LEN2044", /* L470 */ 187 187 "LEN2054", /* E480 */ 188 188 "LEN2055", /* E580 */ 189 + "LEN2064", /* T14 Gen 1 AMD / P14s Gen 1 AMD */ 189 190 "LEN2068", /* T14 Gen 1 */ 190 191 "SYN3052", /* HP EliteBook 840 G4 */ 191 192 "SYN3221", /* HP 15-ay000 */
+126 -69
drivers/input/serio/ps2-gpio.c
··· 19 19 #include <linux/of.h> 20 20 #include <linux/jiffies.h> 21 21 #include <linux/delay.h> 22 + #include <linux/timekeeping.h> 22 23 23 24 #define DRIVER_NAME "ps2-gpio" 24 25 ··· 37 36 #define PS2_DATA_BIT7 8 38 37 #define PS2_PARITY_BIT 9 39 38 #define PS2_STOP_BIT 10 40 - #define PS2_TX_TIMEOUT 11 41 - #define PS2_ACK_BIT 12 39 + #define PS2_ACK_BIT 11 42 40 43 41 #define PS2_DEV_RET_ACK 0xfa 44 42 #define PS2_DEV_RET_NACK 0xfe 45 43 46 44 #define PS2_CMD_RESEND 0xfe 45 + 46 + /* 47 + * The PS2 protocol specifies a clock frequency between 10kHz and 16.7kHz, 48 + * therefore the maximal interrupt interval should be 100us and the minimum 49 + * interrupt interval should be ~60us. Let's allow +/- 20us for frequency 50 + * deviations and interrupt latency. 51 + * 52 + * The data line must be samples after ~30us to 50us after the falling edge, 53 + * since the device updates the data line at the rising edge. 54 + * 55 + * ___ ______ ______ ______ ___ 56 + * \ / \ / \ / \ / 57 + * \ / \ / \ / \ / 58 + * \______/ \______/ \______/ \______/ 59 + * 60 + * |-----------------| |--------| 61 + * 60us/100us 30us/50us 62 + */ 63 + #define PS2_CLK_FREQ_MIN_HZ 10000 64 + #define PS2_CLK_FREQ_MAX_HZ 16700 65 + #define PS2_CLK_MIN_INTERVAL_US ((1000 * 1000) / PS2_CLK_FREQ_MAX_HZ) 66 + #define PS2_CLK_MAX_INTERVAL_US ((1000 * 1000) / PS2_CLK_FREQ_MIN_HZ) 67 + #define PS2_IRQ_MIN_INTERVAL_US (PS2_CLK_MIN_INTERVAL_US - 20) 68 + #define PS2_IRQ_MAX_INTERVAL_US (PS2_CLK_MAX_INTERVAL_US + 20) 47 69 48 70 struct ps2_gpio_data { 49 71 struct device *dev; ··· 76 52 struct gpio_desc *gpio_data; 77 53 bool write_enable; 78 54 int irq; 79 - unsigned char rx_cnt; 80 - unsigned char rx_byte; 81 - unsigned char tx_cnt; 82 - unsigned char tx_byte; 83 - struct completion tx_done; 84 - struct mutex tx_mutex; 85 - struct delayed_work tx_work; 55 + ktime_t t_irq_now; 56 + ktime_t t_irq_last; 57 + struct { 58 + unsigned char cnt; 59 + unsigned char byte; 60 + } rx; 61 + struct { 62 + unsigned char cnt; 63 + unsigned char byte; 64 + ktime_t t_xfer_start; 65 + ktime_t t_xfer_end; 66 + struct completion complete; 67 + struct mutex mutex; 68 + struct delayed_work work; 69 + } tx; 86 70 }; 87 71 88 72 static int ps2_gpio_open(struct serio *serio) 89 73 { 90 74 struct ps2_gpio_data *drvdata = serio->port_data; 75 + 76 + drvdata->t_irq_last = 0; 77 + drvdata->tx.t_xfer_end = 0; 91 78 92 79 enable_irq(drvdata->irq); 93 80 return 0; ··· 108 73 { 109 74 struct ps2_gpio_data *drvdata = serio->port_data; 110 75 111 - flush_delayed_work(&drvdata->tx_work); 76 + flush_delayed_work(&drvdata->tx.work); 112 77 disable_irq(drvdata->irq); 113 78 } 114 79 ··· 120 85 gpiod_direction_output(drvdata->gpio_clk, 0); 121 86 122 87 drvdata->mode = PS2_MODE_TX; 123 - drvdata->tx_byte = val; 88 + drvdata->tx.byte = val; 124 89 125 - schedule_delayed_work(&drvdata->tx_work, usecs_to_jiffies(200)); 90 + schedule_delayed_work(&drvdata->tx.work, usecs_to_jiffies(200)); 126 91 127 92 return 0; 128 93 } ··· 133 98 int ret = 0; 134 99 135 100 if (in_task()) { 136 - mutex_lock(&drvdata->tx_mutex); 101 + mutex_lock(&drvdata->tx.mutex); 137 102 __ps2_gpio_write(serio, val); 138 - if (!wait_for_completion_timeout(&drvdata->tx_done, 103 + if (!wait_for_completion_timeout(&drvdata->tx.complete, 139 104 msecs_to_jiffies(10000))) 140 105 ret = SERIO_TIMEOUT; 141 - mutex_unlock(&drvdata->tx_mutex); 106 + mutex_unlock(&drvdata->tx.mutex); 142 107 } else { 143 108 __ps2_gpio_write(serio, val); 144 109 } ··· 150 115 { 151 116 struct delayed_work *dwork = to_delayed_work(work); 152 117 struct ps2_gpio_data *drvdata = container_of(dwork, 153 - struct ps2_gpio_data, 154 - tx_work); 118 + struct ps2_gpio_data, 119 + tx.work); 155 120 121 + drvdata->tx.t_xfer_start = ktime_get(); 156 122 enable_irq(drvdata->irq); 157 123 gpiod_direction_output(drvdata->gpio_data, 0); 158 124 gpiod_direction_input(drvdata->gpio_clk); ··· 164 128 unsigned char byte, cnt; 165 129 int data; 166 130 int rxflags = 0; 167 - static unsigned long old_jiffies; 131 + s64 us_delta; 168 132 169 - byte = drvdata->rx_byte; 170 - cnt = drvdata->rx_cnt; 133 + byte = drvdata->rx.byte; 134 + cnt = drvdata->rx.cnt; 171 135 172 - if (old_jiffies == 0) 173 - old_jiffies = jiffies; 136 + drvdata->t_irq_now = ktime_get(); 174 137 175 - if ((jiffies - old_jiffies) > usecs_to_jiffies(100)) { 138 + /* 139 + * We need to consider spurious interrupts happening right after 140 + * a TX xfer finished. 141 + */ 142 + us_delta = ktime_us_delta(drvdata->t_irq_now, drvdata->tx.t_xfer_end); 143 + if (unlikely(us_delta < PS2_IRQ_MIN_INTERVAL_US)) 144 + goto end; 145 + 146 + us_delta = ktime_us_delta(drvdata->t_irq_now, drvdata->t_irq_last); 147 + if (us_delta > PS2_IRQ_MAX_INTERVAL_US && cnt) { 176 148 dev_err(drvdata->dev, 177 149 "RX: timeout, probably we missed an interrupt\n"); 178 150 goto err; 151 + } else if (unlikely(us_delta < PS2_IRQ_MIN_INTERVAL_US)) { 152 + /* Ignore spurious IRQs. */ 153 + goto end; 179 154 } 180 - old_jiffies = jiffies; 155 + drvdata->t_irq_last = drvdata->t_irq_now; 181 156 182 157 data = gpiod_get_value(drvdata->gpio_data); 183 158 if (unlikely(data < 0)) { ··· 225 178 if (!drvdata->write_enable) 226 179 goto err; 227 180 } 181 + break; 182 + case PS2_STOP_BIT: 183 + /* stop bit should be high */ 184 + if (unlikely(!data)) { 185 + dev_err(drvdata->dev, "RX: stop bit should be high\n"); 186 + goto err; 187 + } 228 188 229 - /* Do not send spurious ACK's and NACK's when write fn is 189 + /* 190 + * Do not send spurious ACK's and NACK's when write fn is 230 191 * not provided. 231 192 */ 232 193 if (!drvdata->write_enable) { ··· 244 189 break; 245 190 } 246 191 247 - /* Let's send the data without waiting for the stop bit to be 248 - * sent. It may happen that we miss the stop bit. When this 249 - * happens we have no way to recover from this, certainly 250 - * missing the parity bit would be recognized when processing 251 - * the stop bit. When missing both, data is lost. 252 - */ 253 192 serio_interrupt(drvdata->serio, byte, rxflags); 254 193 dev_dbg(drvdata->dev, "RX: sending byte 0x%x\n", byte); 255 - break; 256 - case PS2_STOP_BIT: 257 - /* stop bit should be high */ 258 - if (unlikely(!data)) { 259 - dev_err(drvdata->dev, "RX: stop bit should be high\n"); 260 - goto err; 261 - } 194 + 262 195 cnt = byte = 0; 263 - old_jiffies = 0; 196 + 264 197 goto end; /* success */ 265 198 default: 266 199 dev_err(drvdata->dev, "RX: got out of sync with the device\n"); ··· 260 217 261 218 err: 262 219 cnt = byte = 0; 263 - old_jiffies = 0; 264 220 __ps2_gpio_write(drvdata->serio, PS2_CMD_RESEND); 265 221 end: 266 - drvdata->rx_cnt = cnt; 267 - drvdata->rx_byte = byte; 222 + drvdata->rx.cnt = cnt; 223 + drvdata->rx.byte = byte; 268 224 return IRQ_HANDLED; 269 225 } 270 226 ··· 271 229 { 272 230 unsigned char byte, cnt; 273 231 int data; 274 - static unsigned long old_jiffies; 232 + s64 us_delta; 275 233 276 - cnt = drvdata->tx_cnt; 277 - byte = drvdata->tx_byte; 234 + cnt = drvdata->tx.cnt; 235 + byte = drvdata->tx.byte; 278 236 279 - if (old_jiffies == 0) 280 - old_jiffies = jiffies; 237 + drvdata->t_irq_now = ktime_get(); 281 238 282 - if ((jiffies - old_jiffies) > usecs_to_jiffies(100)) { 239 + /* 240 + * There might be pending IRQs since we disabled IRQs in 241 + * __ps2_gpio_write(). We can expect at least one clock period until 242 + * the device generates the first falling edge after releasing the 243 + * clock line. 244 + */ 245 + us_delta = ktime_us_delta(drvdata->t_irq_now, 246 + drvdata->tx.t_xfer_start); 247 + if (unlikely(us_delta < PS2_CLK_MIN_INTERVAL_US)) 248 + goto end; 249 + 250 + us_delta = ktime_us_delta(drvdata->t_irq_now, drvdata->t_irq_last); 251 + if (us_delta > PS2_IRQ_MAX_INTERVAL_US && cnt > 1) { 283 252 dev_err(drvdata->dev, 284 253 "TX: timeout, probably we missed an interrupt\n"); 285 254 goto err; 255 + } else if (unlikely(us_delta < PS2_IRQ_MIN_INTERVAL_US)) { 256 + /* Ignore spurious IRQs. */ 257 + goto end; 286 258 } 287 - old_jiffies = jiffies; 259 + drvdata->t_irq_last = drvdata->t_irq_now; 288 260 289 261 switch (cnt) { 290 262 case PS2_START_BIT: ··· 326 270 /* release data line to generate stop bit */ 327 271 gpiod_direction_input(drvdata->gpio_data); 328 272 break; 329 - case PS2_TX_TIMEOUT: 330 - /* Devices generate one extra clock pulse before sending the 331 - * acknowledgment. 332 - */ 333 - break; 334 273 case PS2_ACK_BIT: 335 - gpiod_direction_input(drvdata->gpio_data); 336 274 data = gpiod_get_value(drvdata->gpio_data); 337 275 if (data) { 338 276 dev_warn(drvdata->dev, "TX: received NACK, retry\n"); 339 277 goto err; 340 278 } 341 279 280 + drvdata->tx.t_xfer_end = ktime_get(); 342 281 drvdata->mode = PS2_MODE_RX; 343 - complete(&drvdata->tx_done); 282 + complete(&drvdata->tx.complete); 344 283 345 284 cnt = 1; 346 - old_jiffies = 0; 347 285 goto end; /* success */ 348 286 default: 349 - /* Probably we missed the stop bit. Therefore we release data 287 + /* 288 + * Probably we missed the stop bit. Therefore we release data 350 289 * line and try again. 351 290 */ 352 291 gpiod_direction_input(drvdata->gpio_data); ··· 354 303 355 304 err: 356 305 cnt = 1; 357 - old_jiffies = 0; 358 306 gpiod_direction_input(drvdata->gpio_data); 359 - __ps2_gpio_write(drvdata->serio, drvdata->tx_byte); 307 + __ps2_gpio_write(drvdata->serio, drvdata->tx.byte); 360 308 end: 361 - drvdata->tx_cnt = cnt; 309 + drvdata->tx.cnt = cnt; 362 310 return IRQ_HANDLED; 363 311 } 364 312 ··· 372 322 static int ps2_gpio_get_props(struct device *dev, 373 323 struct ps2_gpio_data *drvdata) 374 324 { 375 - drvdata->gpio_data = devm_gpiod_get(dev, "data", GPIOD_IN); 325 + enum gpiod_flags gflags; 326 + 327 + /* Enforce open drain, since this is required by the PS/2 bus. */ 328 + gflags = GPIOD_IN | GPIOD_FLAGS_BIT_OPEN_DRAIN; 329 + 330 + drvdata->gpio_data = devm_gpiod_get(dev, "data", gflags); 376 331 if (IS_ERR(drvdata->gpio_data)) { 377 332 dev_err(dev, "failed to request data gpio: %ld", 378 333 PTR_ERR(drvdata->gpio_data)); 379 334 return PTR_ERR(drvdata->gpio_data); 380 335 } 381 336 382 - drvdata->gpio_clk = devm_gpiod_get(dev, "clk", GPIOD_IN); 337 + drvdata->gpio_clk = devm_gpiod_get(dev, "clk", gflags); 383 338 if (IS_ERR(drvdata->gpio_clk)) { 384 339 dev_err(dev, "failed to request clock gpio: %ld", 385 340 PTR_ERR(drvdata->gpio_clk)); ··· 442 387 serio->id.type = SERIO_8042; 443 388 serio->open = ps2_gpio_open; 444 389 serio->close = ps2_gpio_close; 445 - /* Write can be enabled in platform/dt data, but possibly it will not 390 + /* 391 + * Write can be enabled in platform/dt data, but possibly it will not 446 392 * work because of the tough timings. 447 393 */ 448 394 serio->write = drvdata->write_enable ? ps2_gpio_write : NULL; ··· 456 400 drvdata->dev = dev; 457 401 drvdata->mode = PS2_MODE_RX; 458 402 459 - /* Tx count always starts at 1, as the start bit is sent implicitly by 403 + /* 404 + * Tx count always starts at 1, as the start bit is sent implicitly by 460 405 * host-to-device communication initialization. 461 406 */ 462 - drvdata->tx_cnt = 1; 407 + drvdata->tx.cnt = 1; 463 408 464 - INIT_DELAYED_WORK(&drvdata->tx_work, ps2_gpio_tx_work_fn); 465 - init_completion(&drvdata->tx_done); 466 - mutex_init(&drvdata->tx_mutex); 409 + INIT_DELAYED_WORK(&drvdata->tx.work, ps2_gpio_tx_work_fn); 410 + init_completion(&drvdata->tx.complete); 411 + mutex_init(&drvdata->tx.mutex); 467 412 468 413 serio_register_port(serio); 469 414 platform_set_drvdata(pdev, drvdata);
+10
drivers/input/touchscreen/Kconfig
··· 638 638 To compile this driver as a module, choose M here: the 639 639 module will be called mtouch. 640 640 641 + config TOUCHSCREEN_IMAGIS 642 + tristate "Imagis touchscreen support" 643 + depends on I2C 644 + help 645 + Say Y here if you have an Imagis IST30xxC touchscreen. 646 + If unsure, say N. 647 + 648 + To compile this driver as a module, choose M here: the 649 + module will be called imagis. 650 + 641 651 config TOUCHSCREEN_IMX6UL_TSC 642 652 tristate "Freescale i.MX6UL touchscreen controller" 643 653 depends on ((OF && GPIOLIB) || COMPILE_TEST) && HAS_IOMEM
+1
drivers/input/touchscreen/Makefile
··· 49 49 obj-$(CONFIG_TOUCHSCREEN_HIDEEP) += hideep.o 50 50 obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o 51 51 obj-$(CONFIG_TOUCHSCREEN_ILITEK) += ilitek_ts_i2c.o 52 + obj-$(CONFIG_TOUCHSCREEN_IMAGIS) += imagis.o 52 53 obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o 53 54 obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o 54 55 obj-$(CONFIG_TOUCHSCREEN_IPROC) += bcm_iproc_tsc.o
+31 -30
drivers/input/touchscreen/goodix.c
··· 298 298 return -ENOMSG; 299 299 } 300 300 301 - static struct input_dev *goodix_create_pen_input(struct goodix_ts_data *ts) 301 + static int goodix_create_pen_input(struct goodix_ts_data *ts) 302 302 { 303 303 struct device *dev = &ts->client->dev; 304 304 struct input_dev *input; 305 305 306 306 input = devm_input_allocate_device(dev); 307 307 if (!input) 308 - return NULL; 308 + return -ENOMEM; 309 309 310 - input_alloc_absinfo(input); 311 - if (!input->absinfo) { 312 - input_free_device(input); 313 - return NULL; 314 - } 315 - 316 - input->absinfo[ABS_X] = ts->input_dev->absinfo[ABS_MT_POSITION_X]; 317 - input->absinfo[ABS_Y] = ts->input_dev->absinfo[ABS_MT_POSITION_Y]; 318 - __set_bit(ABS_X, input->absbit); 319 - __set_bit(ABS_Y, input->absbit); 320 - input_set_abs_params(input, ABS_PRESSURE, 0, 255, 0, 0); 321 - 322 - input_set_capability(input, EV_KEY, BTN_TOUCH); 323 - input_set_capability(input, EV_KEY, BTN_TOOL_PEN); 324 - input_set_capability(input, EV_KEY, BTN_STYLUS); 325 - input_set_capability(input, EV_KEY, BTN_STYLUS2); 326 - __set_bit(INPUT_PROP_DIRECT, input->propbit); 310 + input_copy_abs(input, ABS_X, ts->input_dev, ABS_MT_POSITION_X); 311 + input_copy_abs(input, ABS_Y, ts->input_dev, ABS_MT_POSITION_Y); 327 312 /* 328 313 * The resolution of these touchscreens is about 10 units/mm, the actual 329 314 * resolution does not matter much since we set INPUT_PROP_DIRECT. ··· 316 331 */ 317 332 input_abs_set_res(input, ABS_X, 10); 318 333 input_abs_set_res(input, ABS_Y, 10); 334 + input_set_abs_params(input, ABS_PRESSURE, 0, 255, 0, 0); 335 + 336 + input_set_capability(input, EV_KEY, BTN_TOUCH); 337 + input_set_capability(input, EV_KEY, BTN_TOOL_PEN); 338 + input_set_capability(input, EV_KEY, BTN_STYLUS); 339 + input_set_capability(input, EV_KEY, BTN_STYLUS2); 340 + __set_bit(INPUT_PROP_DIRECT, input->propbit); 319 341 320 342 input->name = "Goodix Active Pen"; 321 343 input->phys = "input/pen"; ··· 332 340 input->id.product = 0x1001; 333 341 input->id.version = ts->version; 334 342 335 - if (input_register_device(input) != 0) { 336 - input_free_device(input); 337 - return NULL; 338 - } 339 - 340 - return input; 343 + ts->input_pen = input; 344 + return 0; 341 345 } 342 346 343 347 static void goodix_ts_report_pen_down(struct goodix_ts_data *ts, u8 *data) 344 348 { 345 - int input_x, input_y, input_w; 349 + int input_x, input_y, input_w, error; 346 350 u8 key_value; 347 351 348 - if (!ts->input_pen) { 349 - ts->input_pen = goodix_create_pen_input(ts); 350 - if (!ts->input_pen) 351 - return; 352 + if (!ts->pen_input_registered) { 353 + error = input_register_device(ts->input_pen); 354 + ts->pen_input_registered = (error == 0) ? 1 : error; 352 355 } 356 + 357 + if (ts->pen_input_registered < 0) 358 + return; 353 359 354 360 if (ts->contact_size == 9) { 355 361 input_x = get_unaligned_le16(&data[4]); ··· 1204 1214 "Failed to register input device: %d", error); 1205 1215 return error; 1206 1216 } 1217 + 1218 + /* 1219 + * Create the input_pen device before goodix_request_irq() calls 1220 + * devm_request_threaded_irq() so that the devm framework frees 1221 + * it after disabling the irq. 1222 + * Unfortunately there is no way to detect if the touchscreen has pen 1223 + * support, so registering the dev is delayed till the first pen event. 1224 + */ 1225 + error = goodix_create_pen_input(ts); 1226 + if (error) 1227 + return error; 1207 1228 1208 1229 ts->irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; 1209 1230 error = goodix_request_irq(ts);
+1
drivers/input/touchscreen/goodix.h
··· 94 94 u16 version; 95 95 bool reset_controller_at_probe; 96 96 bool load_cfg_from_disk; 97 + int pen_input_registered; 97 98 struct completion firmware_loading_complete; 98 99 unsigned long irq_flags; 99 100 enum goodix_irq_pin_access_method irq_pin_access_method;
+367
drivers/input/touchscreen/imagis.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #include <linux/bits.h> 4 + #include <linux/delay.h> 5 + #include <linux/i2c.h> 6 + #include <linux/input.h> 7 + #include <linux/input/mt.h> 8 + #include <linux/input/touchscreen.h> 9 + #include <linux/kernel.h> 10 + #include <linux/module.h> 11 + #include <linux/property.h> 12 + #include <linux/regulator/consumer.h> 13 + 14 + #define IST3038C_HIB_ACCESS (0x800B << 16) 15 + #define IST3038C_DIRECT_ACCESS BIT(31) 16 + #define IST3038C_REG_CHIPID 0x40001000 17 + #define IST3038C_REG_HIB_BASE 0x30000100 18 + #define IST3038C_REG_TOUCH_STATUS (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS) 19 + #define IST3038C_REG_TOUCH_COORD (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS | 0x8) 20 + #define IST3038C_REG_INTR_MESSAGE (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS | 0x4) 21 + #define IST3038C_WHOAMI 0x38c 22 + #define IST3038C_CHIP_ON_DELAY_MS 60 23 + #define IST3038C_I2C_RETRY_COUNT 3 24 + #define IST3038C_MAX_FINGER_NUM 10 25 + #define IST3038C_X_MASK GENMASK(23, 12) 26 + #define IST3038C_X_SHIFT 12 27 + #define IST3038C_Y_MASK GENMASK(11, 0) 28 + #define IST3038C_AREA_MASK GENMASK(27, 24) 29 + #define IST3038C_AREA_SHIFT 24 30 + #define IST3038C_FINGER_COUNT_MASK GENMASK(15, 12) 31 + #define IST3038C_FINGER_COUNT_SHIFT 12 32 + #define IST3038C_FINGER_STATUS_MASK GENMASK(9, 0) 33 + 34 + struct imagis_ts { 35 + struct i2c_client *client; 36 + struct input_dev *input_dev; 37 + struct touchscreen_properties prop; 38 + struct regulator_bulk_data supplies[2]; 39 + }; 40 + 41 + static int imagis_i2c_read_reg(struct imagis_ts *ts, 42 + unsigned int reg, u32 *data) 43 + { 44 + __be32 ret_be; 45 + __be32 reg_be = cpu_to_be32(reg); 46 + struct i2c_msg msg[] = { 47 + { 48 + .addr = ts->client->addr, 49 + .flags = 0, 50 + .buf = (unsigned char *)&reg_be, 51 + .len = sizeof(reg_be), 52 + }, { 53 + .addr = ts->client->addr, 54 + .flags = I2C_M_RD, 55 + .buf = (unsigned char *)&ret_be, 56 + .len = sizeof(ret_be), 57 + }, 58 + }; 59 + int ret, error; 60 + int retry = IST3038C_I2C_RETRY_COUNT; 61 + 62 + /* Retry in case the controller fails to respond */ 63 + do { 64 + ret = i2c_transfer(ts->client->adapter, msg, ARRAY_SIZE(msg)); 65 + if (ret == ARRAY_SIZE(msg)) { 66 + *data = be32_to_cpu(ret_be); 67 + return 0; 68 + } 69 + 70 + error = ret < 0 ? ret : -EIO; 71 + dev_err(&ts->client->dev, 72 + "%s - i2c_transfer failed: %d (%d)\n", 73 + __func__, error, ret); 74 + } while (--retry); 75 + 76 + return error; 77 + } 78 + 79 + static irqreturn_t imagis_interrupt(int irq, void *dev_id) 80 + { 81 + struct imagis_ts *ts = dev_id; 82 + u32 intr_message, finger_status; 83 + unsigned int finger_count, finger_pressed; 84 + int i; 85 + int error; 86 + 87 + error = imagis_i2c_read_reg(ts, IST3038C_REG_INTR_MESSAGE, 88 + &intr_message); 89 + if (error) { 90 + dev_err(&ts->client->dev, 91 + "failed to read the interrupt message: %d\n", error); 92 + goto out; 93 + } 94 + 95 + finger_count = (intr_message & IST3038C_FINGER_COUNT_MASK) >> 96 + IST3038C_FINGER_COUNT_SHIFT; 97 + if (finger_count > IST3038C_MAX_FINGER_NUM) { 98 + dev_err(&ts->client->dev, 99 + "finger count %d is more than maximum supported\n", 100 + finger_count); 101 + goto out; 102 + } 103 + 104 + finger_pressed = intr_message & IST3038C_FINGER_STATUS_MASK; 105 + 106 + for (i = 0; i < finger_count; i++) { 107 + error = imagis_i2c_read_reg(ts, 108 + IST3038C_REG_TOUCH_COORD + (i * 4), 109 + &finger_status); 110 + if (error) { 111 + dev_err(&ts->client->dev, 112 + "failed to read coordinates for finger %d: %d\n", 113 + i, error); 114 + goto out; 115 + } 116 + 117 + input_mt_slot(ts->input_dev, i); 118 + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 119 + finger_pressed & BIT(i)); 120 + touchscreen_report_pos(ts->input_dev, &ts->prop, 121 + (finger_status & IST3038C_X_MASK) >> 122 + IST3038C_X_SHIFT, 123 + finger_status & IST3038C_Y_MASK, 1); 124 + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 125 + (finger_status & IST3038C_AREA_MASK) >> 126 + IST3038C_AREA_SHIFT); 127 + } 128 + 129 + input_mt_sync_frame(ts->input_dev); 130 + input_sync(ts->input_dev); 131 + 132 + out: 133 + return IRQ_HANDLED; 134 + } 135 + 136 + static void imagis_power_off(void *_ts) 137 + { 138 + struct imagis_ts *ts = _ts; 139 + 140 + regulator_bulk_disable(ARRAY_SIZE(ts->supplies), ts->supplies); 141 + } 142 + 143 + static int imagis_power_on(struct imagis_ts *ts) 144 + { 145 + int error; 146 + 147 + error = regulator_bulk_enable(ARRAY_SIZE(ts->supplies), ts->supplies); 148 + if (error) 149 + return error; 150 + 151 + msleep(IST3038C_CHIP_ON_DELAY_MS); 152 + 153 + return 0; 154 + } 155 + 156 + static int imagis_start(struct imagis_ts *ts) 157 + { 158 + int error; 159 + 160 + error = imagis_power_on(ts); 161 + if (error) 162 + return error; 163 + 164 + enable_irq(ts->client->irq); 165 + 166 + return 0; 167 + } 168 + 169 + static int imagis_stop(struct imagis_ts *ts) 170 + { 171 + disable_irq(ts->client->irq); 172 + 173 + imagis_power_off(ts); 174 + 175 + return 0; 176 + } 177 + 178 + static int imagis_input_open(struct input_dev *dev) 179 + { 180 + struct imagis_ts *ts = input_get_drvdata(dev); 181 + 182 + return imagis_start(ts); 183 + } 184 + 185 + static void imagis_input_close(struct input_dev *dev) 186 + { 187 + struct imagis_ts *ts = input_get_drvdata(dev); 188 + 189 + imagis_stop(ts); 190 + } 191 + 192 + static int imagis_init_input_dev(struct imagis_ts *ts) 193 + { 194 + struct input_dev *input_dev; 195 + int error; 196 + 197 + input_dev = devm_input_allocate_device(&ts->client->dev); 198 + if (!input_dev) 199 + return -ENOMEM; 200 + 201 + ts->input_dev = input_dev; 202 + 203 + input_dev->name = "Imagis capacitive touchscreen"; 204 + input_dev->phys = "input/ts"; 205 + input_dev->id.bustype = BUS_I2C; 206 + input_dev->open = imagis_input_open; 207 + input_dev->close = imagis_input_close; 208 + 209 + input_set_drvdata(input_dev, ts); 210 + 211 + input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X); 212 + input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y); 213 + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); 214 + 215 + touchscreen_parse_properties(input_dev, true, &ts->prop); 216 + if (!ts->prop.max_x || !ts->prop.max_y) { 217 + dev_err(&ts->client->dev, 218 + "Touchscreen-size-x and/or touchscreen-size-y not set in dts\n"); 219 + return -EINVAL; 220 + } 221 + 222 + error = input_mt_init_slots(input_dev, 223 + IST3038C_MAX_FINGER_NUM, 224 + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); 225 + if (error) { 226 + dev_err(&ts->client->dev, 227 + "Failed to initialize MT slots: %d", error); 228 + return error; 229 + } 230 + 231 + error = input_register_device(input_dev); 232 + if (error) { 233 + dev_err(&ts->client->dev, 234 + "Failed to register input device: %d", error); 235 + return error; 236 + } 237 + 238 + return 0; 239 + } 240 + 241 + static int imagis_init_regulators(struct imagis_ts *ts) 242 + { 243 + struct i2c_client *client = ts->client; 244 + 245 + ts->supplies[0].supply = "vdd"; 246 + ts->supplies[1].supply = "vddio"; 247 + return devm_regulator_bulk_get(&client->dev, 248 + ARRAY_SIZE(ts->supplies), 249 + ts->supplies); 250 + } 251 + 252 + static int imagis_probe(struct i2c_client *i2c) 253 + { 254 + struct device *dev = &i2c->dev; 255 + struct imagis_ts *ts; 256 + int chip_id, error; 257 + 258 + ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); 259 + if (!ts) 260 + return -ENOMEM; 261 + 262 + ts->client = i2c; 263 + 264 + error = imagis_init_regulators(ts); 265 + if (error) { 266 + dev_err(dev, "regulator init error: %d\n", error); 267 + return error; 268 + } 269 + 270 + error = imagis_power_on(ts); 271 + if (error) { 272 + dev_err(dev, "failed to enable regulators: %d\n", error); 273 + return error; 274 + } 275 + 276 + error = devm_add_action_or_reset(dev, imagis_power_off, ts); 277 + if (error) { 278 + dev_err(dev, "failed to install poweroff action: %d\n", error); 279 + return error; 280 + } 281 + 282 + error = imagis_i2c_read_reg(ts, 283 + IST3038C_REG_CHIPID | IST3038C_DIRECT_ACCESS, 284 + &chip_id); 285 + if (error) { 286 + dev_err(dev, "chip ID read failure: %d\n", error); 287 + return error; 288 + } 289 + 290 + if (chip_id != IST3038C_WHOAMI) { 291 + dev_err(dev, "unknown chip ID: 0x%x\n", chip_id); 292 + return -EINVAL; 293 + } 294 + 295 + error = devm_request_threaded_irq(dev, i2c->irq, 296 + NULL, imagis_interrupt, 297 + IRQF_ONESHOT | IRQF_NO_AUTOEN, 298 + "imagis-touchscreen", ts); 299 + if (error) { 300 + dev_err(dev, "IRQ %d allocation failure: %d\n", 301 + i2c->irq, error); 302 + return error; 303 + } 304 + 305 + error = imagis_init_input_dev(ts); 306 + if (error) 307 + return error; 308 + 309 + return 0; 310 + } 311 + 312 + static int __maybe_unused imagis_suspend(struct device *dev) 313 + { 314 + struct i2c_client *client = to_i2c_client(dev); 315 + struct imagis_ts *ts = i2c_get_clientdata(client); 316 + int retval = 0; 317 + 318 + mutex_lock(&ts->input_dev->mutex); 319 + 320 + if (input_device_enabled(ts->input_dev)) 321 + retval = imagis_stop(ts); 322 + 323 + mutex_unlock(&ts->input_dev->mutex); 324 + 325 + return retval; 326 + } 327 + 328 + static int __maybe_unused imagis_resume(struct device *dev) 329 + { 330 + struct i2c_client *client = to_i2c_client(dev); 331 + struct imagis_ts *ts = i2c_get_clientdata(client); 332 + int retval = 0; 333 + 334 + mutex_lock(&ts->input_dev->mutex); 335 + 336 + if (input_device_enabled(ts->input_dev)) 337 + retval = imagis_start(ts); 338 + 339 + mutex_unlock(&ts->input_dev->mutex); 340 + 341 + return retval; 342 + } 343 + 344 + static SIMPLE_DEV_PM_OPS(imagis_pm_ops, imagis_suspend, imagis_resume); 345 + 346 + #ifdef CONFIG_OF 347 + static const struct of_device_id imagis_of_match[] = { 348 + { .compatible = "imagis,ist3038c", }, 349 + { }, 350 + }; 351 + MODULE_DEVICE_TABLE(of, imagis_of_match); 352 + #endif 353 + 354 + static struct i2c_driver imagis_ts_driver = { 355 + .driver = { 356 + .name = "imagis-touchscreen", 357 + .pm = &imagis_pm_ops, 358 + .of_match_table = of_match_ptr(imagis_of_match), 359 + }, 360 + .probe_new = imagis_probe, 361 + }; 362 + 363 + module_i2c_driver(imagis_ts_driver); 364 + 365 + MODULE_DESCRIPTION("Imagis IST3038C Touchscreen Driver"); 366 + MODULE_AUTHOR("Markuss Broks <markuss.broks@gmail.com>"); 367 + MODULE_LICENSE("GPL");
+8 -8
drivers/input/touchscreen/iqs5xx.c
··· 486 486 { 487 487 struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client); 488 488 struct touchscreen_properties *prop = &iqs5xx->prop; 489 - struct input_dev *input; 489 + struct input_dev *input = iqs5xx->input; 490 490 u16 max_x, max_y; 491 491 int error; 492 492 493 - if (!iqs5xx->input) { 493 + if (!input) { 494 494 input = devm_input_allocate_device(&client->dev); 495 495 if (!input) 496 496 return -ENOMEM; ··· 512 512 if (error) 513 513 return error; 514 514 515 - input_set_abs_params(iqs5xx->input, ABS_MT_POSITION_X, 0, max_x, 0, 0); 516 - input_set_abs_params(iqs5xx->input, ABS_MT_POSITION_Y, 0, max_y, 0, 0); 517 - input_set_abs_params(iqs5xx->input, ABS_MT_PRESSURE, 0, U16_MAX, 0, 0); 515 + input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_x, 0, 0); 516 + input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_y, 0, 0); 517 + input_set_abs_params(input, ABS_MT_PRESSURE, 0, U16_MAX, 0, 0); 518 518 519 - touchscreen_parse_properties(iqs5xx->input, true, prop); 519 + touchscreen_parse_properties(input, true, prop); 520 520 521 521 /* 522 522 * The device reserves 0xFFFF for coordinates that correspond to slots ··· 540 540 return error; 541 541 } 542 542 543 - error = input_mt_init_slots(iqs5xx->input, IQS5XX_NUM_CONTACTS, 543 + error = input_mt_init_slots(input, IQS5XX_NUM_CONTACTS, 544 544 INPUT_MT_DIRECT); 545 545 if (error) 546 546 dev_err(&client->dev, "Failed to initialize slots: %d\n", ··· 674 674 input_mt_slot(input, i); 675 675 if (input_mt_report_slot_state(input, MT_TOOL_FINGER, 676 676 pressure != 0)) { 677 - touchscreen_report_pos(iqs5xx->input, &iqs5xx->prop, 677 + touchscreen_report_pos(input, &iqs5xx->prop, 678 678 be16_to_cpu(touch_data->abs_x), 679 679 be16_to_cpu(touch_data->abs_y), 680 680 true);
+5 -3
drivers/input/touchscreen/stmfts.c
··· 339 339 340 340 err = pm_runtime_get_sync(&sdata->client->dev); 341 341 if (err < 0) 342 - return err; 342 + goto out; 343 343 344 344 err = i2c_smbus_write_byte(sdata->client, STMFTS_MS_MT_SENSE_ON); 345 345 if (err) 346 - return err; 346 + goto out; 347 347 348 348 mutex_lock(&sdata->mutex); 349 349 sdata->running = true; ··· 366 366 "failed to enable touchkey\n"); 367 367 } 368 368 369 - return 0; 369 + out: 370 + pm_runtime_put_noidle(&sdata->client->dev); 371 + return err; 370 372 } 371 373 372 374 static void stmfts_input_close(struct input_dev *dev)
+4 -3
drivers/input/touchscreen/tsc200x-core.c
··· 88 88 int in_z1; 89 89 int in_z2; 90 90 91 + struct touchscreen_properties prop; 92 + 91 93 spinlock_t lock; 92 94 struct timer_list penup_timer; 93 95 ··· 115 113 int x, int y, int pressure) 116 114 { 117 115 if (pressure) { 118 - input_report_abs(ts->idev, ABS_X, x); 119 - input_report_abs(ts->idev, ABS_Y, y); 116 + touchscreen_report_pos(ts->idev, &ts->prop, x, y, false); 120 117 input_report_abs(ts->idev, ABS_PRESSURE, pressure); 121 118 if (!ts->pen_down) { 122 119 input_report_key(ts->idev, BTN_TOUCH, !!pressure); ··· 534 533 input_set_abs_params(input_dev, ABS_PRESSURE, 535 534 0, MAX_12BIT, TSC200X_DEF_P_FUZZ, 0); 536 535 537 - touchscreen_parse_properties(input_dev, false, NULL); 536 + touchscreen_parse_properties(input_dev, false, &ts->prop); 538 537 539 538 /* Ensure the touchscreen is off */ 540 539 tsc200x_stop_scan(ts);
+39
drivers/input/vivaldi-fmap.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Helpers for ChromeOS Vivaldi keyboard function row mapping 4 + * 5 + * Copyright (C) 2022 Google, Inc 6 + */ 7 + 8 + #include <linux/export.h> 9 + #include <linux/input/vivaldi-fmap.h> 10 + #include <linux/kernel.h> 11 + #include <linux/module.h> 12 + #include <linux/types.h> 13 + 14 + /** 15 + * vivaldi_function_row_physmap_show - Print vivaldi function row physmap attribute 16 + * @data: The vivaldi function row map 17 + * @buf: Buffer to print the function row phsymap to 18 + */ 19 + ssize_t vivaldi_function_row_physmap_show(const struct vivaldi_data *data, 20 + char *buf) 21 + { 22 + ssize_t size = 0; 23 + int i; 24 + const u32 *physmap = data->function_row_physmap; 25 + 26 + if (!data->num_function_row_keys) 27 + return 0; 28 + 29 + for (i = 0; i < data->num_function_row_keys; i++) 30 + size += scnprintf(buf + size, PAGE_SIZE - size, 31 + "%s%02X", size ? " " : "", physmap[i]); 32 + if (size) 33 + size += scnprintf(buf + size, PAGE_SIZE - size, "\n"); 34 + 35 + return size; 36 + } 37 + EXPORT_SYMBOL_GPL(vivaldi_function_row_physmap_show); 38 + 39 + MODULE_LICENSE("GPL");
+2
include/linux/input.h
··· 475 475 void input_alloc_absinfo(struct input_dev *dev); 476 476 void input_set_abs_params(struct input_dev *dev, unsigned int axis, 477 477 int min, int max, int fuzz, int flat); 478 + void input_copy_abs(struct input_dev *dst, unsigned int dst_axis, 479 + const struct input_dev *src, unsigned int src_axis); 478 480 479 481 #define INPUT_GENERATE_ABS_ACCESSORS(_suffix, _item) \ 480 482 static inline int input_abs_get_##_suffix(struct input_dev *dev, \
+27
include/linux/input/vivaldi-fmap.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _VIVALDI_FMAP_H 3 + #define _VIVALDI_FMAP_H 4 + 5 + #include <linux/types.h> 6 + 7 + #define VIVALDI_MAX_FUNCTION_ROW_KEYS 24 8 + 9 + /** 10 + * struct vivaldi_data - Function row map data for ChromeOS Vivaldi keyboards 11 + * @function_row_physmap: An array of scancodes or their equivalent (HID usage 12 + * codes, encoded rows/columns, etc) for the top 13 + * row function keys, in an order from left to right 14 + * @num_function_row_keys: The number of top row keys in a custom keyboard 15 + * 16 + * This structure is supposed to be used by ChromeOS keyboards using 17 + * the Vivaldi keyboard function row design. 18 + */ 19 + struct vivaldi_data { 20 + u32 function_row_physmap[VIVALDI_MAX_FUNCTION_ROW_KEYS]; 21 + unsigned int num_function_row_keys; 22 + }; 23 + 24 + ssize_t vivaldi_function_row_physmap_show(const struct vivaldi_data *data, 25 + char *buf); 26 + 27 + #endif /* _VIVALDI_FMAP_H */