Prepare input updates for 5.10 merge window.
Unified · Split
| @@ -0,0 +1,121 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | ||
| 2 | # Copyright 2019-2020 Artur Rojek | ||
| 3 | %YAML 1.2 | ||
| 4 | --- | ||
| 5 | $id: "http://devicetree.org/schemas/input/adc-joystick.yaml#" | ||
| 6 | $schema: "http://devicetree.org/meta-schemas/core.yaml#" | ||
| 7 | |||
| 8 | title: ADC attached joystick | ||
| 9 | |||
| 10 | maintainers: | ||
| 11 | - Artur Rojek <contact@artur-rojek.eu> | ||
| 12 | |||
| 13 | description: > | ||
| 14 | Bindings for joystick devices connected to ADC controllers supporting | ||
| 15 | the Industrial I/O subsystem. | ||
| 16 | |||
| 17 | properties: | ||
| 18 | compatible: | ||
| 19 | const: adc-joystick | ||
| 20 | |||
| 21 | io-channels: | ||
| 22 | minItems: 1 | ||
| 23 | maxItems: 1024 | ||
| 24 | description: > | ||
| 25 | List of phandle and IIO specifier pairs. | ||
| 26 | Each pair defines one ADC channel to which a joystick axis is connected. | ||
| 27 | See Documentation/devicetree/bindings/iio/iio-bindings.txt for details. | ||
| 28 | |||
| 29 | '#address-cells': | ||
| 30 | const: 1 | ||
| 31 | |||
| 32 | '#size-cells': | ||
| 33 | const: 0 | ||
| 34 | |||
| 35 | required: | ||
| 36 | - compatible | ||
| 37 | - io-channels | ||
| 38 | - '#address-cells' | ||
| 39 | - '#size-cells' | ||
| 40 | |||
| 41 | additionalProperties: false | ||
| 42 | |||
| 43 | patternProperties: | ||
| 44 | "^axis@[0-9a-f]+$": | ||
| 45 | type: object | ||
| 46 | description: > | ||
| 47 | Represents a joystick axis bound to the given ADC channel. | ||
| 48 | For each entry in the io-channels list, one axis subnode with a matching | ||
| 49 | reg property must be specified. | ||
| 50 | |||
| 51 | properties: | ||
| 52 | reg: | ||
| 53 | minimum: 0 | ||
| 54 | maximum: 1023 | ||
| 55 | description: Index of an io-channels list entry bound to this axis. | ||
| 56 | |||
| 57 | linux,code: | ||
| 58 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 59 | description: EV_ABS specific event code generated by the axis. | ||
| 60 | |||
| 61 | abs-range: | ||
| 62 | allOf: | ||
| 63 | - $ref: /schemas/types.yaml#/definitions/uint32-array | ||
| 64 | - items: | ||
| 65 | - description: minimum value | ||
| 66 | - description: maximum value | ||
| 67 | description: > | ||
| 68 | Minimum and maximum values produced by the axis. | ||
| 69 | For an ABS_X axis this will be the left-most and right-most | ||
| 70 | inclination of the joystick. If min > max, it is left to userspace to | ||
| 71 | treat the axis as inverted. | ||
| 72 | This property is interpreted as two signed 32 bit values. | ||
| 73 | |||
| 74 | abs-fuzz: | ||
| 75 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 76 | description: > | ||
| 77 | Amount of noise in the input value. | ||
| 78 | Omitting this property indicates the axis is precise. | ||
| 79 | |||
| 80 | abs-flat: | ||
| 81 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 82 | description: > | ||
| 83 | Axial "deadzone", or area around the center position, where the axis | ||
| 84 | is considered to be at rest. | ||
| 85 | Omitting this property indicates the axis always returns to exactly | ||
| 86 | the center position. | ||
| 87 | |||
| 88 | required: | ||
| 89 | - reg | ||
| 90 | - linux,code | ||
| 91 | - abs-range | ||
| 92 | |||
| 93 | additionalProperties: false | ||
| 94 | |||
| 95 | examples: | ||
| 96 | - | | ||
| 97 | #include <dt-bindings/iio/adc/ingenic,adc.h> | ||
| 98 | #include <dt-bindings/input/input.h> | ||
| 99 | |||
| 100 | joystick: adc-joystick { | ||
| 101 | compatible = "adc-joystick"; | ||
| 102 | io-channels = <&adc INGENIC_ADC_TOUCH_XP>, | ||
| 103 | <&adc INGENIC_ADC_TOUCH_YP>; | ||
| 104 | #address-cells = <1>; | ||
| 105 | #size-cells = <0>; | ||
| 106 | |||
| 107 | axis@0 { | ||
| 108 | reg = <0>; | ||
| 109 | linux,code = <ABS_X>; | ||
| 110 | abs-range = <3300 0>; | ||
| 111 | abs-fuzz = <4>; | ||
| 112 | abs-flat = <200>; | ||
| 113 | }; | ||
| 114 | axis@1 { | ||
| 115 | reg = <1>; | ||
| 116 | linux,code = <ABS_Y>; | ||
| 117 | abs-range = <0 3300>; | ||
| 118 | abs-fuzz = <4>; | ||
| 119 | abs-flat = <200>; | ||
| 120 | }; | ||
| 121 | }; | ||
| @@ -0,0 +1,40 @@ | |||
| 1 | Device tree bindings for Zinitx BT541 touchscreen controller | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | |||
| 5 | - compatible : Should be "zinitix,bt541" | ||
| 6 | - reg : I2C address of the chip. Should be 0x20 | ||
| 7 | - interrupts : Interrupt to which the chip is connected | ||
| 8 | |||
| 9 | Optional properties: | ||
| 10 | |||
| 11 | - vdd-supply : Analog power supply regulator on VCCA pin | ||
| 12 | - vddo-supply : Digital power supply regulator on VDD pin | ||
| 13 | - zinitix,mode : Mode of reporting touch points. Some modes may not work | ||
| 14 | with a particular ts firmware for unknown reasons. Available | ||
| 15 | modes are 1 and 2. Mode 2 is the default and preferred. | ||
| 16 | |||
| 17 | The touchscreen-* properties are documented in touchscreen.txt in this | ||
| 18 | directory. | ||
| 19 | |||
| 20 | Example: | ||
| 21 | |||
| 22 | i2c@00000000 { | ||
| 23 | /* ... */ | ||
| 24 | |||
| 25 | bt541@20 { | ||
| 26 | compatible = "zinitix,bt541"; | ||
| 27 | reg = <0x20>; | ||
| 28 | interrupt-parent = <&msmgpio>; | ||
| 29 | interrupts = <13 IRQ_TYPE_EDGE_FALLING>; | ||
| 30 | pinctrl-names = "default"; | ||
| 31 | pinctrl-0 = <&tsp_default>; | ||
| 32 | vdd-supply = <®_vdd_tsp>; | ||
| 33 | vddo-supply = <&pm8916_l6>; | ||
| 34 | touchscreen-size-x = <540>; | ||
| 35 | touchscreen-size-y = <960>; | ||
| 36 | zinitix,mode = <2>; | ||
| 37 | }; | ||
| 38 | |||
| 39 | /* ... */ | ||
| 40 | }; | ||
| @@ -1143,6 +1143,8 @@ patternProperties: · 1142 unmodified lines | |||
| 1143 | description: Shenzhen Zidoo Technology Co., Ltd. | 1143 | description: Shenzhen Zidoo Technology Co., Ltd. |
| 1144 | "^zii,.*": | 1144 | "^zii,.*": |
| 1145 | description: Zodiac Inflight Innovations | 1145 | description: Zodiac Inflight Innovations |
| 1146 | "^zinitix,.*": | ||
| 1147 | description: Zinitix Co., Ltd | ||
| 1146 | "^zte,.*": | 1148 | "^zte,.*": |
| 1147 | description: ZTE Corp. | 1149 | description: ZTE Corp. |
| 1148 | "^zyxel,.*": | 1150 | "^zyxel,.*": |
| @@ -15441,6 +15441,13 @@ F: Documentation/fb/sisfb.rst · 15440 unmodified lines | |||
| 15441 | F: drivers/video/fbdev/sis/ | 15441 | F: drivers/video/fbdev/sis/ |
| 15442 | F: include/video/sisfb.h | 15442 | F: include/video/sisfb.h |
| 15443 | 15443 | ||
| 15444 | SIS I2C TOUCHSCREEN DRIVER | ||
| 15445 | M: Mika Penttilä <mika.penttila@nextfour.com> | ||
| 15446 | L: linux-input@vger.kernel.org | ||
| 15447 | S: Maintained | ||
| 15448 | F: Documentation/devicetree/bindings/input/touchscreen/sis_i2c.txt | ||
| 15449 | F: drivers/input/touchscreen/sis_i2c.c | ||
| 15450 | |||
| 15444 | SIS USB2VGA DRIVER | 15451 | SIS USB2VGA DRIVER |
| 15445 | M: Thomas Winischhofer <thomas@winischhofer.net> | 15452 | M: Thomas Winischhofer <thomas@winischhofer.net> |
| 15446 | S: Maintained | 15453 | S: Maintained |
| @@ -721,7 +721,7 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) · 720 unmodified lines | |||
| 721 | } | 721 | } |
| 722 | 722 | ||
| 723 | if (data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) | 723 | if (data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS) |
| 724 | rmi_hid_pdata.f30_data.disable = true; | 724 | rmi_hid_pdata.gpio_data.disable = true; |
| 725 | 725 | ||
| 726 | data->xport.dev = hdev->dev.parent; | 726 | data->xport.dev = hdev->dev.parent; |
| 727 | data->xport.pdata = rmi_hid_pdata; | 727 | data->xport.pdata = rmi_hid_pdata; |
| @@ -28,7 +28,6 @@ · 27 unmodified lines | |||
| 28 | struct evdev { | 28 | struct evdev { |
| 29 | int open; | 29 | int open; |
| 30 | struct input_handle handle; | 30 | struct input_handle handle; |
| 31 | wait_queue_head_t wait; | ||
| 32 | struct evdev_client __rcu *grab; | 31 | struct evdev_client __rcu *grab; |
| 33 | struct list_head client_list; | 32 | struct list_head client_list; |
| 34 | spinlock_t client_lock; /* protects client_list */ | 33 | spinlock_t client_lock; /* protects client_list */ |
| @@ -43,6 +42,7 @@ struct evdev_client { · 8 unmodified lines | |||
| 43 | unsigned int tail; | 42 | unsigned int tail; |
| 44 | unsigned int packet_head; /* [future] position of the first element of next packet */ | 43 | unsigned int packet_head; /* [future] position of the first element of next packet */ |
| 45 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ | 44 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ |
| 45 | wait_queue_head_t wait; | ||
| 46 | struct fasync_struct *fasync; | 46 | struct fasync_struct *fasync; |
| 47 | struct evdev *evdev; | 47 | struct evdev *evdev; |
| 48 | struct list_head node; | 48 | struct list_head node; |
| @@ -245,7 +245,6 @@ static void evdev_pass_values(struct evdev_client *client, · 196 unmodified lines | |||
| 245 | const struct input_value *vals, unsigned int count, | 245 | const struct input_value *vals, unsigned int count, |
| 246 | ktime_t *ev_time) | 246 | ktime_t *ev_time) |
| 247 | { | 247 | { |
| 248 | struct evdev *evdev = client->evdev; | ||
| 249 | const struct input_value *v; | 248 | const struct input_value *v; |
| 250 | struct input_event event; | 249 | struct input_event event; |
| 251 | struct timespec64 ts; | 250 | struct timespec64 ts; |
| @@ -282,7 +281,7 @@ static void evdev_pass_values(struct evdev_client *client, · 30 unmodified lines | |||
| 282 | spin_unlock(&client->buffer_lock); | 281 | spin_unlock(&client->buffer_lock); |
| 283 | 282 | ||
| 284 | if (wakeup) | 283 | if (wakeup) |
| 285 | wake_up_interruptible_poll(&evdev->wait, | 284 | wake_up_interruptible_poll(&client->wait, |
| 286 | EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM); | 285 | EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM); |
| 287 | } | 286 | } |
| 288 | 287 | ||
| @@ -426,11 +425,11 @@ static void evdev_hangup(struct evdev *evdev) · 137 unmodified lines | |||
| 426 | struct evdev_client *client; | 425 | struct evdev_client *client; |
| 427 | 426 | ||
| 428 | spin_lock(&evdev->client_lock); | 427 | spin_lock(&evdev->client_lock); |
| 429 | list_for_each_entry(client, &evdev->client_list, node) | 428 | list_for_each_entry(client, &evdev->client_list, node) { |
| 430 | kill_fasync(&client->fasync, SIGIO, POLL_HUP); | 429 | kill_fasync(&client->fasync, SIGIO, POLL_HUP); |
| 430 | wake_up_interruptible_poll(&client->wait, EPOLLHUP | EPOLLERR); | ||
| 431 | } | ||
| 431 | spin_unlock(&evdev->client_lock); | 432 | spin_unlock(&evdev->client_lock); |
| 432 | |||
| 433 | wake_up_interruptible_poll(&evdev->wait, EPOLLHUP | EPOLLERR); | ||
| 434 | } | 433 | } |
| 435 | 434 | ||
| 436 | static int evdev_release(struct inode *inode, struct file *file) | 435 | static int evdev_release(struct inode *inode, struct file *file) |
| @@ -479,6 +478,7 @@ static int evdev_open(struct inode *inode, struct file *file) · 42 unmodified lines | |||
| 479 | if (!client) | 478 | if (!client) |
| 480 | return -ENOMEM; | 479 | return -ENOMEM; |
| 481 | 480 | ||
| 481 | init_waitqueue_head(&client->wait); | ||
| 482 | client->bufsize = bufsize; | 482 | client->bufsize = bufsize; |
| 483 | spin_lock_init(&client->buffer_lock); | 483 | spin_lock_init(&client->buffer_lock); |
| 484 | client->evdev = evdev; | 484 | client->evdev = evdev; |
| @@ -595,7 +595,7 @@ static ssize_t evdev_read(struct file *file, char __user *buffer, · 110 unmodified lines | |||
| 595 | break; | 595 | break; |
| 596 | 596 | ||
| 597 | if (!(file->f_flags & O_NONBLOCK)) { | 597 | if (!(file->f_flags & O_NONBLOCK)) { |
| 598 | error = wait_event_interruptible(evdev->wait, | 598 | error = wait_event_interruptible(client->wait, |
| 599 | client->packet_head != client->tail || | 599 | client->packet_head != client->tail || |
| 600 | !evdev->exist || client->revoked); | 600 | !evdev->exist || client->revoked); |
| 601 | if (error) | 601 | if (error) |
| @@ -613,7 +613,7 @@ static __poll_t evdev_poll(struct file *file, poll_table *wait) · 11 unmodified lines | |||
| 613 | struct evdev *evdev = client->evdev; | 613 | struct evdev *evdev = client->evdev; |
| 614 | __poll_t mask; | 614 | __poll_t mask; |
| 615 | 615 | ||
| 616 | poll_wait(file, &evdev->wait, wait); | 616 | poll_wait(file, &client->wait, wait); |
| 617 | 617 | ||
| 618 | if (evdev->exist && !client->revoked) | 618 | if (evdev->exist && !client->revoked) |
| 619 | mask = EPOLLOUT | EPOLLWRNORM; | 619 | mask = EPOLLOUT | EPOLLWRNORM; |
| @@ -946,7 +946,7 @@ static int evdev_revoke(struct evdev *evdev, struct evdev_client *client, · 326 unmodified lines | |||
| 946 | client->revoked = true; | 946 | client->revoked = true; |
| 947 | evdev_ungrab(evdev, client); | 947 | evdev_ungrab(evdev, client); |
| 948 | input_flush_device(&evdev->handle, file); | 948 | input_flush_device(&evdev->handle, file); |
| 949 | wake_up_interruptible_poll(&evdev->wait, EPOLLHUP | EPOLLERR); | 949 | wake_up_interruptible_poll(&client->wait, EPOLLHUP | EPOLLERR); |
| 950 | 950 | ||
| 951 | return 0; | 951 | return 0; |
| 952 | } | 952 | } |
| @@ -1358,7 +1358,6 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, · 405 unmodified lines | |||
| 1358 | INIT_LIST_HEAD(&evdev->client_list); | 1358 | INIT_LIST_HEAD(&evdev->client_list); |
| 1359 | spin_lock_init(&evdev->client_lock); | 1359 | spin_lock_init(&evdev->client_lock); |
| 1360 | mutex_init(&evdev->mutex); | 1360 | mutex_init(&evdev->mutex); |
| 1361 | init_waitqueue_head(&evdev->wait); | ||
| 1362 | evdev->exist = true; | 1361 | evdev->exist = true; |
| 1363 | 1362 | ||
| 1364 | dev_no = minor; | 1363 | dev_no = minor; |
| @@ -323,11 +323,14 @@ static int adjust_dual(int *begin, int step, int *end, int eq, int mu) · 322 unmodified lines | |||
| 323 | p = begin + step; | 323 | p = begin + step; |
| 324 | s = p == end ? f + 1 : *p; | 324 | s = p == end ? f + 1 : *p; |
| 325 | 325 | ||
| 326 | for (; p != end; p += step) | 326 | for (; p != end; p += step) { |
| 327 | if (*p < f) | 327 | if (*p < f) { |
| 328 | s = f, f = *p; | 328 | s = f; |
| 329 | else if (*p < s) | 329 | f = *p; |
| 330 | } else if (*p < s) { | ||
| 330 | s = *p; | 331 | s = *p; |
| 332 | } | ||
| 333 | } | ||
| 331 | 334 | ||
| 332 | c = (f + s + 1) / 2; | 335 | c = (f + s + 1) / 2; |
| 333 | if (c == 0 || (c > mu && (!eq || mu > 0))) | 336 | if (c == 0 || (c > mu && (!eq || mu > 0))) |
| @@ -42,6 +42,16 @@ config JOYSTICK_A3D · 41 unmodified lines | |||
| 42 | To compile this driver as a module, choose M here: the | 42 | To compile this driver as a module, choose M here: the |
| 43 | module will be called a3d. | 43 | module will be called a3d. |
| 44 | 44 | ||
| 45 | config JOYSTICK_ADC | ||
| 46 | tristate "Simple joystick connected over ADC" | ||
| 47 | depends on IIO | ||
| 48 | select IIO_BUFFER_CB | ||
| 49 | help | ||
| 50 | Say Y here if you have a simple joystick connected over ADC. | ||
| 51 | |||
| 52 | To compile this driver as a module, choose M here: the | ||
| 53 | module will be called adc-joystick. | ||
| 54 | |||
| 45 | config JOYSTICK_ADI | 55 | config JOYSTICK_ADI |
| 46 | tristate "Logitech ADI digital joysticks and gamepads" | 56 | tristate "Logitech ADI digital joysticks and gamepads" |
| 47 | select GAMEPORT | 57 | select GAMEPORT |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | # Each configuration option enables a list of files. | 6 | # Each configuration option enables a list of files. |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_JOYSTICK_A3D) += a3d.o | 8 | obj-$(CONFIG_JOYSTICK_A3D) += a3d.o |
| 9 | obj-$(CONFIG_JOYSTICK_ADC) += adc-joystick.o | ||
| 9 | obj-$(CONFIG_JOYSTICK_ADI) += adi.o | 10 | obj-$(CONFIG_JOYSTICK_ADI) += adi.o |
| 10 | obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o | 11 | obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o |
| 11 | obj-$(CONFIG_JOYSTICK_AS5011) += as5011.o | 12 | obj-$(CONFIG_JOYSTICK_AS5011) += as5011.o |
| @@ -0,0 +1,264 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Input driver for joysticks connected over ADC. | ||
| 4 | * Copyright (c) 2019-2020 Artur Rojek <contact@artur-rojek.eu> | ||
| 5 | */ | ||
| 6 | #include <linux/ctype.h> | ||
| 7 | #include <linux/input.h> | ||
| 8 | #include <linux/iio/iio.h> | ||
| 9 | #include <linux/iio/consumer.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/platform_device.h> | ||
| 12 | #include <linux/property.h> | ||
| 13 | |||
| 14 | #include <asm/unaligned.h> | ||
| 15 | |||
| 16 | struct adc_joystick_axis { | ||
| 17 | u32 code; | ||
| 18 | s32 range[2]; | ||
| 19 | s32 fuzz; | ||
| 20 | s32 flat; | ||
| 21 | }; | ||
| 22 | |||
| 23 | struct adc_joystick { | ||
| 24 | struct input_dev *input; | ||
| 25 | struct iio_cb_buffer *buffer; | ||
| 26 | struct adc_joystick_axis *axes; | ||
| 27 | struct iio_channel *chans; | ||
| 28 | int num_chans; | ||
| 29 | }; | ||
| 30 | |||
| 31 | static int adc_joystick_handle(const void *data, void *private) | ||
| 32 | { | ||
| 33 | struct adc_joystick *joy = private; | ||
| 34 | enum iio_endian endianness; | ||
| 35 | int bytes, msb, val, idx, i; | ||
| 36 | const u16 *data_u16; | ||
| 37 | bool sign; | ||
| 38 | |||
| 39 | bytes = joy->chans[0].channel->scan_type.storagebits >> 3; | ||
| 40 | |||
| 41 | for (i = 0; i < joy->num_chans; ++i) { | ||
| 42 | idx = joy->chans[i].channel->scan_index; | ||
| 43 | endianness = joy->chans[i].channel->scan_type.endianness; | ||
| 44 | msb = joy->chans[i].channel->scan_type.realbits - 1; | ||
| 45 | sign = tolower(joy->chans[i].channel->scan_type.sign) == 's'; | ||
| 46 | |||
| 47 | switch (bytes) { | ||
| 48 | case 1: | ||
| 49 | val = ((const u8 *)data)[idx]; | ||
| 50 | break; | ||
| 51 | case 2: | ||
| 52 | data_u16 = (const u16 *)data + idx; | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Data is aligned to the sample size by IIO core. | ||
| 56 | * Call `get_unaligned_xe16` to hide type casting. | ||
| 57 | */ | ||
| 58 | if (endianness == IIO_BE) | ||
| 59 | val = get_unaligned_be16(data_u16); | ||
| 60 | else if (endianness == IIO_LE) | ||
| 61 | val = get_unaligned_le16(data_u16); | ||
| 62 | else /* IIO_CPU */ | ||
| 63 | val = *data_u16; | ||
| 64 | break; | ||
| 65 | default: | ||
| 66 | return -EINVAL; | ||
| 67 | } | ||
| 68 | |||
| 69 | val >>= joy->chans[i].channel->scan_type.shift; | ||
| 70 | if (sign) | ||
| 71 | val = sign_extend32(val, msb); | ||
| 72 | else | ||
| 73 | val &= GENMASK(msb, 0); | ||
| 74 | input_report_abs(joy->input, joy->axes[i].code, val); | ||
| 75 | } | ||
| 76 | |||
| 77 | input_sync(joy->input); | ||
| 78 | |||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | static int adc_joystick_open(struct input_dev *dev) | ||
| 83 | { | ||
| 84 | struct adc_joystick *joy = input_get_drvdata(dev); | ||
| 85 | struct device *devp = &dev->dev; | ||
| 86 | int ret; | ||
| 87 | |||
| 88 | ret = iio_channel_start_all_cb(joy->buffer); | ||
| 89 | if (ret) | ||
| 90 | dev_err(devp, "Unable to start callback buffer: %d\n", ret); | ||
| 91 | |||
| 92 | return ret; | ||
| 93 | } | ||
| 94 | |||
| 95 | static void adc_joystick_close(struct input_dev *dev) | ||
| 96 | { | ||
| 97 | struct adc_joystick *joy = input_get_drvdata(dev); | ||
| 98 | |||
| 99 | iio_channel_stop_all_cb(joy->buffer); | ||
| 100 | } | ||
| 101 | |||
| 102 | static void adc_joystick_cleanup(void *data) | ||
| 103 | { | ||
| 104 | iio_channel_release_all_cb(data); | ||
| 105 | } | ||
| 106 | |||
| 107 | static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy) | ||
| 108 | { | ||
| 109 | struct adc_joystick_axis *axes; | ||
| 110 | struct fwnode_handle *child; | ||
| 111 | int num_axes, error, i; | ||
| 112 | |||
| 113 | num_axes = device_get_child_node_count(dev); | ||
| 114 | if (!num_axes) { | ||
| 115 | dev_err(dev, "Unable to find child nodes\n"); | ||
| 116 | return -EINVAL; | ||
| 117 | } | ||
| 118 | |||
| 119 | if (num_axes != joy->num_chans) { | ||
| 120 | dev_err(dev, "Got %d child nodes for %d channels\n", | ||
| 121 | num_axes, joy->num_chans); | ||
| 122 | return -EINVAL; | ||
| 123 | } | ||
| 124 | |||
| 125 | axes = devm_kmalloc_array(dev, num_axes, sizeof(*axes), GFP_KERNEL); | ||
| 126 | if (!axes) | ||
| 127 | return -ENOMEM; | ||
| 128 | |||
| 129 | device_for_each_child_node(dev, child) { | ||
| 130 | error = fwnode_property_read_u32(child, "reg", &i); | ||
| 131 | if (error) { | ||
| 132 | dev_err(dev, "reg invalid or missing\n"); | ||
| 133 | goto err_fwnode_put; | ||
| 134 | } | ||
| 135 | |||
| 136 | if (i >= num_axes) { | ||
| 137 | error = -EINVAL; | ||
| 138 | dev_err(dev, "No matching axis for reg %d\n", i); | ||
| 139 | goto err_fwnode_put; | ||
| 140 | } | ||
| 141 | |||
| 142 | error = fwnode_property_read_u32(child, "linux,code", | ||
| 143 | &axes[i].code); | ||
| 144 | if (error) { | ||
| 145 | dev_err(dev, "linux,code invalid or missing\n"); | ||
| 146 | goto err_fwnode_put; | ||
| 147 | } | ||
| 148 | |||
| 149 | error = fwnode_property_read_u32_array(child, "abs-range", | ||
| 150 | axes[i].range, 2); | ||
| 151 | if (error) { | ||
| 152 | dev_err(dev, "abs-range invalid or missing\n"); | ||
| 153 | goto err_fwnode_put; | ||
| 154 | } | ||
| 155 | |||
| 156 | fwnode_property_read_u32(child, "abs-fuzz", &axes[i].fuzz); | ||
| 157 | fwnode_property_read_u32(child, "abs-flat", &axes[i].flat); | ||
| 158 | |||
| 159 | input_set_abs_params(joy->input, axes[i].code, | ||
| 160 | axes[i].range[0], axes[i].range[1], | ||
| 161 | axes[i].fuzz, axes[i].flat); | ||
| 162 | input_set_capability(joy->input, EV_ABS, axes[i].code); | ||
| 163 | } | ||
| 164 | |||
| 165 | joy->axes = axes; | ||
| 166 | |||
| 167 | return 0; | ||
| 168 | |||
| 169 | err_fwnode_put: | ||
| 170 | fwnode_handle_put(child); | ||
| 171 | return error; | ||
| 172 | } | ||
| 173 | |||
| 174 | static int adc_joystick_probe(struct platform_device *pdev) | ||
| 175 | { | ||
| 176 | struct device *dev = &pdev->dev; | ||
| 177 | struct adc_joystick *joy; | ||
| 178 | struct input_dev *input; | ||
| 179 | int error; | ||
| 180 | int bits; | ||
| 181 | int i; | ||
| 182 | |||
| 183 | joy = devm_kzalloc(dev, sizeof(*joy), GFP_KERNEL); | ||
| 184 | if (!joy) | ||
| 185 | return -ENOMEM; | ||
| 186 | |||
| 187 | joy->chans = devm_iio_channel_get_all(dev); | ||
| 188 | if (IS_ERR(joy->chans)) { | ||
| 189 | error = PTR_ERR(joy->chans); | ||
| 190 | if (error != -EPROBE_DEFER) | ||
| 191 | dev_err(dev, "Unable to get IIO channels"); | ||
| 192 | return error; | ||
| 193 | } | ||
| 194 | |||
| 195 | /* Count how many channels we got. NULL terminated. */ | ||
| 196 | for (i = 0; joy->chans[i].indio_dev; i++) { | ||
| 197 | bits = joy->chans[i].channel->scan_type.storagebits; | ||
| 198 | if (!bits || bits > 16) { | ||
| 199 | dev_err(dev, "Unsupported channel storage size\n"); | ||
| 200 | return -EINVAL; | ||
| 201 | } | ||
| 202 | if (bits != joy->chans[0].channel->scan_type.storagebits) { | ||
| 203 | dev_err(dev, "Channels must have equal storage size\n"); | ||
| 204 | return -EINVAL; | ||
| 205 | } | ||
| 206 | } | ||
| 207 | joy->num_chans = i; | ||
| 208 | |||
| 209 | input = devm_input_allocate_device(dev); | ||
| 210 | if (!input) { | ||
| 211 | dev_err(dev, "Unable to allocate input device\n"); | ||
| 212 | return -ENOMEM; | ||
| 213 | } | ||
| 214 | |||
| 215 | joy->input = input; | ||
| 216 | input->name = pdev->name; | ||
| 217 | input->id.bustype = BUS_HOST; | ||
| 218 | input->open = adc_joystick_open; | ||
| 219 | input->close = adc_joystick_close; | ||
| 220 | |||
| 221 | error = adc_joystick_set_axes(dev, joy); | ||
| 222 | if (error) | ||
| 223 | return error; | ||
| 224 | |||
| 225 | input_set_drvdata(input, joy); | ||
| 226 | error = input_register_device(input); | ||
| 227 | if (error) { | ||
| 228 | dev_err(dev, "Unable to register input device\n"); | ||
| 229 | return error; | ||
| 230 | } | ||
| 231 | |||
| 232 | joy->buffer = iio_channel_get_all_cb(dev, adc_joystick_handle, joy); | ||
| 233 | if (IS_ERR(joy->buffer)) { | ||
| 234 | dev_err(dev, "Unable to allocate callback buffer\n"); | ||
| 235 | return PTR_ERR(joy->buffer); | ||
| 236 | } | ||
| 237 | |||
| 238 | error = devm_add_action_or_reset(dev, adc_joystick_cleanup, joy->buffer); | ||
| 239 | if (error) { | ||
| 240 | dev_err(dev, "Unable to add action\n"); | ||
| 241 | return error; | ||
| 242 | } | ||
| 243 | |||
| 244 | return 0; | ||
| 245 | } | ||
| 246 | |||
| 247 | static const struct of_device_id adc_joystick_of_match[] = { | ||
| 248 | { .compatible = "adc-joystick", }, | ||
| 249 | { } | ||
| 250 | }; | ||
| 251 | MODULE_DEVICE_TABLE(of, adc_joystick_of_match); | ||
| 252 | |||
| 253 | static struct platform_driver adc_joystick_driver = { | ||
| 254 | .driver = { | ||
| 255 | .name = "adc-joystick", | ||
| 256 | .of_match_table = adc_joystick_of_match, | ||
| 257 | }, | ||
| 258 | .probe = adc_joystick_probe, | ||
| 259 | }; | ||
| 260 | module_platform_driver(adc_joystick_driver); | ||
| 261 | |||
| 262 | MODULE_DESCRIPTION("Input driver for joysticks connected over ADC"); | ||
| 263 | MODULE_AUTHOR("Artur Rojek <contact@artur-rojek.eu>"); | ||
| 264 | MODULE_LICENSE("GPL"); | ||
| @@ -250,8 +250,8 @@ static int ep93xx_keypad_probe(struct platform_device *pdev) · 249 unmodified lines | |||
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | keypad->irq = platform_get_irq(pdev, 0); | 252 | keypad->irq = platform_get_irq(pdev, 0); |
| 253 | if (!keypad->irq) { | 253 | if (keypad->irq < 0) { |
| 254 | err = -ENXIO; | 254 | err = keypad->irq; |
| 255 | goto failed_free; | 255 | goto failed_free; |
| 256 | } | 256 | } |
| 257 | 257 | ||
| @@ -240,10 +240,8 @@ static int omap4_keypad_probe(struct platform_device *pdev) · 239 unmodified lines | |||
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | irq = platform_get_irq(pdev, 0); | 242 | irq = platform_get_irq(pdev, 0); |
| 243 | if (!irq) { | 243 | if (irq < 0) |
| 244 | dev_err(&pdev->dev, "no keyboard irq assigned\n"); | 244 | return irq; |
| 245 | return -EINVAL; | ||
| 246 | } | ||
| 247 | 245 | ||
| 248 | keypad_data = kzalloc(sizeof(struct omap4_keypad), GFP_KERNEL); | 246 | keypad_data = kzalloc(sizeof(struct omap4_keypad), GFP_KERNEL); |
| 249 | if (!keypad_data) { | 247 | if (!keypad_data) { |
| @@ -50,7 +50,7 @@ struct twl4030_keypad { · 49 unmodified lines | |||
| 50 | bool autorepeat; | 50 | bool autorepeat; |
| 51 | unsigned int n_rows; | 51 | unsigned int n_rows; |
| 52 | unsigned int n_cols; | 52 | unsigned int n_cols; |
| 53 | unsigned int irq; | 53 | int irq; |
| 54 | 54 | ||
| 55 | struct device *dbg_dev; | 55 | struct device *dbg_dev; |
| 56 | struct input_dev *input; | 56 | struct input_dev *input; |
| @@ -376,10 +376,8 @@ static int twl4030_kp_probe(struct platform_device *pdev) · 319 unmodified lines | |||
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | kp->irq = platform_get_irq(pdev, 0); | 378 | kp->irq = platform_get_irq(pdev, 0); |
| 379 | if (!kp->irq) { | 379 | if (kp->irq < 0) |
| 380 | dev_err(&pdev->dev, "no keyboard irq assigned\n"); | 380 | return kp->irq; |
| 381 | return -EINVAL; | ||
| 382 | } | ||
| 383 | 381 | ||
| 384 | error = matrix_keypad_build_keymap(keymap_data, NULL, | 382 | error = matrix_keypad_build_keymap(keymap_data, NULL, |
| 385 | TWL4030_MAX_ROWS, | 383 | TWL4030_MAX_ROWS, |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
| 12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
| 13 | #include <linux/acpi.h> | 13 | #include <linux/acpi.h> |
| 14 | #include <linux/dmi.h> | ||
| 14 | #include <linux/gpio/consumer.h> | 15 | #include <linux/gpio/consumer.h> |
| 15 | #include <linux/gpio_keys.h> | 16 | #include <linux/gpio_keys.h> |
| 16 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
| @@ -23,6 +24,7 @@ struct soc_button_info { · 6 unmodified lines | |||
| 23 | unsigned int event_code; | 24 | unsigned int event_code; |
| 24 | bool autorepeat; | 25 | bool autorepeat; |
| 25 | bool wakeup; | 26 | bool wakeup; |
| 27 | bool active_low; | ||
| 26 | }; | 28 | }; |
| 27 | 29 | ||
| 28 | struct soc_device_data { | 30 | struct soc_device_data { |
| @@ -41,23 +43,66 @@ struct soc_button_data { · 12 unmodified lines | |||
| 41 | struct platform_device *children[BUTTON_TYPES]; | 43 | struct platform_device *children[BUTTON_TYPES]; |
| 42 | }; | 44 | }; |
| 43 | 45 | ||
| 46 | /* | ||
| 47 | * Some 2-in-1s which use the soc_button_array driver have this ugly issue in | ||
| 48 | * their DSDT where the _LID method modifies the irq-type settings of the GPIOs | ||
| 49 | * used for the power and home buttons. The intend of this AML code is to | ||
| 50 | * disable these buttons when the lid is closed. | ||
| 51 | * The AML does this by directly poking the GPIO controllers registers. This is | ||
| 52 | * problematic because when re-enabling the irq, which happens whenever _LID | ||
| 53 | * gets called with the lid open (e.g. on boot and on resume), it sets the | ||
| 54 | * irq-type to IRQ_TYPE_LEVEL_LOW. Where as the gpio-keys driver programs the | ||
| 55 | * type to, and expects it to be, IRQ_TYPE_EDGE_BOTH. | ||
| 56 | * To work around this we don't set gpio_keys_button.gpio on these 2-in-1s, | ||
| 57 | * instead we get the irq for the GPIO ourselves, configure it as | ||
| 58 | * IRQ_TYPE_LEVEL_LOW (to match how the _LID AML code configures it) and pass | ||
| 59 | * the irq in gpio_keys_button.irq. Below is a list of affected devices. | ||
| 60 | */ | ||
| 61 | static const struct dmi_system_id dmi_use_low_level_irq[] = { | ||
| 62 | { | ||
| 63 | /* | ||
| 64 | * Acer Switch 10 SW5-012. _LID method messes with home- and | ||
| 65 | * power-button GPIO IRQ settings. When (re-)enabling the irq | ||
| 66 | * it ors in its own flags without clearing the previous set | ||
| 67 | * ones, leading to an irq-type of IRQ_TYPE_LEVEL_LOW | | ||
| 68 | * IRQ_TYPE_LEVEL_HIGH causing a continuous interrupt storm. | ||
| 69 | */ | ||
| 70 | .matches = { | ||
| 71 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
| 72 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), | ||
| 73 | }, | ||
| 74 | }, | ||
| 75 | { | ||
| 76 | /* | ||
| 77 | * Acer One S1003. _LID method messes with power-button GPIO | ||
| 78 | * IRQ settings, leading to a non working power-button. | ||
| 79 | */ | ||
| 80 | .matches = { | ||
| 81 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
| 82 | DMI_MATCH(DMI_PRODUCT_NAME, "One S1003"), | ||
| 83 | }, | ||
| 84 | }, | ||
| 85 | {} /* Terminating entry */ | ||
| 86 | }; | ||
| 87 | |||
| 44 | /* | 88 | /* |
| 45 | * Get the Nth GPIO number from the ACPI object. | 89 | * Get the Nth GPIO number from the ACPI object. |
| 46 | */ | 90 | */ |
| 47 | static int soc_button_lookup_gpio(struct device *dev, int acpi_index) | 91 | static int soc_button_lookup_gpio(struct device *dev, int acpi_index, |
| 92 | int *gpio_ret, int *irq_ret) | ||
| 48 | { | 93 | { |
| 49 | struct gpio_desc *desc; | 94 | struct gpio_desc *desc; |
| 50 | int gpio; | ||
| 51 | 95 | ||
| 52 | desc = gpiod_get_index(dev, NULL, acpi_index, GPIOD_ASIS); | 96 | desc = gpiod_get_index(dev, NULL, acpi_index, GPIOD_ASIS); |
| 53 | if (IS_ERR(desc)) | 97 | if (IS_ERR(desc)) |
| 54 | return PTR_ERR(desc); | 98 | return PTR_ERR(desc); |
| 55 | 99 | ||
| 56 | gpio = desc_to_gpio(desc); | 100 | *gpio_ret = desc_to_gpio(desc); |
| 101 | *irq_ret = gpiod_to_irq(desc); | ||
| 57 | 102 | ||
| 58 | gpiod_put(desc); | 103 | gpiod_put(desc); |
| 59 | 104 | ||
| 60 | return gpio; | 105 | return 0; |
| 61 | } | 106 | } |
| 62 | 107 | ||
| 63 | static struct platform_device * | 108 | static struct platform_device * |
| @@ -69,9 +114,8 @@ soc_button_device_create(struct platform_device *pdev, · 5 unmodified lines | |||
| 69 | struct platform_device *pd; | 114 | struct platform_device *pd; |
| 70 | struct gpio_keys_button *gpio_keys; | 115 | struct gpio_keys_button *gpio_keys; |
| 71 | struct gpio_keys_platform_data *gpio_keys_pdata; | 116 | struct gpio_keys_platform_data *gpio_keys_pdata; |
| 117 | int error, gpio, irq; | ||
| 72 | int n_buttons = 0; | 118 | int n_buttons = 0; |
| 73 | int gpio; | ||
| 74 | int error; | ||
| 75 | 119 | ||
| 76 | for (info = button_info; info->name; info++) | 120 | for (info = button_info; info->name; info++) |
| 77 | if (info->autorepeat == autorepeat) | 121 | if (info->autorepeat == autorepeat) |
| @@ -91,8 +135,8 @@ soc_button_device_create(struct platform_device *pdev, · 13 unmodified lines | |||
| 91 | if (info->autorepeat != autorepeat) | 135 | if (info->autorepeat != autorepeat) |
| 92 | continue; | 136 | continue; |
| 93 | 137 | ||
| 94 | gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index); | 138 | error = soc_button_lookup_gpio(&pdev->dev, info->acpi_index, &gpio, &irq); |
| 95 | if (!gpio_is_valid(gpio)) { | 139 | if (error || irq < 0) { |
| 96 | /* | 140 | /* |
| 97 | * Skip GPIO if not present. Note we deliberately | 141 | * Skip GPIO if not present. Note we deliberately |
| 98 | * ignore -EPROBE_DEFER errors here. On some devices | 142 | * ignore -EPROBE_DEFER errors here. On some devices |
| @@ -107,10 +151,18 @@ soc_button_device_create(struct platform_device *pdev, · 8 unmodified lines | |||
| 107 | continue; | 151 | continue; |
| 108 | } | 152 | } |
| 109 | 153 | ||
| 154 | /* See dmi_use_low_level_irq[] comment */ | ||
| 155 | if (!autorepeat && dmi_check_system(dmi_use_low_level_irq)) { | ||
| 156 | irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); | ||
| 157 | gpio_keys[n_buttons].irq = irq; | ||
| 158 | gpio_keys[n_buttons].gpio = -ENOENT; | ||
| 159 | } else { | ||
| 160 | gpio_keys[n_buttons].gpio = gpio; | ||
| 161 | } | ||
| 162 | |||
| 110 | gpio_keys[n_buttons].type = info->event_type; | 163 | gpio_keys[n_buttons].type = info->event_type; |
| 111 | gpio_keys[n_buttons].code = info->event_code; | 164 | gpio_keys[n_buttons].code = info->event_code; |
| 112 | gpio_keys[n_buttons].gpio = gpio; | 165 | gpio_keys[n_buttons].active_low = info->active_low; |
| 113 | gpio_keys[n_buttons].active_low = 1; | ||
| 114 | gpio_keys[n_buttons].desc = info->name; | 166 | gpio_keys[n_buttons].desc = info->name; |
| 115 | gpio_keys[n_buttons].wakeup = info->wakeup; | 167 | gpio_keys[n_buttons].wakeup = info->wakeup; |
| 116 | /* These devices often use cheap buttons, use 50 ms debounce */ | 168 | /* These devices often use cheap buttons, use 50 ms debounce */ |
| @@ -173,6 +225,7 @@ static int soc_button_parse_btn_desc(struct device *dev, · 56 unmodified lines | |||
| 173 | } | 225 | } |
| 174 | 226 | ||
| 175 | info->event_type = EV_KEY; | 227 | info->event_type = EV_KEY; |
| 228 | info->active_low = true; | ||
| 176 | info->acpi_index = | 229 | info->acpi_index = |
| 177 | soc_button_get_acpi_object_int(&desc->package.elements[1]); | 230 | soc_button_get_acpi_object_int(&desc->package.elements[1]); |
| 178 | upage = soc_button_get_acpi_object_int(&desc->package.elements[3]); | 231 | upage = soc_button_get_acpi_object_int(&desc->package.elements[3]); |
| @@ -383,11 +436,11 @@ static int soc_button_probe(struct platform_device *pdev) · 204 unmodified lines | |||
| 383 | * Platforms" | 436 | * Platforms" |
| 384 | */ | 437 | */ |
| 385 | static const struct soc_button_info soc_button_PNP0C40[] = { | 438 | static const struct soc_button_info soc_button_PNP0C40[] = { |
| 386 | { "power", 0, EV_KEY, KEY_POWER, false, true }, | 439 | { "power", 0, EV_KEY, KEY_POWER, false, true, true }, |
| 387 | { "home", 1, EV_KEY, KEY_LEFTMETA, false, true }, | 440 | { "home", 1, EV_KEY, KEY_LEFTMETA, false, true, true }, |
| 388 | { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false }, | 441 | { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false, true }, |
| 389 | { "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false }, | 442 | { "volume_down", 3, EV_KEY, KEY_VOLUMEDOWN, true, false, true }, |
| 390 | { "rotation_lock", 4, EV_KEY, KEY_ROTATE_LOCK_TOGGLE, false, false }, | 443 | { "rotation_lock", 4, EV_KEY, KEY_ROTATE_LOCK_TOGGLE, false, false, true }, |
| 391 | { } | 444 | { } |
| 392 | }; | 445 | }; |
| 393 | 446 | ||
| @@ -395,6 +448,15 @@ static const struct soc_device_data soc_device_PNP0C40 = { · 1 unmodified line | |||
| 395 | .button_info = soc_button_PNP0C40, | 448 | .button_info = soc_button_PNP0C40, |
| 396 | }; | 449 | }; |
| 397 | 450 | ||
| 451 | static const struct soc_button_info soc_button_INT33D3[] = { | ||
| 452 | { "tablet_mode", 0, EV_SW, SW_TABLET_MODE, false, false, false }, | ||
| 453 | { } | ||
| 454 | }; | ||
| 455 | |||
| 456 | static const struct soc_device_data soc_device_INT33D3 = { | ||
| 457 | .button_info = soc_button_INT33D3, | ||
| 458 | }; | ||
| 459 | |||
| 398 | /* | 460 | /* |
| 399 | * Special device check for Surface Book 2 and Surface Pro (2017). | 461 | * Special device check for Surface Book 2 and Surface Pro (2017). |
| 400 | * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned | 462 | * Both, the Surface Pro 4 (surfacepro3_button.c) and the above mentioned |
| @@ -444,9 +506,9 @@ static int soc_device_check_MSHW0040(struct device *dev) · 43 unmodified lines | |||
| 444 | * Obtained from DSDT/testing. | 506 | * Obtained from DSDT/testing. |
| 445 | */ | 507 | */ |
| 446 | static const struct soc_button_info soc_button_MSHW0040[] = { | 508 | static const struct soc_button_info soc_button_MSHW0040[] = { |
| 447 | { "power", 0, EV_KEY, KEY_POWER, false, true }, | 509 | { "power", 0, EV_KEY, KEY_POWER, false, true, true }, |
| 448 | { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false }, | 510 | { "volume_up", 2, EV_KEY, KEY_VOLUMEUP, true, false, true }, |
| 449 | { "volume_down", 4, EV_KEY, KEY_VOLUMEDOWN, true, false }, | 511 | { "volume_down", 4, EV_KEY, KEY_VOLUMEDOWN, true, false, true }, |
| 450 | { } | 512 | { } |
| 451 | }; | 513 | }; |
| 452 | 514 | ||
| @@ -457,6 +519,8 @@ static const struct soc_device_data soc_device_MSHW0040 = { · 4 unmodified lines | |||
| 457 | 519 | ||
| 458 | static const struct acpi_device_id soc_button_acpi_match[] = { | 520 | static const struct acpi_device_id soc_button_acpi_match[] = { |
| 459 | { "PNP0C40", (unsigned long)&soc_device_PNP0C40 }, | 521 | { "PNP0C40", (unsigned long)&soc_device_PNP0C40 }, |
| 522 | { "INT33D3", (unsigned long)&soc_device_INT33D3 }, | ||
| 523 | { "ID9001", (unsigned long)&soc_device_INT33D3 }, | ||
| 460 | { "ACPI0011", 0 }, | 524 | { "ACPI0011", 0 }, |
| 461 | 525 | ||
| 462 | /* Microsoft Surface Devices (5th and 6th generation) */ | 526 | /* Microsoft Surface Devices (5th and 6th generation) */ |
| @@ -179,12 +179,14 @@ static const char * const smbus_pnp_ids[] = { · 178 unmodified lines | |||
| 179 | "LEN0093", /* T480 */ | 179 | "LEN0093", /* T480 */ |
| 180 | "LEN0096", /* X280 */ | 180 | "LEN0096", /* X280 */ |
| 181 | "LEN0097", /* X280 -> ALPS trackpoint */ | 181 | "LEN0097", /* X280 -> ALPS trackpoint */ |
| 182 | "LEN0099", /* X1 Extreme 1st */ | 182 | "LEN0099", /* X1 Extreme Gen 1 / P1 Gen 1 */ |
| 183 | "LEN009b", /* T580 */ | 183 | "LEN009b", /* T580 */ |
| 184 | "LEN0402", /* X1 Extreme Gen 2 / P1 Gen 2 */ | ||
| 184 | "LEN200f", /* T450s */ | 185 | "LEN200f", /* T450s */ |
| 185 | "LEN2044", /* L470 */ | 186 | "LEN2044", /* L470 */ |
| 186 | "LEN2054", /* E480 */ | 187 | "LEN2054", /* E480 */ |
| 187 | "LEN2055", /* E580 */ | 188 | "LEN2055", /* E580 */ |
| 189 | "LEN2068", /* T14 Gen 1 */ | ||
| 188 | "SYN3052", /* HP EliteBook 840 G4 */ | 190 | "SYN3052", /* HP EliteBook 840 G4 */ |
| 189 | "SYN3221", /* HP 15-ay000 */ | 191 | "SYN3221", /* HP 15-ay000 */ |
| 190 | "SYN323d", /* HP Spectre X360 13-w013dx */ | 192 | "SYN323d", /* HP Spectre X360 13-w013dx */ |
| @@ -1752,7 +1754,7 @@ static int synaptics_create_intertouch(struct psmouse *psmouse, · 1561 unmodified lines | |||
| 1752 | .kernel_tracking = false, | 1754 | .kernel_tracking = false, |
| 1753 | .topbuttonpad = topbuttonpad, | 1755 | .topbuttonpad = topbuttonpad, |
| 1754 | }, | 1756 | }, |
| 1755 | .f30_data = { | 1757 | .gpio_data = { |
| 1756 | .buttonpad = SYN_CAP_CLICKPAD(info->ext_cap_0c), | 1758 | .buttonpad = SYN_CAP_CLICKPAD(info->ext_cap_0c), |
| 1757 | .trackstick_buttons = | 1759 | .trackstick_buttons = |
| 1758 | !!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10), | 1760 | !!SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10), |
| @@ -100,6 +100,14 @@ config RMI4_F34 · 99 unmodified lines | |||
| 100 | device via the firmware loader interface. This is triggered using a | 100 | device via the firmware loader interface. This is triggered using a |
| 101 | sysfs attribute. | 101 | sysfs attribute. |
| 102 | 102 | ||
| 103 | config RMI4_F3A | ||
| 104 | bool "RMI4 Function 3A (GPIO)" | ||
| 105 | help | ||
| 106 | Say Y here if you want to add support for RMI4 function 3A. | ||
| 107 | |||
| 108 | Function 3A provides GPIO support for RMI4 devices. This includes | ||
| 109 | support for buttons on TouchPads and ClickPads. | ||
| 110 | |||
| 103 | config RMI4_F54 | 111 | config RMI4_F54 |
| 104 | bool "RMI4 Function 54 (Analog diagnostics)" | 112 | bool "RMI4 Function 54 (Analog diagnostics)" |
| 105 | depends on VIDEO_V4L2=y || (RMI4_CORE=m && VIDEO_V4L2=m) | 113 | depends on VIDEO_V4L2=y || (RMI4_CORE=m && VIDEO_V4L2=m) |
| @@ -10,6 +10,7 @@ rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o · 9 unmodified lines | |||
| 10 | rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o | 10 | rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o |
| 11 | rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o | 11 | rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o |
| 12 | rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o | 12 | rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o |
| 13 | rmi_core-$(CONFIG_RMI4_F3A) += rmi_f3a.o | ||
| 13 | rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o | 14 | rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o |
| 14 | rmi_core-$(CONFIG_RMI4_F55) += rmi_f55.o | 15 | rmi_core-$(CONFIG_RMI4_F55) += rmi_f55.o |
| 15 | 16 | ||
| @@ -365,6 +365,9 @@ static struct rmi_function_handler *fn_handlers[] = { · 364 unmodified lines | |||
| 365 | #ifdef CONFIG_RMI4_F34 | 365 | #ifdef CONFIG_RMI4_F34 |
| 366 | &rmi_f34_handler, | 366 | &rmi_f34_handler, |
| 367 | #endif | 367 | #endif |
| 368 | #ifdef CONFIG_RMI4_F3A | ||
| 369 | &rmi_f3a_handler, | ||
| 370 | #endif | ||
| 368 | #ifdef CONFIG_RMI4_F54 | 371 | #ifdef CONFIG_RMI4_F54 |
| 369 | &rmi_f54_handler, | 372 | &rmi_f54_handler, |
| 370 | #endif | 373 | #endif |
| @@ -135,6 +135,7 @@ extern struct rmi_function_handler rmi_f11_handler; · 134 unmodified lines | |||
| 135 | extern struct rmi_function_handler rmi_f12_handler; | 135 | extern struct rmi_function_handler rmi_f12_handler; |
| 136 | extern struct rmi_function_handler rmi_f30_handler; | 136 | extern struct rmi_function_handler rmi_f30_handler; |
| 137 | extern struct rmi_function_handler rmi_f34_handler; | 137 | extern struct rmi_function_handler rmi_f34_handler; |
| 138 | extern struct rmi_function_handler rmi_f3a_handler; | ||
| 138 | extern struct rmi_function_handler rmi_f54_handler; | 139 | extern struct rmi_function_handler rmi_f54_handler; |
| 139 | extern struct rmi_function_handler rmi_f55_handler; | 140 | extern struct rmi_function_handler rmi_f55_handler; |
| 140 | #endif | 141 | #endif |
| @@ -168,17 +168,17 @@ static int rmi_f30_config(struct rmi_function *fn) · 167 unmodified lines | |||
| 168 | rmi_get_platform_data(fn->rmi_dev); | 168 | rmi_get_platform_data(fn->rmi_dev); |
| 169 | int error; | 169 | int error; |
| 170 | 170 | ||
| 171 | /* can happen if f30_data.disable is set */ | 171 | /* can happen if gpio_data.disable is set */ |
| 172 | if (!f30) | 172 | if (!f30) |
| 173 | return 0; | 173 | return 0; |
| 174 | 174 | ||
| 175 | if (pdata->f30_data.trackstick_buttons) { | 175 | if (pdata->gpio_data.trackstick_buttons) { |
| 176 | /* Try [re-]establish link to F03. */ | 176 | /* Try [re-]establish link to F03. */ |
| 177 | f30->f03 = rmi_find_function(fn->rmi_dev, 0x03); | 177 | f30->f03 = rmi_find_function(fn->rmi_dev, 0x03); |
| 178 | f30->trackstick_buttons = f30->f03 != NULL; | 178 | f30->trackstick_buttons = f30->f03 != NULL; |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | if (pdata->f30_data.disable) { | 181 | if (pdata->gpio_data.disable) { |
| 182 | drv->clear_irq_bits(fn->rmi_dev, fn->irq_mask); | 182 | drv->clear_irq_bits(fn->rmi_dev, fn->irq_mask); |
| 183 | } else { | 183 | } else { |
| 184 | /* Write Control Register values back to device */ | 184 | /* Write Control Register values back to device */ |
| @@ -245,10 +245,10 @@ static int rmi_f30_map_gpios(struct rmi_function *fn, · 60 unmodified lines | |||
| 245 | if (!rmi_f30_is_valid_button(i, f30->ctrl)) | 245 | if (!rmi_f30_is_valid_button(i, f30->ctrl)) |
| 246 | continue; | 246 | continue; |
| 247 | 247 | ||
| 248 | if (pdata->f30_data.trackstick_buttons && | 248 | if (pdata->gpio_data.trackstick_buttons && |
| 249 | i >= TRACKSTICK_RANGE_START && i < TRACKSTICK_RANGE_END) { | 249 | i >= TRACKSTICK_RANGE_START && i < TRACKSTICK_RANGE_END) { |
| 250 | f30->gpioled_key_map[i] = trackstick_button++; | 250 | f30->gpioled_key_map[i] = trackstick_button++; |
| 251 | } else if (!pdata->f30_data.buttonpad || !button_mapped) { | 251 | } else if (!pdata->gpio_data.buttonpad || !button_mapped) { |
| 252 | f30->gpioled_key_map[i] = button; | 252 | f30->gpioled_key_map[i] = button; |
| 253 | input_set_capability(input, EV_KEY, button++); | 253 | input_set_capability(input, EV_KEY, button++); |
| 254 | button_mapped = true; | 254 | button_mapped = true; |
| @@ -264,7 +264,7 @@ static int rmi_f30_map_gpios(struct rmi_function *fn, · 9 unmodified lines | |||
| 264 | * but I am not sure, so use only the pdata info and the number of | 264 | * but I am not sure, so use only the pdata info and the number of |
| 265 | * mapped buttons. | 265 | * mapped buttons. |
| 266 | */ | 266 | */ |
| 267 | if (pdata->f30_data.buttonpad || (button - BTN_LEFT == 1)) | 267 | if (pdata->gpio_data.buttonpad || (button - BTN_LEFT == 1)) |
| 268 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); | 268 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); |
| 269 | 269 | ||
| 270 | return 0; | 270 | return 0; |
| @@ -372,7 +372,7 @@ static int rmi_f30_probe(struct rmi_function *fn) · 101 unmodified lines | |||
| 372 | struct f30_data *f30; | 372 | struct f30_data *f30; |
| 373 | int error; | 373 | int error; |
| 374 | 374 | ||
| 375 | if (pdata->f30_data.disable) | 375 | if (pdata->gpio_data.disable) |
| 376 | return 0; | 376 | return 0; |
| 377 | 377 | ||
| 378 | if (!drv_data->input) { | 378 | if (!drv_data->input) { |
| @@ -1364,9 +1364,14 @@ int rmi_f34v7_probe(struct f34_data *f34) · 1363 unmodified lines | |||
| 1364 | f34->bl_version = 6; | 1364 | f34->bl_version = 6; |
| 1365 | } else if (f34->bootloader_id[1] == 7) { | 1365 | } else if (f34->bootloader_id[1] == 7) { |
| 1366 | f34->bl_version = 7; | 1366 | f34->bl_version = 7; |
| 1367 | } else if (f34->bootloader_id[1] == 8) { | ||
| 1368 | f34->bl_version = 8; | ||
| 1367 | } else { | 1369 | } else { |
| 1368 | dev_err(&f34->fn->dev, "%s: Unrecognized bootloader version\n", | 1370 | dev_err(&f34->fn->dev, |
| 1369 | __func__); | 1371 | "%s: Unrecognized bootloader version: %d (%c) %d (%c)\n", |
| 1372 | __func__, | ||
| 1373 | f34->bootloader_id[0], f34->bootloader_id[0], | ||
| 1374 | f34->bootloader_id[1], f34->bootloader_id[1]); | ||
| 1370 | return -EINVAL; | 1375 | return -EINVAL; |
| 1371 | } | 1376 | } |
| 1372 | 1377 | ||
| @@ -0,0 +1,241 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2012-2020 Synaptics Incorporated | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/kernel.h> | ||
| 7 | #include <linux/rmi.h> | ||
| 8 | #include <linux/input.h> | ||
| 9 | #include <linux/slab.h> | ||
| 10 | #include "rmi_driver.h" | ||
| 11 | |||
| 12 | #define RMI_F3A_MAX_GPIO_COUNT 128 | ||
| 13 | #define RMI_F3A_MAX_REG_SIZE DIV_ROUND_UP(RMI_F3A_MAX_GPIO_COUNT, 8) | ||
| 14 | |||
| 15 | /* Defs for Query 0 */ | ||
| 16 | #define RMI_F3A_GPIO_COUNT 0x7F | ||
| 17 | |||
| 18 | #define RMI_F3A_DATA_REGS_MAX_SIZE RMI_F3A_MAX_REG_SIZE | ||
| 19 | |||
| 20 | #define TRACKSTICK_RANGE_START 3 | ||
| 21 | #define TRACKSTICK_RANGE_END 6 | ||
| 22 | |||
| 23 | struct f3a_data { | ||
| 24 | /* Query Data */ | ||
| 25 | u8 gpio_count; | ||
| 26 | |||
| 27 | u8 register_count; | ||
| 28 | |||
| 29 | u8 data_regs[RMI_F3A_DATA_REGS_MAX_SIZE]; | ||
| 30 | u16 *gpio_key_map; | ||
| 31 | |||
| 32 | struct input_dev *input; | ||
| 33 | |||
| 34 | struct rmi_function *f03; | ||
| 35 | bool trackstick_buttons; | ||
| 36 | }; | ||
| 37 | |||
| 38 | static void rmi_f3a_report_button(struct rmi_function *fn, | ||
| 39 | struct f3a_data *f3a, unsigned int button) | ||
| 40 | { | ||
| 41 | u16 key_code = f3a->gpio_key_map[button]; | ||
| 42 | bool key_down = !(f3a->data_regs[0] & BIT(button)); | ||
| 43 | |||
| 44 | if (f3a->trackstick_buttons && | ||
| 45 | button >= TRACKSTICK_RANGE_START && | ||
| 46 | button <= TRACKSTICK_RANGE_END) { | ||
| 47 | rmi_f03_overwrite_button(f3a->f03, key_code, key_down); | ||
| 48 | } else { | ||
| 49 | rmi_dbg(RMI_DEBUG_FN, &fn->dev, | ||
| 50 | "%s: call input report key (0x%04x) value (0x%02x)", | ||
| 51 | __func__, key_code, key_down); | ||
| 52 | input_report_key(f3a->input, key_code, key_down); | ||
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | static irqreturn_t rmi_f3a_attention(int irq, void *ctx) | ||
| 57 | { | ||
| 58 | struct rmi_function *fn = ctx; | ||
| 59 | struct f3a_data *f3a = dev_get_drvdata(&fn->dev); | ||
| 60 | struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev); | ||
| 61 | int error; | ||
| 62 | int i; | ||
| 63 | |||
| 64 | if (drvdata->attn_data.data) { | ||
| 65 | if (drvdata->attn_data.size < f3a->register_count) { | ||
| 66 | dev_warn(&fn->dev, | ||
| 67 | "F3A interrupted, but data is missing\n"); | ||
| 68 | return IRQ_HANDLED; | ||
| 69 | } | ||
| 70 | memcpy(f3a->data_regs, drvdata->attn_data.data, | ||
| 71 | f3a->register_count); | ||
| 72 | drvdata->attn_data.data += f3a->register_count; | ||
| 73 | drvdata->attn_data.size -= f3a->register_count; | ||
| 74 | } else { | ||
| 75 | error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr, | ||
| 76 | f3a->data_regs, f3a->register_count); | ||
| 77 | if (error) { | ||
| 78 | dev_err(&fn->dev, | ||
| 79 | "%s: Failed to read F3a data registers: %d\n", | ||
| 80 | __func__, error); | ||
| 81 | return IRQ_RETVAL(error); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | for (i = 0; i < f3a->gpio_count; i++) | ||
| 86 | if (f3a->gpio_key_map[i] != KEY_RESERVED) | ||
| 87 | rmi_f3a_report_button(fn, f3a, i); | ||
| 88 | if (f3a->trackstick_buttons) | ||
| 89 | rmi_f03_commit_buttons(f3a->f03); | ||
| 90 | |||
| 91 | return IRQ_HANDLED; | ||
| 92 | } | ||
| 93 | |||
| 94 | static int rmi_f3a_config(struct rmi_function *fn) | ||
| 95 | { | ||
| 96 | struct f3a_data *f3a = dev_get_drvdata(&fn->dev); | ||
| 97 | struct rmi_driver *drv = fn->rmi_dev->driver; | ||
| 98 | const struct rmi_device_platform_data *pdata = | ||
| 99 | rmi_get_platform_data(fn->rmi_dev); | ||
| 100 | |||
| 101 | if (!f3a) | ||
| 102 | return 0; | ||
| 103 | |||
| 104 | if (pdata->gpio_data.trackstick_buttons) { | ||
| 105 | /* Try [re-]establish link to F03. */ | ||
| 106 | f3a->f03 = rmi_find_function(fn->rmi_dev, 0x03); | ||
| 107 | f3a->trackstick_buttons = f3a->f03 != NULL; | ||
| 108 | } | ||
| 109 | |||
| 110 | drv->set_irq_bits(fn->rmi_dev, fn->irq_mask); | ||
| 111 | |||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | static bool rmi_f3a_is_valid_button(int button, struct f3a_data *f3a, | ||
| 116 | u8 *query1_regs, u8 *ctrl1_regs) | ||
| 117 | { | ||
| 118 | /* gpio exist && direction input */ | ||
| 119 | return (query1_regs[0] & BIT(button)) && !(ctrl1_regs[0] & BIT(button)); | ||
| 120 | } | ||
| 121 | |||
| 122 | static int rmi_f3a_map_gpios(struct rmi_function *fn, struct f3a_data *f3a, | ||
| 123 | u8 *query1_regs, u8 *ctrl1_regs) | ||
| 124 | { | ||
| 125 | const struct rmi_device_platform_data *pdata = | ||
| 126 | rmi_get_platform_data(fn->rmi_dev); | ||
| 127 | struct input_dev *input = f3a->input; | ||
| 128 | unsigned int button = BTN_LEFT; | ||
| 129 | unsigned int trackstick_button = BTN_LEFT; | ||
| 130 | bool button_mapped = false; | ||
| 131 | int i; | ||
| 132 | int button_count = min_t(u8, f3a->gpio_count, TRACKSTICK_RANGE_END); | ||
| 133 | |||
| 134 | f3a->gpio_key_map = devm_kcalloc(&fn->dev, | ||
| 135 | button_count, | ||
| 136 | sizeof(f3a->gpio_key_map[0]), | ||
| 137 | GFP_KERNEL); | ||
| 138 | if (!f3a->gpio_key_map) { | ||
| 139 | dev_err(&fn->dev, "Failed to allocate gpio map memory.\n"); | ||
| 140 | return -ENOMEM; | ||
| 141 | } | ||
| 142 | |||
| 143 | for (i = 0; i < button_count; i++) { | ||
| 144 | if (!rmi_f3a_is_valid_button(i, f3a, query1_regs, ctrl1_regs)) | ||
| 145 | continue; | ||
| 146 | |||
| 147 | if (pdata->gpio_data.trackstick_buttons && | ||
| 148 | i >= TRACKSTICK_RANGE_START && | ||
| 149 | i < TRACKSTICK_RANGE_END) { | ||
| 150 | f3a->gpio_key_map[i] = trackstick_button++; | ||
| 151 | } else if (!pdata->gpio_data.buttonpad || !button_mapped) { | ||
| 152 | f3a->gpio_key_map[i] = button; | ||
| 153 | input_set_capability(input, EV_KEY, button++); | ||
| 154 | button_mapped = true; | ||
| 155 | } | ||
| 156 | } | ||
| 157 | input->keycode = f3a->gpio_key_map; | ||
| 158 | input->keycodesize = sizeof(f3a->gpio_key_map[0]); | ||
| 159 | input->keycodemax = f3a->gpio_count; | ||
| 160 | |||
| 161 | if (pdata->gpio_data.buttonpad || (button - BTN_LEFT == 1)) | ||
| 162 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | static int rmi_f3a_initialize(struct rmi_function *fn, struct f3a_data *f3a) | ||
| 168 | { | ||
| 169 | u8 query1[RMI_F3A_MAX_REG_SIZE]; | ||
| 170 | u8 ctrl1[RMI_F3A_MAX_REG_SIZE]; | ||
| 171 | u8 buf; | ||
| 172 | int error; | ||
| 173 | |||
| 174 | error = rmi_read(fn->rmi_dev, fn->fd.query_base_addr, &buf); | ||
| 175 | if (error < 0) { | ||
| 176 | dev_err(&fn->dev, "Failed to read general info register: %d\n", | ||
| 177 | error); | ||
| 178 | return -ENODEV; | ||
| 179 | } | ||
| 180 | |||
| 181 | f3a->gpio_count = buf & RMI_F3A_GPIO_COUNT; | ||
| 182 | f3a->register_count = DIV_ROUND_UP(f3a->gpio_count, 8); | ||
| 183 | |||
| 184 | /* Query1 -> gpio exist */ | ||
| 185 | error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr + 1, | ||
| 186 | query1, f3a->register_count); | ||
| 187 | if (error) { | ||
| 188 | dev_err(&fn->dev, "Failed to read query1 register\n"); | ||
| 189 | return error; | ||
| 190 | } | ||
| 191 | |||
| 192 | /* Ctrl1 -> gpio direction */ | ||
| 193 | error = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr + 1, | ||
| 194 | ctrl1, f3a->register_count); | ||
| 195 | if (error) { | ||
| 196 | dev_err(&fn->dev, "Failed to read control1 register\n"); | ||
| 197 | return error; | ||
| 198 | } | ||
| 199 | |||
| 200 | error = rmi_f3a_map_gpios(fn, f3a, query1, ctrl1); | ||
| 201 | if (error) | ||
| 202 | return error; | ||
| 203 | |||
| 204 | return 0; | ||
| 205 | } | ||
| 206 | |||
| 207 | static int rmi_f3a_probe(struct rmi_function *fn) | ||
| 208 | { | ||
| 209 | struct rmi_device *rmi_dev = fn->rmi_dev; | ||
| 210 | struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev); | ||
| 211 | struct f3a_data *f3a; | ||
| 212 | int error; | ||
| 213 | |||
| 214 | if (!drv_data->input) { | ||
| 215 | dev_info(&fn->dev, "F3A: no input device found, ignoring\n"); | ||
| 216 | return -ENXIO; | ||
| 217 | } | ||
| 218 | |||
| 219 | f3a = devm_kzalloc(&fn->dev, sizeof(*f3a), GFP_KERNEL); | ||
| 220 | if (!f3a) | ||
| 221 | return -ENOMEM; | ||
| 222 | |||
| 223 | f3a->input = drv_data->input; | ||
| 224 | |||
| 225 | error = rmi_f3a_initialize(fn, f3a); | ||
| 226 | if (error) | ||
| 227 | return error; | ||
| 228 | |||
| 229 | dev_set_drvdata(&fn->dev, f3a); | ||
| 230 | return 0; | ||
| 231 | } | ||
| 232 | |||
| 233 | struct rmi_function_handler rmi_f3a_handler = { | ||
| 234 | .driver = { | ||
| 235 | .name = "rmi4_f3a", | ||
| 236 | }, | ||
| 237 | .func = 0x3a, | ||
| 238 | .probe = rmi_f3a_probe, | ||
| 239 | .config = rmi_f3a_config, | ||
| 240 | .attention = rmi_f3a_attention, | ||
| 241 | }; | ||
| @@ -211,7 +211,6 @@ static int sun4i_ps2_probe(struct platform_device *pdev) · 210 unmodified lines | |||
| 211 | struct sun4i_ps2data *drvdata; | 211 | struct sun4i_ps2data *drvdata; |
| 212 | struct serio *serio; | 212 | struct serio *serio; |
| 213 | struct device *dev = &pdev->dev; | 213 | struct device *dev = &pdev->dev; |
| 214 | unsigned int irq; | ||
| 215 | int error; | 214 | int error; |
| 216 | 215 | ||
| 217 | drvdata = kzalloc(sizeof(struct sun4i_ps2data), GFP_KERNEL); | 216 | drvdata = kzalloc(sizeof(struct sun4i_ps2data), GFP_KERNEL); |
| @@ -264,14 +263,12 @@ static int sun4i_ps2_probe(struct platform_device *pdev) · 46 unmodified lines | |||
| 264 | writel(0, drvdata->reg_base + PS2_REG_GCTL); | 263 | writel(0, drvdata->reg_base + PS2_REG_GCTL); |
| 265 | 264 | ||
| 266 | /* Get IRQ for the device */ | 265 | /* Get IRQ for the device */ |
| 267 | irq = platform_get_irq(pdev, 0); | 266 | drvdata->irq = platform_get_irq(pdev, 0); |
| 268 | if (!irq) { | 267 | if (drvdata->irq < 0) { |
| 269 | dev_err(dev, "no IRQ found\n"); | 268 | error = drvdata->irq; |
| 270 | error = -ENXIO; | ||
| 271 | goto err_disable_clk; | 269 | goto err_disable_clk; |
| 272 | } | 270 | } |
| 273 | 271 | ||
| 274 | drvdata->irq = irq; | ||
| 275 | drvdata->serio = serio; | 272 | drvdata->serio = serio; |
| 276 | drvdata->dev = dev; | 273 | drvdata->dev = dev; |
| 277 | 274 | ||
| @@ -1322,4 +1322,16 @@ config TOUCHSCREEN_IQS5XX · 1321 unmodified lines | |||
| 1322 | To compile this driver as a module, choose M here: the | 1322 | To compile this driver as a module, choose M here: the |
| 1323 | module will be called iqs5xx. | 1323 | module will be called iqs5xx. |
| 1324 | 1324 | ||
| 1325 | config TOUCHSCREEN_ZINITIX | ||
| 1326 | tristate "Zinitix touchscreen support" | ||
| 1327 | depends on I2C | ||
| 1328 | help | ||
| 1329 | Say Y here if you have a touchscreen using Zinitix bt541, | ||
| 1330 | or something similar enough. | ||
| 1331 | |||
| 1332 | If unsure, say N. | ||
| 1333 | |||
| 1334 | To compile this driver as a module, choose M here: the | ||
| 1335 | module will be called zinitix. | ||
| 1336 | |||
| 1325 | endif | 1337 | endif |
| @@ -111,3 +111,4 @@ obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o · 110 unmodified lines | |||
| 111 | obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o | 111 | obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o |
| 112 | obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o | 112 | obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o |
| 113 | obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.o | 113 | obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.o |
| 114 | obj-$(CONFIG_TOUCHSCREEN_ZINITIX) += zinitix.o | ||
| @@ -90,7 +90,7 @@ · 89 unmodified lines | |||
| 90 | /* FW read command, 0x53 0x?? 0x0, 0x01 */ | 90 | /* FW read command, 0x53 0x?? 0x0, 0x01 */ |
| 91 | #define E_ELAN_INFO_FW_VER 0x00 | 91 | #define E_ELAN_INFO_FW_VER 0x00 |
| 92 | #define E_ELAN_INFO_BC_VER 0x10 | 92 | #define E_ELAN_INFO_BC_VER 0x10 |
| 93 | #define E_ELAN_INFO_REK 0xE0 | 93 | #define E_ELAN_INFO_REK 0xD0 |
| 94 | #define E_ELAN_INFO_TEST_VER 0xE0 | 94 | #define E_ELAN_INFO_TEST_VER 0xE0 |
| 95 | #define E_ELAN_INFO_FW_ID 0xF0 | 95 | #define E_ELAN_INFO_FW_ID 0xF0 |
| 96 | #define E_INFO_OSR 0xD6 | 96 | #define E_INFO_OSR 0xD6 |
| @@ -134,6 +134,7 @@ struct elants_data { · 37 unmodified lines | |||
| 134 | u8 bc_version; | 134 | u8 bc_version; |
| 135 | u8 iap_version; | 135 | u8 iap_version; |
| 136 | u16 hw_version; | 136 | u16 hw_version; |
| 137 | u8 major_res; | ||
| 137 | unsigned int x_res; /* resolution in units/mm */ | 138 | unsigned int x_res; /* resolution in units/mm */ |
| 138 | unsigned int y_res; | 139 | unsigned int y_res; |
| 139 | unsigned int x_max; | 140 | unsigned int x_max; |
| @@ -459,6 +460,9 @@ static int elants_i2c_query_ts_info(struct elants_data *ts) · 319 unmodified lines | |||
| 459 | rows = resp[2] + resp[6] + resp[10]; | 460 | rows = resp[2] + resp[6] + resp[10]; |
| 460 | cols = resp[3] + resp[7] + resp[11]; | 461 | cols = resp[3] + resp[7] + resp[11]; |
| 461 | 462 | ||
| 463 | /* Get report resolution value of ABS_MT_TOUCH_MAJOR */ | ||
| 464 | ts->major_res = resp[16]; | ||
| 465 | |||
| 462 | /* Process mm_to_pixel information */ | 466 | /* Process mm_to_pixel information */ |
| 463 | error = elants_i2c_execute_command(client, | 467 | error = elants_i2c_execute_command(client, |
| 464 | get_osr_cmd, sizeof(get_osr_cmd), | 468 | get_osr_cmd, sizeof(get_osr_cmd), |
| @@ -1325,6 +1329,8 @@ static int elants_i2c_probe(struct i2c_client *client, · 860 unmodified lines | |||
| 1325 | 0, MT_TOOL_PALM, 0, 0); | 1329 | 0, MT_TOOL_PALM, 0, 0); |
| 1326 | input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res); | 1330 | input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res); |
| 1327 | input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res); | 1331 | input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res); |
| 1332 | if (ts->major_res > 0) | ||
| 1333 | input_abs_set_res(ts->input, ABS_MT_TOUCH_MAJOR, ts->major_res); | ||
| 1328 | 1334 | ||
| 1329 | touchscreen_parse_properties(ts->input, true, &ts->prop); | 1335 | touchscreen_parse_properties(ts->input, true, &ts->prop); |
| 1330 | 1336 | ||
| @@ -315,9 +315,8 @@ static irqreturn_t adc_irq_fn(int irq, void *dev_id) · 314 unmodified lines | |||
| 315 | return IRQ_HANDLED; | 315 | return IRQ_HANDLED; |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | static int imx6ul_tsc_open(struct input_dev *input_dev) | 318 | static int imx6ul_tsc_start(struct imx6ul_tsc *tsc) |
| 319 | { | 319 | { |
| 320 | struct imx6ul_tsc *tsc = input_get_drvdata(input_dev); | ||
| 321 | int err; | 320 | int err; |
| 322 | 321 | ||
| 323 | err = clk_prepare_enable(tsc->adc_clk); | 322 | err = clk_prepare_enable(tsc->adc_clk); |
| @@ -349,16 +348,29 @@ disable_adc_clk: · 25 unmodified lines | |||
| 349 | return err; | 348 | return err; |
| 350 | } | 349 | } |
| 351 | 350 | ||
| 352 | static void imx6ul_tsc_close(struct input_dev *input_dev) | 351 | static void imx6ul_tsc_stop(struct imx6ul_tsc *tsc) |
| 353 | { | 352 | { |
| 354 | struct imx6ul_tsc *tsc = input_get_drvdata(input_dev); | ||
| 355 | |||
| 356 | imx6ul_tsc_disable(tsc); | 353 | imx6ul_tsc_disable(tsc); |
| 357 | 354 | ||
| 358 | clk_disable_unprepare(tsc->tsc_clk); | 355 | clk_disable_unprepare(tsc->tsc_clk); |
| 359 | clk_disable_unprepare(tsc->adc_clk); | 356 | clk_disable_unprepare(tsc->adc_clk); |
| 360 | } | 357 | } |
| 361 | 358 | ||
| 359 | |||
| 360 | static int imx6ul_tsc_open(struct input_dev *input_dev) | ||
| 361 | { | ||
| 362 | struct imx6ul_tsc *tsc = input_get_drvdata(input_dev); | ||
| 363 | |||
| 364 | return imx6ul_tsc_start(tsc); | ||
| 365 | } | ||
| 366 | |||
| 367 | static void imx6ul_tsc_close(struct input_dev *input_dev) | ||
| 368 | { | ||
| 369 | struct imx6ul_tsc *tsc = input_get_drvdata(input_dev); | ||
| 370 | |||
| 371 | imx6ul_tsc_stop(tsc); | ||
| 372 | } | ||
| 373 | |||
| 362 | static int imx6ul_tsc_probe(struct platform_device *pdev) | 374 | static int imx6ul_tsc_probe(struct platform_device *pdev) |
| 363 | { | 375 | { |
| 364 | struct device_node *np = pdev->dev.of_node; | 376 | struct device_node *np = pdev->dev.of_node; |
| @@ -509,12 +521,8 @@ static int __maybe_unused imx6ul_tsc_suspend(struct device *dev) · 144 unmodified lines | |||
| 509 | 521 | ||
| 510 | mutex_lock(&input_dev->mutex); | 522 | mutex_lock(&input_dev->mutex); |
| 511 | 523 | ||
| 512 | if (input_dev->users) { | 524 | if (input_dev->users) |
| 513 | imx6ul_tsc_disable(tsc); | 525 | imx6ul_tsc_stop(tsc); |
| 514 | |||
| 515 | clk_disable_unprepare(tsc->tsc_clk); | ||
| 516 | clk_disable_unprepare(tsc->adc_clk); | ||
| 517 | } | ||
| 518 | 526 | ||
| 519 | mutex_unlock(&input_dev->mutex); | 527 | mutex_unlock(&input_dev->mutex); |
| 520 | 528 | ||
| @@ -530,22 +538,11 @@ static int __maybe_unused imx6ul_tsc_resume(struct device *dev) · 9 unmodified lines | |||
| 530 | 538 | ||
| 531 | mutex_lock(&input_dev->mutex); | 539 | mutex_lock(&input_dev->mutex); |
| 532 | 540 | ||
| 533 | if (input_dev->users) { | 541 | if (input_dev->users) |
| 534 | retval = clk_prepare_enable(tsc->adc_clk); | 542 | retval = imx6ul_tsc_start(tsc); |
| 535 | if (retval) | ||
| 536 | goto out; | ||
| 537 | |||
| 538 | retval = clk_prepare_enable(tsc->tsc_clk); | ||
| 539 | if (retval) { | ||
| 540 | clk_disable_unprepare(tsc->adc_clk); | ||
| 541 | goto out; | ||
| 542 | } | ||
| 543 | |||
| 544 | retval = imx6ul_tsc_init(tsc); | ||
| 545 | } | ||
| 546 | 543 | ||
| 547 | out: | ||
| 548 | mutex_unlock(&input_dev->mutex); | 544 | mutex_unlock(&input_dev->mutex); |
| 545 | |||
| 549 | return retval; | 546 | return retval; |
| 550 | } | 547 | } |
| 551 | 548 | ||
| @@ -51,6 +51,7 @@ · 50 unmodified lines | |||
| 51 | 51 | ||
| 52 | /* Touch relative info */ | 52 | /* Touch relative info */ |
| 53 | #define RM_MAX_RETRIES 3 | 53 | #define RM_MAX_RETRIES 3 |
| 54 | #define RM_RETRY_DELAY_MS 20 | ||
| 54 | #define RM_MAX_TOUCH_NUM 10 | 55 | #define RM_MAX_TOUCH_NUM 10 |
| 55 | #define RM_BOOT_DELAY_MS 100 | 56 | #define RM_BOOT_DELAY_MS 100 |
| 56 | 57 | ||
| @@ -136,83 +137,82 @@ struct raydium_data { · 79 unmodified lines | |||
| 136 | bool wake_irq_enabled; | 137 | bool wake_irq_enabled; |
| 137 | }; | 138 | }; |
| 138 | 139 | ||
| 139 | static int raydium_i2c_send(struct i2c_client *client, | 140 | static int raydium_i2c_xfer(struct i2c_client *client, |
| 140 | u8 addr, const void *data, size_t len) | 141 | u32 addr, void *data, size_t len, bool is_read) |
| 141 | { | 142 | { |
| 142 | u8 *buf; | 143 | struct raydium_bank_switch_header { |
| 143 | int tries = 0; | 144 | u8 cmd; |
| 144 | int ret; | 145 | __be32 be_addr; |
| 145 | 146 | } __packed header = { | |
| 146 | buf = kmalloc(len + 1, GFP_KERNEL); | 147 | .cmd = RM_CMD_BANK_SWITCH, |
| 147 | if (!buf) | 148 | .be_addr = cpu_to_be32(addr), |
| 148 | return -ENOMEM; | 149 | }; |
| 149 | |||
| 150 | buf[0] = addr; | ||
| 151 | memcpy(buf + 1, data, len); | ||
| 152 | |||
| 153 | do { | ||
| 154 | ret = i2c_master_send(client, buf, len + 1); | ||
| 155 | if (likely(ret == len + 1)) | ||
| 156 | break; | ||
| 157 | |||
| 158 | msleep(20); | ||
| 159 | } while (++tries < RM_MAX_RETRIES); | ||
| 160 | |||
| 161 | kfree(buf); | ||
| 162 | |||
| 163 | if (unlikely(ret != len + 1)) { | ||
| 164 | if (ret >= 0) | ||
| 165 | ret = -EIO; | ||
| 166 | dev_err(&client->dev, "%s failed: %d\n", __func__, ret); | ||
| 167 | return ret; | ||
| 168 | } | ||
| 169 | 150 | ||
| 170 | return 0; | 151 | u8 reg_addr = addr & 0xff; |
| 171 | } | ||
| 172 | 152 | ||
| 173 | static int raydium_i2c_read(struct i2c_client *client, | ||
| 174 | u8 addr, void *data, size_t len) | ||
| 175 | { | ||
| 176 | struct i2c_msg xfer[] = { | 153 | struct i2c_msg xfer[] = { |
| 154 | { | ||
| 155 | .addr = client->addr, | ||
| 156 | .len = sizeof(header), | ||
| 157 | .buf = (u8 *)&header, | ||
| 158 | }, | ||
| 177 | { | 159 | { |
| 178 | .addr = client->addr, | 160 | .addr = client->addr, |
| 179 | .len = 1, | 161 | .len = 1, |
| 180 | .buf = &addr, | 162 | .buf = ®_addr, |
| 181 | }, | 163 | }, |
| 182 | { | 164 | { |
| 183 | .addr = client->addr, | 165 | .addr = client->addr, |
| 184 | .flags = I2C_M_RD, | ||
| 185 | .len = len, | 166 | .len = len, |
| 186 | .buf = data, | 167 | .buf = data, |
| 168 | .flags = is_read ? I2C_M_RD : 0, | ||
| 187 | } | 169 | } |
| 188 | }; | 170 | }; |
| 171 | |||
| 172 | /* | ||
| 173 | * If address is greater than 255, then RM_CMD_BANK_SWITCH needs to be | ||
| 174 | * sent first. Else, skip the header i.e. xfer[0]. | ||
| 175 | */ | ||
| 176 | int xfer_start_idx = (addr > 0xff) ? 0 : 1; | ||
| 177 | size_t xfer_count = ARRAY_SIZE(xfer) - xfer_start_idx; | ||
| 189 | int ret; | 178 | int ret; |
| 190 | 179 | ||
| 191 | ret = i2c_transfer(client->adapter, xfer, ARRAY_SIZE(xfer)); | 180 | ret = i2c_transfer(client->adapter, &xfer[xfer_start_idx], xfer_count); |
| 192 | if (unlikely(ret != ARRAY_SIZE(xfer))) | 181 | if (likely(ret == xfer_count)) |
| 193 | return ret < 0 ? ret : -EIO; | 182 | return 0; |
| 183 | |||
| 184 | return ret < 0 ? ret : -EIO; | ||
| 185 | } | ||
| 194 | 186 | ||
| 195 | return 0; | 187 | static int raydium_i2c_send(struct i2c_client *client, |
| 188 | u32 addr, const void *data, size_t len) | ||
| 189 | { | ||
| 190 | int tries = 0; | ||
| 191 | int error; | ||
| 192 | |||
| 193 | do { | ||
| 194 | error = raydium_i2c_xfer(client, addr, (void *)data, len, | ||
| 195 | false); | ||
| 196 | if (likely(!error)) | ||
| 197 | return 0; | ||
| 198 | |||
| 199 | msleep(RM_RETRY_DELAY_MS); | ||
| 200 | } while (++tries < RM_MAX_RETRIES); | ||
| 201 | |||
| 202 | dev_err(&client->dev, "%s failed: %d\n", __func__, error); | ||
| 203 | return error; | ||
| 196 | } | 204 | } |
| 197 | 205 | ||
| 198 | static int raydium_i2c_read_message(struct i2c_client *client, | 206 | static int raydium_i2c_read(struct i2c_client *client, |
| 199 | u32 addr, void *data, size_t len) | 207 | u32 addr, void *data, size_t len) |
| 200 | { | 208 | { |
| 201 | __be32 be_addr; | ||
| 202 | size_t xfer_len; | 209 | size_t xfer_len; |
| 203 | int error; | 210 | int error; |
| 204 | 211 | ||
| 205 | while (len) { | 212 | while (len) { |
| 206 | xfer_len = min_t(size_t, len, RM_MAX_READ_SIZE); | 213 | xfer_len = min_t(size_t, len, RM_MAX_READ_SIZE); |
| 207 | 214 | error = raydium_i2c_xfer(client, addr, data, xfer_len, true); | |
| 208 | be_addr = cpu_to_be32(addr); | 215 | if (unlikely(error)) |
| 209 | |||
| 210 | error = raydium_i2c_send(client, RM_CMD_BANK_SWITCH, | ||
| 211 | &be_addr, sizeof(be_addr)); | ||
| 212 | if (!error) | ||
| 213 | error = raydium_i2c_read(client, addr & 0xff, | ||
| 214 | data, xfer_len); | ||
| 215 | if (error) | ||
| 216 | return error; | 216 | return error; |
| 217 | 217 | ||
| 218 | len -= xfer_len; | 218 | len -= xfer_len; |
| @@ -223,27 +223,13 @@ static int raydium_i2c_read_message(struct i2c_client *client, · 4 unmodified lines | |||
| 223 | return 0; | 223 | return 0; |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | static int raydium_i2c_send_message(struct i2c_client *client, | ||
| 227 | u32 addr, const void *data, size_t len) | ||
| 228 | { | ||
| 229 | __be32 be_addr = cpu_to_be32(addr); | ||
| 230 | int error; | ||
| 231 | |||
| 232 | error = raydium_i2c_send(client, RM_CMD_BANK_SWITCH, | ||
| 233 | &be_addr, sizeof(be_addr)); | ||
| 234 | if (!error) | ||
| 235 | error = raydium_i2c_send(client, addr & 0xff, data, len); | ||
| 236 | |||
| 237 | return error; | ||
| 238 | } | ||
| 239 | |||
| 240 | static int raydium_i2c_sw_reset(struct i2c_client *client) | 226 | static int raydium_i2c_sw_reset(struct i2c_client *client) |
| 241 | { | 227 | { |
| 242 | const u8 soft_rst_cmd = 0x01; | 228 | const u8 soft_rst_cmd = 0x01; |
| 243 | int error; | 229 | int error; |
| 244 | 230 | ||
| 245 | error = raydium_i2c_send_message(client, RM_RESET_MSG_ADDR, | 231 | error = raydium_i2c_send(client, RM_RESET_MSG_ADDR, &soft_rst_cmd, |
| 246 | &soft_rst_cmd, sizeof(soft_rst_cmd)); | 232 | sizeof(soft_rst_cmd)); |
| 247 | if (error) { | 233 | if (error) { |
| 248 | dev_err(&client->dev, "software reset failed: %d\n", error); | 234 | dev_err(&client->dev, "software reset failed: %d\n", error); |
| 249 | return error; | 235 | return error; |
| @@ -295,9 +281,8 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts) · 45 unmodified lines | |||
| 295 | if (error) | 281 | if (error) |
| 296 | continue; | 282 | continue; |
| 297 | 283 | ||
| 298 | error = raydium_i2c_read_message(client, | 284 | error = raydium_i2c_read(client, le32_to_cpu(query_bank_addr), |
| 299 | le32_to_cpu(query_bank_addr), | 285 | &ts->info, sizeof(ts->info)); |
| 300 | &ts->info, sizeof(ts->info)); | ||
| 301 | if (error) | 286 | if (error) |
| 302 | continue; | 287 | continue; |
| 303 | 288 | ||
| @@ -834,8 +819,8 @@ static irqreturn_t raydium_i2c_irq(int irq, void *_dev) · 530 unmodified lines | |||
| 834 | if (ts->boot_mode != RAYDIUM_TS_MAIN) | 819 | if (ts->boot_mode != RAYDIUM_TS_MAIN) |
| 835 | goto out; | 820 | goto out; |
| 836 | 821 | ||
| 837 | error = raydium_i2c_read_message(ts->client, ts->data_bank_addr, | 822 | error = raydium_i2c_read(ts->client, ts->data_bank_addr, |
| 838 | ts->report_data, ts->pkg_size); | 823 | ts->report_data, ts->pkg_size); |
| 839 | if (error) | 824 | if (error) |
| 840 | goto out; | 825 | goto out; |
| 841 | 826 | ||
| @@ -479,7 +479,7 @@ static ssize_t stmfts_sysfs_hover_enable_write(struct device *dev, · 478 unmodified lines | |||
| 479 | 479 | ||
| 480 | mutex_lock(&sdata->mutex); | 480 | mutex_lock(&sdata->mutex); |
| 481 | 481 | ||
| 482 | if (value & sdata->hover_enabled) | 482 | if (value && sdata->hover_enabled) |
| 483 | goto out; | 483 | goto out; |
| 484 | 484 | ||
| 485 | if (sdata->running) | 485 | if (sdata->running) |
| @@ -0,0 +1,581 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | |||
| 3 | #include <linux/delay.h> | ||
| 4 | #include <linux/i2c.h> | ||
| 5 | #include <linux/input.h> | ||
| 6 | #include <linux/input/mt.h> | ||
| 7 | #include <linux/input/touchscreen.h> | ||
| 8 | #include <linux/interrupt.h> | ||
| 9 | #include <linux/irq.h> | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/of.h> | ||
| 13 | #include <linux/regulator/consumer.h> | ||
| 14 | #include <linux/slab.h> | ||
| 15 | |||
| 16 | /* Register Map */ | ||
| 17 | |||
| 18 | #define BT541_SWRESET_CMD 0x0000 | ||
| 19 | #define BT541_WAKEUP_CMD 0x0001 | ||
| 20 | |||
| 21 | #define BT541_IDLE_CMD 0x0004 | ||
| 22 | #define BT541_SLEEP_CMD 0x0005 | ||
| 23 | |||
| 24 | #define BT541_CLEAR_INT_STATUS_CMD 0x0003 | ||
| 25 | #define BT541_CALIBRATE_CMD 0x0006 | ||
| 26 | #define BT541_SAVE_STATUS_CMD 0x0007 | ||
| 27 | #define BT541_SAVE_CALIBRATION_CMD 0x0008 | ||
| 28 | #define BT541_RECALL_FACTORY_CMD 0x000f | ||
| 29 | |||
| 30 | #define BT541_THRESHOLD 0x0020 | ||
| 31 | |||
| 32 | #define BT541_LARGE_PALM_REJECT_AREA_TH 0x003F | ||
| 33 | |||
| 34 | #define BT541_DEBUG_REG 0x0115 /* 0~7 */ | ||
| 35 | |||
| 36 | #define BT541_TOUCH_MODE 0x0010 | ||
| 37 | #define BT541_CHIP_REVISION 0x0011 | ||
| 38 | #define BT541_FIRMWARE_VERSION 0x0012 | ||
| 39 | |||
| 40 | #define ZINITIX_USB_DETECT 0x116 | ||
| 41 | |||
| 42 | #define BT541_MINOR_FW_VERSION 0x0121 | ||
| 43 | |||
| 44 | #define BT541_VENDOR_ID 0x001C | ||
| 45 | #define BT541_HW_ID 0x0014 | ||
| 46 | |||
| 47 | #define BT541_DATA_VERSION_REG 0x0013 | ||
| 48 | #define BT541_SUPPORTED_FINGER_NUM 0x0015 | ||
| 49 | #define BT541_EEPROM_INFO 0x0018 | ||
| 50 | #define BT541_INITIAL_TOUCH_MODE 0x0019 | ||
| 51 | |||
| 52 | #define BT541_TOTAL_NUMBER_OF_X 0x0060 | ||
| 53 | #define BT541_TOTAL_NUMBER_OF_Y 0x0061 | ||
| 54 | |||
| 55 | #define BT541_DELAY_RAW_FOR_HOST 0x007f | ||
| 56 | |||
| 57 | #define BT541_BUTTON_SUPPORTED_NUM 0x00B0 | ||
| 58 | #define BT541_BUTTON_SENSITIVITY 0x00B2 | ||
| 59 | #define BT541_DUMMY_BUTTON_SENSITIVITY 0X00C8 | ||
| 60 | |||
| 61 | #define BT541_X_RESOLUTION 0x00C0 | ||
| 62 | #define BT541_Y_RESOLUTION 0x00C1 | ||
| 63 | |||
| 64 | #define BT541_POINT_STATUS_REG 0x0080 | ||
| 65 | #define BT541_ICON_STATUS_REG 0x00AA | ||
| 66 | |||
| 67 | #define BT541_POINT_COORD_REG (BT541_POINT_STATUS_REG + 2) | ||
| 68 | |||
| 69 | #define BT541_AFE_FREQUENCY 0x0100 | ||
| 70 | #define BT541_DND_N_COUNT 0x0122 | ||
| 71 | #define BT541_DND_U_COUNT 0x0135 | ||
| 72 | |||
| 73 | #define BT541_RAWDATA_REG 0x0200 | ||
| 74 | |||
| 75 | #define BT541_EEPROM_INFO_REG 0x0018 | ||
| 76 | |||
| 77 | #define BT541_INT_ENABLE_FLAG 0x00f0 | ||
| 78 | #define BT541_PERIODICAL_INTERRUPT_INTERVAL 0x00f1 | ||
| 79 | |||
| 80 | #define BT541_BTN_WIDTH 0x016d | ||
| 81 | |||
| 82 | #define BT541_CHECKSUM_RESULT 0x012c | ||
| 83 | |||
| 84 | #define BT541_INIT_FLASH 0x01d0 | ||
| 85 | #define BT541_WRITE_FLASH 0x01d1 | ||
| 86 | #define BT541_READ_FLASH 0x01d2 | ||
| 87 | |||
| 88 | #define ZINITIX_INTERNAL_FLAG_02 0x011e | ||
| 89 | #define ZINITIX_INTERNAL_FLAG_03 0x011f | ||
| 90 | |||
| 91 | #define ZINITIX_I2C_CHECKSUM_WCNT 0x016a | ||
| 92 | #define ZINITIX_I2C_CHECKSUM_RESULT 0x016c | ||
| 93 | |||
| 94 | /* Interrupt & status register flags */ | ||
| 95 | |||
| 96 | #define BIT_PT_CNT_CHANGE BIT(0) | ||
| 97 | #define BIT_DOWN BIT(1) | ||
| 98 | #define BIT_MOVE BIT(2) | ||
| 99 | #define BIT_UP BIT(3) | ||
| 100 | #define BIT_PALM BIT(4) | ||
| 101 | #define BIT_PALM_REJECT BIT(5) | ||
| 102 | #define BIT_RESERVED_0 BIT(6) | ||
| 103 | #define BIT_RESERVED_1 BIT(7) | ||
| 104 | #define BIT_WEIGHT_CHANGE BIT(8) | ||
| 105 | #define BIT_PT_NO_CHANGE BIT(9) | ||
| 106 | #define BIT_REJECT BIT(10) | ||
| 107 | #define BIT_PT_EXIST BIT(11) | ||
| 108 | #define BIT_RESERVED_2 BIT(12) | ||
| 109 | #define BIT_ERROR BIT(13) | ||
| 110 | #define BIT_DEBUG BIT(14) | ||
| 111 | #define BIT_ICON_EVENT BIT(15) | ||
| 112 | |||
| 113 | #define SUB_BIT_EXIST BIT(0) | ||
| 114 | #define SUB_BIT_DOWN BIT(1) | ||
| 115 | #define SUB_BIT_MOVE BIT(2) | ||
| 116 | #define SUB_BIT_UP BIT(3) | ||
| 117 | #define SUB_BIT_UPDATE BIT(4) | ||
| 118 | #define SUB_BIT_WAIT BIT(5) | ||
| 119 | |||
| 120 | #define DEFAULT_TOUCH_POINT_MODE 2 | ||
| 121 | #define MAX_SUPPORTED_FINGER_NUM 5 | ||
| 122 | |||
| 123 | #define CHIP_ON_DELAY 15 // ms | ||
| 124 | #define FIRMWARE_ON_DELAY 40 // ms | ||
| 125 | |||
| 126 | struct point_coord { | ||
| 127 | __le16 x; | ||
| 128 | __le16 y; | ||
| 129 | u8 width; | ||
| 130 | u8 sub_status; | ||
| 131 | // currently unused, but needed as padding: | ||
| 132 | u8 minor_width; | ||
| 133 | u8 angle; | ||
| 134 | }; | ||
| 135 | |||
| 136 | struct touch_event { | ||
| 137 | __le16 status; | ||
| 138 | u8 finger_cnt; | ||
| 139 | u8 time_stamp; | ||
| 140 | struct point_coord point_coord[MAX_SUPPORTED_FINGER_NUM]; | ||
| 141 | }; | ||
| 142 | |||
| 143 | struct bt541_ts_data { | ||
| 144 | struct i2c_client *client; | ||
| 145 | struct input_dev *input_dev; | ||
| 146 | struct touchscreen_properties prop; | ||
| 147 | struct regulator_bulk_data supplies[2]; | ||
| 148 | u32 zinitix_mode; | ||
| 149 | }; | ||
| 150 | |||
| 151 | static int zinitix_read_data(struct i2c_client *client, | ||
| 152 | u16 reg, void *values, size_t length) | ||
| 153 | { | ||
| 154 | __le16 reg_le = cpu_to_le16(reg); | ||
| 155 | int ret; | ||
| 156 | |||
| 157 | /* A single i2c_transfer() transaction does not work here. */ | ||
| 158 | ret = i2c_master_send(client, (u8 *)®_le, sizeof(reg_le)); | ||
| 159 | if (ret != sizeof(reg_le)) | ||
| 160 | return ret < 0 ? ret : -EIO; | ||
| 161 | |||
| 162 | ret = i2c_master_recv(client, (u8 *)values, length); | ||
| 163 | if (ret != length) | ||
| 164 | return ret < 0 ? ret : -EIO; ; | ||
| 165 | |||
| 166 | return 0; | ||
| 167 | } | ||
| 168 | |||
| 169 | static int zinitix_write_u16(struct i2c_client *client, u16 reg, u16 value) | ||
| 170 | { | ||
| 171 | __le16 packet[2] = {cpu_to_le16(reg), cpu_to_le16(value)}; | ||
| 172 | int ret; | ||
| 173 | |||
| 174 | ret = i2c_master_send(client, (u8 *)packet, sizeof(packet)); | ||
| 175 | if (ret != sizeof(packet)) | ||
| 176 | return ret < 0 ? ret : -EIO; | ||
| 177 | |||
| 178 | return 0; | ||
| 179 | } | ||
| 180 | |||
| 181 | static int zinitix_write_cmd(struct i2c_client *client, u16 reg) | ||
| 182 | { | ||
| 183 | __le16 reg_le = cpu_to_le16(reg); | ||
| 184 | int ret; | ||
| 185 | |||
| 186 | ret = i2c_master_send(client, (u8 *)®_le, sizeof(reg_le)); | ||
| 187 | if (ret != sizeof(reg_le)) | ||
| 188 | return ret < 0 ? ret : -EIO; | ||
| 189 | |||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | |||
| 193 | static bool zinitix_init_touch(struct bt541_ts_data *bt541) | ||
| 194 | { | ||
| 195 | struct i2c_client *client = bt541->client; | ||
| 196 | int i; | ||
| 197 | int error; | ||
| 198 | |||
| 199 | error = zinitix_write_cmd(client, BT541_SWRESET_CMD); | ||
| 200 | if (error) { | ||
| 201 | dev_err(&client->dev, "Failed to write reset command\n"); | ||
| 202 | return error; | ||
| 203 | } | ||
| 204 | |||
| 205 | error = zinitix_write_u16(client, BT541_INT_ENABLE_FLAG, 0x0); | ||
| 206 | if (error) { | ||
| 207 | dev_err(&client->dev, | ||
| 208 | "Failed to reset interrupt enable flag\n"); | ||
| 209 | return error; | ||
| 210 | } | ||
| 211 | |||
| 212 | /* initialize */ | ||
| 213 | error = zinitix_write_u16(client, BT541_X_RESOLUTION, | ||
| 214 | bt541->prop.max_x); | ||
| 215 | if (error) | ||
| 216 | return error; | ||
| 217 | |||
| 218 | error = zinitix_write_u16(client, BT541_Y_RESOLUTION, | ||
| 219 | bt541->prop.max_y); | ||
| 220 | if (error) | ||
| 221 | return error; | ||
| 222 | |||
| 223 | error = zinitix_write_u16(client, BT541_SUPPORTED_FINGER_NUM, | ||
| 224 | MAX_SUPPORTED_FINGER_NUM); | ||
| 225 | if (error) | ||
| 226 | return error; | ||
| 227 | |||
| 228 | error = zinitix_write_u16(client, BT541_INITIAL_TOUCH_MODE, | ||
| 229 | bt541->zinitix_mode); | ||
| 230 | if (error) | ||
| 231 | return error; | ||
| 232 | |||
| 233 | error = zinitix_write_u16(client, BT541_TOUCH_MODE, | ||
| 234 | bt541->zinitix_mode); | ||
| 235 | if (error) | ||
| 236 | return error; | ||
| 237 | |||
| 238 | error = zinitix_write_u16(client, BT541_INT_ENABLE_FLAG, | ||
| 239 | BIT_PT_CNT_CHANGE | BIT_DOWN | BIT_MOVE | | ||
| 240 | BIT_UP); | ||
| 241 | if (error) | ||
| 242 | return error; | ||
| 243 | |||
| 244 | /* clear queue */ | ||
| 245 | for (i = 0; i < 10; i++) { | ||
| 246 | zinitix_write_cmd(client, BT541_CLEAR_INT_STATUS_CMD); | ||
| 247 | udelay(10); | ||
| 248 | } | ||
| 249 | |||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | |||
| 253 | static int zinitix_init_regulators(struct bt541_ts_data *bt541) | ||
| 254 | { | ||
| 255 | struct i2c_client *client = bt541->client; | ||
| 256 | int error; | ||
| 257 | |||
| 258 | bt541->supplies[0].supply = "vdd"; | ||
| 259 | bt541->supplies[1].supply = "vddo"; | ||
| 260 | error = devm_regulator_bulk_get(&client->dev, | ||
| 261 | ARRAY_SIZE(bt541->supplies), | ||
| 262 | bt541->supplies); | ||
| 263 | if (error < 0) { | ||
| 264 | dev_err(&client->dev, "Failed to get regulators: %d\n", error); | ||
| 265 | return error; | ||
| 266 | } | ||
| 267 | |||
| 268 | return 0; | ||
| 269 | } | ||
| 270 | |||
| 271 | static int zinitix_send_power_on_sequence(struct bt541_ts_data *bt541) | ||
| 272 | { | ||
| 273 | int error; | ||
| 274 | struct i2c_client *client = bt541->client; | ||
| 275 | |||
| 276 | error = zinitix_write_u16(client, 0xc000, 0x0001); | ||
| 277 | if (error) { | ||
| 278 | dev_err(&client->dev, | ||
| 279 | "Failed to send power sequence(vendor cmd enable)\n"); | ||
| 280 | return error; | ||
| 281 | } | ||
| 282 | udelay(10); | ||
| 283 | |||
| 284 | error = zinitix_write_cmd(client, 0xc004); | ||
| 285 | if (error) { | ||
| 286 | dev_err(&client->dev, | ||
| 287 | "Failed to send power sequence (intn clear)\n"); | ||
| 288 | return error; | ||
| 289 | } | ||
| 290 | udelay(10); | ||
| 291 | |||
| 292 | error = zinitix_write_u16(client, 0xc002, 0x0001); | ||
| 293 | if (error) { | ||
| 294 | dev_err(&client->dev, | ||
| 295 | "Failed to send power sequence (nvm init)\n"); | ||
| 296 | return error; | ||
| 297 | } | ||
| 298 | mdelay(2); | ||
| 299 | |||
| 300 | error = zinitix_write_u16(client, 0xc001, 0x0001); | ||
| 301 | if (error) { | ||
| 302 | dev_err(&client->dev, | ||
| 303 | "Failed to send power sequence (program start)\n"); | ||
| 304 | return error; | ||
| 305 | } | ||
| 306 | msleep(FIRMWARE_ON_DELAY); | ||
| 307 | |||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | |||
| 311 | static void zinitix_report_finger(struct bt541_ts_data *bt541, int slot, | ||
| 312 | const struct point_coord *p) | ||
| 313 | { | ||
| 314 | input_mt_slot(bt541->input_dev, slot); | ||
| 315 | input_mt_report_slot_state(bt541->input_dev, MT_TOOL_FINGER, true); | ||
| 316 | touchscreen_report_pos(bt541->input_dev, &bt541->prop, | ||
| 317 | le16_to_cpu(p->x), le16_to_cpu(p->y), true); | ||
| 318 | input_report_abs(bt541->input_dev, ABS_MT_TOUCH_MAJOR, p->width); | ||
| 319 | } | ||
| 320 | |||
| 321 | static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler) | ||
| 322 | { | ||
| 323 | struct bt541_ts_data *bt541 = bt541_handler; | ||
| 324 | struct i2c_client *client = bt541->client; | ||
| 325 | struct touch_event touch_event; | ||
| 326 | int error; | ||
| 327 | int i; | ||
| 328 | |||
| 329 | memset(&touch_event, 0, sizeof(struct touch_event)); | ||
| 330 | |||
| 331 | error = zinitix_read_data(bt541->client, BT541_POINT_STATUS_REG, | ||
| 332 | &touch_event, sizeof(struct touch_event)); | ||
| 333 | if (error) { | ||
| 334 | dev_err(&client->dev, "Failed to read in touchpoint struct\n"); | ||
| 335 | goto out; | ||
| 336 | } | ||
| 337 | |||
| 338 | for (i = 0; i < MAX_SUPPORTED_FINGER_NUM; i++) | ||
| 339 | if (touch_event.point_coord[i].sub_status & SUB_BIT_EXIST) | ||
| 340 | zinitix_report_finger(bt541, i, | ||
| 341 | &touch_event.point_coord[i]); | ||
| 342 | |||
| 343 | input_mt_sync_frame(bt541->input_dev); | ||
| 344 | input_sync(bt541->input_dev); | ||
| 345 | |||
| 346 | out: | ||
| 347 | zinitix_write_cmd(bt541->client, BT541_CLEAR_INT_STATUS_CMD); | ||
| 348 | return IRQ_HANDLED; | ||
| 349 | } | ||
| 350 | |||
| 351 | static int zinitix_start(struct bt541_ts_data *bt541) | ||
| 352 | { | ||
| 353 | int error; | ||
| 354 | |||
| 355 | error = regulator_bulk_enable(ARRAY_SIZE(bt541->supplies), | ||
| 356 | bt541->supplies); | ||
| 357 | if (error) { | ||
| 358 | dev_err(&bt541->client->dev, | ||
| 359 | "Failed to enable regulators: %d\n", error); | ||
| 360 | return error; | ||
| 361 | } | ||
| 362 | |||
| 363 | msleep(CHIP_ON_DELAY); | ||
| 364 | |||
| 365 | error = zinitix_send_power_on_sequence(bt541); | ||
| 366 | if (error) { | ||
| 367 | dev_err(&bt541->client->dev, | ||
| 368 | "Error while sending power-on sequence: %d\n", error); | ||
| 369 | return error; | ||
| 370 | } | ||
| 371 | |||
| 372 | error = zinitix_init_touch(bt541); | ||
| 373 | if (error) { | ||
| 374 | dev_err(&bt541->client->dev, | ||
| 375 | "Error while configuring touch IC\n"); | ||
| 376 | return error; | ||
| 377 | } | ||
| 378 | |||
| 379 | enable_irq(bt541->client->irq); | ||
| 380 | |||
| 381 | return 0; | ||
| 382 | } | ||
| 383 | |||
| 384 | static int zinitix_stop(struct bt541_ts_data *bt541) | ||
| 385 | { | ||
| 386 | int error; | ||
| 387 | |||
| 388 | disable_irq(bt541->client->irq); | ||
| 389 | |||
| 390 | error = regulator_bulk_disable(ARRAY_SIZE(bt541->supplies), | ||
| 391 | bt541->supplies); | ||
| 392 | if (error) { | ||
| 393 | dev_err(&bt541->client->dev, | ||
| 394 | "Failed to disable regulators: %d\n", error); | ||
| 395 | return error; | ||
| 396 | } | ||
| 397 | |||
| 398 | return 0; | ||
| 399 | } | ||
| 400 | |||
| 401 | static int zinitix_input_open(struct input_dev *dev) | ||
| 402 | { | ||
| 403 | struct bt541_ts_data *bt541 = input_get_drvdata(dev); | ||
| 404 | |||
| 405 | return zinitix_start(bt541); | ||
| 406 | } | ||
| 407 | |||
| 408 | static void zinitix_input_close(struct input_dev *dev) | ||
| 409 | { | ||
| 410 | struct bt541_ts_data *bt541 = input_get_drvdata(dev); | ||
| 411 | |||
| 412 | zinitix_stop(bt541); | ||
| 413 | } | ||
| 414 | |||
| 415 | static int zinitix_init_input_dev(struct bt541_ts_data *bt541) | ||
| 416 | { | ||
| 417 | struct input_dev *input_dev; | ||
| 418 | int error; | ||
| 419 | |||
| 420 | input_dev = devm_input_allocate_device(&bt541->client->dev); | ||
| 421 | if (!input_dev) { | ||
| 422 | dev_err(&bt541->client->dev, | ||
| 423 | "Failed to allocate input device."); | ||
| 424 | return -ENOMEM; | ||
| 425 | } | ||
| 426 | |||
| 427 | input_set_drvdata(input_dev, bt541); | ||
| 428 | bt541->input_dev = input_dev; | ||
| 429 | |||
| 430 | input_dev->name = "Zinitix Capacitive TouchScreen"; | ||
| 431 | input_dev->phys = "input/ts"; | ||
| 432 | input_dev->id.bustype = BUS_I2C; | ||
| 433 | input_dev->open = zinitix_input_open; | ||
| 434 | input_dev->close = zinitix_input_close; | ||
| 435 | |||
| 436 | input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X); | ||
| 437 | input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y); | ||
| 438 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); | ||
| 439 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); | ||
| 440 | |||
| 441 | touchscreen_parse_properties(input_dev, true, &bt541->prop); | ||
| 442 | if (!bt541->prop.max_x || !bt541->prop.max_y) { | ||
| 443 | dev_err(&bt541->client->dev, | ||
| 444 | "Touchscreen-size-x and/or touchscreen-size-y not set in dts\n"); | ||
| 445 | return -EINVAL; | ||
| 446 | } | ||
| 447 | |||
| 448 | error = input_mt_init_slots(input_dev, MAX_SUPPORTED_FINGER_NUM, | ||
| 449 | INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); | ||
| 450 | if (error) { | ||
| 451 | dev_err(&bt541->client->dev, | ||
| 452 | "Failed to initialize MT slots: %d", error); | ||
| 453 | return error; | ||
| 454 | } | ||
| 455 | |||
| 456 | error = input_register_device(input_dev); | ||
| 457 | if (error) { | ||
| 458 | dev_err(&bt541->client->dev, | ||
| 459 | "Failed to register input device: %d", error); | ||
| 460 | return error; | ||
| 461 | } | ||
| 462 | |||
| 463 | return 0; | ||
| 464 | } | ||
| 465 | |||
| 466 | static int zinitix_ts_probe(struct i2c_client *client) | ||
| 467 | { | ||
| 468 | struct bt541_ts_data *bt541; | ||
| 469 | int error; | ||
| 470 | |||
| 471 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
| 472 | dev_err(&client->dev, | ||
| 473 | "Failed to assert adapter's support for plain I2C.\n"); | ||
| 474 | return -ENXIO; | ||
| 475 | } | ||
| 476 | |||
| 477 | bt541 = devm_kzalloc(&client->dev, sizeof(*bt541), GFP_KERNEL); | ||
| 478 | if (!bt541) | ||
| 479 | return -ENOMEM; | ||
| 480 | |||
| 481 | bt541->client = client; | ||
| 482 | i2c_set_clientdata(client, bt541); | ||
| 483 | |||
| 484 | error = zinitix_init_regulators(bt541); | ||
| 485 | if (error) { | ||
| 486 | dev_err(&client->dev, | ||
| 487 | "Failed to initialize regulators: %d\n", error); | ||
| 488 | return error; | ||
| 489 | } | ||
| 490 | |||
| 491 | error = zinitix_init_input_dev(bt541); | ||
| 492 | if (error) { | ||
| 493 | dev_err(&client->dev, | ||
| 494 | "Failed to initialize input device: %d\n", error); | ||
| 495 | return error; | ||
| 496 | } | ||
| 497 | |||
| 498 | error = device_property_read_u32(&client->dev, "zinitix,mode", | ||
| 499 | &bt541->zinitix_mode); | ||
| 500 | if (error < 0) { | ||
| 501 | /* fall back to mode 2 */ | ||
| 502 | bt541->zinitix_mode = DEFAULT_TOUCH_POINT_MODE; | ||
| 503 | } | ||
| 504 | |||
| 505 | if (bt541->zinitix_mode != 2) { | ||
| 506 | /* | ||
| 507 | * If there are devices that don't support mode 2, support | ||
| 508 | * for other modes (0, 1) will be needed. | ||
| 509 | */ | ||
| 510 | dev_err(&client->dev, | ||
| 511 | "Malformed zinitix,mode property, must be 2 (supplied: %d)\n", | ||
| 512 | bt541->zinitix_mode); | ||
| 513 | return -EINVAL; | ||
| 514 | } | ||
| 515 | |||
| 516 | irq_set_status_flags(client->irq, IRQ_NOAUTOEN); | ||
| 517 | error = devm_request_threaded_irq(&client->dev, client->irq, | ||
| 518 | NULL, zinitix_ts_irq_handler, | ||
| 519 | IRQF_ONESHOT, client->name, bt541); | ||
| 520 | if (error) { | ||
| 521 | dev_err(&client->dev, "Failed to request IRQ: %d\n", error); | ||
| 522 | return error; | ||
| 523 | } | ||
| 524 | |||
| 525 | return 0; | ||
| 526 | } | ||
| 527 | |||
| 528 | static int __maybe_unused zinitix_suspend(struct device *dev) | ||
| 529 | { | ||
| 530 | struct i2c_client *client = to_i2c_client(dev); | ||
| 531 | struct bt541_ts_data *bt541 = i2c_get_clientdata(client); | ||
| 532 | |||
| 533 | mutex_lock(&bt541->input_dev->mutex); | ||
| 534 | |||
| 535 | if (bt541->input_dev->users) | ||
| 536 | zinitix_stop(bt541); | ||
| 537 | |||
| 538 | mutex_unlock(&bt541->input_dev->mutex); | ||
| 539 | |||
| 540 | return 0; | ||
| 541 | } | ||
| 542 | |||
| 543 | static int __maybe_unused zinitix_resume(struct device *dev) | ||
| 544 | { | ||
| 545 | struct i2c_client *client = to_i2c_client(dev); | ||
| 546 | struct bt541_ts_data *bt541 = i2c_get_clientdata(client); | ||
| 547 | int ret = 0; | ||
| 548 | |||
| 549 | mutex_lock(&bt541->input_dev->mutex); | ||
| 550 | |||
| 551 | if (bt541->input_dev->users) | ||
| 552 | ret = zinitix_start(bt541); | ||
| 553 | |||
| 554 | mutex_unlock(&bt541->input_dev->mutex); | ||
| 555 | |||
| 556 | return ret; | ||
| 557 | } | ||
| 558 | |||
| 559 | static SIMPLE_DEV_PM_OPS(zinitix_pm_ops, zinitix_suspend, zinitix_resume); | ||
| 560 | |||
| 561 | #ifdef CONFIG_OF | ||
| 562 | static const struct of_device_id zinitix_of_match[] = { | ||
| 563 | { .compatible = "zinitix,bt541" }, | ||
| 564 | { } | ||
| 565 | }; | ||
| 566 | MODULE_DEVICE_TABLE(of, zinitix_of_match); | ||
| 567 | #endif | ||
| 568 | |||
| 569 | static struct i2c_driver zinitix_ts_driver = { | ||
| 570 | .probe_new = zinitix_ts_probe, | ||
| 571 | .driver = { | ||
| 572 | .name = "Zinitix-TS", | ||
| 573 | .pm = &zinitix_pm_ops, | ||
| 574 | .of_match_table = of_match_ptr(zinitix_of_match), | ||
| 575 | }, | ||
| 576 | }; | ||
| 577 | module_i2c_driver(zinitix_ts_driver); | ||
| 578 | |||
| 579 | MODULE_AUTHOR("Michael Srba <Michael.Srba@seznam.cz>"); | ||
| 580 | MODULE_DESCRIPTION("Zinitix touchscreen driver"); | ||
| 581 | MODULE_LICENSE("GPL v2"); | ||
| @@ -1930,6 +1930,10 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */ · 1929 unmodified lines | |||
| 1930 | TP_ACPI_HOTKEYSCAN_CALCULATOR, | 1930 | TP_ACPI_HOTKEYSCAN_CALCULATOR, |
| 1931 | TP_ACPI_HOTKEYSCAN_BLUETOOTH, | 1931 | TP_ACPI_HOTKEYSCAN_BLUETOOTH, |
| 1932 | TP_ACPI_HOTKEYSCAN_KEYBOARD, | 1932 | TP_ACPI_HOTKEYSCAN_KEYBOARD, |
| 1933 | TP_ACPI_HOTKEYSCAN_FN_RIGHT_SHIFT, /* Used by "Lenovo Quick Clean" */ | ||
| 1934 | TP_ACPI_HOTKEYSCAN_NOTIFICATION_CENTER, | ||
| 1935 | TP_ACPI_HOTKEYSCAN_PICKUP_PHONE, | ||
| 1936 | TP_ACPI_HOTKEYSCAN_HANGUP_PHONE, | ||
| 1933 | 1937 | ||
| 1934 | /* Hotkey keymap size */ | 1938 | /* Hotkey keymap size */ |
| 1935 | TPACPI_HOTKEY_MAP_LEN | 1939 | TPACPI_HOTKEY_MAP_LEN |
| @@ -3446,11 +3450,15 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) · 1510 unmodified lines | |||
| 3446 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | 3450 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, |
| 3447 | KEY_UNKNOWN, | 3451 | KEY_UNKNOWN, |
| 3448 | 3452 | ||
| 3449 | KEY_BOOKMARKS, /* Favorite app, 0x311 */ | 3453 | KEY_BOOKMARKS, /* Favorite app, 0x311 */ |
| 3450 | KEY_RESERVED, /* Clipping tool */ | 3454 | KEY_SELECTIVE_SCREENSHOT, /* Clipping tool */ |
| 3451 | KEY_CALC, /* Calculator (above numpad, P52) */ | 3455 | KEY_CALC, /* Calculator (above numpad, P52) */ |
| 3452 | KEY_BLUETOOTH, /* Bluetooth */ | 3456 | KEY_BLUETOOTH, /* Bluetooth */ |
| 3453 | KEY_KEYBOARD /* Keyboard, 0x315 */ | 3457 | KEY_KEYBOARD, /* Keyboard, 0x315 */ |
| 3458 | KEY_FN_RIGHT_SHIFT, /* Fn + right Shift */ | ||
| 3459 | KEY_NOTIFICATION_CENTER, /* Notification Center */ | ||
| 3460 | KEY_PICKUP_PHONE, /* Answer incoming call */ | ||
| 3461 | KEY_HANGUP_PHONE, /* Decline incoming call */ | ||
| 3454 | }, | 3462 | }, |
| 3455 | }; | 3463 | }; |
| 3456 | 3464 | ||
| @@ -102,15 +102,16 @@ struct rmi_2d_sensor_platform_data { · 101 unmodified lines | |||
| 102 | }; | 102 | }; |
| 103 | 103 | ||
| 104 | /** | 104 | /** |
| 105 | * struct rmi_f30_data - overrides defaults for a single F30 GPIOs/LED chip. | 105 | * struct rmi_gpio_data - overrides defaults for a single F30/F3A GPIOs/LED |
| 106 | * chip. | ||
| 106 | * @buttonpad - the touchpad is a buttonpad, so enable only the first actual | 107 | * @buttonpad - the touchpad is a buttonpad, so enable only the first actual |
| 107 | * button that is found. | 108 | * button that is found. |
| 108 | * @trackstick_buttons - Set when the function 30 is handling the physical | 109 | * @trackstick_buttons - Set when the function 30 or 3a is handling the physical |
| 109 | * buttons of the trackstick (as a PS/2 passthrough device). | 110 | * buttons of the trackstick (as a PS/2 passthrough device). |
| 110 | * @disable - the touchpad incorrectly reports F30 and it should be ignored. | 111 | * @disable - the touchpad incorrectly reports F30/F3A and it should be ignored. |
| 111 | * This is a special case which is due to misconfigured firmware. | 112 | * This is a special case which is due to misconfigured firmware. |
| 112 | */ | 113 | */ |
| 113 | struct rmi_f30_data { | 114 | struct rmi_gpio_data { |
| 114 | bool buttonpad; | 115 | bool buttonpad; |
| 115 | bool trackstick_buttons; | 116 | bool trackstick_buttons; |
| 116 | bool disable; | 117 | bool disable; |
| @@ -218,7 +219,7 @@ struct rmi_device_platform_data { · 101 unmodified lines | |||
| 218 | /* function handler pdata */ | 219 | /* function handler pdata */ |
| 219 | struct rmi_2d_sensor_platform_data sensor_pdata; | 220 | struct rmi_2d_sensor_platform_data sensor_pdata; |
| 220 | struct rmi_f01_power_management power_management; | 221 | struct rmi_f01_power_management power_management; |
| 221 | struct rmi_f30_data f30_data; | 222 | struct rmi_gpio_data gpio_data; |
| 222 | }; | 223 | }; |
| 223 | 224 | ||
| 224 | /** | 225 | /** |
| @@ -515,6 +515,9 @@ · 514 unmodified lines | |||
| 515 | #define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */ | 515 | #define KEY_10CHANNELSUP 0x1b8 /* 10 channels up (10+) */ |
| 516 | #define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */ | 516 | #define KEY_10CHANNELSDOWN 0x1b9 /* 10 channels down (10-) */ |
| 517 | #define KEY_IMAGES 0x1ba /* AL Image Browser */ | 517 | #define KEY_IMAGES 0x1ba /* AL Image Browser */ |
| 518 | #define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */ | ||
| 519 | #define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */ | ||
| 520 | #define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */ | ||
| 518 | 521 | ||
| 519 | #define KEY_DEL_EOL 0x1c0 | 522 | #define KEY_DEL_EOL 0x1c0 |
| 520 | #define KEY_DEL_EOS 0x1c1 | 523 | #define KEY_DEL_EOS 0x1c1 |
| @@ -542,6 +545,7 @@ · 21 unmodified lines | |||
| 542 | #define KEY_FN_F 0x1e2 | 545 | #define KEY_FN_F 0x1e2 |
| 543 | #define KEY_FN_S 0x1e3 | 546 | #define KEY_FN_S 0x1e3 |
| 544 | #define KEY_FN_B 0x1e4 | 547 | #define KEY_FN_B 0x1e4 |
| 548 | #define KEY_FN_RIGHT_SHIFT 0x1e5 | ||
| 545 | 549 | ||
| 546 | #define KEY_BRL_DOT1 0x1f1 | 550 | #define KEY_BRL_DOT1 0x1f1 |
| 547 | #define KEY_BRL_DOT2 0x1f2 | 551 | #define KEY_BRL_DOT2 0x1f2 |