^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Touch Screen driver for SiS 9200 family I2C Touch panels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015 SiS, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2016 Nextfour Group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/crc-itu-t.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/input/mt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define SIS_I2C_NAME "sis_i2c_ts"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * The I2C packet format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * le16 byte count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * u8 Report ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * <contact data - variable length>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * u8 Number of contacts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * le16 Scan Time (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * le16 CRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * One touch point information consists of 6+ bytes, the order is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * u8 contact state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * u8 finger id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * le16 x axis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * le16 y axis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * u8 contact width (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * u8 contact height (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * u8 pressure (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * Maximum amount of data transmitted in one shot is 64 bytes, if controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * needs to report more contacts than fit in one packet it will send true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * number of contacts in first packet and 0 as number of contacts in second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define SIS_MAX_PACKET_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define SIS_PKT_LEN_OFFSET 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define SIS_PKT_REPORT_OFFSET 2 /* Report ID/type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define SIS_PKT_CONTACT_OFFSET 3 /* First contact */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define SIS_SCAN_TIME_LEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* Supported report types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SIS_ALL_IN_ONE_PACKAGE 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SIS_PKT_IS_TOUCH(x) (((x) & 0x0f) == 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SIS_PKT_IS_HIDI2C(x) (((x) & 0x0f) == 0x06)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* Contact properties within report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SIS_PKT_HAS_AREA(x) ((x) & BIT(4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define SIS_PKT_HAS_PRESSURE(x) ((x) & BIT(5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SIS_PKT_HAS_SCANTIME(x) ((x) & BIT(6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* Contact size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define SIS_BASE_LEN_PER_CONTACT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define SIS_AREA_LEN_PER_CONTACT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define SIS_PRESSURE_LEN_PER_CONTACT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* Offsets within contact data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define SIS_CONTACT_STATUS_OFFSET 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SIS_CONTACT_ID_OFFSET 1 /* Contact ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define SIS_CONTACT_X_OFFSET 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define SIS_CONTACT_Y_OFFSET 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define SIS_CONTACT_WIDTH_OFFSET 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SIS_CONTACT_HEIGHT_OFFSET 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SIS_CONTACT_PRESSURE_OFFSET(id) (SIS_PKT_HAS_AREA(id) ? 8 : 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Individual contact state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SIS_STATUS_UP 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define SIS_STATUS_DOWN 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* Touchscreen parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define SIS_MAX_FINGERS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define SIS_MAX_X 4095
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define SIS_MAX_Y 4095
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define SIS_MAX_PRESSURE 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* Resolution diagonal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define SIS_AREA_LENGTH_LONGER 5792
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /*((SIS_MAX_X^2) + (SIS_MAX_Y^2))^0.5*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define SIS_AREA_LENGTH_SHORT 5792
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define SIS_AREA_UNIT (5792 / 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct sis_ts_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct gpio_desc *attn_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct gpio_desc *reset_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u8 packet[SIS_MAX_PACKET_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int sis_read_packet(struct i2c_client *client, u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) unsigned int *num_contacts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned int *contact_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int count_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) u16 crc, pkg_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u8 report_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ret = i2c_master_recv(client, buf, SIS_MAX_PACKET_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (ret <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) len = get_unaligned_le16(&buf[SIS_PKT_LEN_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (len > SIS_MAX_PACKET_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) "%s: invalid packet length (%d vs %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) __func__, len, SIS_MAX_PACKET_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (len < 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) report_id = buf[SIS_PKT_REPORT_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) count_idx = len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) *contact_size = SIS_BASE_LEN_PER_CONTACT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (report_id != SIS_ALL_IN_ONE_PACKAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (SIS_PKT_IS_TOUCH(report_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * Calculate CRC ignoring packet length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * in the beginning and CRC transmitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * at the end of the packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) crc = crc_itu_t(0, buf + 2, len - 2 - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) pkg_crc = get_unaligned_le16(&buf[len - 2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (crc != pkg_crc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) "%s: CRC Error (%d vs %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) __func__, crc, pkg_crc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) count_idx -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) } else if (!SIS_PKT_IS_HIDI2C(report_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) "%s: invalid packet ID %#02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) __func__, report_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (SIS_PKT_HAS_SCANTIME(report_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) count_idx -= SIS_SCAN_TIME_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (SIS_PKT_HAS_AREA(report_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) *contact_size += SIS_AREA_LEN_PER_CONTACT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (SIS_PKT_HAS_PRESSURE(report_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) *contact_size += SIS_PRESSURE_LEN_PER_CONTACT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) *num_contacts = buf[count_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int sis_ts_report_contact(struct sis_ts_data *ts, const u8 *data, u8 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct input_dev *input = ts->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u8 status = data[SIS_CONTACT_STATUS_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u8 pressure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u8 height, width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u16 x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (status != SIS_STATUS_DOWN && status != SIS_STATUS_UP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) dev_err(&ts->client->dev, "Unexpected touch status: %#02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) data[SIS_CONTACT_STATUS_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) slot = input_mt_get_slot_by_key(input, data[SIS_CONTACT_ID_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (slot < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) input_mt_slot(input, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) input_mt_report_slot_state(input, MT_TOOL_FINGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) status == SIS_STATUS_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (status == SIS_STATUS_DOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) pressure = height = width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (id != SIS_ALL_IN_ONE_PACKAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (SIS_PKT_HAS_AREA(id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) width = data[SIS_CONTACT_WIDTH_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) height = data[SIS_CONTACT_HEIGHT_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (SIS_PKT_HAS_PRESSURE(id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) pressure =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) data[SIS_CONTACT_PRESSURE_OFFSET(id)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) x = get_unaligned_le16(&data[SIS_CONTACT_X_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) y = get_unaligned_le16(&data[SIS_CONTACT_Y_OFFSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) input_report_abs(input, ABS_MT_TOUCH_MAJOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) width * SIS_AREA_UNIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) input_report_abs(input, ABS_MT_TOUCH_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) height * SIS_AREA_UNIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) input_report_abs(input, ABS_MT_PRESSURE, pressure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) input_report_abs(input, ABS_MT_POSITION_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) input_report_abs(input, ABS_MT_POSITION_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static void sis_ts_handle_packet(struct sis_ts_data *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) const u8 *contact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) unsigned int num_to_report = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) unsigned int num_contacts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) unsigned int num_reported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) unsigned int contact_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u8 report_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) error = sis_read_packet(ts->client, ts->packet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) &num_contacts, &contact_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (num_to_report == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) num_to_report = num_contacts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) } else if (num_contacts != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) dev_err(&ts->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) "%s: nonzero (%d) point count in tail packet\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) __func__, num_contacts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) report_id = ts->packet[SIS_PKT_REPORT_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) contact = &ts->packet[SIS_PKT_CONTACT_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) num_reported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) while (num_to_report > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) error = sis_ts_report_contact(ts, contact, report_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) contact += contact_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) num_to_report--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) num_reported++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (report_id != SIS_ALL_IN_ONE_PACKAGE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) num_reported >= 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * The remainder of contacts is sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * in the 2nd packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) } while (num_to_report > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) input_mt_sync_frame(ts->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) input_sync(ts->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static irqreturn_t sis_ts_irq_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct sis_ts_data *ts = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) sis_ts_handle_packet(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) } while (ts->attn_gpio && gpiod_get_value_cansleep(ts->attn_gpio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static void sis_ts_reset(struct sis_ts_data *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (ts->reset_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* Get out of reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) gpiod_set_value(ts->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) gpiod_set_value(ts->reset_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static int sis_ts_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct sis_ts_data *ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (!ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ts->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ts->attn_gpio = devm_gpiod_get_optional(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) "attn", GPIOD_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (IS_ERR(ts->attn_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) error = PTR_ERR(ts->attn_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (error != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) "Failed to get attention GPIO: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ts->reset_gpio = devm_gpiod_get_optional(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) "reset", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (IS_ERR(ts->reset_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) error = PTR_ERR(ts->reset_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (error != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) "Failed to get reset GPIO: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) sis_ts_reset(ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) ts->input = input = devm_input_allocate_device(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (!input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) dev_err(&client->dev, "Failed to allocate input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) input->name = "SiS Touchscreen";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) input->id.bustype = BUS_I2C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) input_set_abs_params(input, ABS_MT_POSITION_X, 0, SIS_MAX_X, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) input_set_abs_params(input, ABS_MT_POSITION_Y, 0, SIS_MAX_Y, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) input_set_abs_params(input, ABS_MT_PRESSURE, 0, SIS_MAX_PRESSURE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) input_set_abs_params(input, ABS_MT_TOUCH_MAJOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 0, SIS_AREA_LENGTH_LONGER, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) input_set_abs_params(input, ABS_MT_TOUCH_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 0, SIS_AREA_LENGTH_SHORT, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) error = input_mt_init_slots(input, SIS_MAX_FINGERS, INPUT_MT_DIRECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) "Failed to initialize MT slots: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) error = devm_request_threaded_irq(&client->dev, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) NULL, sis_ts_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) client->name, ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) dev_err(&client->dev, "Failed to request IRQ: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) error = input_register_device(ts->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) "Failed to register input device: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static const struct of_device_id sis_ts_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) { .compatible = "sis,9200-ts" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) MODULE_DEVICE_TABLE(of, sis_ts_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static const struct i2c_device_id sis_ts_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) { SIS_I2C_NAME, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) { "9200-ts", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) MODULE_DEVICE_TABLE(i2c, sis_ts_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static struct i2c_driver sis_ts_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .name = SIS_I2C_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .of_match_table = of_match_ptr(sis_ts_dt_ids),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .probe = sis_ts_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .id_table = sis_ts_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) module_i2c_driver(sis_ts_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) MODULE_DESCRIPTION("SiS 9200 Family Touchscreen Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) MODULE_AUTHOR("Mika Penttilä <mika.penttila@nextfour.com>");