^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) * Driver for I2C connected EETI EXC3000 multiple touch controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2017 Ahmet Inan <inan@distec.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * minimal implementation based on egalax_ts.c and egalax_i2c.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/input/mt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/input/touchscreen.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/sizes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define EXC3000_NUM_SLOTS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define EXC3000_SLOTS_PER_FRAME 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define EXC3000_LEN_FRAME 66
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define EXC3000_LEN_POINT 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define EXC3000_LEN_MODEL_NAME 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define EXC3000_LEN_FW_VERSION 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define EXC3000_MT1_EVENT 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define EXC3000_MT2_EVENT 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define EXC3000_TIMEOUT_MS 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define EXC3000_RESET_MS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define EXC3000_READY_MS 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static const struct i2c_device_id exc3000_id[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct eeti_dev_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int max_xy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) enum eeti_dev_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) EETI_EXC3000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) EETI_EXC80H60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) EETI_EXC80H84,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static struct eeti_dev_info exc3000_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) [EETI_EXC3000] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .name = "EETI EXC3000 Touch Screen",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .max_xy = SZ_4K - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) [EETI_EXC80H60] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .name = "EETI EXC80H60 Touch Screen",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .max_xy = SZ_16K - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) [EETI_EXC80H84] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .name = "EETI EXC80H84 Touch Screen",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .max_xy = SZ_16K - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct exc3000_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) const struct eeti_dev_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct touchscreen_properties prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct gpio_desc *reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) u8 buf[2 * EXC3000_LEN_FRAME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct completion wait_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct mutex query_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int query_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) char model[EXC3000_LEN_MODEL_NAME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) char fw_version[EXC3000_LEN_FW_VERSION];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static void exc3000_report_slots(struct input_dev *input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct touchscreen_properties *prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) const u8 *buf, int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) for (; num--; buf += EXC3000_LEN_POINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (buf[0] & BIT(0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) input_mt_slot(input, buf[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) touchscreen_report_pos(input, prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) get_unaligned_le16(buf + 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) get_unaligned_le16(buf + 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void exc3000_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct exc3000_data *data = from_timer(data, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) input_mt_sync_frame(data->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) input_sync(data->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int exc3000_read_frame(struct exc3000_data *data, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) u8 expected_event = EXC3000_MT1_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (data->info->max_xy == SZ_16K - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) expected_event = EXC3000_MT2_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ret = i2c_master_send(client, "'", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (ret != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ret = i2c_master_recv(client, buf, EXC3000_LEN_FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (ret != EXC3000_LEN_FRAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (get_unaligned_le16(buf) != EXC3000_LEN_FRAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (buf[2] != expected_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int exc3000_read_data(struct exc3000_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u8 *buf, int *n_slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) error = exc3000_read_frame(data, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *n_slots = buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (!*n_slots || *n_slots > EXC3000_NUM_SLOTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (*n_slots > EXC3000_SLOTS_PER_FRAME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* Read 2nd frame to get the rest of the contacts. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) error = exc3000_read_frame(data, buf + EXC3000_LEN_FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* 2nd chunk must have number of contacts set to 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (buf[EXC3000_LEN_FRAME + 3] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int exc3000_query_interrupt(struct exc3000_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u8 *buf = data->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) error = i2c_master_recv(data->client, buf, EXC3000_LEN_FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (buf[0] != 'B')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (buf[4] == 'E')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) strlcpy(data->model, buf + 5, sizeof(data->model));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) else if (buf[4] == 'D')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) strlcpy(data->fw_version, buf + 5, sizeof(data->fw_version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static irqreturn_t exc3000_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct exc3000_data *data = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct input_dev *input = data->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u8 *buf = data->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int slots, total_slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (mutex_is_locked(&data->query_lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) data->query_result = exc3000_query_interrupt(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) complete(&data->wait_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) goto out;
^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) error = exc3000_read_data(data, buf, &total_slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* Schedule a timer to release "stuck" contacts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) mod_timer(&data->timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) jiffies + msecs_to_jiffies(EXC3000_TIMEOUT_MS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * We read full state successfully, no contacts will be "stuck".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) del_timer_sync(&data->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) while (total_slots > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) slots = min(total_slots, EXC3000_SLOTS_PER_FRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) exc3000_report_slots(input, &data->prop, buf + 4, slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) total_slots -= slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) buf += EXC3000_LEN_FRAME;
^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) input_mt_sync_frame(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) input_sync(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static ssize_t fw_version_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct exc3000_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static const u8 request[68] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 0x67, 0x00, 0x42, 0x00, 0x03, 0x01, 'D', 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) mutex_lock(&data->query_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) data->query_result = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) reinit_completion(&data->wait_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) error = i2c_master_send(client, request, sizeof(request));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) mutex_unlock(&data->query_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) wait_for_completion_interruptible_timeout(&data->wait_event, 1 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mutex_unlock(&data->query_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (data->query_result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return data->query_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return sprintf(buf, "%s\n", data->fw_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static DEVICE_ATTR_RO(fw_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static ssize_t exc3000_get_model(struct exc3000_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static const u8 request[68] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 0x67, 0x00, 0x42, 0x00, 0x03, 0x01, 'E', 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) mutex_lock(&data->query_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) data->query_result = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) reinit_completion(&data->wait_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) error = i2c_master_send(client, request, sizeof(request));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) mutex_unlock(&data->query_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) wait_for_completion_interruptible_timeout(&data->wait_event, 1 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) mutex_unlock(&data->query_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return data->query_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static ssize_t model_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct exc3000_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) error = exc3000_get_model(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return sprintf(buf, "%s\n", data->model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static DEVICE_ATTR_RO(model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static struct attribute *sysfs_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) &dev_attr_fw_version.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) &dev_attr_model.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static struct attribute_group exc3000_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .attrs = sysfs_attrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static int exc3000_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct exc3000_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int error, max_xy, retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) data->info = device_get_match_data(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (!data->info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) enum eeti_dev_id eeti_dev_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) i2c_match_id(exc3000_id, client)->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) data->info = &exc3000_info[eeti_dev_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) timer_setup(&data->timer, exc3000_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) init_completion(&data->wait_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) mutex_init(&data->query_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) data->reset = devm_gpiod_get_optional(&client->dev, "reset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (IS_ERR(data->reset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return PTR_ERR(data->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (data->reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) msleep(EXC3000_RESET_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) gpiod_set_value_cansleep(data->reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) msleep(EXC3000_READY_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) input = devm_input_allocate_device(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) data->input = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) input_set_drvdata(input, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) input->name = data->info->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) input->id.bustype = BUS_I2C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) max_xy = data->info->max_xy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_xy, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_xy, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) touchscreen_parse_properties(input, true, &data->prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) error = input_mt_init_slots(input, EXC3000_NUM_SLOTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) error = input_register_device(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) error = devm_request_threaded_irq(&client->dev, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) NULL, exc3000_interrupt, IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) client->name, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (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) * I²C does not have built-in recovery, so retry on failure. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * ensures, that the device probe will not fail for temporary issues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * on the bus. This is not needed for the sysfs calls (userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * will receive the error code and can start another query) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * cannot be done for touch events (but that only means loosing one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * or two touch events anyways).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) for (retry = 0; retry < 3; retry++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) error = exc3000_get_model(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) dev_warn(&client->dev, "Retry %d get EETI EXC3000 model: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) retry + 1, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dev_dbg(&client->dev, "TS Model: %s", data->model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) i2c_set_clientdata(client, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) error = devm_device_add_group(&client->dev, &exc3000_attribute_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static const struct i2c_device_id exc3000_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) { "exc3000", EETI_EXC3000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) { "exc80h60", EETI_EXC80H60 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) { "exc80h84", EETI_EXC80H84 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) MODULE_DEVICE_TABLE(i2c, exc3000_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static const struct of_device_id exc3000_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) { .compatible = "eeti,exc3000", .data = &exc3000_info[EETI_EXC3000] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) { .compatible = "eeti,exc80h60", .data = &exc3000_info[EETI_EXC80H60] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) { .compatible = "eeti,exc80h84", .data = &exc3000_info[EETI_EXC80H84] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) MODULE_DEVICE_TABLE(of, exc3000_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static struct i2c_driver exc3000_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .name = "exc3000",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .of_match_table = of_match_ptr(exc3000_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .id_table = exc3000_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .probe_new = exc3000_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) module_i2c_driver(exc3000_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) MODULE_AUTHOR("Ahmet Inan <inan@distec.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) MODULE_DESCRIPTION("I2C connected EETI EXC3000 multiple touch controller driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) MODULE_LICENSE("GPL v2");