exc3000.c (62b31a045757eac81fed94b19df47418a0818528) | exc3000.c (a63d0120a2dd89eabf24b415b27208e190e989b0) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Driver for I2C connected EETI EXC3000 multiple touch controller 4 * 5 * Copyright (C) 2017 Ahmet Inan <inan@distec.de> 6 * 7 * minimal implementation based on egalax_ts.c and egalax_i2c.c 8 */ --- 16 unchanged lines hidden (view full) --- 25#define EXC3000_NUM_SLOTS 10 26#define EXC3000_SLOTS_PER_FRAME 5 27#define EXC3000_LEN_FRAME 66 28#define EXC3000_LEN_POINT 10 29 30#define EXC3000_LEN_MODEL_NAME 16 31#define EXC3000_LEN_FW_VERSION 16 32 | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Driver for I2C connected EETI EXC3000 multiple touch controller 4 * 5 * Copyright (C) 2017 Ahmet Inan <inan@distec.de> 6 * 7 * minimal implementation based on egalax_ts.c and egalax_i2c.c 8 */ --- 16 unchanged lines hidden (view full) --- 25#define EXC3000_NUM_SLOTS 10 26#define EXC3000_SLOTS_PER_FRAME 5 27#define EXC3000_LEN_FRAME 66 28#define EXC3000_LEN_POINT 10 29 30#define EXC3000_LEN_MODEL_NAME 16 31#define EXC3000_LEN_FW_VERSION 16 32 |
33#define EXC3000_VENDOR_EVENT 0x03 |
|
33#define EXC3000_MT1_EVENT 0x06 34#define EXC3000_MT2_EVENT 0x18 35 36#define EXC3000_TIMEOUT_MS 100 37 38#define EXC3000_RESET_MS 10 39#define EXC3000_READY_MS 100 40 --- 59 unchanged lines hidden (view full) --- 100static void exc3000_timer(struct timer_list *t) 101{ 102 struct exc3000_data *data = from_timer(data, t, timer); 103 104 input_mt_sync_frame(data->input); 105 input_sync(data->input); 106} 107 | 34#define EXC3000_MT1_EVENT 0x06 35#define EXC3000_MT2_EVENT 0x18 36 37#define EXC3000_TIMEOUT_MS 100 38 39#define EXC3000_RESET_MS 10 40#define EXC3000_READY_MS 100 41 --- 59 unchanged lines hidden (view full) --- 101static void exc3000_timer(struct timer_list *t) 102{ 103 struct exc3000_data *data = from_timer(data, t, timer); 104 105 input_mt_sync_frame(data->input); 106 input_sync(data->input); 107} 108 |
109static inline void exc3000_schedule_timer(struct exc3000_data *data) 110{ 111 mod_timer(&data->timer, jiffies + msecs_to_jiffies(EXC3000_TIMEOUT_MS)); 112} 113 |
|
108static int exc3000_read_frame(struct exc3000_data *data, u8 *buf) 109{ 110 struct i2c_client *client = data->client; | 114static int exc3000_read_frame(struct exc3000_data *data, u8 *buf) 115{ 116 struct i2c_client *client = data->client; |
111 u8 expected_event = EXC3000_MT1_EVENT; | |
112 int ret; 113 | 117 int ret; 118 |
114 if (data->info->max_xy == SZ_16K - 1) 115 expected_event = EXC3000_MT2_EVENT; 116 | |
117 ret = i2c_master_send(client, "'", 2); 118 if (ret < 0) 119 return ret; 120 121 if (ret != 2) 122 return -EIO; 123 124 ret = i2c_master_recv(client, buf, EXC3000_LEN_FRAME); 125 if (ret < 0) 126 return ret; 127 128 if (ret != EXC3000_LEN_FRAME) 129 return -EIO; 130 131 if (get_unaligned_le16(buf) != EXC3000_LEN_FRAME) 132 return -EINVAL; 133 | 119 ret = i2c_master_send(client, "'", 2); 120 if (ret < 0) 121 return ret; 122 123 if (ret != 2) 124 return -EIO; 125 126 ret = i2c_master_recv(client, buf, EXC3000_LEN_FRAME); 127 if (ret < 0) 128 return ret; 129 130 if (ret != EXC3000_LEN_FRAME) 131 return -EIO; 132 133 if (get_unaligned_le16(buf) != EXC3000_LEN_FRAME) 134 return -EINVAL; 135 |
134 if (buf[2] != expected_event) 135 return -EINVAL; 136 | |
137 return 0; 138} 139 | 136 return 0; 137} 138 |
140static int exc3000_read_data(struct exc3000_data *data, 141 u8 *buf, int *n_slots) | 139static int exc3000_handle_mt_event(struct exc3000_data *data) |
142{ | 140{ |
143 int error; | 141 struct input_dev *input = data->input; 142 int ret, total_slots; 143 u8 *buf = data->buf; |
144 | 144 |
145 error = exc3000_read_frame(data, buf); 146 if (error) 147 return error; | 145 total_slots = buf[3]; 146 if (!total_slots || total_slots > EXC3000_NUM_SLOTS) { 147 ret = -EINVAL; 148 goto out_fail; 149 } |
148 | 150 |
149 *n_slots = buf[3]; 150 if (!*n_slots || *n_slots > EXC3000_NUM_SLOTS) 151 return -EINVAL; 152 153 if (*n_slots > EXC3000_SLOTS_PER_FRAME) { | 151 if (total_slots > EXC3000_SLOTS_PER_FRAME) { |
154 /* Read 2nd frame to get the rest of the contacts. */ | 152 /* Read 2nd frame to get the rest of the contacts. */ |
155 error = exc3000_read_frame(data, buf + EXC3000_LEN_FRAME); 156 if (error) 157 return error; | 153 ret = exc3000_read_frame(data, buf + EXC3000_LEN_FRAME); 154 if (ret) 155 goto out_fail; |
158 159 /* 2nd chunk must have number of contacts set to 0. */ | 156 157 /* 2nd chunk must have number of contacts set to 0. */ |
160 if (buf[EXC3000_LEN_FRAME + 3] != 0) 161 return -EINVAL; | 158 if (buf[EXC3000_LEN_FRAME + 3] != 0) { 159 ret = -EINVAL; 160 goto out_fail; 161 } |
162 } 163 | 162 } 163 |
164 /* 165 * We read full state successfully, no contacts will be "stuck". 166 */ 167 del_timer_sync(&data->timer); 168 169 while (total_slots > 0) { 170 int slots = min(total_slots, EXC3000_SLOTS_PER_FRAME); 171 172 exc3000_report_slots(input, &data->prop, buf + 4, slots); 173 total_slots -= slots; 174 buf += EXC3000_LEN_FRAME; 175 } 176 177 input_mt_sync_frame(input); 178 input_sync(input); 179 |
|
164 return 0; | 180 return 0; |
181 182out_fail: 183 /* Schedule a timer to release "stuck" contacts */ 184 exc3000_schedule_timer(data); 185 186 return ret; |
|
165} 166 167static int exc3000_query_interrupt(struct exc3000_data *data) 168{ 169 u8 *buf = data->buf; | 187} 188 189static int exc3000_query_interrupt(struct exc3000_data *data) 190{ 191 u8 *buf = data->buf; |
170 int error; | |
171 | 192 |
172 error = i2c_master_recv(data->client, buf, EXC3000_LEN_FRAME); 173 if (error < 0) 174 return error; 175 | |
176 if (buf[0] != 'B') 177 return -EPROTO; 178 179 if (buf[4] == 'E') 180 strlcpy(data->model, buf + 5, sizeof(data->model)); 181 else if (buf[4] == 'D') 182 strlcpy(data->fw_version, buf + 5, sizeof(data->fw_version)); 183 else 184 return -EPROTO; 185 186 return 0; 187} 188 189static irqreturn_t exc3000_interrupt(int irq, void *dev_id) 190{ 191 struct exc3000_data *data = dev_id; | 193 if (buf[0] != 'B') 194 return -EPROTO; 195 196 if (buf[4] == 'E') 197 strlcpy(data->model, buf + 5, sizeof(data->model)); 198 else if (buf[4] == 'D') 199 strlcpy(data->fw_version, buf + 5, sizeof(data->fw_version)); 200 else 201 return -EPROTO; 202 203 return 0; 204} 205 206static irqreturn_t exc3000_interrupt(int irq, void *dev_id) 207{ 208 struct exc3000_data *data = dev_id; |
192 struct input_dev *input = data->input; | |
193 u8 *buf = data->buf; | 209 u8 *buf = data->buf; |
194 int slots, total_slots; 195 int error; | 210 int ret; |
196 | 211 |
197 if (mutex_is_locked(&data->query_lock)) { 198 data->query_result = exc3000_query_interrupt(data); 199 complete(&data->wait_event); 200 goto out; 201 } 202 203 error = exc3000_read_data(data, buf, &total_slots); 204 if (error) { | 212 ret = exc3000_read_frame(data, buf); 213 if (ret) { |
205 /* Schedule a timer to release "stuck" contacts */ | 214 /* Schedule a timer to release "stuck" contacts */ |
206 mod_timer(&data->timer, 207 jiffies + msecs_to_jiffies(EXC3000_TIMEOUT_MS)); | 215 exc3000_schedule_timer(data); |
208 goto out; 209 } 210 | 216 goto out; 217 } 218 |
211 /* 212 * We read full state successfully, no contacts will be "stuck". 213 */ 214 del_timer_sync(&data->timer); | 219 switch (buf[2]) { 220 case EXC3000_VENDOR_EVENT: 221 data->query_result = exc3000_query_interrupt(data); 222 complete(&data->wait_event); 223 break; |
215 | 224 |
216 while (total_slots > 0) { 217 slots = min(total_slots, EXC3000_SLOTS_PER_FRAME); 218 exc3000_report_slots(input, &data->prop, buf + 4, slots); 219 total_slots -= slots; 220 buf += EXC3000_LEN_FRAME; | 225 case EXC3000_MT1_EVENT: 226 case EXC3000_MT2_EVENT: 227 exc3000_handle_mt_event(data); 228 break; 229 230 default: 231 break; |
221 } 222 | 232 } 233 |
223 input_mt_sync_frame(input); 224 input_sync(input); 225 | |
226out: 227 return IRQ_HANDLED; 228} 229 230static ssize_t fw_version_show(struct device *dev, 231 struct device_attribute *attr, char *buf) 232{ 233 struct i2c_client *client = to_i2c_client(dev); --- 201 unchanged lines hidden --- | 234out: 235 return IRQ_HANDLED; 236} 237 238static ssize_t fw_version_show(struct device *dev, 239 struct device_attribute *attr, char *buf) 240{ 241 struct i2c_client *client = to_i2c_client(dev); --- 201 unchanged lines hidden --- |