1 | /* |
2 | * Cypress APA trackpad with I2C interface |
3 | * |
4 | * Author: Dudley Du <dudl@cypress.com> |
5 | * Further cleanup and restructuring by: |
6 | * Daniel Kurtz <djkurtz@chromium.org> |
7 | * Benson Leung <bleung@chromium.org> |
8 | * |
9 | * Copyright (C) 2011-2015 Cypress Semiconductor, Inc. |
10 | * Copyright (C) 2011-2012 Google, Inc. |
11 | * |
12 | * This file is subject to the terms and conditions of the GNU General Public |
13 | * License. See the file COPYING in the main directory of this archive for |
14 | * more details. |
15 | */ |
16 | |
17 | #include <linux/delay.h> |
18 | #include <linux/i2c.h> |
19 | #include <linux/input.h> |
20 | #include <linux/input/mt.h> |
21 | #include <linux/module.h> |
22 | #include <linux/slab.h> |
23 | #include <asm/unaligned.h> |
24 | #include "cyapa.h" |
25 | |
26 | |
27 | #define GEN3_MAX_FINGERS 5 |
28 | #define GEN3_FINGER_NUM(x) (((x) >> 4) & 0x07) |
29 | |
30 | #define BLK_HEAD_BYTES 32 |
31 | |
32 | /* Macro for register map group offset. */ |
33 | #define PRODUCT_ID_SIZE 16 |
34 | #define QUERY_DATA_SIZE 27 |
35 | #define REG_PROTOCOL_GEN_QUERY_OFFSET 20 |
36 | |
37 | #define REG_OFFSET_DATA_BASE 0x0000 |
38 | #define REG_OFFSET_COMMAND_BASE 0x0028 |
39 | #define REG_OFFSET_QUERY_BASE 0x002a |
40 | |
41 | #define CYAPA_OFFSET_SOFT_RESET REG_OFFSET_COMMAND_BASE |
42 | #define OP_RECALIBRATION_MASK 0x80 |
43 | #define OP_REPORT_BASELINE_MASK 0x40 |
44 | #define REG_OFFSET_MAX_BASELINE 0x0026 |
45 | #define REG_OFFSET_MIN_BASELINE 0x0027 |
46 | |
47 | #define REG_OFFSET_POWER_MODE (REG_OFFSET_COMMAND_BASE + 1) |
48 | #define SET_POWER_MODE_DELAY 10000 /* Unit: us */ |
49 | #define SET_POWER_MODE_TRIES 5 |
50 | |
51 | #define GEN3_BL_CMD_CHECKSUM_SEED 0xff |
52 | #define GEN3_BL_CMD_INITIATE_BL 0x38 |
53 | #define GEN3_BL_CMD_WRITE_BLOCK 0x39 |
54 | #define GEN3_BL_CMD_VERIFY_BLOCK 0x3a |
55 | #define GEN3_BL_CMD_TERMINATE_BL 0x3b |
56 | #define GEN3_BL_CMD_LAUNCH_APP 0xa5 |
57 | |
58 | /* |
59 | * CYAPA trackpad device states. |
60 | * Used in register 0x00, bit1-0, DeviceStatus field. |
61 | * Other values indicate device is in an abnormal state and must be reset. |
62 | */ |
63 | #define CYAPA_DEV_NORMAL 0x03 |
64 | #define CYAPA_DEV_BUSY 0x01 |
65 | |
66 | #define CYAPA_FW_BLOCK_SIZE 64 |
67 | #define CYAPA_FW_READ_SIZE 16 |
68 | #define CYAPA_FW_HDR_START 0x0780 |
69 | #define CYAPA_FW_HDR_BLOCK_COUNT 2 |
70 | #define CYAPA_FW_HDR_BLOCK_START (CYAPA_FW_HDR_START / CYAPA_FW_BLOCK_SIZE) |
71 | #define CYAPA_FW_HDR_SIZE (CYAPA_FW_HDR_BLOCK_COUNT * \ |
72 | CYAPA_FW_BLOCK_SIZE) |
73 | #define CYAPA_FW_DATA_START 0x0800 |
74 | #define CYAPA_FW_DATA_BLOCK_COUNT 480 |
75 | #define CYAPA_FW_DATA_BLOCK_START (CYAPA_FW_DATA_START / CYAPA_FW_BLOCK_SIZE) |
76 | #define CYAPA_FW_DATA_SIZE (CYAPA_FW_DATA_BLOCK_COUNT * \ |
77 | CYAPA_FW_BLOCK_SIZE) |
78 | #define CYAPA_FW_SIZE (CYAPA_FW_HDR_SIZE + CYAPA_FW_DATA_SIZE) |
79 | #define CYAPA_CMD_LEN 16 |
80 | |
81 | #define GEN3_BL_IDLE_FW_MAJ_VER_OFFSET 0x0b |
82 | #define GEN3_BL_IDLE_FW_MIN_VER_OFFSET (GEN3_BL_IDLE_FW_MAJ_VER_OFFSET + 1) |
83 | |
84 | |
85 | struct cyapa_touch { |
86 | /* |
87 | * high bits or x/y position value |
88 | * bit 7 - 4: high 4 bits of x position value |
89 | * bit 3 - 0: high 4 bits of y position value |
90 | */ |
91 | u8 xy_hi; |
92 | u8 x_lo; /* low 8 bits of x position value. */ |
93 | u8 y_lo; /* low 8 bits of y position value. */ |
94 | u8 pressure; |
95 | /* id range is 1 - 15. It is incremented with every new touch. */ |
96 | u8 id; |
97 | } __packed; |
98 | |
99 | struct cyapa_reg_data { |
100 | /* |
101 | * bit 0 - 1: device status |
102 | * bit 3 - 2: power mode |
103 | * bit 6 - 4: reserved |
104 | * bit 7: interrupt valid bit |
105 | */ |
106 | u8 device_status; |
107 | /* |
108 | * bit 7 - 4: number of fingers currently touching pad |
109 | * bit 3: valid data check bit |
110 | * bit 2: middle mechanism button state if exists |
111 | * bit 1: right mechanism button state if exists |
112 | * bit 0: left mechanism button state if exists |
113 | */ |
114 | u8 finger_btn; |
115 | /* CYAPA reports up to 5 touches per packet. */ |
116 | struct cyapa_touch touches[5]; |
117 | } __packed; |
118 | |
119 | struct gen3_write_block_cmd { |
120 | u8 checksum_seed; /* Always be 0xff */ |
121 | u8 cmd_code; /* command code: 0x39 */ |
122 | u8 key[8]; /* 8-byte security key */ |
123 | __be16 block_num; |
124 | u8 block_data[CYAPA_FW_BLOCK_SIZE]; |
125 | u8 block_checksum; /* Calculated using bytes 12 - 75 */ |
126 | u8 cmd_checksum; /* Calculated using bytes 0-76 */ |
127 | } __packed; |
128 | |
129 | static const u8 security_key[] = { |
130 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; |
131 | static const u8 bl_activate[] = { 0x00, 0xff, 0x38, 0x00, 0x01, 0x02, 0x03, |
132 | 0x04, 0x05, 0x06, 0x07 }; |
133 | static const u8 bl_deactivate[] = { 0x00, 0xff, 0x3b, 0x00, 0x01, 0x02, 0x03, |
134 | 0x04, 0x05, 0x06, 0x07 }; |
135 | static const u8 bl_exit[] = { 0x00, 0xff, 0xa5, 0x00, 0x01, 0x02, 0x03, 0x04, |
136 | 0x05, 0x06, 0x07 }; |
137 | |
138 | |
139 | /* for byte read/write command */ |
140 | #define CMD_RESET 0 |
141 | #define CMD_POWER_MODE 1 |
142 | #define CMD_DEV_STATUS 2 |
143 | #define CMD_REPORT_MAX_BASELINE 3 |
144 | #define CMD_REPORT_MIN_BASELINE 4 |
145 | #define SMBUS_BYTE_CMD(cmd) (((cmd) & 0x3f) << 1) |
146 | #define CYAPA_SMBUS_RESET SMBUS_BYTE_CMD(CMD_RESET) |
147 | #define CYAPA_SMBUS_POWER_MODE SMBUS_BYTE_CMD(CMD_POWER_MODE) |
148 | #define CYAPA_SMBUS_DEV_STATUS SMBUS_BYTE_CMD(CMD_DEV_STATUS) |
149 | #define CYAPA_SMBUS_MAX_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MAX_BASELINE) |
150 | #define CYAPA_SMBUS_MIN_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MIN_BASELINE) |
151 | |
152 | /* for group registers read/write command */ |
153 | #define REG_GROUP_DATA 0 |
154 | #define REG_GROUP_CMD 2 |
155 | #define REG_GROUP_QUERY 3 |
156 | #define SMBUS_GROUP_CMD(grp) (0x80 | (((grp) & 0x07) << 3)) |
157 | #define CYAPA_SMBUS_GROUP_DATA SMBUS_GROUP_CMD(REG_GROUP_DATA) |
158 | #define CYAPA_SMBUS_GROUP_CMD SMBUS_GROUP_CMD(REG_GROUP_CMD) |
159 | #define CYAPA_SMBUS_GROUP_QUERY SMBUS_GROUP_CMD(REG_GROUP_QUERY) |
160 | |
161 | /* for register block read/write command */ |
162 | #define CMD_BL_STATUS 0 |
163 | #define CMD_BL_HEAD 1 |
164 | #define CMD_BL_CMD 2 |
165 | #define CMD_BL_DATA 3 |
166 | #define CMD_BL_ALL 4 |
167 | #define CMD_BLK_PRODUCT_ID 5 |
168 | #define CMD_BLK_HEAD 6 |
169 | #define SMBUS_BLOCK_CMD(cmd) (0xc0 | (((cmd) & 0x1f) << 1)) |
170 | |
171 | /* register block read/write command in bootloader mode */ |
172 | #define CYAPA_SMBUS_BL_STATUS SMBUS_BLOCK_CMD(CMD_BL_STATUS) |
173 | #define CYAPA_SMBUS_BL_HEAD SMBUS_BLOCK_CMD(CMD_BL_HEAD) |
174 | #define CYAPA_SMBUS_BL_CMD SMBUS_BLOCK_CMD(CMD_BL_CMD) |
175 | #define CYAPA_SMBUS_BL_DATA SMBUS_BLOCK_CMD(CMD_BL_DATA) |
176 | #define CYAPA_SMBUS_BL_ALL SMBUS_BLOCK_CMD(CMD_BL_ALL) |
177 | |
178 | /* register block read/write command in operational mode */ |
179 | #define CYAPA_SMBUS_BLK_PRODUCT_ID SMBUS_BLOCK_CMD(CMD_BLK_PRODUCT_ID) |
180 | #define CYAPA_SMBUS_BLK_HEAD SMBUS_BLOCK_CMD(CMD_BLK_HEAD) |
181 | |
182 | struct cyapa_cmd_len { |
183 | u8 cmd; |
184 | u8 len; |
185 | }; |
186 | |
187 | /* maps generic CYAPA_CMD_* code to the I2C equivalent */ |
188 | static const struct cyapa_cmd_len cyapa_i2c_cmds[] = { |
189 | { CYAPA_OFFSET_SOFT_RESET, 1 }, /* CYAPA_CMD_SOFT_RESET */ |
190 | { REG_OFFSET_COMMAND_BASE + 1, 1 }, /* CYAPA_CMD_POWER_MODE */ |
191 | { REG_OFFSET_DATA_BASE, 1 }, /* CYAPA_CMD_DEV_STATUS */ |
192 | { REG_OFFSET_DATA_BASE, sizeof(struct cyapa_reg_data) }, |
193 | /* CYAPA_CMD_GROUP_DATA */ |
194 | { REG_OFFSET_COMMAND_BASE, 0 }, /* CYAPA_CMD_GROUP_CMD */ |
195 | { REG_OFFSET_QUERY_BASE, QUERY_DATA_SIZE }, /* CYAPA_CMD_GROUP_QUERY */ |
196 | { BL_HEAD_OFFSET, 3 }, /* CYAPA_CMD_BL_STATUS */ |
197 | { BL_HEAD_OFFSET, 16 }, /* CYAPA_CMD_BL_HEAD */ |
198 | { BL_HEAD_OFFSET, 16 }, /* CYAPA_CMD_BL_CMD */ |
199 | { BL_DATA_OFFSET, 16 }, /* CYAPA_CMD_BL_DATA */ |
200 | { BL_HEAD_OFFSET, 32 }, /* CYAPA_CMD_BL_ALL */ |
201 | { REG_OFFSET_QUERY_BASE, PRODUCT_ID_SIZE }, |
202 | /* CYAPA_CMD_BLK_PRODUCT_ID */ |
203 | { REG_OFFSET_DATA_BASE, 32 }, /* CYAPA_CMD_BLK_HEAD */ |
204 | { REG_OFFSET_MAX_BASELINE, 1 }, /* CYAPA_CMD_MAX_BASELINE */ |
205 | { REG_OFFSET_MIN_BASELINE, 1 }, /* CYAPA_CMD_MIN_BASELINE */ |
206 | }; |
207 | |
208 | static const struct cyapa_cmd_len cyapa_smbus_cmds[] = { |
209 | { CYAPA_SMBUS_RESET, 1 }, /* CYAPA_CMD_SOFT_RESET */ |
210 | { CYAPA_SMBUS_POWER_MODE, 1 }, /* CYAPA_CMD_POWER_MODE */ |
211 | { CYAPA_SMBUS_DEV_STATUS, 1 }, /* CYAPA_CMD_DEV_STATUS */ |
212 | { CYAPA_SMBUS_GROUP_DATA, sizeof(struct cyapa_reg_data) }, |
213 | /* CYAPA_CMD_GROUP_DATA */ |
214 | { CYAPA_SMBUS_GROUP_CMD, 2 }, /* CYAPA_CMD_GROUP_CMD */ |
215 | { CYAPA_SMBUS_GROUP_QUERY, QUERY_DATA_SIZE }, |
216 | /* CYAPA_CMD_GROUP_QUERY */ |
217 | { CYAPA_SMBUS_BL_STATUS, 3 }, /* CYAPA_CMD_BL_STATUS */ |
218 | { CYAPA_SMBUS_BL_HEAD, 16 }, /* CYAPA_CMD_BL_HEAD */ |
219 | { CYAPA_SMBUS_BL_CMD, 16 }, /* CYAPA_CMD_BL_CMD */ |
220 | { CYAPA_SMBUS_BL_DATA, 16 }, /* CYAPA_CMD_BL_DATA */ |
221 | { CYAPA_SMBUS_BL_ALL, 32 }, /* CYAPA_CMD_BL_ALL */ |
222 | { CYAPA_SMBUS_BLK_PRODUCT_ID, PRODUCT_ID_SIZE }, |
223 | /* CYAPA_CMD_BLK_PRODUCT_ID */ |
224 | { CYAPA_SMBUS_BLK_HEAD, 16 }, /* CYAPA_CMD_BLK_HEAD */ |
225 | { CYAPA_SMBUS_MAX_BASELINE, 1 }, /* CYAPA_CMD_MAX_BASELINE */ |
226 | { CYAPA_SMBUS_MIN_BASELINE, 1 }, /* CYAPA_CMD_MIN_BASELINE */ |
227 | }; |
228 | |
229 | static int cyapa_gen3_try_poll_handler(struct cyapa *cyapa); |
230 | |
231 | /* |
232 | * cyapa_smbus_read_block - perform smbus block read command |
233 | * @cyapa - private data structure of the driver |
234 | * @cmd - the properly encoded smbus command |
235 | * @len - expected length of smbus command result |
236 | * @values - buffer to store smbus command result |
237 | * |
238 | * Returns negative errno, else the number of bytes written. |
239 | * |
240 | * Note: |
241 | * In trackpad device, the memory block allocated for I2C register map |
242 | * is 256 bytes, so the max read block for I2C bus is 256 bytes. |
243 | */ |
244 | ssize_t cyapa_smbus_read_block(struct cyapa *cyapa, u8 cmd, size_t len, |
245 | u8 *values) |
246 | { |
247 | ssize_t ret; |
248 | u8 index; |
249 | u8 smbus_cmd; |
250 | u8 *buf; |
251 | struct i2c_client *client = cyapa->client; |
252 | |
253 | if (!(SMBUS_BYTE_BLOCK_CMD_MASK & cmd)) |
254 | return -EINVAL; |
255 | |
256 | if (SMBUS_GROUP_BLOCK_CMD_MASK & cmd) { |
257 | /* read specific block registers command. */ |
258 | smbus_cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ); |
259 | ret = i2c_smbus_read_block_data(client, command: smbus_cmd, values); |
260 | goto out; |
261 | } |
262 | |
263 | ret = 0; |
264 | for (index = 0; index * I2C_SMBUS_BLOCK_MAX < len; index++) { |
265 | smbus_cmd = SMBUS_ENCODE_IDX(cmd, index); |
266 | smbus_cmd = SMBUS_ENCODE_RW(smbus_cmd, SMBUS_READ); |
267 | buf = values + I2C_SMBUS_BLOCK_MAX * index; |
268 | ret = i2c_smbus_read_block_data(client, command: smbus_cmd, values: buf); |
269 | if (ret < 0) |
270 | goto out; |
271 | } |
272 | |
273 | out: |
274 | return ret > 0 ? len : ret; |
275 | } |
276 | |
277 | static s32 cyapa_read_byte(struct cyapa *cyapa, u8 cmd_idx) |
278 | { |
279 | u8 cmd; |
280 | |
281 | if (cyapa->smbus) { |
282 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; |
283 | cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ); |
284 | } else { |
285 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; |
286 | } |
287 | return i2c_smbus_read_byte_data(client: cyapa->client, command: cmd); |
288 | } |
289 | |
290 | static s32 cyapa_write_byte(struct cyapa *cyapa, u8 cmd_idx, u8 value) |
291 | { |
292 | u8 cmd; |
293 | |
294 | if (cyapa->smbus) { |
295 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; |
296 | cmd = SMBUS_ENCODE_RW(cmd, SMBUS_WRITE); |
297 | } else { |
298 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; |
299 | } |
300 | return i2c_smbus_write_byte_data(client: cyapa->client, command: cmd, value); |
301 | } |
302 | |
303 | ssize_t cyapa_i2c_reg_read_block(struct cyapa *cyapa, u8 reg, size_t len, |
304 | u8 *values) |
305 | { |
306 | return i2c_smbus_read_i2c_block_data(client: cyapa->client, command: reg, length: len, values); |
307 | } |
308 | |
309 | static ssize_t cyapa_i2c_reg_write_block(struct cyapa *cyapa, u8 reg, |
310 | size_t len, const u8 *values) |
311 | { |
312 | return i2c_smbus_write_i2c_block_data(client: cyapa->client, command: reg, length: len, values); |
313 | } |
314 | |
315 | ssize_t cyapa_read_block(struct cyapa *cyapa, u8 cmd_idx, u8 *values) |
316 | { |
317 | u8 cmd; |
318 | size_t len; |
319 | |
320 | if (cyapa->smbus) { |
321 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; |
322 | len = cyapa_smbus_cmds[cmd_idx].len; |
323 | return cyapa_smbus_read_block(cyapa, cmd, len, values); |
324 | } |
325 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; |
326 | len = cyapa_i2c_cmds[cmd_idx].len; |
327 | return cyapa_i2c_reg_read_block(cyapa, reg: cmd, len, values); |
328 | } |
329 | |
330 | /* |
331 | * Determine the Gen3 trackpad device's current operating state. |
332 | * |
333 | */ |
334 | static int cyapa_gen3_state_parse(struct cyapa *cyapa, u8 *reg_data, int len) |
335 | { |
336 | cyapa->state = CYAPA_STATE_NO_DEVICE; |
337 | |
338 | /* Parse based on Gen3 characteristic registers and bits */ |
339 | if (reg_data[REG_BL_FILE] == BL_FILE && |
340 | reg_data[REG_BL_ERROR] == BL_ERROR_NO_ERR_IDLE && |
341 | (reg_data[REG_BL_STATUS] == |
342 | (BL_STATUS_RUNNING | BL_STATUS_CSUM_VALID) || |
343 | reg_data[REG_BL_STATUS] == BL_STATUS_RUNNING)) { |
344 | /* |
345 | * Normal state after power on or reset, |
346 | * REG_BL_STATUS == 0x11, firmware image checksum is valid. |
347 | * REG_BL_STATUS == 0x10, firmware image checksum is invalid. |
348 | */ |
349 | cyapa->gen = CYAPA_GEN3; |
350 | cyapa->state = CYAPA_STATE_BL_IDLE; |
351 | } else if (reg_data[REG_BL_FILE] == BL_FILE && |
352 | (reg_data[REG_BL_STATUS] & BL_STATUS_RUNNING) == |
353 | BL_STATUS_RUNNING) { |
354 | cyapa->gen = CYAPA_GEN3; |
355 | if (reg_data[REG_BL_STATUS] & BL_STATUS_BUSY) { |
356 | cyapa->state = CYAPA_STATE_BL_BUSY; |
357 | } else { |
358 | if ((reg_data[REG_BL_ERROR] & BL_ERROR_BOOTLOADING) == |
359 | BL_ERROR_BOOTLOADING) |
360 | cyapa->state = CYAPA_STATE_BL_ACTIVE; |
361 | else |
362 | cyapa->state = CYAPA_STATE_BL_IDLE; |
363 | } |
364 | } else if ((reg_data[REG_OP_STATUS] & OP_STATUS_SRC) && |
365 | (reg_data[REG_OP_DATA1] & OP_DATA_VALID)) { |
366 | /* |
367 | * Normal state when running in operational mode, |
368 | * may also not in full power state or |
369 | * busying in command process. |
370 | */ |
371 | if (GEN3_FINGER_NUM(reg_data[REG_OP_DATA1]) <= |
372 | GEN3_MAX_FINGERS) { |
373 | /* Finger number data is valid. */ |
374 | cyapa->gen = CYAPA_GEN3; |
375 | cyapa->state = CYAPA_STATE_OP; |
376 | } |
377 | } else if (reg_data[REG_OP_STATUS] == 0x0C && |
378 | reg_data[REG_OP_DATA1] == 0x08) { |
379 | /* Op state when first two registers overwritten with 0x00 */ |
380 | cyapa->gen = CYAPA_GEN3; |
381 | cyapa->state = CYAPA_STATE_OP; |
382 | } else if (reg_data[REG_BL_STATUS] & |
383 | (BL_STATUS_RUNNING | BL_STATUS_BUSY)) { |
384 | cyapa->gen = CYAPA_GEN3; |
385 | cyapa->state = CYAPA_STATE_BL_BUSY; |
386 | } |
387 | |
388 | if (cyapa->gen == CYAPA_GEN3 && (cyapa->state == CYAPA_STATE_OP || |
389 | cyapa->state == CYAPA_STATE_BL_IDLE || |
390 | cyapa->state == CYAPA_STATE_BL_ACTIVE || |
391 | cyapa->state == CYAPA_STATE_BL_BUSY)) |
392 | return 0; |
393 | |
394 | return -EAGAIN; |
395 | } |
396 | |
397 | /* |
398 | * Enter bootloader by soft resetting the device. |
399 | * |
400 | * If device is already in the bootloader, the function just returns. |
401 | * Otherwise, reset the device; after reset, device enters bootloader idle |
402 | * state immediately. |
403 | * |
404 | * Returns: |
405 | * 0 on success |
406 | * -EAGAIN device was reset, but is not now in bootloader idle state |
407 | * < 0 if the device never responds within the timeout |
408 | */ |
409 | static int cyapa_gen3_bl_enter(struct cyapa *cyapa) |
410 | { |
411 | int error; |
412 | int waiting_time; |
413 | |
414 | error = cyapa_poll_state(cyapa, timeout: 500); |
415 | if (error) |
416 | return error; |
417 | if (cyapa->state == CYAPA_STATE_BL_IDLE) { |
418 | /* Already in BL_IDLE. Skipping reset. */ |
419 | return 0; |
420 | } |
421 | |
422 | if (cyapa->state != CYAPA_STATE_OP) |
423 | return -EAGAIN; |
424 | |
425 | cyapa->operational = false; |
426 | cyapa->state = CYAPA_STATE_NO_DEVICE; |
427 | error = cyapa_write_byte(cyapa, CYAPA_CMD_SOFT_RESET, value: 0x01); |
428 | if (error) |
429 | return -EIO; |
430 | |
431 | usleep_range(min: 25000, max: 50000); |
432 | waiting_time = 2000; /* For some shipset, max waiting time is 1~2s. */ |
433 | do { |
434 | error = cyapa_poll_state(cyapa, timeout: 500); |
435 | if (error) { |
436 | if (error == -ETIMEDOUT) { |
437 | waiting_time -= 500; |
438 | continue; |
439 | } |
440 | return error; |
441 | } |
442 | |
443 | if ((cyapa->state == CYAPA_STATE_BL_IDLE) && |
444 | !(cyapa->status[REG_BL_STATUS] & BL_STATUS_WATCHDOG)) |
445 | break; |
446 | |
447 | msleep(msecs: 100); |
448 | waiting_time -= 100; |
449 | } while (waiting_time > 0); |
450 | |
451 | if ((cyapa->state != CYAPA_STATE_BL_IDLE) || |
452 | (cyapa->status[REG_BL_STATUS] & BL_STATUS_WATCHDOG)) |
453 | return -EAGAIN; |
454 | |
455 | return 0; |
456 | } |
457 | |
458 | static int cyapa_gen3_bl_activate(struct cyapa *cyapa) |
459 | { |
460 | int error; |
461 | |
462 | error = cyapa_i2c_reg_write_block(cyapa, reg: 0, len: sizeof(bl_activate), |
463 | values: bl_activate); |
464 | if (error) |
465 | return error; |
466 | |
467 | /* Wait for bootloader to activate; takes between 2 and 12 seconds */ |
468 | msleep(msecs: 2000); |
469 | error = cyapa_poll_state(cyapa, timeout: 11000); |
470 | if (error) |
471 | return error; |
472 | if (cyapa->state != CYAPA_STATE_BL_ACTIVE) |
473 | return -EAGAIN; |
474 | |
475 | return 0; |
476 | } |
477 | |
478 | static int cyapa_gen3_bl_deactivate(struct cyapa *cyapa) |
479 | { |
480 | int error; |
481 | |
482 | error = cyapa_i2c_reg_write_block(cyapa, reg: 0, len: sizeof(bl_deactivate), |
483 | values: bl_deactivate); |
484 | if (error) |
485 | return error; |
486 | |
487 | /* Wait for bootloader to switch to idle state; should take < 100ms */ |
488 | msleep(msecs: 100); |
489 | error = cyapa_poll_state(cyapa, timeout: 500); |
490 | if (error) |
491 | return error; |
492 | if (cyapa->state != CYAPA_STATE_BL_IDLE) |
493 | return -EAGAIN; |
494 | return 0; |
495 | } |
496 | |
497 | /* |
498 | * Exit bootloader |
499 | * |
500 | * Send bl_exit command, then wait 50 - 100 ms to let device transition to |
501 | * operational mode. If this is the first time the device's firmware is |
502 | * running, it can take up to 2 seconds to calibrate its sensors. So, poll |
503 | * the device's new state for up to 2 seconds. |
504 | * |
505 | * Returns: |
506 | * -EIO failure while reading from device |
507 | * -EAGAIN device is stuck in bootloader, b/c it has invalid firmware |
508 | * 0 device is supported and in operational mode |
509 | */ |
510 | static int cyapa_gen3_bl_exit(struct cyapa *cyapa) |
511 | { |
512 | int error; |
513 | |
514 | error = cyapa_i2c_reg_write_block(cyapa, reg: 0, len: sizeof(bl_exit), values: bl_exit); |
515 | if (error) |
516 | return error; |
517 | |
518 | /* |
519 | * Wait for bootloader to exit, and operation mode to start. |
520 | * Normally, this takes at least 50 ms. |
521 | */ |
522 | msleep(msecs: 50); |
523 | /* |
524 | * In addition, when a device boots for the first time after being |
525 | * updated to new firmware, it must first calibrate its sensors, which |
526 | * can take up to an additional 2 seconds. If the device power is |
527 | * running low, this may take even longer. |
528 | */ |
529 | error = cyapa_poll_state(cyapa, timeout: 4000); |
530 | if (error < 0) |
531 | return error; |
532 | if (cyapa->state != CYAPA_STATE_OP) |
533 | return -EAGAIN; |
534 | |
535 | return 0; |
536 | } |
537 | |
538 | static u16 cyapa_gen3_csum(const u8 *buf, size_t count) |
539 | { |
540 | int i; |
541 | u16 csum = 0; |
542 | |
543 | for (i = 0; i < count; i++) |
544 | csum += buf[i]; |
545 | |
546 | return csum; |
547 | } |
548 | |
549 | /* |
550 | * Verify the integrity of a CYAPA firmware image file. |
551 | * |
552 | * The firmware image file is 30848 bytes, composed of 482 64-byte blocks. |
553 | * |
554 | * The first 2 blocks are the firmware header. |
555 | * The next 480 blocks are the firmware image. |
556 | * |
557 | * The first two bytes of the header hold the header checksum, computed by |
558 | * summing the other 126 bytes of the header. |
559 | * The last two bytes of the header hold the firmware image checksum, computed |
560 | * by summing the 30720 bytes of the image modulo 0xffff. |
561 | * |
562 | * Both checksums are stored little-endian. |
563 | */ |
564 | static int cyapa_gen3_check_fw(struct cyapa *cyapa, const struct firmware *fw) |
565 | { |
566 | struct device *dev = &cyapa->client->dev; |
567 | u16 csum; |
568 | u16 csum_expected; |
569 | |
570 | /* Firmware must match exact 30848 bytes = 482 64-byte blocks. */ |
571 | if (fw->size != CYAPA_FW_SIZE) { |
572 | dev_err(dev, "invalid firmware size = %zu, expected %u.\n" , |
573 | fw->size, CYAPA_FW_SIZE); |
574 | return -EINVAL; |
575 | } |
576 | |
577 | /* Verify header block */ |
578 | csum_expected = (fw->data[0] << 8) | fw->data[1]; |
579 | csum = cyapa_gen3_csum(buf: &fw->data[2], CYAPA_FW_HDR_SIZE - 2); |
580 | if (csum != csum_expected) { |
581 | dev_err(dev, "%s %04x, expected: %04x\n" , |
582 | "invalid firmware header checksum = " , |
583 | csum, csum_expected); |
584 | return -EINVAL; |
585 | } |
586 | |
587 | /* Verify firmware image */ |
588 | csum_expected = (fw->data[CYAPA_FW_HDR_SIZE - 2] << 8) | |
589 | fw->data[CYAPA_FW_HDR_SIZE - 1]; |
590 | csum = cyapa_gen3_csum(buf: &fw->data[CYAPA_FW_HDR_SIZE], |
591 | CYAPA_FW_DATA_SIZE); |
592 | if (csum != csum_expected) { |
593 | dev_err(dev, "%s %04x, expected: %04x\n" , |
594 | "invalid firmware header checksum = " , |
595 | csum, csum_expected); |
596 | return -EINVAL; |
597 | } |
598 | return 0; |
599 | } |
600 | |
601 | /* |
602 | * Write a |len| byte long buffer |buf| to the device, by chopping it up into a |
603 | * sequence of smaller |CYAPA_CMD_LEN|-length write commands. |
604 | * |
605 | * The data bytes for a write command are prepended with the 1-byte offset |
606 | * of the data relative to the start of |buf|. |
607 | */ |
608 | static int cyapa_gen3_write_buffer(struct cyapa *cyapa, |
609 | const u8 *buf, size_t len) |
610 | { |
611 | int error; |
612 | size_t i; |
613 | unsigned char cmd[CYAPA_CMD_LEN + 1]; |
614 | size_t cmd_len; |
615 | |
616 | for (i = 0; i < len; i += CYAPA_CMD_LEN) { |
617 | const u8 *payload = &buf[i]; |
618 | |
619 | cmd_len = (len - i >= CYAPA_CMD_LEN) ? CYAPA_CMD_LEN : len - i; |
620 | cmd[0] = i; |
621 | memcpy(&cmd[1], payload, cmd_len); |
622 | |
623 | error = cyapa_i2c_reg_write_block(cyapa, reg: 0, len: cmd_len + 1, values: cmd); |
624 | if (error) |
625 | return error; |
626 | } |
627 | return 0; |
628 | } |
629 | |
630 | /* |
631 | * A firmware block write command writes 64 bytes of data to a single flash |
632 | * page in the device. The 78-byte block write command has the format: |
633 | * <0xff> <CMD> <Key> <Start> <Data> <Data-Checksum> <CMD Checksum> |
634 | * |
635 | * <0xff> - every command starts with 0xff |
636 | * <CMD> - the write command value is 0x39 |
637 | * <Key> - write commands include an 8-byte key: { 00 01 02 03 04 05 06 07 } |
638 | * <Block> - Memory Block number (address / 64) (16-bit, big-endian) |
639 | * <Data> - 64 bytes of firmware image data |
640 | * <Data Checksum> - sum of 64 <Data> bytes, modulo 0xff |
641 | * <CMD Checksum> - sum of 77 bytes, from 0xff to <Data Checksum> |
642 | * |
643 | * Each write command is split into 5 i2c write transactions of up to 16 bytes. |
644 | * Each transaction starts with an i2c register offset: (00, 10, 20, 30, 40). |
645 | */ |
646 | static int cyapa_gen3_write_fw_block(struct cyapa *cyapa, |
647 | u16 block, const u8 *data) |
648 | { |
649 | int ret; |
650 | struct gen3_write_block_cmd write_block_cmd; |
651 | u8 status[BL_STATUS_SIZE]; |
652 | int tries; |
653 | u8 bl_status, bl_error; |
654 | |
655 | /* Set write command and security key bytes. */ |
656 | write_block_cmd.checksum_seed = GEN3_BL_CMD_CHECKSUM_SEED; |
657 | write_block_cmd.cmd_code = GEN3_BL_CMD_WRITE_BLOCK; |
658 | memcpy(write_block_cmd.key, security_key, sizeof(security_key)); |
659 | put_unaligned_be16(val: block, p: &write_block_cmd.block_num); |
660 | memcpy(write_block_cmd.block_data, data, CYAPA_FW_BLOCK_SIZE); |
661 | write_block_cmd.block_checksum = cyapa_gen3_csum( |
662 | buf: write_block_cmd.block_data, CYAPA_FW_BLOCK_SIZE); |
663 | write_block_cmd.cmd_checksum = cyapa_gen3_csum(buf: (u8 *)&write_block_cmd, |
664 | count: sizeof(write_block_cmd) - 1); |
665 | |
666 | ret = cyapa_gen3_write_buffer(cyapa, buf: (u8 *)&write_block_cmd, |
667 | len: sizeof(write_block_cmd)); |
668 | if (ret) |
669 | return ret; |
670 | |
671 | /* Wait for write to finish */ |
672 | tries = 11; /* Programming for one block can take about 100ms. */ |
673 | do { |
674 | usleep_range(min: 10000, max: 20000); |
675 | |
676 | /* Check block write command result status. */ |
677 | ret = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, |
678 | BL_STATUS_SIZE, values: status); |
679 | if (ret != BL_STATUS_SIZE) |
680 | return (ret < 0) ? ret : -EIO; |
681 | } while ((status[REG_BL_STATUS] & BL_STATUS_BUSY) && --tries); |
682 | |
683 | /* Ignore WATCHDOG bit and reserved bits. */ |
684 | bl_status = status[REG_BL_STATUS] & ~BL_STATUS_REV_MASK; |
685 | bl_error = status[REG_BL_ERROR] & ~BL_ERROR_RESERVED; |
686 | |
687 | if (bl_status & BL_STATUS_BUSY) |
688 | ret = -ETIMEDOUT; |
689 | else if (bl_status != BL_STATUS_RUNNING || |
690 | bl_error != BL_ERROR_BOOTLOADING) |
691 | ret = -EIO; |
692 | else |
693 | ret = 0; |
694 | |
695 | return ret; |
696 | } |
697 | |
698 | static int cyapa_gen3_write_blocks(struct cyapa *cyapa, |
699 | size_t start_block, size_t block_count, |
700 | const u8 *image_data) |
701 | { |
702 | int error; |
703 | int i; |
704 | |
705 | for (i = 0; i < block_count; i++) { |
706 | size_t block = start_block + i; |
707 | size_t addr = i * CYAPA_FW_BLOCK_SIZE; |
708 | const u8 *data = &image_data[addr]; |
709 | |
710 | error = cyapa_gen3_write_fw_block(cyapa, block, data); |
711 | if (error) |
712 | return error; |
713 | } |
714 | return 0; |
715 | } |
716 | |
717 | static int cyapa_gen3_do_fw_update(struct cyapa *cyapa, |
718 | const struct firmware *fw) |
719 | { |
720 | struct device *dev = &cyapa->client->dev; |
721 | int error; |
722 | |
723 | /* First write data, starting at byte 128 of fw->data */ |
724 | error = cyapa_gen3_write_blocks(cyapa, |
725 | CYAPA_FW_DATA_BLOCK_START, CYAPA_FW_DATA_BLOCK_COUNT, |
726 | image_data: &fw->data[CYAPA_FW_HDR_BLOCK_COUNT * CYAPA_FW_BLOCK_SIZE]); |
727 | if (error) { |
728 | dev_err(dev, "FW update aborted, write image: %d\n" , error); |
729 | return error; |
730 | } |
731 | |
732 | /* Then write checksum */ |
733 | error = cyapa_gen3_write_blocks(cyapa, |
734 | CYAPA_FW_HDR_BLOCK_START, CYAPA_FW_HDR_BLOCK_COUNT, |
735 | image_data: &fw->data[0]); |
736 | if (error) { |
737 | dev_err(dev, "FW update aborted, write checksum: %d\n" , error); |
738 | return error; |
739 | } |
740 | |
741 | return 0; |
742 | } |
743 | |
744 | static ssize_t cyapa_gen3_do_calibrate(struct device *dev, |
745 | struct device_attribute *attr, |
746 | const char *buf, size_t count) |
747 | { |
748 | struct cyapa *cyapa = dev_get_drvdata(dev); |
749 | unsigned long timeout; |
750 | int ret; |
751 | |
752 | ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS); |
753 | if (ret < 0) { |
754 | dev_err(dev, "Error reading dev status: %d\n" , ret); |
755 | goto out; |
756 | } |
757 | if ((ret & CYAPA_DEV_NORMAL) != CYAPA_DEV_NORMAL) { |
758 | dev_warn(dev, "Trackpad device is busy, device state: 0x%02x\n" , |
759 | ret); |
760 | ret = -EAGAIN; |
761 | goto out; |
762 | } |
763 | |
764 | ret = cyapa_write_byte(cyapa, CYAPA_CMD_SOFT_RESET, |
765 | OP_RECALIBRATION_MASK); |
766 | if (ret < 0) { |
767 | dev_err(dev, "Failed to send calibrate command: %d\n" , |
768 | ret); |
769 | goto out; |
770 | } |
771 | |
772 | /* max recalibration timeout 2s. */ |
773 | timeout = jiffies + 2 * HZ; |
774 | do { |
775 | /* |
776 | * For this recalibration, the max time will not exceed 2s. |
777 | * The average time is approximately 500 - 700 ms, and we |
778 | * will check the status every 100 - 200ms. |
779 | */ |
780 | msleep(msecs: 100); |
781 | ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS); |
782 | if (ret < 0) { |
783 | dev_err(dev, "Error reading dev status: %d\n" , ret); |
784 | goto out; |
785 | } |
786 | if ((ret & CYAPA_DEV_NORMAL) == CYAPA_DEV_NORMAL) { |
787 | dev_dbg(dev, "Calibration successful.\n" ); |
788 | goto out; |
789 | } |
790 | } while (time_is_after_jiffies(timeout)); |
791 | |
792 | dev_err(dev, "Failed to calibrate. Timeout.\n" ); |
793 | ret = -ETIMEDOUT; |
794 | |
795 | out: |
796 | return ret < 0 ? ret : count; |
797 | } |
798 | |
799 | static ssize_t cyapa_gen3_show_baseline(struct device *dev, |
800 | struct device_attribute *attr, char *buf) |
801 | { |
802 | struct cyapa *cyapa = dev_get_drvdata(dev); |
803 | int max_baseline, min_baseline; |
804 | int tries; |
805 | int ret; |
806 | |
807 | ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS); |
808 | if (ret < 0) { |
809 | dev_err(dev, "Error reading dev status. err = %d\n" , ret); |
810 | goto out; |
811 | } |
812 | if ((ret & CYAPA_DEV_NORMAL) != CYAPA_DEV_NORMAL) { |
813 | dev_warn(dev, "Trackpad device is busy. device state = 0x%x\n" , |
814 | ret); |
815 | ret = -EAGAIN; |
816 | goto out; |
817 | } |
818 | |
819 | ret = cyapa_write_byte(cyapa, CYAPA_CMD_SOFT_RESET, |
820 | OP_REPORT_BASELINE_MASK); |
821 | if (ret < 0) { |
822 | dev_err(dev, "Failed to send report baseline command. %d\n" , |
823 | ret); |
824 | goto out; |
825 | } |
826 | |
827 | tries = 3; /* Try for 30 to 60 ms */ |
828 | do { |
829 | usleep_range(min: 10000, max: 20000); |
830 | |
831 | ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS); |
832 | if (ret < 0) { |
833 | dev_err(dev, "Error reading dev status. err = %d\n" , |
834 | ret); |
835 | goto out; |
836 | } |
837 | if ((ret & CYAPA_DEV_NORMAL) == CYAPA_DEV_NORMAL) |
838 | break; |
839 | } while (--tries); |
840 | |
841 | if (tries == 0) { |
842 | dev_err(dev, "Device timed out going to Normal state.\n" ); |
843 | ret = -ETIMEDOUT; |
844 | goto out; |
845 | } |
846 | |
847 | ret = cyapa_read_byte(cyapa, CYAPA_CMD_MAX_BASELINE); |
848 | if (ret < 0) { |
849 | dev_err(dev, "Failed to read max baseline. err = %d\n" , ret); |
850 | goto out; |
851 | } |
852 | max_baseline = ret; |
853 | |
854 | ret = cyapa_read_byte(cyapa, CYAPA_CMD_MIN_BASELINE); |
855 | if (ret < 0) { |
856 | dev_err(dev, "Failed to read min baseline. err = %d\n" , ret); |
857 | goto out; |
858 | } |
859 | min_baseline = ret; |
860 | |
861 | dev_dbg(dev, "Baseline report successful. Max: %d Min: %d\n" , |
862 | max_baseline, min_baseline); |
863 | ret = scnprintf(buf, PAGE_SIZE, fmt: "%d %d\n" , max_baseline, min_baseline); |
864 | |
865 | out: |
866 | return ret; |
867 | } |
868 | |
869 | /* |
870 | * cyapa_get_wait_time_for_pwr_cmd |
871 | * |
872 | * Compute the amount of time we need to wait after updating the touchpad |
873 | * power mode. The touchpad needs to consume the incoming power mode set |
874 | * command at the current clock rate. |
875 | */ |
876 | |
877 | static u16 cyapa_get_wait_time_for_pwr_cmd(u8 pwr_mode) |
878 | { |
879 | switch (pwr_mode) { |
880 | case PWR_MODE_FULL_ACTIVE: return 20; |
881 | case PWR_MODE_BTN_ONLY: return 20; |
882 | case PWR_MODE_OFF: return 20; |
883 | default: return cyapa_pwr_cmd_to_sleep_time(pwr_mode) + 50; |
884 | } |
885 | } |
886 | |
887 | /* |
888 | * Set device power mode |
889 | * |
890 | * Write to the field to configure power state. Power states include : |
891 | * Full : Max scans and report rate. |
892 | * Idle : Report rate set by user specified time. |
893 | * ButtonOnly : No scans for fingers. When the button is triggered, |
894 | * a slave interrupt is asserted to notify host to wake up. |
895 | * Off : Only awake for i2c commands from host. No function for button |
896 | * or touch sensors. |
897 | * |
898 | * The power_mode command should conform to the following : |
899 | * Full : 0x3f |
900 | * Idle : Configurable from 20 to 1000ms. See note below for |
901 | * cyapa_sleep_time_to_pwr_cmd and cyapa_pwr_cmd_to_sleep_time |
902 | * ButtonOnly : 0x01 |
903 | * Off : 0x00 |
904 | * |
905 | * Device power mode can only be set when device is in operational mode. |
906 | */ |
907 | static int cyapa_gen3_set_power_mode(struct cyapa *cyapa, u8 power_mode, |
908 | u16 always_unused, enum cyapa_pm_stage pm_stage) |
909 | { |
910 | struct input_dev *input = cyapa->input; |
911 | u8 power; |
912 | int tries; |
913 | int sleep_time; |
914 | int interval; |
915 | int ret; |
916 | |
917 | if (cyapa->state != CYAPA_STATE_OP) |
918 | return 0; |
919 | |
920 | tries = SET_POWER_MODE_TRIES; |
921 | while (tries--) { |
922 | ret = cyapa_read_byte(cyapa, CYAPA_CMD_POWER_MODE); |
923 | if (ret >= 0) |
924 | break; |
925 | usleep_range(SET_POWER_MODE_DELAY, max: 2 * SET_POWER_MODE_DELAY); |
926 | } |
927 | if (ret < 0) |
928 | return ret; |
929 | |
930 | /* |
931 | * Return early if the power mode to set is the same as the current |
932 | * one. |
933 | */ |
934 | if ((ret & PWR_MODE_MASK) == power_mode) |
935 | return 0; |
936 | |
937 | sleep_time = (int)cyapa_get_wait_time_for_pwr_cmd(pwr_mode: ret & PWR_MODE_MASK); |
938 | power = ret; |
939 | power &= ~PWR_MODE_MASK; |
940 | power |= power_mode & PWR_MODE_MASK; |
941 | tries = SET_POWER_MODE_TRIES; |
942 | while (tries--) { |
943 | ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, value: power); |
944 | if (!ret) |
945 | break; |
946 | usleep_range(SET_POWER_MODE_DELAY, max: 2 * SET_POWER_MODE_DELAY); |
947 | } |
948 | |
949 | /* |
950 | * Wait for the newly set power command to go in at the previous |
951 | * clock speed (scanrate) used by the touchpad firmware. Not |
952 | * doing so before issuing the next command may result in errors |
953 | * depending on the command's content. |
954 | */ |
955 | if (cyapa->operational && |
956 | input && input_device_enabled(dev: input) && |
957 | (pm_stage == CYAPA_PM_RUNTIME_SUSPEND || |
958 | pm_stage == CYAPA_PM_RUNTIME_RESUME)) { |
959 | /* Try to polling in 120Hz, read may fail, just ignore it. */ |
960 | interval = 1000 / 120; |
961 | while (sleep_time > 0) { |
962 | if (sleep_time > interval) |
963 | msleep(msecs: interval); |
964 | else |
965 | msleep(msecs: sleep_time); |
966 | sleep_time -= interval; |
967 | cyapa_gen3_try_poll_handler(cyapa); |
968 | } |
969 | } else { |
970 | msleep(msecs: sleep_time); |
971 | } |
972 | |
973 | return ret; |
974 | } |
975 | |
976 | static int cyapa_gen3_set_proximity(struct cyapa *cyapa, bool enable) |
977 | { |
978 | return -EOPNOTSUPP; |
979 | } |
980 | |
981 | static int cyapa_gen3_get_query_data(struct cyapa *cyapa) |
982 | { |
983 | u8 query_data[QUERY_DATA_SIZE]; |
984 | int ret; |
985 | |
986 | if (cyapa->state != CYAPA_STATE_OP) |
987 | return -EBUSY; |
988 | |
989 | ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_QUERY, values: query_data); |
990 | if (ret != QUERY_DATA_SIZE) |
991 | return (ret < 0) ? ret : -EIO; |
992 | |
993 | memcpy(&cyapa->product_id[0], &query_data[0], 5); |
994 | cyapa->product_id[5] = '-'; |
995 | memcpy(&cyapa->product_id[6], &query_data[5], 6); |
996 | cyapa->product_id[12] = '-'; |
997 | memcpy(&cyapa->product_id[13], &query_data[11], 2); |
998 | cyapa->product_id[15] = '\0'; |
999 | |
1000 | cyapa->fw_maj_ver = query_data[15]; |
1001 | cyapa->fw_min_ver = query_data[16]; |
1002 | |
1003 | cyapa->btn_capability = query_data[19] & CAPABILITY_BTN_MASK; |
1004 | |
1005 | cyapa->gen = query_data[20] & 0x0f; |
1006 | |
1007 | cyapa->max_abs_x = ((query_data[21] & 0xf0) << 4) | query_data[22]; |
1008 | cyapa->max_abs_y = ((query_data[21] & 0x0f) << 8) | query_data[23]; |
1009 | |
1010 | cyapa->physical_size_x = |
1011 | ((query_data[24] & 0xf0) << 4) | query_data[25]; |
1012 | cyapa->physical_size_y = |
1013 | ((query_data[24] & 0x0f) << 8) | query_data[26]; |
1014 | |
1015 | cyapa->max_z = 255; |
1016 | |
1017 | return 0; |
1018 | } |
1019 | |
1020 | static int cyapa_gen3_bl_query_data(struct cyapa *cyapa) |
1021 | { |
1022 | u8 bl_data[CYAPA_CMD_LEN]; |
1023 | int ret; |
1024 | |
1025 | ret = cyapa_i2c_reg_read_block(cyapa, reg: 0, CYAPA_CMD_LEN, values: bl_data); |
1026 | if (ret != CYAPA_CMD_LEN) |
1027 | return (ret < 0) ? ret : -EIO; |
1028 | |
1029 | /* |
1030 | * This value will be updated again when entered application mode. |
1031 | * If TP failed to enter application mode, this fw version values |
1032 | * can be used as a reference. |
1033 | * This firmware version valid when fw image checksum is valid. |
1034 | */ |
1035 | if (bl_data[REG_BL_STATUS] == |
1036 | (BL_STATUS_RUNNING | BL_STATUS_CSUM_VALID)) { |
1037 | cyapa->fw_maj_ver = bl_data[GEN3_BL_IDLE_FW_MAJ_VER_OFFSET]; |
1038 | cyapa->fw_min_ver = bl_data[GEN3_BL_IDLE_FW_MIN_VER_OFFSET]; |
1039 | } |
1040 | |
1041 | return 0; |
1042 | } |
1043 | |
1044 | /* |
1045 | * Check if device is operational. |
1046 | * |
1047 | * An operational device is responding, has exited bootloader, and has |
1048 | * firmware supported by this driver. |
1049 | * |
1050 | * Returns: |
1051 | * -EBUSY no device or in bootloader |
1052 | * -EIO failure while reading from device |
1053 | * -EAGAIN device is still in bootloader |
1054 | * if ->state = CYAPA_STATE_BL_IDLE, device has invalid firmware |
1055 | * -EINVAL device is in operational mode, but not supported by this driver |
1056 | * 0 device is supported |
1057 | */ |
1058 | static int cyapa_gen3_do_operational_check(struct cyapa *cyapa) |
1059 | { |
1060 | struct device *dev = &cyapa->client->dev; |
1061 | int error; |
1062 | |
1063 | switch (cyapa->state) { |
1064 | case CYAPA_STATE_BL_ACTIVE: |
1065 | error = cyapa_gen3_bl_deactivate(cyapa); |
1066 | if (error) { |
1067 | dev_err(dev, "failed to bl_deactivate: %d\n" , error); |
1068 | return error; |
1069 | } |
1070 | |
1071 | fallthrough; |
1072 | case CYAPA_STATE_BL_IDLE: |
1073 | /* Try to get firmware version in bootloader mode. */ |
1074 | cyapa_gen3_bl_query_data(cyapa); |
1075 | |
1076 | error = cyapa_gen3_bl_exit(cyapa); |
1077 | if (error) { |
1078 | dev_err(dev, "failed to bl_exit: %d\n" , error); |
1079 | return error; |
1080 | } |
1081 | |
1082 | fallthrough; |
1083 | case CYAPA_STATE_OP: |
1084 | /* |
1085 | * Reading query data before going back to the full mode |
1086 | * may cause problems, so we set the power mode first here. |
1087 | */ |
1088 | error = cyapa_gen3_set_power_mode(cyapa, |
1089 | PWR_MODE_FULL_ACTIVE, always_unused: 0, pm_stage: CYAPA_PM_ACTIVE); |
1090 | if (error) |
1091 | dev_err(dev, "%s: set full power mode failed: %d\n" , |
1092 | __func__, error); |
1093 | error = cyapa_gen3_get_query_data(cyapa); |
1094 | if (error < 0) |
1095 | return error; |
1096 | |
1097 | /* Only support firmware protocol gen3 */ |
1098 | if (cyapa->gen != CYAPA_GEN3) { |
1099 | dev_err(dev, "unsupported protocol version (%d)" , |
1100 | cyapa->gen); |
1101 | return -EINVAL; |
1102 | } |
1103 | |
1104 | /* Only support product ID starting with CYTRA */ |
1105 | if (memcmp(p: cyapa->product_id, q: product_id, |
1106 | strlen(product_id)) != 0) { |
1107 | dev_err(dev, "unsupported product ID (%s)\n" , |
1108 | cyapa->product_id); |
1109 | return -EINVAL; |
1110 | } |
1111 | |
1112 | return 0; |
1113 | |
1114 | default: |
1115 | return -EIO; |
1116 | } |
1117 | return 0; |
1118 | } |
1119 | |
1120 | /* |
1121 | * Return false, do not continue process |
1122 | * Return true, continue process. |
1123 | */ |
1124 | static bool cyapa_gen3_irq_cmd_handler(struct cyapa *cyapa) |
1125 | { |
1126 | /* Not gen3 irq command response, skip for continue. */ |
1127 | if (cyapa->gen != CYAPA_GEN3) |
1128 | return true; |
1129 | |
1130 | if (cyapa->operational) |
1131 | return true; |
1132 | |
1133 | /* |
1134 | * Driver in detecting or other interface function processing, |
1135 | * so, stop cyapa_gen3_irq_handler to continue process to |
1136 | * avoid unwanted to error detecting and processing. |
1137 | * |
1138 | * And also, avoid the periodically asserted interrupts to be processed |
1139 | * as touch inputs when gen3 failed to launch into application mode, |
1140 | * which will cause gen3 stays in bootloader mode. |
1141 | */ |
1142 | return false; |
1143 | } |
1144 | |
1145 | static int cyapa_gen3_event_process(struct cyapa *cyapa, |
1146 | struct cyapa_reg_data *data) |
1147 | { |
1148 | struct input_dev *input = cyapa->input; |
1149 | int num_fingers; |
1150 | int i; |
1151 | |
1152 | num_fingers = (data->finger_btn >> 4) & 0x0f; |
1153 | for (i = 0; i < num_fingers; i++) { |
1154 | const struct cyapa_touch *touch = &data->touches[i]; |
1155 | /* Note: touch->id range is 1 to 15; slots are 0 to 14. */ |
1156 | int slot = touch->id - 1; |
1157 | |
1158 | input_mt_slot(dev: input, slot); |
1159 | input_mt_report_slot_state(dev: input, MT_TOOL_FINGER, active: true); |
1160 | input_report_abs(dev: input, ABS_MT_POSITION_X, |
1161 | value: ((touch->xy_hi & 0xf0) << 4) | touch->x_lo); |
1162 | input_report_abs(dev: input, ABS_MT_POSITION_Y, |
1163 | value: ((touch->xy_hi & 0x0f) << 8) | touch->y_lo); |
1164 | input_report_abs(dev: input, ABS_MT_PRESSURE, value: touch->pressure); |
1165 | } |
1166 | |
1167 | input_mt_sync_frame(dev: input); |
1168 | |
1169 | if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK) |
1170 | input_report_key(dev: input, BTN_LEFT, |
1171 | value: !!(data->finger_btn & OP_DATA_LEFT_BTN)); |
1172 | if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK) |
1173 | input_report_key(dev: input, BTN_MIDDLE, |
1174 | value: !!(data->finger_btn & OP_DATA_MIDDLE_BTN)); |
1175 | if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK) |
1176 | input_report_key(dev: input, BTN_RIGHT, |
1177 | value: !!(data->finger_btn & OP_DATA_RIGHT_BTN)); |
1178 | input_sync(dev: input); |
1179 | |
1180 | return 0; |
1181 | } |
1182 | |
1183 | static int cyapa_gen3_irq_handler(struct cyapa *cyapa) |
1184 | { |
1185 | struct device *dev = &cyapa->client->dev; |
1186 | struct cyapa_reg_data data; |
1187 | int ret; |
1188 | |
1189 | ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_DATA, values: (u8 *)&data); |
1190 | if (ret != sizeof(data)) { |
1191 | dev_err(dev, "failed to read report data, (%d)\n" , ret); |
1192 | return -EINVAL; |
1193 | } |
1194 | |
1195 | if ((data.device_status & OP_STATUS_SRC) != OP_STATUS_SRC || |
1196 | (data.device_status & OP_STATUS_DEV) != CYAPA_DEV_NORMAL || |
1197 | (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID) { |
1198 | dev_err(dev, "invalid device state bytes: %02x %02x\n" , |
1199 | data.device_status, data.finger_btn); |
1200 | return -EINVAL; |
1201 | } |
1202 | |
1203 | return cyapa_gen3_event_process(cyapa, data: &data); |
1204 | } |
1205 | |
1206 | /* |
1207 | * This function will be called in the cyapa_gen3_set_power_mode function, |
1208 | * and it's known that it may failed in some situation after the set power |
1209 | * mode command was sent. So this function is aimed to avoid the knwon |
1210 | * and unwanted output I2C and data parse error messages. |
1211 | */ |
1212 | static int cyapa_gen3_try_poll_handler(struct cyapa *cyapa) |
1213 | { |
1214 | struct cyapa_reg_data data; |
1215 | int ret; |
1216 | |
1217 | ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_DATA, values: (u8 *)&data); |
1218 | if (ret != sizeof(data)) |
1219 | return -EINVAL; |
1220 | |
1221 | if ((data.device_status & OP_STATUS_SRC) != OP_STATUS_SRC || |
1222 | (data.device_status & OP_STATUS_DEV) != CYAPA_DEV_NORMAL || |
1223 | (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID) |
1224 | return -EINVAL; |
1225 | |
1226 | return cyapa_gen3_event_process(cyapa, data: &data); |
1227 | |
1228 | } |
1229 | |
1230 | static int cyapa_gen3_initialize(struct cyapa *cyapa) { return 0; } |
1231 | static int cyapa_gen3_bl_initiate(struct cyapa *cyapa, |
1232 | const struct firmware *fw) { return 0; } |
1233 | static int cyapa_gen3_empty_output_data(struct cyapa *cyapa, |
1234 | u8 *buf, int *len, cb_sort func) { return 0; } |
1235 | |
1236 | const struct cyapa_dev_ops cyapa_gen3_ops = { |
1237 | .check_fw = cyapa_gen3_check_fw, |
1238 | .bl_enter = cyapa_gen3_bl_enter, |
1239 | .bl_activate = cyapa_gen3_bl_activate, |
1240 | .update_fw = cyapa_gen3_do_fw_update, |
1241 | .bl_deactivate = cyapa_gen3_bl_deactivate, |
1242 | .bl_initiate = cyapa_gen3_bl_initiate, |
1243 | |
1244 | .show_baseline = cyapa_gen3_show_baseline, |
1245 | .calibrate_store = cyapa_gen3_do_calibrate, |
1246 | |
1247 | .initialize = cyapa_gen3_initialize, |
1248 | |
1249 | .state_parse = cyapa_gen3_state_parse, |
1250 | .operational_check = cyapa_gen3_do_operational_check, |
1251 | |
1252 | .irq_handler = cyapa_gen3_irq_handler, |
1253 | .irq_cmd_handler = cyapa_gen3_irq_cmd_handler, |
1254 | .sort_empty_output_data = cyapa_gen3_empty_output_data, |
1255 | .set_power_mode = cyapa_gen3_set_power_mode, |
1256 | |
1257 | .set_proximity = cyapa_gen3_set_proximity, |
1258 | }; |
1259 | |