diff options
-rw-r--r-- | drivers/input/mouse/Makefile | 3 | ||||
-rw-r--r-- | drivers/input/mouse/cyapa.c | 1076 | ||||
-rw-r--r-- | drivers/input/mouse/cyapa.h | 296 | ||||
-rw-r--r-- | drivers/input/mouse/cyapa_gen3.c | 807 |
4 files changed, 1516 insertions, 666 deletions
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 560003dcac37..8bd950d52d5c 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
@@ -8,7 +8,7 @@ obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o | |||
8 | obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o | 8 | obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o |
9 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o | 9 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o |
10 | obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o | 10 | obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o |
11 | obj-$(CONFIG_MOUSE_CYAPA) += cyapa.o | 11 | obj-$(CONFIG_MOUSE_CYAPA) += cyapatp.o |
12 | obj-$(CONFIG_MOUSE_ELAN_I2C) += elan_i2c.o | 12 | obj-$(CONFIG_MOUSE_ELAN_I2C) += elan_i2c.o |
13 | obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o | 13 | obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o |
14 | obj-$(CONFIG_MOUSE_INPORT) += inport.o | 14 | obj-$(CONFIG_MOUSE_INPORT) += inport.o |
@@ -24,6 +24,7 @@ obj-$(CONFIG_MOUSE_SYNAPTICS_I2C) += synaptics_i2c.o | |||
24 | obj-$(CONFIG_MOUSE_SYNAPTICS_USB) += synaptics_usb.o | 24 | obj-$(CONFIG_MOUSE_SYNAPTICS_USB) += synaptics_usb.o |
25 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o | 25 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o |
26 | 26 | ||
27 | cyapatp-objs := cyapa.o cyapa_gen3.o | ||
27 | psmouse-objs := psmouse-base.o synaptics.o focaltech.o | 28 | psmouse-objs := psmouse-base.o synaptics.o focaltech.o |
28 | 29 | ||
29 | psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o | 30 | psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o |
diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index 1bece8cad46f..36c64335662c 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c | |||
@@ -20,408 +20,127 @@ | |||
20 | #include <linux/input/mt.h> | 20 | #include <linux/input/mt.h> |
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/mutex.h> | ||
23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/uaccess.h> | ||
26 | #include "cyapa.h" | ||
24 | 27 | ||
25 | /* APA trackpad firmware generation */ | ||
26 | #define CYAPA_GEN3 0x03 /* support MT-protocol B with tracking ID. */ | ||
27 | |||
28 | #define CYAPA_NAME "Cypress APA Trackpad (cyapa)" | ||
29 | |||
30 | /* commands for read/write registers of Cypress trackpad */ | ||
31 | #define CYAPA_CMD_SOFT_RESET 0x00 | ||
32 | #define CYAPA_CMD_POWER_MODE 0x01 | ||
33 | #define CYAPA_CMD_DEV_STATUS 0x02 | ||
34 | #define CYAPA_CMD_GROUP_DATA 0x03 | ||
35 | #define CYAPA_CMD_GROUP_CMD 0x04 | ||
36 | #define CYAPA_CMD_GROUP_QUERY 0x05 | ||
37 | #define CYAPA_CMD_BL_STATUS 0x06 | ||
38 | #define CYAPA_CMD_BL_HEAD 0x07 | ||
39 | #define CYAPA_CMD_BL_CMD 0x08 | ||
40 | #define CYAPA_CMD_BL_DATA 0x09 | ||
41 | #define CYAPA_CMD_BL_ALL 0x0a | ||
42 | #define CYAPA_CMD_BLK_PRODUCT_ID 0x0b | ||
43 | #define CYAPA_CMD_BLK_HEAD 0x0c | ||
44 | |||
45 | /* report data start reg offset address. */ | ||
46 | #define DATA_REG_START_OFFSET 0x0000 | ||
47 | |||
48 | #define BL_HEAD_OFFSET 0x00 | ||
49 | #define BL_DATA_OFFSET 0x10 | ||
50 | |||
51 | /* | ||
52 | * Operational Device Status Register | ||
53 | * | ||
54 | * bit 7: Valid interrupt source | ||
55 | * bit 6 - 4: Reserved | ||
56 | * bit 3 - 2: Power status | ||
57 | * bit 1 - 0: Device status | ||
58 | */ | ||
59 | #define REG_OP_STATUS 0x00 | ||
60 | #define OP_STATUS_SRC 0x80 | ||
61 | #define OP_STATUS_POWER 0x0c | ||
62 | #define OP_STATUS_DEV 0x03 | ||
63 | #define OP_STATUS_MASK (OP_STATUS_SRC | OP_STATUS_POWER | OP_STATUS_DEV) | ||
64 | |||
65 | /* | ||
66 | * Operational Finger Count/Button Flags Register | ||
67 | * | ||
68 | * bit 7 - 4: Number of touched finger | ||
69 | * bit 3: Valid data | ||
70 | * bit 2: Middle Physical Button | ||
71 | * bit 1: Right Physical Button | ||
72 | * bit 0: Left physical Button | ||
73 | */ | ||
74 | #define REG_OP_DATA1 0x01 | ||
75 | #define OP_DATA_VALID 0x08 | ||
76 | #define OP_DATA_MIDDLE_BTN 0x04 | ||
77 | #define OP_DATA_RIGHT_BTN 0x02 | ||
78 | #define OP_DATA_LEFT_BTN 0x01 | ||
79 | #define OP_DATA_BTN_MASK (OP_DATA_MIDDLE_BTN | OP_DATA_RIGHT_BTN | \ | ||
80 | OP_DATA_LEFT_BTN) | ||
81 | |||
82 | /* | ||
83 | * Bootloader Status Register | ||
84 | * | ||
85 | * bit 7: Busy | ||
86 | * bit 6 - 5: Reserved | ||
87 | * bit 4: Bootloader running | ||
88 | * bit 3 - 1: Reserved | ||
89 | * bit 0: Checksum valid | ||
90 | */ | ||
91 | #define REG_BL_STATUS 0x01 | ||
92 | #define BL_STATUS_BUSY 0x80 | ||
93 | #define BL_STATUS_RUNNING 0x10 | ||
94 | #define BL_STATUS_DATA_VALID 0x08 | ||
95 | #define BL_STATUS_CSUM_VALID 0x01 | ||
96 | |||
97 | /* | ||
98 | * Bootloader Error Register | ||
99 | * | ||
100 | * bit 7: Invalid | ||
101 | * bit 6: Invalid security key | ||
102 | * bit 5: Bootloading | ||
103 | * bit 4: Command checksum | ||
104 | * bit 3: Flash protection error | ||
105 | * bit 2: Flash checksum error | ||
106 | * bit 1 - 0: Reserved | ||
107 | */ | ||
108 | #define REG_BL_ERROR 0x02 | ||
109 | #define BL_ERROR_INVALID 0x80 | ||
110 | #define BL_ERROR_INVALID_KEY 0x40 | ||
111 | #define BL_ERROR_BOOTLOADING 0x20 | ||
112 | #define BL_ERROR_CMD_CSUM 0x10 | ||
113 | #define BL_ERROR_FLASH_PROT 0x08 | ||
114 | #define BL_ERROR_FLASH_CSUM 0x04 | ||
115 | |||
116 | #define BL_STATUS_SIZE 3 /* length of bootloader status registers */ | ||
117 | #define BLK_HEAD_BYTES 32 | ||
118 | |||
119 | #define PRODUCT_ID_SIZE 16 | ||
120 | #define QUERY_DATA_SIZE 27 | ||
121 | #define REG_PROTOCOL_GEN_QUERY_OFFSET 20 | ||
122 | |||
123 | #define REG_OFFSET_DATA_BASE 0x0000 | ||
124 | #define REG_OFFSET_COMMAND_BASE 0x0028 | ||
125 | #define REG_OFFSET_QUERY_BASE 0x002a | ||
126 | |||
127 | #define CAPABILITY_LEFT_BTN_MASK (0x01 << 3) | ||
128 | #define CAPABILITY_RIGHT_BTN_MASK (0x01 << 4) | ||
129 | #define CAPABILITY_MIDDLE_BTN_MASK (0x01 << 5) | ||
130 | #define CAPABILITY_BTN_MASK (CAPABILITY_LEFT_BTN_MASK | \ | ||
131 | CAPABILITY_RIGHT_BTN_MASK | \ | ||
132 | CAPABILITY_MIDDLE_BTN_MASK) | ||
133 | |||
134 | #define CYAPA_OFFSET_SOFT_RESET REG_OFFSET_COMMAND_BASE | ||
135 | |||
136 | #define REG_OFFSET_POWER_MODE (REG_OFFSET_COMMAND_BASE + 1) | ||
137 | |||
138 | #define PWR_MODE_MASK 0xfc | ||
139 | #define PWR_MODE_FULL_ACTIVE (0x3f << 2) | ||
140 | #define PWR_MODE_IDLE (0x05 << 2) /* default sleep time is 50 ms. */ | ||
141 | #define PWR_MODE_OFF (0x00 << 2) | ||
142 | |||
143 | #define PWR_STATUS_MASK 0x0c | ||
144 | #define PWR_STATUS_ACTIVE (0x03 << 2) | ||
145 | #define PWR_STATUS_IDLE (0x02 << 2) | ||
146 | #define PWR_STATUS_OFF (0x00 << 2) | ||
147 | |||
148 | /* | ||
149 | * CYAPA trackpad device states. | ||
150 | * Used in register 0x00, bit1-0, DeviceStatus field. | ||
151 | * Other values indicate device is in an abnormal state and must be reset. | ||
152 | */ | ||
153 | #define CYAPA_DEV_NORMAL 0x03 | ||
154 | #define CYAPA_DEV_BUSY 0x01 | ||
155 | |||
156 | enum cyapa_state { | ||
157 | CYAPA_STATE_OP, | ||
158 | CYAPA_STATE_BL_IDLE, | ||
159 | CYAPA_STATE_BL_ACTIVE, | ||
160 | CYAPA_STATE_BL_BUSY, | ||
161 | CYAPA_STATE_NO_DEVICE, | ||
162 | }; | ||
163 | |||
164 | |||
165 | struct cyapa_touch { | ||
166 | /* | ||
167 | * high bits or x/y position value | ||
168 | * bit 7 - 4: high 4 bits of x position value | ||
169 | * bit 3 - 0: high 4 bits of y position value | ||
170 | */ | ||
171 | u8 xy_hi; | ||
172 | u8 x_lo; /* low 8 bits of x position value. */ | ||
173 | u8 y_lo; /* low 8 bits of y position value. */ | ||
174 | u8 pressure; | ||
175 | /* id range is 1 - 15. It is incremented with every new touch. */ | ||
176 | u8 id; | ||
177 | } __packed; | ||
178 | |||
179 | /* The touch.id is used as the MT slot id, thus max MT slot is 15 */ | ||
180 | #define CYAPA_MAX_MT_SLOTS 15 | ||
181 | |||
182 | struct cyapa_reg_data { | ||
183 | /* | ||
184 | * bit 0 - 1: device status | ||
185 | * bit 3 - 2: power mode | ||
186 | * bit 6 - 4: reserved | ||
187 | * bit 7: interrupt valid bit | ||
188 | */ | ||
189 | u8 device_status; | ||
190 | /* | ||
191 | * bit 7 - 4: number of fingers currently touching pad | ||
192 | * bit 3: valid data check bit | ||
193 | * bit 2: middle mechanism button state if exists | ||
194 | * bit 1: right mechanism button state if exists | ||
195 | * bit 0: left mechanism button state if exists | ||
196 | */ | ||
197 | u8 finger_btn; | ||
198 | /* CYAPA reports up to 5 touches per packet. */ | ||
199 | struct cyapa_touch touches[5]; | ||
200 | } __packed; | ||
201 | |||
202 | /* The main device structure */ | ||
203 | struct cyapa { | ||
204 | enum cyapa_state state; | ||
205 | |||
206 | struct i2c_client *client; | ||
207 | struct input_dev *input; | ||
208 | char phys[32]; /* device physical location */ | ||
209 | bool irq_wake; /* irq wake is enabled */ | ||
210 | bool smbus; | ||
211 | |||
212 | /* read from query data region. */ | ||
213 | char product_id[16]; | ||
214 | u8 btn_capability; | ||
215 | u8 gen; | ||
216 | int max_abs_x; | ||
217 | int max_abs_y; | ||
218 | int physical_size_x; | ||
219 | int physical_size_y; | ||
220 | }; | ||
221 | |||
222 | static const u8 bl_deactivate[] = { 0x00, 0xff, 0x3b, 0x00, 0x01, 0x02, 0x03, | ||
223 | 0x04, 0x05, 0x06, 0x07 }; | ||
224 | static const u8 bl_exit[] = { 0x00, 0xff, 0xa5, 0x00, 0x01, 0x02, 0x03, 0x04, | ||
225 | 0x05, 0x06, 0x07 }; | ||
226 | |||
227 | struct cyapa_cmd_len { | ||
228 | u8 cmd; | ||
229 | u8 len; | ||
230 | }; | ||
231 | 28 | ||
232 | #define CYAPA_ADAPTER_FUNC_NONE 0 | 29 | #define CYAPA_ADAPTER_FUNC_NONE 0 |
233 | #define CYAPA_ADAPTER_FUNC_I2C 1 | 30 | #define CYAPA_ADAPTER_FUNC_I2C 1 |
234 | #define CYAPA_ADAPTER_FUNC_SMBUS 2 | 31 | #define CYAPA_ADAPTER_FUNC_SMBUS 2 |
235 | #define CYAPA_ADAPTER_FUNC_BOTH 3 | 32 | #define CYAPA_ADAPTER_FUNC_BOTH 3 |
236 | 33 | ||
237 | /* | 34 | const char product_id[] = "CYTRA"; |
238 | * macros for SMBus communication | ||
239 | */ | ||
240 | #define SMBUS_READ 0x01 | ||
241 | #define SMBUS_WRITE 0x00 | ||
242 | #define SMBUS_ENCODE_IDX(cmd, idx) ((cmd) | (((idx) & 0x03) << 1)) | ||
243 | #define SMBUS_ENCODE_RW(cmd, rw) ((cmd) | ((rw) & 0x01)) | ||
244 | #define SMBUS_BYTE_BLOCK_CMD_MASK 0x80 | ||
245 | #define SMBUS_GROUP_BLOCK_CMD_MASK 0x40 | ||
246 | |||
247 | /* for byte read/write command */ | ||
248 | #define CMD_RESET 0 | ||
249 | #define CMD_POWER_MODE 1 | ||
250 | #define CMD_DEV_STATUS 2 | ||
251 | #define SMBUS_BYTE_CMD(cmd) (((cmd) & 0x3f) << 1) | ||
252 | #define CYAPA_SMBUS_RESET SMBUS_BYTE_CMD(CMD_RESET) | ||
253 | #define CYAPA_SMBUS_POWER_MODE SMBUS_BYTE_CMD(CMD_POWER_MODE) | ||
254 | #define CYAPA_SMBUS_DEV_STATUS SMBUS_BYTE_CMD(CMD_DEV_STATUS) | ||
255 | |||
256 | /* for group registers read/write command */ | ||
257 | #define REG_GROUP_DATA 0 | ||
258 | #define REG_GROUP_CMD 2 | ||
259 | #define REG_GROUP_QUERY 3 | ||
260 | #define SMBUS_GROUP_CMD(grp) (0x80 | (((grp) & 0x07) << 3)) | ||
261 | #define CYAPA_SMBUS_GROUP_DATA SMBUS_GROUP_CMD(REG_GROUP_DATA) | ||
262 | #define CYAPA_SMBUS_GROUP_CMD SMBUS_GROUP_CMD(REG_GROUP_CMD) | ||
263 | #define CYAPA_SMBUS_GROUP_QUERY SMBUS_GROUP_CMD(REG_GROUP_QUERY) | ||
264 | |||
265 | /* for register block read/write command */ | ||
266 | #define CMD_BL_STATUS 0 | ||
267 | #define CMD_BL_HEAD 1 | ||
268 | #define CMD_BL_CMD 2 | ||
269 | #define CMD_BL_DATA 3 | ||
270 | #define CMD_BL_ALL 4 | ||
271 | #define CMD_BLK_PRODUCT_ID 5 | ||
272 | #define CMD_BLK_HEAD 6 | ||
273 | #define SMBUS_BLOCK_CMD(cmd) (0xc0 | (((cmd) & 0x1f) << 1)) | ||
274 | |||
275 | /* register block read/write command in bootloader mode */ | ||
276 | #define CYAPA_SMBUS_BL_STATUS SMBUS_BLOCK_CMD(CMD_BL_STATUS) | ||
277 | #define CYAPA_SMBUS_BL_HEAD SMBUS_BLOCK_CMD(CMD_BL_HEAD) | ||
278 | #define CYAPA_SMBUS_BL_CMD SMBUS_BLOCK_CMD(CMD_BL_CMD) | ||
279 | #define CYAPA_SMBUS_BL_DATA SMBUS_BLOCK_CMD(CMD_BL_DATA) | ||
280 | #define CYAPA_SMBUS_BL_ALL SMBUS_BLOCK_CMD(CMD_BL_ALL) | ||
281 | |||
282 | /* register block read/write command in operational mode */ | ||
283 | #define CYAPA_SMBUS_BLK_PRODUCT_ID SMBUS_BLOCK_CMD(CMD_BLK_PRODUCT_ID) | ||
284 | #define CYAPA_SMBUS_BLK_HEAD SMBUS_BLOCK_CMD(CMD_BLK_HEAD) | ||
285 | |||
286 | static const struct cyapa_cmd_len cyapa_i2c_cmds[] = { | ||
287 | { CYAPA_OFFSET_SOFT_RESET, 1 }, | ||
288 | { REG_OFFSET_COMMAND_BASE + 1, 1 }, | ||
289 | { REG_OFFSET_DATA_BASE, 1 }, | ||
290 | { REG_OFFSET_DATA_BASE, sizeof(struct cyapa_reg_data) }, | ||
291 | { REG_OFFSET_COMMAND_BASE, 0 }, | ||
292 | { REG_OFFSET_QUERY_BASE, QUERY_DATA_SIZE }, | ||
293 | { BL_HEAD_OFFSET, 3 }, | ||
294 | { BL_HEAD_OFFSET, 16 }, | ||
295 | { BL_HEAD_OFFSET, 16 }, | ||
296 | { BL_DATA_OFFSET, 16 }, | ||
297 | { BL_HEAD_OFFSET, 32 }, | ||
298 | { REG_OFFSET_QUERY_BASE, PRODUCT_ID_SIZE }, | ||
299 | { REG_OFFSET_DATA_BASE, 32 } | ||
300 | }; | ||
301 | 35 | ||
302 | static const struct cyapa_cmd_len cyapa_smbus_cmds[] = { | 36 | static int cyapa_reinitialize(struct cyapa *cyapa); |
303 | { CYAPA_SMBUS_RESET, 1 }, | ||
304 | { CYAPA_SMBUS_POWER_MODE, 1 }, | ||
305 | { CYAPA_SMBUS_DEV_STATUS, 1 }, | ||
306 | { CYAPA_SMBUS_GROUP_DATA, sizeof(struct cyapa_reg_data) }, | ||
307 | { CYAPA_SMBUS_GROUP_CMD, 2 }, | ||
308 | { CYAPA_SMBUS_GROUP_QUERY, QUERY_DATA_SIZE }, | ||
309 | { CYAPA_SMBUS_BL_STATUS, 3 }, | ||
310 | { CYAPA_SMBUS_BL_HEAD, 16 }, | ||
311 | { CYAPA_SMBUS_BL_CMD, 16 }, | ||
312 | { CYAPA_SMBUS_BL_DATA, 16 }, | ||
313 | { CYAPA_SMBUS_BL_ALL, 32 }, | ||
314 | { CYAPA_SMBUS_BLK_PRODUCT_ID, PRODUCT_ID_SIZE }, | ||
315 | { CYAPA_SMBUS_BLK_HEAD, 16 }, | ||
316 | }; | ||
317 | 37 | ||
318 | static ssize_t cyapa_i2c_reg_read_block(struct cyapa *cyapa, u8 reg, size_t len, | 38 | static inline bool cyapa_is_bootloader_mode(struct cyapa *cyapa) |
319 | u8 *values) | ||
320 | { | 39 | { |
321 | return i2c_smbus_read_i2c_block_data(cyapa->client, reg, len, values); | 40 | if (cyapa->gen == CYAPA_GEN5 && cyapa->state == CYAPA_STATE_GEN5_BL) |
41 | return true; | ||
42 | |||
43 | if (cyapa->gen == CYAPA_GEN3 && | ||
44 | cyapa->state >= CYAPA_STATE_BL_BUSY && | ||
45 | cyapa->state <= CYAPA_STATE_BL_ACTIVE) | ||
46 | return true; | ||
47 | |||
48 | return false; | ||
322 | } | 49 | } |
323 | 50 | ||
324 | static ssize_t cyapa_i2c_reg_write_block(struct cyapa *cyapa, u8 reg, | 51 | static inline bool cyapa_is_operational_mode(struct cyapa *cyapa) |
325 | size_t len, const u8 *values) | ||
326 | { | 52 | { |
327 | return i2c_smbus_write_i2c_block_data(cyapa->client, reg, len, values); | 53 | if (cyapa->gen == CYAPA_GEN5 && cyapa->state == CYAPA_STATE_GEN5_APP) |
54 | return true; | ||
55 | |||
56 | if (cyapa->gen == CYAPA_GEN3 && cyapa->state == CYAPA_STATE_OP) | ||
57 | return true; | ||
58 | |||
59 | return false; | ||
328 | } | 60 | } |
329 | 61 | ||
330 | /* | 62 | /* Returns 0 on success, else negative errno on failure. */ |
331 | * cyapa_smbus_read_block - perform smbus block read command | 63 | static ssize_t cyapa_i2c_read(struct cyapa *cyapa, u8 reg, size_t len, |
332 | * @cyapa - private data structure of the driver | 64 | u8 *values) |
333 | * @cmd - the properly encoded smbus command | ||
334 | * @len - expected length of smbus command result | ||
335 | * @values - buffer to store smbus command result | ||
336 | * | ||
337 | * Returns negative errno, else the number of bytes written. | ||
338 | * | ||
339 | * Note: | ||
340 | * In trackpad device, the memory block allocated for I2C register map | ||
341 | * is 256 bytes, so the max read block for I2C bus is 256 bytes. | ||
342 | */ | ||
343 | static ssize_t cyapa_smbus_read_block(struct cyapa *cyapa, u8 cmd, size_t len, | ||
344 | u8 *values) | ||
345 | { | 65 | { |
346 | ssize_t ret; | ||
347 | u8 index; | ||
348 | u8 smbus_cmd; | ||
349 | u8 *buf; | ||
350 | struct i2c_client *client = cyapa->client; | 66 | struct i2c_client *client = cyapa->client; |
67 | struct i2c_msg msgs[] = { | ||
68 | { | ||
69 | .addr = client->addr, | ||
70 | .flags = 0, | ||
71 | .len = 1, | ||
72 | .buf = ®, | ||
73 | }, | ||
74 | { | ||
75 | .addr = client->addr, | ||
76 | .flags = I2C_M_RD, | ||
77 | .len = len, | ||
78 | .buf = values, | ||
79 | }, | ||
80 | }; | ||
81 | int ret; | ||
351 | 82 | ||
352 | if (!(SMBUS_BYTE_BLOCK_CMD_MASK & cmd)) | 83 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); |
353 | return -EINVAL; | ||
354 | |||
355 | if (SMBUS_GROUP_BLOCK_CMD_MASK & cmd) { | ||
356 | /* read specific block registers command. */ | ||
357 | smbus_cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ); | ||
358 | ret = i2c_smbus_read_block_data(client, smbus_cmd, values); | ||
359 | goto out; | ||
360 | } | ||
361 | 84 | ||
362 | ret = 0; | 85 | if (ret != ARRAY_SIZE(msgs)) |
363 | for (index = 0; index * I2C_SMBUS_BLOCK_MAX < len; index++) { | 86 | return ret < 0 ? ret : -EIO; |
364 | smbus_cmd = SMBUS_ENCODE_IDX(cmd, index); | ||
365 | smbus_cmd = SMBUS_ENCODE_RW(smbus_cmd, SMBUS_READ); | ||
366 | buf = values + I2C_SMBUS_BLOCK_MAX * index; | ||
367 | ret = i2c_smbus_read_block_data(client, smbus_cmd, buf); | ||
368 | if (ret < 0) | ||
369 | goto out; | ||
370 | } | ||
371 | 87 | ||
372 | out: | 88 | return 0; |
373 | return ret > 0 ? len : ret; | ||
374 | } | 89 | } |
375 | 90 | ||
376 | static s32 cyapa_read_byte(struct cyapa *cyapa, u8 cmd_idx) | 91 | /** |
92 | * cyapa_i2c_write - Execute i2c block data write operation | ||
93 | * @cyapa: Handle to this driver | ||
94 | * @ret: Offset of the data to written in the register map | ||
95 | * @len: number of bytes to write | ||
96 | * @values: Data to be written | ||
97 | * | ||
98 | * Return negative errno code on error; return zero when success. | ||
99 | */ | ||
100 | static int cyapa_i2c_write(struct cyapa *cyapa, u8 reg, | ||
101 | size_t len, const void *values) | ||
377 | { | 102 | { |
378 | u8 cmd; | 103 | struct i2c_client *client = cyapa->client; |
104 | char buf[32]; | ||
105 | int ret; | ||
379 | 106 | ||
380 | if (cyapa->smbus) { | 107 | if (len > sizeof(buf) - 1) |
381 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; | 108 | return -ENOMEM; |
382 | cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ); | ||
383 | } else { | ||
384 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; | ||
385 | } | ||
386 | return i2c_smbus_read_byte_data(cyapa->client, cmd); | ||
387 | } | ||
388 | 109 | ||
389 | static s32 cyapa_write_byte(struct cyapa *cyapa, u8 cmd_idx, u8 value) | 110 | buf[0] = reg; |
390 | { | 111 | memcpy(&buf[1], values, len); |
391 | u8 cmd; | ||
392 | 112 | ||
393 | if (cyapa->smbus) { | 113 | ret = i2c_master_send(client, buf, len + 1); |
394 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; | 114 | if (ret != len + 1) |
395 | cmd = SMBUS_ENCODE_RW(cmd, SMBUS_WRITE); | 115 | return ret < 0 ? ret : -EIO; |
396 | } else { | 116 | |
397 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; | 117 | return 0; |
398 | } | ||
399 | return i2c_smbus_write_byte_data(cyapa->client, cmd, value); | ||
400 | } | 118 | } |
401 | 119 | ||
402 | static ssize_t cyapa_read_block(struct cyapa *cyapa, u8 cmd_idx, u8 *values) | 120 | static u8 cyapa_check_adapter_functionality(struct i2c_client *client) |
403 | { | 121 | { |
404 | u8 cmd; | 122 | u8 ret = CYAPA_ADAPTER_FUNC_NONE; |
405 | size_t len; | ||
406 | 123 | ||
407 | if (cyapa->smbus) { | 124 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
408 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; | 125 | ret |= CYAPA_ADAPTER_FUNC_I2C; |
409 | len = cyapa_smbus_cmds[cmd_idx].len; | 126 | if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
410 | return cyapa_smbus_read_block(cyapa, cmd, len, values); | 127 | I2C_FUNC_SMBUS_BLOCK_DATA | |
411 | } else { | 128 | I2C_FUNC_SMBUS_I2C_BLOCK)) |
412 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; | 129 | ret |= CYAPA_ADAPTER_FUNC_SMBUS; |
413 | len = cyapa_i2c_cmds[cmd_idx].len; | 130 | return ret; |
414 | return cyapa_i2c_reg_read_block(cyapa, cmd, len, values); | ||
415 | } | ||
416 | } | 131 | } |
417 | 132 | ||
418 | /* | 133 | /* |
419 | * Query device for its current operating state. | 134 | * Query device for its current operating state. |
420 | * | ||
421 | */ | 135 | */ |
422 | static int cyapa_get_state(struct cyapa *cyapa) | 136 | static int cyapa_get_state(struct cyapa *cyapa) |
423 | { | 137 | { |
424 | u8 status[BL_STATUS_SIZE]; | 138 | u8 status[BL_STATUS_SIZE]; |
139 | u8 cmd[32]; | ||
140 | /* The i2c address of gen4 and gen5 trackpad device must be even. */ | ||
141 | bool even_addr = ((cyapa->client->addr & 0x0001) == 0); | ||
142 | bool smbus = false; | ||
143 | int retries = 2; | ||
425 | int error; | 144 | int error; |
426 | 145 | ||
427 | cyapa->state = CYAPA_STATE_NO_DEVICE; | 146 | cyapa->state = CYAPA_STATE_NO_DEVICE; |
@@ -433,39 +152,66 @@ static int cyapa_get_state(struct cyapa *cyapa) | |||
433 | * | 152 | * |
434 | */ | 153 | */ |
435 | error = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, BL_STATUS_SIZE, | 154 | error = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, BL_STATUS_SIZE, |
436 | status); | 155 | status); |
437 | 156 | ||
438 | /* | 157 | /* |
439 | * On smbus systems in OP mode, the i2c_reg_read will fail with | 158 | * On smbus systems in OP mode, the i2c_reg_read will fail with |
440 | * -ETIMEDOUT. In this case, try again using the smbus equivalent | 159 | * -ETIMEDOUT. In this case, try again using the smbus equivalent |
441 | * command. This should return a BL_HEAD indicating CYAPA_STATE_OP. | 160 | * command. This should return a BL_HEAD indicating CYAPA_STATE_OP. |
442 | */ | 161 | */ |
443 | if (cyapa->smbus && (error == -ETIMEDOUT || error == -ENXIO)) | 162 | if (cyapa->smbus && (error == -ETIMEDOUT || error == -ENXIO)) { |
444 | error = cyapa_read_block(cyapa, CYAPA_CMD_BL_STATUS, status); | 163 | if (!even_addr) |
164 | error = cyapa_read_block(cyapa, | ||
165 | CYAPA_CMD_BL_STATUS, status); | ||
166 | smbus = true; | ||
167 | } | ||
445 | 168 | ||
446 | if (error != BL_STATUS_SIZE) | 169 | if (error != BL_STATUS_SIZE) |
447 | goto error; | 170 | goto error; |
448 | 171 | ||
449 | if ((status[REG_OP_STATUS] & OP_STATUS_SRC) == OP_STATUS_SRC) { | 172 | /* |
450 | switch (status[REG_OP_STATUS] & OP_STATUS_DEV) { | 173 | * Detect trackpad protocol based on characteristic registers and bits. |
451 | case CYAPA_DEV_NORMAL: | 174 | */ |
452 | case CYAPA_DEV_BUSY: | 175 | do { |
453 | cyapa->state = CYAPA_STATE_OP; | 176 | cyapa->status[REG_OP_STATUS] = status[REG_OP_STATUS]; |
454 | break; | 177 | cyapa->status[REG_BL_STATUS] = status[REG_BL_STATUS]; |
455 | default: | 178 | cyapa->status[REG_BL_ERROR] = status[REG_BL_ERROR]; |
456 | error = -EAGAIN; | 179 | |
457 | goto error; | 180 | if (cyapa->gen == CYAPA_GEN_UNKNOWN || |
181 | cyapa->gen == CYAPA_GEN3) { | ||
182 | error = cyapa_gen3_ops.state_parse(cyapa, | ||
183 | status, BL_STATUS_SIZE); | ||
184 | if (!error) | ||
185 | goto out_detected; | ||
458 | } | 186 | } |
459 | } else { | ||
460 | if (status[REG_BL_STATUS] & BL_STATUS_BUSY) | ||
461 | cyapa->state = CYAPA_STATE_BL_BUSY; | ||
462 | else if (status[REG_BL_ERROR] & BL_ERROR_BOOTLOADING) | ||
463 | cyapa->state = CYAPA_STATE_BL_ACTIVE; | ||
464 | else | ||
465 | cyapa->state = CYAPA_STATE_BL_IDLE; | ||
466 | } | ||
467 | 187 | ||
188 | /* | ||
189 | * Write 0x00 0x00 to trackpad device to force update its | ||
190 | * status, then redo the detection again. | ||
191 | */ | ||
192 | if (!smbus) { | ||
193 | cmd[0] = 0x00; | ||
194 | cmd[1] = 0x00; | ||
195 | error = cyapa_i2c_write(cyapa, 0, 2, cmd); | ||
196 | if (error) | ||
197 | goto error; | ||
198 | |||
199 | msleep(50); | ||
200 | |||
201 | error = cyapa_i2c_read(cyapa, BL_HEAD_OFFSET, | ||
202 | BL_STATUS_SIZE, status); | ||
203 | if (error) | ||
204 | goto error; | ||
205 | } | ||
206 | } while (--retries > 0 && !smbus); | ||
207 | |||
208 | goto error; | ||
209 | |||
210 | out_detected: | ||
211 | if (cyapa->state <= CYAPA_STATE_BL_BUSY) | ||
212 | return -EAGAIN; | ||
468 | return 0; | 213 | return 0; |
214 | |||
469 | error: | 215 | error: |
470 | return (error < 0) ? error : -EAGAIN; | 216 | return (error < 0) ? error : -EAGAIN; |
471 | } | 217 | } |
@@ -482,143 +228,23 @@ error: | |||
482 | * Returns: | 228 | * Returns: |
483 | * 0 when the device eventually responds with a valid non-busy state. | 229 | * 0 when the device eventually responds with a valid non-busy state. |
484 | * -ETIMEDOUT if device never responds (too many -EAGAIN) | 230 | * -ETIMEDOUT if device never responds (too many -EAGAIN) |
485 | * < 0 other errors | 231 | * -EAGAIN if bootload is busy, or unknown state. |
232 | * < 0 other errors | ||
486 | */ | 233 | */ |
487 | static int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout) | 234 | int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout) |
488 | { | 235 | { |
489 | int error; | 236 | int error; |
490 | int tries = timeout / 100; | 237 | int tries = timeout / 100; |
491 | 238 | ||
492 | error = cyapa_get_state(cyapa); | 239 | do { |
493 | while ((error || cyapa->state >= CYAPA_STATE_BL_BUSY) && tries--) { | ||
494 | msleep(100); | ||
495 | error = cyapa_get_state(cyapa); | 240 | error = cyapa_get_state(cyapa); |
496 | } | 241 | if (!error && cyapa->state > CYAPA_STATE_BL_BUSY) |
497 | return (error == -EAGAIN || error == -ETIMEDOUT) ? -ETIMEDOUT : error; | 242 | return 0; |
498 | } | ||
499 | 243 | ||
500 | static int cyapa_bl_deactivate(struct cyapa *cyapa) | 244 | msleep(100); |
501 | { | 245 | } while (tries--); |
502 | int error; | ||
503 | |||
504 | error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_deactivate), | ||
505 | bl_deactivate); | ||
506 | if (error) | ||
507 | return error; | ||
508 | |||
509 | /* wait for bootloader to switch to idle state; should take < 100ms */ | ||
510 | msleep(100); | ||
511 | error = cyapa_poll_state(cyapa, 500); | ||
512 | if (error) | ||
513 | return error; | ||
514 | if (cyapa->state != CYAPA_STATE_BL_IDLE) | ||
515 | return -EAGAIN; | ||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | /* | ||
520 | * Exit bootloader | ||
521 | * | ||
522 | * Send bl_exit command, then wait 50 - 100 ms to let device transition to | ||
523 | * operational mode. If this is the first time the device's firmware is | ||
524 | * running, it can take up to 2 seconds to calibrate its sensors. So, poll | ||
525 | * the device's new state for up to 2 seconds. | ||
526 | * | ||
527 | * Returns: | ||
528 | * -EIO failure while reading from device | ||
529 | * -EAGAIN device is stuck in bootloader, b/c it has invalid firmware | ||
530 | * 0 device is supported and in operational mode | ||
531 | */ | ||
532 | static int cyapa_bl_exit(struct cyapa *cyapa) | ||
533 | { | ||
534 | int error; | ||
535 | |||
536 | error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_exit), bl_exit); | ||
537 | if (error) | ||
538 | return error; | ||
539 | |||
540 | /* | ||
541 | * Wait for bootloader to exit, and operation mode to start. | ||
542 | * Normally, this takes at least 50 ms. | ||
543 | */ | ||
544 | usleep_range(50000, 100000); | ||
545 | /* | ||
546 | * In addition, when a device boots for the first time after being | ||
547 | * updated to new firmware, it must first calibrate its sensors, which | ||
548 | * can take up to an additional 2 seconds. | ||
549 | */ | ||
550 | error = cyapa_poll_state(cyapa, 2000); | ||
551 | if (error < 0) | ||
552 | return error; | ||
553 | if (cyapa->state != CYAPA_STATE_OP) | ||
554 | return -EAGAIN; | ||
555 | |||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | /* | ||
560 | * Set device power mode | ||
561 | * | ||
562 | */ | ||
563 | static int cyapa_set_power_mode(struct cyapa *cyapa, u8 power_mode) | ||
564 | { | ||
565 | struct device *dev = &cyapa->client->dev; | ||
566 | int ret; | ||
567 | u8 power; | ||
568 | |||
569 | if (cyapa->state != CYAPA_STATE_OP) | ||
570 | return 0; | ||
571 | |||
572 | ret = cyapa_read_byte(cyapa, CYAPA_CMD_POWER_MODE); | ||
573 | if (ret < 0) | ||
574 | return ret; | ||
575 | |||
576 | power = ret & ~PWR_MODE_MASK; | ||
577 | power |= power_mode & PWR_MODE_MASK; | ||
578 | ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power); | ||
579 | if (ret < 0) { | ||
580 | dev_err(dev, "failed to set power_mode 0x%02x err = %d\n", | ||
581 | power_mode, ret); | ||
582 | return ret; | ||
583 | } | ||
584 | |||
585 | return 0; | ||
586 | } | ||
587 | |||
588 | static int cyapa_get_query_data(struct cyapa *cyapa) | ||
589 | { | ||
590 | u8 query_data[QUERY_DATA_SIZE]; | ||
591 | int ret; | ||
592 | |||
593 | if (cyapa->state != CYAPA_STATE_OP) | ||
594 | return -EBUSY; | ||
595 | |||
596 | ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_QUERY, query_data); | ||
597 | if (ret < 0) | ||
598 | return ret; | ||
599 | if (ret != QUERY_DATA_SIZE) | ||
600 | return -EIO; | ||
601 | |||
602 | memcpy(&cyapa->product_id[0], &query_data[0], 5); | ||
603 | cyapa->product_id[5] = '-'; | ||
604 | memcpy(&cyapa->product_id[6], &query_data[5], 6); | ||
605 | cyapa->product_id[12] = '-'; | ||
606 | memcpy(&cyapa->product_id[13], &query_data[11], 2); | ||
607 | cyapa->product_id[15] = '\0'; | ||
608 | |||
609 | cyapa->btn_capability = query_data[19] & CAPABILITY_BTN_MASK; | ||
610 | |||
611 | cyapa->gen = query_data[20] & 0x0f; | ||
612 | |||
613 | cyapa->max_abs_x = ((query_data[21] & 0xf0) << 4) | query_data[22]; | ||
614 | cyapa->max_abs_y = ((query_data[21] & 0x0f) << 8) | query_data[23]; | ||
615 | |||
616 | cyapa->physical_size_x = | ||
617 | ((query_data[24] & 0xf0) << 4) | query_data[25]; | ||
618 | cyapa->physical_size_y = | ||
619 | ((query_data[24] & 0x0f) << 8) | query_data[26]; | ||
620 | 246 | ||
621 | return 0; | 247 | return (error == -EAGAIN || error == -ETIMEDOUT) ? -ETIMEDOUT : error; |
622 | } | 248 | } |
623 | 249 | ||
624 | /* | 250 | /* |
@@ -628,8 +254,10 @@ static int cyapa_get_query_data(struct cyapa *cyapa) | |||
628 | * firmware supported by this driver. | 254 | * firmware supported by this driver. |
629 | * | 255 | * |
630 | * Returns: | 256 | * Returns: |
257 | * -ENODEV no device | ||
631 | * -EBUSY no device or in bootloader | 258 | * -EBUSY no device or in bootloader |
632 | * -EIO failure while reading from device | 259 | * -EIO failure while reading from device |
260 | * -ETIMEDOUT timeout failure for bus idle or bus no response | ||
633 | * -EAGAIN device is still in bootloader | 261 | * -EAGAIN device is still in bootloader |
634 | * if ->state = CYAPA_STATE_BL_IDLE, device has invalid firmware | 262 | * if ->state = CYAPA_STATE_BL_IDLE, device has invalid firmware |
635 | * -EINVAL device is in operational mode, but not supported by this driver | 263 | * -EINVAL device is in operational mode, but not supported by this driver |
@@ -637,122 +265,53 @@ static int cyapa_get_query_data(struct cyapa *cyapa) | |||
637 | */ | 265 | */ |
638 | static int cyapa_check_is_operational(struct cyapa *cyapa) | 266 | static int cyapa_check_is_operational(struct cyapa *cyapa) |
639 | { | 267 | { |
640 | struct device *dev = &cyapa->client->dev; | ||
641 | static const char unique_str[] = "CYTRA"; | ||
642 | int error; | 268 | int error; |
643 | 269 | ||
644 | error = cyapa_poll_state(cyapa, 2000); | 270 | error = cyapa_poll_state(cyapa, 4000); |
645 | if (error) | 271 | if (error) |
646 | return error; | 272 | return error; |
647 | switch (cyapa->state) { | ||
648 | case CYAPA_STATE_BL_ACTIVE: | ||
649 | error = cyapa_bl_deactivate(cyapa); | ||
650 | if (error) | ||
651 | return error; | ||
652 | |||
653 | /* Fallthrough state */ | ||
654 | case CYAPA_STATE_BL_IDLE: | ||
655 | error = cyapa_bl_exit(cyapa); | ||
656 | if (error) | ||
657 | return error; | ||
658 | |||
659 | /* Fallthrough state */ | ||
660 | case CYAPA_STATE_OP: | ||
661 | error = cyapa_get_query_data(cyapa); | ||
662 | if (error) | ||
663 | return error; | ||
664 | |||
665 | /* only support firmware protocol gen3 */ | ||
666 | if (cyapa->gen != CYAPA_GEN3) { | ||
667 | dev_err(dev, "unsupported protocol version (%d)", | ||
668 | cyapa->gen); | ||
669 | return -EINVAL; | ||
670 | } | ||
671 | |||
672 | /* only support product ID starting with CYTRA */ | ||
673 | if (memcmp(cyapa->product_id, unique_str, | ||
674 | sizeof(unique_str) - 1) != 0) { | ||
675 | dev_err(dev, "unsupported product ID (%s)\n", | ||
676 | cyapa->product_id); | ||
677 | return -EINVAL; | ||
678 | } | ||
679 | return 0; | ||
680 | 273 | ||
274 | switch (cyapa->gen) { | ||
275 | case CYAPA_GEN3: | ||
276 | cyapa->ops = &cyapa_gen3_ops; | ||
277 | break; | ||
681 | default: | 278 | default: |
682 | return -EIO; | 279 | return -ENODEV; |
683 | } | 280 | } |
684 | return 0; | 281 | |
282 | error = cyapa->ops->operational_check(cyapa); | ||
283 | if (!error && cyapa_is_operational_mode(cyapa)) | ||
284 | cyapa->operational = true; | ||
285 | else | ||
286 | cyapa->operational = false; | ||
287 | |||
288 | return error; | ||
685 | } | 289 | } |
686 | 290 | ||
687 | static irqreturn_t cyapa_irq(int irq, void *dev_id) | 291 | |
292 | /* | ||
293 | * Returns 0 on device detected, negative errno on no device detected. | ||
294 | * And when the device is detected and opertaional, it will be reset to | ||
295 | * full power active mode automatically. | ||
296 | */ | ||
297 | static int cyapa_detect(struct cyapa *cyapa) | ||
688 | { | 298 | { |
689 | struct cyapa *cyapa = dev_id; | ||
690 | struct device *dev = &cyapa->client->dev; | 299 | struct device *dev = &cyapa->client->dev; |
691 | struct input_dev *input = cyapa->input; | 300 | int error; |
692 | struct cyapa_reg_data data; | ||
693 | int i; | ||
694 | int ret; | ||
695 | int num_fingers; | ||
696 | |||
697 | if (device_may_wakeup(dev)) | ||
698 | pm_wakeup_event(dev, 0); | ||
699 | |||
700 | ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_DATA, (u8 *)&data); | ||
701 | if (ret != sizeof(data)) | ||
702 | goto out; | ||
703 | 301 | ||
704 | if ((data.device_status & OP_STATUS_SRC) != OP_STATUS_SRC || | 302 | error = cyapa_check_is_operational(cyapa); |
705 | (data.device_status & OP_STATUS_DEV) != CYAPA_DEV_NORMAL || | 303 | if (error) { |
706 | (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID) { | 304 | if (error != -ETIMEDOUT && error != -ENODEV && |
707 | goto out; | 305 | cyapa_is_bootloader_mode(cyapa)) { |
708 | } | 306 | dev_warn(dev, "device detected but not operational\n"); |
307 | return 0; | ||
308 | } | ||
709 | 309 | ||
710 | num_fingers = (data.finger_btn >> 4) & 0x0f; | 310 | dev_err(dev, "no device detected: %d\n", error); |
711 | for (i = 0; i < num_fingers; i++) { | 311 | return error; |
712 | const struct cyapa_touch *touch = &data.touches[i]; | ||
713 | /* Note: touch->id range is 1 to 15; slots are 0 to 14. */ | ||
714 | int slot = touch->id - 1; | ||
715 | |||
716 | input_mt_slot(input, slot); | ||
717 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); | ||
718 | input_report_abs(input, ABS_MT_POSITION_X, | ||
719 | ((touch->xy_hi & 0xf0) << 4) | touch->x_lo); | ||
720 | input_report_abs(input, ABS_MT_POSITION_Y, | ||
721 | ((touch->xy_hi & 0x0f) << 8) | touch->y_lo); | ||
722 | input_report_abs(input, ABS_MT_PRESSURE, touch->pressure); | ||
723 | } | 312 | } |
724 | 313 | ||
725 | input_mt_sync_frame(input); | 314 | return 0; |
726 | |||
727 | if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK) | ||
728 | input_report_key(input, BTN_LEFT, | ||
729 | data.finger_btn & OP_DATA_LEFT_BTN); | ||
730 | |||
731 | if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK) | ||
732 | input_report_key(input, BTN_MIDDLE, | ||
733 | data.finger_btn & OP_DATA_MIDDLE_BTN); | ||
734 | |||
735 | if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK) | ||
736 | input_report_key(input, BTN_RIGHT, | ||
737 | data.finger_btn & OP_DATA_RIGHT_BTN); | ||
738 | |||
739 | input_sync(input); | ||
740 | |||
741 | out: | ||
742 | return IRQ_HANDLED; | ||
743 | } | ||
744 | |||
745 | static u8 cyapa_check_adapter_functionality(struct i2c_client *client) | ||
746 | { | ||
747 | u8 ret = CYAPA_ADAPTER_FUNC_NONE; | ||
748 | |||
749 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
750 | ret |= CYAPA_ADAPTER_FUNC_I2C; | ||
751 | if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | | ||
752 | I2C_FUNC_SMBUS_BLOCK_DATA | | ||
753 | I2C_FUNC_SMBUS_I2C_BLOCK)) | ||
754 | ret |= CYAPA_ADAPTER_FUNC_SMBUS; | ||
755 | return ret; | ||
756 | } | 315 | } |
757 | 316 | ||
758 | static int cyapa_open(struct input_dev *input) | 317 | static int cyapa_open(struct input_dev *input) |
@@ -761,22 +320,49 @@ static int cyapa_open(struct input_dev *input) | |||
761 | struct i2c_client *client = cyapa->client; | 320 | struct i2c_client *client = cyapa->client; |
762 | int error; | 321 | int error; |
763 | 322 | ||
764 | error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); | 323 | error = mutex_lock_interruptible(&cyapa->state_sync_lock); |
765 | if (error) { | 324 | if (error) |
766 | dev_err(&client->dev, "set active power failed: %d\n", error); | ||
767 | return error; | 325 | return error; |
326 | |||
327 | if (cyapa->operational) { | ||
328 | /* | ||
329 | * though failed to set active power mode, | ||
330 | * but still may be able to work in lower scan rate | ||
331 | * when in operational mode. | ||
332 | */ | ||
333 | error = cyapa->ops->set_power_mode(cyapa, | ||
334 | PWR_MODE_FULL_ACTIVE, 0); | ||
335 | if (error) { | ||
336 | dev_warn(&client->dev, | ||
337 | "set active power failed: %d\n", error); | ||
338 | goto out; | ||
339 | } | ||
340 | } else { | ||
341 | error = cyapa_reinitialize(cyapa); | ||
342 | if (error || !cyapa->operational) { | ||
343 | error = error ? error : -EAGAIN; | ||
344 | goto out; | ||
345 | } | ||
768 | } | 346 | } |
769 | 347 | ||
770 | enable_irq(client->irq); | 348 | enable_irq(client->irq); |
771 | return 0; | 349 | out: |
350 | mutex_unlock(&cyapa->state_sync_lock); | ||
351 | return error; | ||
772 | } | 352 | } |
773 | 353 | ||
774 | static void cyapa_close(struct input_dev *input) | 354 | static void cyapa_close(struct input_dev *input) |
775 | { | 355 | { |
776 | struct cyapa *cyapa = input_get_drvdata(input); | 356 | struct cyapa *cyapa = input_get_drvdata(input); |
357 | struct i2c_client *client = cyapa->client; | ||
358 | |||
359 | mutex_lock(&cyapa->state_sync_lock); | ||
777 | 360 | ||
778 | disable_irq(cyapa->client->irq); | 361 | disable_irq(client->irq); |
779 | cyapa_set_power_mode(cyapa, PWR_MODE_OFF); | 362 | if (cyapa->operational) |
363 | cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0); | ||
364 | |||
365 | mutex_unlock(&cyapa->state_sync_lock); | ||
780 | } | 366 | } |
781 | 367 | ||
782 | static int cyapa_create_input_dev(struct cyapa *cyapa) | 368 | static int cyapa_create_input_dev(struct cyapa *cyapa) |
@@ -813,7 +399,28 @@ static int cyapa_create_input_dev(struct cyapa *cyapa) | |||
813 | 0); | 399 | 0); |
814 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cyapa->max_abs_y, 0, | 400 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cyapa->max_abs_y, 0, |
815 | 0); | 401 | 0); |
816 | input_set_abs_params(input, ABS_MT_PRESSURE, 0, 255, 0, 0); | 402 | input_set_abs_params(input, ABS_MT_PRESSURE, 0, cyapa->max_z, 0, 0); |
403 | if (cyapa->gen > CYAPA_GEN3) { | ||
404 | input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); | ||
405 | input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0); | ||
406 | /* | ||
407 | * Orientation is the angle between the vertical axis and | ||
408 | * the major axis of the contact ellipse. | ||
409 | * The range is -127 to 127. | ||
410 | * the positive direction is clockwise form the vertical axis. | ||
411 | * If the ellipse of contact degenerates into a circle, | ||
412 | * orientation is reported as 0. | ||
413 | * | ||
414 | * Also, for Gen5 trackpad the accurate of this orientation | ||
415 | * value is value + (-30 ~ 30). | ||
416 | */ | ||
417 | input_set_abs_params(input, ABS_MT_ORIENTATION, | ||
418 | -127, 127, 0, 0); | ||
419 | } | ||
420 | if (cyapa->gen >= CYAPA_GEN5) { | ||
421 | input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); | ||
422 | input_set_abs_params(input, ABS_MT_WIDTH_MINOR, 0, 255, 0, 0); | ||
423 | } | ||
817 | 424 | ||
818 | input_abs_set_res(input, ABS_MT_POSITION_X, | 425 | input_abs_set_res(input, ABS_MT_POSITION_X, |
819 | cyapa->max_abs_x / cyapa->physical_size_x); | 426 | cyapa->max_abs_x / cyapa->physical_size_x); |
@@ -838,16 +445,159 @@ static int cyapa_create_input_dev(struct cyapa *cyapa) | |||
838 | return error; | 445 | return error; |
839 | } | 446 | } |
840 | 447 | ||
448 | /* Register the device in input subsystem */ | ||
449 | error = input_register_device(input); | ||
450 | if (error) { | ||
451 | dev_err(dev, "failed to register input device: %d\n", error); | ||
452 | return error; | ||
453 | } | ||
454 | |||
841 | cyapa->input = input; | 455 | cyapa->input = input; |
842 | return 0; | 456 | return 0; |
843 | } | 457 | } |
844 | 458 | ||
459 | /* | ||
460 | * cyapa_sleep_time_to_pwr_cmd and cyapa_pwr_cmd_to_sleep_time | ||
461 | * | ||
462 | * These are helper functions that convert to and from integer idle | ||
463 | * times and register settings to write to the PowerMode register. | ||
464 | * The trackpad supports between 20ms to 1000ms scan intervals. | ||
465 | * The time will be increased in increments of 10ms from 20ms to 100ms. | ||
466 | * From 100ms to 1000ms, time will be increased in increments of 20ms. | ||
467 | * | ||
468 | * When Idle_Time < 100, the format to convert Idle_Time to Idle_Command is: | ||
469 | * Idle_Command = Idle Time / 10; | ||
470 | * When Idle_Time >= 100, the format to convert Idle_Time to Idle_Command is: | ||
471 | * Idle_Command = Idle Time / 20 + 5; | ||
472 | */ | ||
473 | u8 cyapa_sleep_time_to_pwr_cmd(u16 sleep_time) | ||
474 | { | ||
475 | u16 encoded_time; | ||
476 | |||
477 | sleep_time = clamp_val(sleep_time, 20, 1000); | ||
478 | encoded_time = sleep_time < 100 ? sleep_time / 10 : sleep_time / 20 + 5; | ||
479 | return (encoded_time << 2) & PWR_MODE_MASK; | ||
480 | } | ||
481 | |||
482 | u16 cyapa_pwr_cmd_to_sleep_time(u8 pwr_mode) | ||
483 | { | ||
484 | u8 encoded_time = pwr_mode >> 2; | ||
485 | |||
486 | return (encoded_time < 10) ? encoded_time * 10 | ||
487 | : (encoded_time - 5) * 20; | ||
488 | } | ||
489 | |||
490 | /* 0 on driver initialize and detected successfully, negative on failure. */ | ||
491 | static int cyapa_initialize(struct cyapa *cyapa) | ||
492 | { | ||
493 | int error = 0; | ||
494 | |||
495 | cyapa->state = CYAPA_STATE_NO_DEVICE; | ||
496 | cyapa->gen = CYAPA_GEN_UNKNOWN; | ||
497 | mutex_init(&cyapa->state_sync_lock); | ||
498 | |||
499 | /* | ||
500 | * Set to hard code default, they will be updated with trackpad set | ||
501 | * default values after probe and initialized. | ||
502 | */ | ||
503 | cyapa->suspend_power_mode = PWR_MODE_SLEEP; | ||
504 | cyapa->suspend_sleep_time = | ||
505 | cyapa_pwr_cmd_to_sleep_time(cyapa->suspend_power_mode); | ||
506 | |||
507 | /* ops.initialize() is aimed to prepare for module communications. */ | ||
508 | error = cyapa_gen3_ops.initialize(cyapa); | ||
509 | if (error) | ||
510 | return error; | ||
511 | |||
512 | error = cyapa_detect(cyapa); | ||
513 | if (error) | ||
514 | return error; | ||
515 | |||
516 | /* Power down the device until we need it. */ | ||
517 | if (cyapa->operational) | ||
518 | cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0); | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | static int cyapa_reinitialize(struct cyapa *cyapa) | ||
524 | { | ||
525 | struct device *dev = &cyapa->client->dev; | ||
526 | struct input_dev *input = cyapa->input; | ||
527 | int error; | ||
528 | |||
529 | /* Avoid command failures when TP was in OFF state. */ | ||
530 | if (cyapa->operational) | ||
531 | cyapa->ops->set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE, 0); | ||
532 | |||
533 | error = cyapa_detect(cyapa); | ||
534 | if (error) | ||
535 | goto out; | ||
536 | |||
537 | if (!input && cyapa->operational) { | ||
538 | error = cyapa_create_input_dev(cyapa); | ||
539 | if (error) { | ||
540 | dev_err(dev, "create input_dev instance failed: %d\n", | ||
541 | error); | ||
542 | goto out; | ||
543 | } | ||
544 | } | ||
545 | |||
546 | out: | ||
547 | if (!input || !input->users) { | ||
548 | /* Reset to power OFF state to save power when no user open. */ | ||
549 | if (cyapa->operational) | ||
550 | cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0); | ||
551 | } | ||
552 | |||
553 | return error; | ||
554 | } | ||
555 | |||
556 | static irqreturn_t cyapa_irq(int irq, void *dev_id) | ||
557 | { | ||
558 | struct cyapa *cyapa = dev_id; | ||
559 | struct device *dev = &cyapa->client->dev; | ||
560 | |||
561 | if (device_may_wakeup(dev)) | ||
562 | pm_wakeup_event(dev, 0); | ||
563 | |||
564 | /* Interrupt event maybe cuased by host command to trackpad device. */ | ||
565 | if (cyapa->ops->irq_cmd_handler(cyapa)) { | ||
566 | /* | ||
567 | * Interrupt event maybe from trackpad device input reporting. | ||
568 | */ | ||
569 | if (!cyapa->input) { | ||
570 | /* | ||
571 | * Still in probling or in firware image | ||
572 | * udpating or reading. | ||
573 | */ | ||
574 | cyapa->ops->sort_empty_output_data(cyapa, | ||
575 | NULL, NULL, NULL); | ||
576 | goto out; | ||
577 | } | ||
578 | |||
579 | if (!cyapa->operational || cyapa->ops->irq_handler(cyapa)) { | ||
580 | if (!mutex_trylock(&cyapa->state_sync_lock)) { | ||
581 | cyapa->ops->sort_empty_output_data(cyapa, | ||
582 | NULL, NULL, NULL); | ||
583 | goto out; | ||
584 | } | ||
585 | cyapa_reinitialize(cyapa); | ||
586 | mutex_unlock(&cyapa->state_sync_lock); | ||
587 | } | ||
588 | } | ||
589 | |||
590 | out: | ||
591 | return IRQ_HANDLED; | ||
592 | } | ||
593 | |||
845 | static int cyapa_probe(struct i2c_client *client, | 594 | static int cyapa_probe(struct i2c_client *client, |
846 | const struct i2c_device_id *dev_id) | 595 | const struct i2c_device_id *dev_id) |
847 | { | 596 | { |
848 | struct device *dev = &client->dev; | 597 | struct device *dev = &client->dev; |
849 | struct cyapa *cyapa; | 598 | struct cyapa *cyapa; |
850 | u8 adapter_func; | 599 | u8 adapter_func; |
600 | union i2c_smbus_data dummy; | ||
851 | int error; | 601 | int error; |
852 | 602 | ||
853 | adapter_func = cyapa_check_adapter_functionality(client); | 603 | adapter_func = cyapa_check_adapter_functionality(client); |
@@ -856,39 +606,30 @@ static int cyapa_probe(struct i2c_client *client, | |||
856 | return -EIO; | 606 | return -EIO; |
857 | } | 607 | } |
858 | 608 | ||
609 | /* Make sure there is something at this address */ | ||
610 | if (i2c_smbus_xfer(client->adapter, client->addr, 0, | ||
611 | I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &dummy) < 0) | ||
612 | return -ENODEV; | ||
613 | |||
859 | cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL); | 614 | cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL); |
860 | if (!cyapa) | 615 | if (!cyapa) |
861 | return -ENOMEM; | 616 | return -ENOMEM; |
862 | 617 | ||
863 | cyapa->gen = CYAPA_GEN3; | ||
864 | cyapa->client = client; | ||
865 | i2c_set_clientdata(client, cyapa); | ||
866 | sprintf(cyapa->phys, "i2c-%d-%04x/input0", client->adapter->nr, | ||
867 | client->addr); | ||
868 | |||
869 | /* i2c isn't supported, use smbus */ | 618 | /* i2c isn't supported, use smbus */ |
870 | if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS) | 619 | if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS) |
871 | cyapa->smbus = true; | 620 | cyapa->smbus = true; |
872 | 621 | ||
873 | cyapa->state = CYAPA_STATE_NO_DEVICE; | 622 | cyapa->client = client; |
874 | 623 | i2c_set_clientdata(client, cyapa); | |
875 | error = cyapa_check_is_operational(cyapa); | 624 | sprintf(cyapa->phys, "i2c-%d-%04x/input0", client->adapter->nr, |
876 | if (error) { | 625 | client->addr); |
877 | dev_err(dev, "device not operational, %d\n", error); | ||
878 | return error; | ||
879 | } | ||
880 | 626 | ||
881 | /* Power down the device until we need it */ | 627 | error = cyapa_initialize(cyapa); |
882 | error = cyapa_set_power_mode(cyapa, PWR_MODE_OFF); | ||
883 | if (error) { | 628 | if (error) { |
884 | dev_err(dev, "failed to quiesce the device: %d\n", error); | 629 | dev_err(dev, "failed to detect and initialize tp device.\n"); |
885 | return error; | 630 | return error; |
886 | } | 631 | } |
887 | 632 | ||
888 | error = cyapa_create_input_dev(cyapa); | ||
889 | if (error) | ||
890 | return error; | ||
891 | |||
892 | error = devm_request_threaded_irq(dev, client->irq, | 633 | error = devm_request_threaded_irq(dev, client->irq, |
893 | NULL, cyapa_irq, | 634 | NULL, cyapa_irq, |
894 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 635 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
@@ -901,11 +642,18 @@ static int cyapa_probe(struct i2c_client *client, | |||
901 | /* Disable IRQ until the device is opened */ | 642 | /* Disable IRQ until the device is opened */ |
902 | disable_irq(client->irq); | 643 | disable_irq(client->irq); |
903 | 644 | ||
904 | /* Register the device in input subsystem */ | 645 | /* |
905 | error = input_register_device(cyapa->input); | 646 | * Register the device in the input subsystem when it's operational. |
906 | if (error) { | 647 | * Otherwise, keep in this driver, so it can be be recovered or updated |
907 | dev_err(dev, "failed to register input device: %d\n", error); | 648 | * through the sysfs mode and update_fw interfaces by user or apps. |
908 | return error; | 649 | */ |
650 | if (cyapa->operational) { | ||
651 | error = cyapa_create_input_dev(cyapa); | ||
652 | if (error) { | ||
653 | dev_err(dev, "create input_dev instance failed: %d\n", | ||
654 | error); | ||
655 | return error; | ||
656 | } | ||
909 | } | 657 | } |
910 | 658 | ||
911 | return 0; | 659 | return 0; |
@@ -915,11 +663,10 @@ static int __maybe_unused cyapa_suspend(struct device *dev) | |||
915 | { | 663 | { |
916 | struct i2c_client *client = to_i2c_client(dev); | 664 | struct i2c_client *client = to_i2c_client(dev); |
917 | struct cyapa *cyapa = i2c_get_clientdata(client); | 665 | struct cyapa *cyapa = i2c_get_clientdata(client); |
918 | struct input_dev *input = cyapa->input; | ||
919 | u8 power_mode; | 666 | u8 power_mode; |
920 | int error; | 667 | int error; |
921 | 668 | ||
922 | error = mutex_lock_interruptible(&input->mutex); | 669 | error = mutex_lock_interruptible(&cyapa->state_sync_lock); |
923 | if (error) | 670 | if (error) |
924 | return error; | 671 | return error; |
925 | 672 | ||
@@ -929,18 +676,20 @@ static int __maybe_unused cyapa_suspend(struct device *dev) | |||
929 | * Set trackpad device to idle mode if wakeup is allowed, | 676 | * Set trackpad device to idle mode if wakeup is allowed, |
930 | * otherwise turn off. | 677 | * otherwise turn off. |
931 | */ | 678 | */ |
932 | power_mode = device_may_wakeup(dev) ? PWR_MODE_IDLE | 679 | if (cyapa->operational) { |
933 | : PWR_MODE_OFF; | 680 | power_mode = device_may_wakeup(dev) ? cyapa->suspend_power_mode |
934 | error = cyapa_set_power_mode(cyapa, power_mode); | 681 | : PWR_MODE_OFF; |
935 | if (error) | 682 | error = cyapa->ops->set_power_mode(cyapa, power_mode, |
936 | dev_err(dev, "resume: set power mode to %d failed: %d\n", | 683 | cyapa->suspend_sleep_time); |
937 | power_mode, error); | 684 | if (error) |
685 | dev_err(dev, "suspend set power mode failed: %d\n", | ||
686 | error); | ||
687 | } | ||
938 | 688 | ||
939 | if (device_may_wakeup(dev)) | 689 | if (device_may_wakeup(dev)) |
940 | cyapa->irq_wake = (enable_irq_wake(client->irq) == 0); | 690 | cyapa->irq_wake = (enable_irq_wake(client->irq) == 0); |
941 | 691 | ||
942 | mutex_unlock(&input->mutex); | 692 | mutex_unlock(&cyapa->state_sync_lock); |
943 | |||
944 | return 0; | 693 | return 0; |
945 | } | 694 | } |
946 | 695 | ||
@@ -948,25 +697,22 @@ static int __maybe_unused cyapa_resume(struct device *dev) | |||
948 | { | 697 | { |
949 | struct i2c_client *client = to_i2c_client(dev); | 698 | struct i2c_client *client = to_i2c_client(dev); |
950 | struct cyapa *cyapa = i2c_get_clientdata(client); | 699 | struct cyapa *cyapa = i2c_get_clientdata(client); |
951 | struct input_dev *input = cyapa->input; | ||
952 | u8 power_mode; | ||
953 | int error; | 700 | int error; |
954 | 701 | ||
955 | mutex_lock(&input->mutex); | 702 | mutex_lock(&cyapa->state_sync_lock); |
956 | 703 | ||
957 | if (device_may_wakeup(dev) && cyapa->irq_wake) | 704 | if (device_may_wakeup(dev) && cyapa->irq_wake) { |
958 | disable_irq_wake(client->irq); | 705 | disable_irq_wake(client->irq); |
706 | cyapa->irq_wake = false; | ||
707 | } | ||
959 | 708 | ||
960 | power_mode = input->users ? PWR_MODE_FULL_ACTIVE : PWR_MODE_OFF; | 709 | error = cyapa_reinitialize(cyapa); |
961 | error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE); | ||
962 | if (error) | 710 | if (error) |
963 | dev_warn(dev, "resume: set power mode to %d failed: %d\n", | 711 | dev_warn(dev, "failed to reinitialize TP device: %d\n", error); |
964 | power_mode, error); | ||
965 | 712 | ||
966 | enable_irq(client->irq); | 713 | enable_irq(client->irq); |
967 | 714 | ||
968 | mutex_unlock(&input->mutex); | 715 | mutex_unlock(&cyapa->state_sync_lock); |
969 | |||
970 | return 0; | 716 | return 0; |
971 | } | 717 | } |
972 | 718 | ||
diff --git a/drivers/input/mouse/cyapa.h b/drivers/input/mouse/cyapa.h new file mode 100644 index 000000000000..aab19b7d9357 --- /dev/null +++ b/drivers/input/mouse/cyapa.h | |||
@@ -0,0 +1,296 @@ | |||
1 | /* | ||
2 | * Cypress APA trackpad with I2C interface | ||
3 | * | ||
4 | * Author: Dudley Du <dudl@cypress.com> | ||
5 | * | ||
6 | * Copyright (C) 2014 Cypress Semiconductor, Inc. | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file COPYING in the main directory of this archive for | ||
10 | * more details. | ||
11 | */ | ||
12 | |||
13 | #ifndef _CYAPA_H | ||
14 | #define _CYAPA_H | ||
15 | |||
16 | #include <linux/firmware.h> | ||
17 | |||
18 | /* APA trackpad firmware generation number. */ | ||
19 | #define CYAPA_GEN_UNKNOWN 0x00 /* unknown protocol. */ | ||
20 | #define CYAPA_GEN3 0x03 /* support MT-protocol B with tracking ID. */ | ||
21 | #define CYAPA_GEN5 0x05 /* support TrueTouch GEN5 trackpad device. */ | ||
22 | |||
23 | #define CYAPA_NAME "Cypress APA Trackpad (cyapa)" | ||
24 | |||
25 | /* | ||
26 | * Macros for SMBus communication | ||
27 | */ | ||
28 | #define SMBUS_READ 0x01 | ||
29 | #define SMBUS_WRITE 0x00 | ||
30 | #define SMBUS_ENCODE_IDX(cmd, idx) ((cmd) | (((idx) & 0x03) << 1)) | ||
31 | #define SMBUS_ENCODE_RW(cmd, rw) ((cmd) | ((rw) & 0x01)) | ||
32 | #define SMBUS_BYTE_BLOCK_CMD_MASK 0x80 | ||
33 | #define SMBUS_GROUP_BLOCK_CMD_MASK 0x40 | ||
34 | |||
35 | /* Commands for read/write registers of Cypress trackpad */ | ||
36 | #define CYAPA_CMD_SOFT_RESET 0x00 | ||
37 | #define CYAPA_CMD_POWER_MODE 0x01 | ||
38 | #define CYAPA_CMD_DEV_STATUS 0x02 | ||
39 | #define CYAPA_CMD_GROUP_DATA 0x03 | ||
40 | #define CYAPA_CMD_GROUP_CMD 0x04 | ||
41 | #define CYAPA_CMD_GROUP_QUERY 0x05 | ||
42 | #define CYAPA_CMD_BL_STATUS 0x06 | ||
43 | #define CYAPA_CMD_BL_HEAD 0x07 | ||
44 | #define CYAPA_CMD_BL_CMD 0x08 | ||
45 | #define CYAPA_CMD_BL_DATA 0x09 | ||
46 | #define CYAPA_CMD_BL_ALL 0x0a | ||
47 | #define CYAPA_CMD_BLK_PRODUCT_ID 0x0b | ||
48 | #define CYAPA_CMD_BLK_HEAD 0x0c | ||
49 | #define CYAPA_CMD_MAX_BASELINE 0x0d | ||
50 | #define CYAPA_CMD_MIN_BASELINE 0x0e | ||
51 | |||
52 | #define BL_HEAD_OFFSET 0x00 | ||
53 | #define BL_DATA_OFFSET 0x10 | ||
54 | |||
55 | #define BL_STATUS_SIZE 3 /* Length of gen3 bootloader status registers */ | ||
56 | #define CYAPA_REG_MAP_SIZE 256 | ||
57 | |||
58 | /* | ||
59 | * Gen3 Operational Device Status Register | ||
60 | * | ||
61 | * bit 7: Valid interrupt source | ||
62 | * bit 6 - 4: Reserved | ||
63 | * bit 3 - 2: Power status | ||
64 | * bit 1 - 0: Device status | ||
65 | */ | ||
66 | #define REG_OP_STATUS 0x00 | ||
67 | #define OP_STATUS_SRC 0x80 | ||
68 | #define OP_STATUS_POWER 0x0c | ||
69 | #define OP_STATUS_DEV 0x03 | ||
70 | #define OP_STATUS_MASK (OP_STATUS_SRC | OP_STATUS_POWER | OP_STATUS_DEV) | ||
71 | |||
72 | /* | ||
73 | * Operational Finger Count/Button Flags Register | ||
74 | * | ||
75 | * bit 7 - 4: Number of touched finger | ||
76 | * bit 3: Valid data | ||
77 | * bit 2: Middle Physical Button | ||
78 | * bit 1: Right Physical Button | ||
79 | * bit 0: Left physical Button | ||
80 | */ | ||
81 | #define REG_OP_DATA1 0x01 | ||
82 | #define OP_DATA_VALID 0x08 | ||
83 | #define OP_DATA_MIDDLE_BTN 0x04 | ||
84 | #define OP_DATA_RIGHT_BTN 0x02 | ||
85 | #define OP_DATA_LEFT_BTN 0x01 | ||
86 | #define OP_DATA_BTN_MASK (OP_DATA_MIDDLE_BTN | OP_DATA_RIGHT_BTN | \ | ||
87 | OP_DATA_LEFT_BTN) | ||
88 | |||
89 | /* | ||
90 | * Write-only command file register used to issue commands and | ||
91 | * parameters to the bootloader. | ||
92 | * The default value read from it is always 0x00. | ||
93 | */ | ||
94 | #define REG_BL_FILE 0x00 | ||
95 | #define BL_FILE 0x00 | ||
96 | |||
97 | /* | ||
98 | * Bootloader Status Register | ||
99 | * | ||
100 | * bit 7: Busy | ||
101 | * bit 6 - 5: Reserved | ||
102 | * bit 4: Bootloader running | ||
103 | * bit 3 - 2: Reserved | ||
104 | * bit 1: Watchdog Reset | ||
105 | * bit 0: Checksum valid | ||
106 | */ | ||
107 | #define REG_BL_STATUS 0x01 | ||
108 | #define BL_STATUS_REV_6_5 0x60 | ||
109 | #define BL_STATUS_BUSY 0x80 | ||
110 | #define BL_STATUS_RUNNING 0x10 | ||
111 | #define BL_STATUS_REV_3_2 0x0c | ||
112 | #define BL_STATUS_WATCHDOG 0x02 | ||
113 | #define BL_STATUS_CSUM_VALID 0x01 | ||
114 | #define BL_STATUS_REV_MASK (BL_STATUS_WATCHDOG | BL_STATUS_REV_3_2 | \ | ||
115 | BL_STATUS_REV_6_5) | ||
116 | |||
117 | /* | ||
118 | * Bootloader Error Register | ||
119 | * | ||
120 | * bit 7: Invalid | ||
121 | * bit 6: Invalid security key | ||
122 | * bit 5: Bootloading | ||
123 | * bit 4: Command checksum | ||
124 | * bit 3: Flash protection error | ||
125 | * bit 2: Flash checksum error | ||
126 | * bit 1 - 0: Reserved | ||
127 | */ | ||
128 | #define REG_BL_ERROR 0x02 | ||
129 | #define BL_ERROR_INVALID 0x80 | ||
130 | #define BL_ERROR_INVALID_KEY 0x40 | ||
131 | #define BL_ERROR_BOOTLOADING 0x20 | ||
132 | #define BL_ERROR_CMD_CSUM 0x10 | ||
133 | #define BL_ERROR_FLASH_PROT 0x08 | ||
134 | #define BL_ERROR_FLASH_CSUM 0x04 | ||
135 | #define BL_ERROR_RESERVED 0x03 | ||
136 | #define BL_ERROR_NO_ERR_IDLE 0x00 | ||
137 | #define BL_ERROR_NO_ERR_ACTIVE (BL_ERROR_BOOTLOADING) | ||
138 | |||
139 | #define CAPABILITY_BTN_SHIFT 3 | ||
140 | #define CAPABILITY_LEFT_BTN_MASK (0x01 << 3) | ||
141 | #define CAPABILITY_RIGHT_BTN_MASK (0x01 << 4) | ||
142 | #define CAPABILITY_MIDDLE_BTN_MASK (0x01 << 5) | ||
143 | #define CAPABILITY_BTN_MASK (CAPABILITY_LEFT_BTN_MASK | \ | ||
144 | CAPABILITY_RIGHT_BTN_MASK | \ | ||
145 | CAPABILITY_MIDDLE_BTN_MASK) | ||
146 | |||
147 | #define PWR_MODE_MASK 0xfc | ||
148 | #define PWR_MODE_FULL_ACTIVE (0x3f << 2) | ||
149 | #define PWR_MODE_IDLE (0x03 << 2) /* Default rt suspend scanrate: 30ms */ | ||
150 | #define PWR_MODE_SLEEP (0x05 << 2) /* Default suspend scanrate: 50ms */ | ||
151 | #define PWR_MODE_BTN_ONLY (0x01 << 2) | ||
152 | #define PWR_MODE_OFF (0x00 << 2) | ||
153 | |||
154 | #define PWR_STATUS_MASK 0x0c | ||
155 | #define PWR_STATUS_ACTIVE (0x03 << 2) | ||
156 | #define PWR_STATUS_IDLE (0x02 << 2) | ||
157 | #define PWR_STATUS_BTN_ONLY (0x01 << 2) | ||
158 | #define PWR_STATUS_OFF (0x00 << 2) | ||
159 | |||
160 | #define AUTOSUSPEND_DELAY 2000 /* unit : ms */ | ||
161 | |||
162 | #define UNINIT_SLEEP_TIME 0xFFFF | ||
163 | #define UNINIT_PWR_MODE 0xFF | ||
164 | |||
165 | #define BTN_ONLY_MODE_NAME "buttononly" | ||
166 | #define OFF_MODE_NAME "off" | ||
167 | |||
168 | /* The touch.id is used as the MT slot id, thus max MT slot is 15 */ | ||
169 | #define CYAPA_MAX_MT_SLOTS 15 | ||
170 | |||
171 | struct cyapa; | ||
172 | |||
173 | typedef bool (*cb_sort)(struct cyapa *, u8 *, int); | ||
174 | |||
175 | struct cyapa_dev_ops { | ||
176 | int (*check_fw)(struct cyapa *, const struct firmware *); | ||
177 | int (*bl_enter)(struct cyapa *); | ||
178 | int (*bl_activate)(struct cyapa *); | ||
179 | int (*bl_initiate)(struct cyapa *, const struct firmware *); | ||
180 | int (*update_fw)(struct cyapa *, const struct firmware *); | ||
181 | int (*bl_deactivate)(struct cyapa *); | ||
182 | |||
183 | ssize_t (*show_baseline)(struct device *, | ||
184 | struct device_attribute *, char *); | ||
185 | ssize_t (*calibrate_store)(struct device *, | ||
186 | struct device_attribute *, const char *, size_t); | ||
187 | |||
188 | int (*initialize)(struct cyapa *cyapa); | ||
189 | |||
190 | int (*state_parse)(struct cyapa *cyapa, u8 *reg_status, int len); | ||
191 | int (*operational_check)(struct cyapa *cyapa); | ||
192 | |||
193 | int (*irq_handler)(struct cyapa *); | ||
194 | bool (*irq_cmd_handler)(struct cyapa *); | ||
195 | int (*sort_empty_output_data)(struct cyapa *, | ||
196 | u8 *, int *, cb_sort); | ||
197 | |||
198 | int (*set_power_mode)(struct cyapa *, u8, u16); | ||
199 | }; | ||
200 | |||
201 | struct cyapa_gen5_cmd_states { | ||
202 | struct mutex cmd_lock; | ||
203 | struct completion cmd_ready; | ||
204 | atomic_t cmd_issued; | ||
205 | u8 in_progress_cmd; | ||
206 | bool is_irq_mode; | ||
207 | |||
208 | cb_sort resp_sort_func; | ||
209 | u8 *resp_data; | ||
210 | int *resp_len; | ||
211 | |||
212 | u8 irq_cmd_buf[CYAPA_REG_MAP_SIZE]; | ||
213 | u8 empty_buf[CYAPA_REG_MAP_SIZE]; | ||
214 | }; | ||
215 | |||
216 | union cyapa_cmd_states { | ||
217 | struct cyapa_gen5_cmd_states gen5; | ||
218 | }; | ||
219 | |||
220 | enum cyapa_state { | ||
221 | CYAPA_STATE_NO_DEVICE, | ||
222 | CYAPA_STATE_BL_BUSY, | ||
223 | CYAPA_STATE_BL_IDLE, | ||
224 | CYAPA_STATE_BL_ACTIVE, | ||
225 | CYAPA_STATE_OP, | ||
226 | CYAPA_STATE_GEN5_BL, | ||
227 | CYAPA_STATE_GEN5_APP, | ||
228 | }; | ||
229 | |||
230 | /* The main device structure */ | ||
231 | struct cyapa { | ||
232 | enum cyapa_state state; | ||
233 | u8 status[BL_STATUS_SIZE]; | ||
234 | bool operational; /* true: ready for data reporting; false: not. */ | ||
235 | |||
236 | struct i2c_client *client; | ||
237 | struct input_dev *input; | ||
238 | char phys[32]; /* Device physical location */ | ||
239 | bool irq_wake; /* Irq wake is enabled */ | ||
240 | bool smbus; | ||
241 | |||
242 | /* power mode settings */ | ||
243 | u8 suspend_power_mode; | ||
244 | u16 suspend_sleep_time; | ||
245 | u8 dev_pwr_mode; | ||
246 | u16 dev_sleep_time; | ||
247 | |||
248 | /* Read from query data region. */ | ||
249 | char product_id[16]; | ||
250 | u8 fw_maj_ver; /* Firmware major version. */ | ||
251 | u8 fw_min_ver; /* Firmware minor version. */ | ||
252 | u8 btn_capability; | ||
253 | u8 gen; | ||
254 | int max_abs_x; | ||
255 | int max_abs_y; | ||
256 | int physical_size_x; | ||
257 | int physical_size_y; | ||
258 | |||
259 | /* Used in ttsp and truetouch based trackpad devices. */ | ||
260 | u8 x_origin; /* X Axis Origin: 0 = left side; 1 = rigth side. */ | ||
261 | u8 y_origin; /* Y Axis Origin: 0 = top; 1 = bottom. */ | ||
262 | int electrodes_x; /* Number of electrodes on the X Axis*/ | ||
263 | int electrodes_y; /* Number of electrodes on the Y Axis*/ | ||
264 | int max_z; | ||
265 | |||
266 | /* | ||
267 | * Used to synchronize the access or update the device state. | ||
268 | * And since update firmware and read firmware image process will take | ||
269 | * quite long time, maybe more than 10 seconds, so use mutex_lock | ||
270 | * to sync and wait other interface and detecting are done or ready. | ||
271 | */ | ||
272 | struct mutex state_sync_lock; | ||
273 | |||
274 | const struct cyapa_dev_ops *ops; | ||
275 | |||
276 | union cyapa_cmd_states cmd_states; | ||
277 | }; | ||
278 | |||
279 | |||
280 | ssize_t cyapa_i2c_reg_read_block(struct cyapa *cyapa, u8 reg, size_t len, | ||
281 | u8 *values); | ||
282 | ssize_t cyapa_smbus_read_block(struct cyapa *cyapa, u8 cmd, size_t len, | ||
283 | u8 *values); | ||
284 | |||
285 | ssize_t cyapa_read_block(struct cyapa *cyapa, u8 cmd_idx, u8 *values); | ||
286 | |||
287 | int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout); | ||
288 | |||
289 | u8 cyapa_sleep_time_to_pwr_cmd(u16 sleep_time); | ||
290 | u16 cyapa_pwr_cmd_to_sleep_time(u8 pwr_mode); | ||
291 | |||
292 | |||
293 | extern const char product_id[]; | ||
294 | extern const struct cyapa_dev_ops cyapa_gen3_ops; | ||
295 | |||
296 | #endif | ||
diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c new file mode 100644 index 000000000000..1b62c7d585a2 --- /dev/null +++ b/drivers/input/mouse/cyapa_gen3.c | |||
@@ -0,0 +1,807 @@ | |||
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-2014 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 "cyapa.h" | ||
24 | |||
25 | |||
26 | #define GEN3_MAX_FINGERS 5 | ||
27 | #define GEN3_FINGER_NUM(x) (((x) >> 4) & 0x07) | ||
28 | |||
29 | #define BLK_HEAD_BYTES 32 | ||
30 | |||
31 | /* Macro for register map group offset. */ | ||
32 | #define PRODUCT_ID_SIZE 16 | ||
33 | #define QUERY_DATA_SIZE 27 | ||
34 | #define REG_PROTOCOL_GEN_QUERY_OFFSET 20 | ||
35 | |||
36 | #define REG_OFFSET_DATA_BASE 0x0000 | ||
37 | #define REG_OFFSET_COMMAND_BASE 0x0028 | ||
38 | #define REG_OFFSET_QUERY_BASE 0x002a | ||
39 | |||
40 | #define CYAPA_OFFSET_SOFT_RESET REG_OFFSET_COMMAND_BASE | ||
41 | #define OP_RECALIBRATION_MASK 0x80 | ||
42 | #define OP_REPORT_BASELINE_MASK 0x40 | ||
43 | #define REG_OFFSET_MAX_BASELINE 0x0026 | ||
44 | #define REG_OFFSET_MIN_BASELINE 0x0027 | ||
45 | |||
46 | #define REG_OFFSET_POWER_MODE (REG_OFFSET_COMMAND_BASE + 1) | ||
47 | #define SET_POWER_MODE_DELAY 10000 /* Unit: us */ | ||
48 | #define SET_POWER_MODE_TRIES 5 | ||
49 | |||
50 | #define GEN3_BL_CMD_CHECKSUM_SEED 0xff | ||
51 | #define GEN3_BL_CMD_INITIATE_BL 0x38 | ||
52 | #define GEN3_BL_CMD_WRITE_BLOCK 0x39 | ||
53 | #define GEN3_BL_CMD_VERIFY_BLOCK 0x3a | ||
54 | #define GEN3_BL_CMD_TERMINATE_BL 0x3b | ||
55 | #define GEN3_BL_CMD_LAUNCH_APP 0xa5 | ||
56 | |||
57 | /* | ||
58 | * CYAPA trackpad device states. | ||
59 | * Used in register 0x00, bit1-0, DeviceStatus field. | ||
60 | * Other values indicate device is in an abnormal state and must be reset. | ||
61 | */ | ||
62 | #define CYAPA_DEV_NORMAL 0x03 | ||
63 | #define CYAPA_DEV_BUSY 0x01 | ||
64 | |||
65 | #define CYAPA_FW_BLOCK_SIZE 64 | ||
66 | #define CYAPA_FW_READ_SIZE 16 | ||
67 | #define CYAPA_FW_HDR_START 0x0780 | ||
68 | #define CYAPA_FW_HDR_BLOCK_COUNT 2 | ||
69 | #define CYAPA_FW_HDR_BLOCK_START (CYAPA_FW_HDR_START / CYAPA_FW_BLOCK_SIZE) | ||
70 | #define CYAPA_FW_HDR_SIZE (CYAPA_FW_HDR_BLOCK_COUNT * \ | ||
71 | CYAPA_FW_BLOCK_SIZE) | ||
72 | #define CYAPA_FW_DATA_START 0x0800 | ||
73 | #define CYAPA_FW_DATA_BLOCK_COUNT 480 | ||
74 | #define CYAPA_FW_DATA_BLOCK_START (CYAPA_FW_DATA_START / CYAPA_FW_BLOCK_SIZE) | ||
75 | #define CYAPA_FW_DATA_SIZE (CYAPA_FW_DATA_BLOCK_COUNT * \ | ||
76 | CYAPA_FW_BLOCK_SIZE) | ||
77 | #define CYAPA_FW_SIZE (CYAPA_FW_HDR_SIZE + CYAPA_FW_DATA_SIZE) | ||
78 | #define CYAPA_CMD_LEN 16 | ||
79 | |||
80 | #define GEN3_BL_IDLE_FW_MAJ_VER_OFFSET 0x0b | ||
81 | #define GEN3_BL_IDLE_FW_MIN_VER_OFFSET (GEN3_BL_IDLE_FW_MAJ_VER_OFFSET + 1) | ||
82 | |||
83 | |||
84 | struct cyapa_touch { | ||
85 | /* | ||
86 | * high bits or x/y position value | ||
87 | * bit 7 - 4: high 4 bits of x position value | ||
88 | * bit 3 - 0: high 4 bits of y position value | ||
89 | */ | ||
90 | u8 xy_hi; | ||
91 | u8 x_lo; /* low 8 bits of x position value. */ | ||
92 | u8 y_lo; /* low 8 bits of y position value. */ | ||
93 | u8 pressure; | ||
94 | /* id range is 1 - 15. It is incremented with every new touch. */ | ||
95 | u8 id; | ||
96 | } __packed; | ||
97 | |||
98 | struct cyapa_reg_data { | ||
99 | /* | ||
100 | * bit 0 - 1: device status | ||
101 | * bit 3 - 2: power mode | ||
102 | * bit 6 - 4: reserved | ||
103 | * bit 7: interrupt valid bit | ||
104 | */ | ||
105 | u8 device_status; | ||
106 | /* | ||
107 | * bit 7 - 4: number of fingers currently touching pad | ||
108 | * bit 3: valid data check bit | ||
109 | * bit 2: middle mechanism button state if exists | ||
110 | * bit 1: right mechanism button state if exists | ||
111 | * bit 0: left mechanism button state if exists | ||
112 | */ | ||
113 | u8 finger_btn; | ||
114 | /* CYAPA reports up to 5 touches per packet. */ | ||
115 | struct cyapa_touch touches[5]; | ||
116 | } __packed; | ||
117 | |||
118 | static const u8 bl_activate[] = { 0x00, 0xff, 0x38, 0x00, 0x01, 0x02, 0x03, | ||
119 | 0x04, 0x05, 0x06, 0x07 }; | ||
120 | static const u8 bl_deactivate[] = { 0x00, 0xff, 0x3b, 0x00, 0x01, 0x02, 0x03, | ||
121 | 0x04, 0x05, 0x06, 0x07 }; | ||
122 | static const u8 bl_exit[] = { 0x00, 0xff, 0xa5, 0x00, 0x01, 0x02, 0x03, 0x04, | ||
123 | 0x05, 0x06, 0x07 }; | ||
124 | |||
125 | |||
126 | /* for byte read/write command */ | ||
127 | #define CMD_RESET 0 | ||
128 | #define CMD_POWER_MODE 1 | ||
129 | #define CMD_DEV_STATUS 2 | ||
130 | #define CMD_REPORT_MAX_BASELINE 3 | ||
131 | #define CMD_REPORT_MIN_BASELINE 4 | ||
132 | #define SMBUS_BYTE_CMD(cmd) (((cmd) & 0x3f) << 1) | ||
133 | #define CYAPA_SMBUS_RESET SMBUS_BYTE_CMD(CMD_RESET) | ||
134 | #define CYAPA_SMBUS_POWER_MODE SMBUS_BYTE_CMD(CMD_POWER_MODE) | ||
135 | #define CYAPA_SMBUS_DEV_STATUS SMBUS_BYTE_CMD(CMD_DEV_STATUS) | ||
136 | #define CYAPA_SMBUS_MAX_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MAX_BASELINE) | ||
137 | #define CYAPA_SMBUS_MIN_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MIN_BASELINE) | ||
138 | |||
139 | /* for group registers read/write command */ | ||
140 | #define REG_GROUP_DATA 0 | ||
141 | #define REG_GROUP_CMD 2 | ||
142 | #define REG_GROUP_QUERY 3 | ||
143 | #define SMBUS_GROUP_CMD(grp) (0x80 | (((grp) & 0x07) << 3)) | ||
144 | #define CYAPA_SMBUS_GROUP_DATA SMBUS_GROUP_CMD(REG_GROUP_DATA) | ||
145 | #define CYAPA_SMBUS_GROUP_CMD SMBUS_GROUP_CMD(REG_GROUP_CMD) | ||
146 | #define CYAPA_SMBUS_GROUP_QUERY SMBUS_GROUP_CMD(REG_GROUP_QUERY) | ||
147 | |||
148 | /* for register block read/write command */ | ||
149 | #define CMD_BL_STATUS 0 | ||
150 | #define CMD_BL_HEAD 1 | ||
151 | #define CMD_BL_CMD 2 | ||
152 | #define CMD_BL_DATA 3 | ||
153 | #define CMD_BL_ALL 4 | ||
154 | #define CMD_BLK_PRODUCT_ID 5 | ||
155 | #define CMD_BLK_HEAD 6 | ||
156 | #define SMBUS_BLOCK_CMD(cmd) (0xc0 | (((cmd) & 0x1f) << 1)) | ||
157 | |||
158 | /* register block read/write command in bootloader mode */ | ||
159 | #define CYAPA_SMBUS_BL_STATUS SMBUS_BLOCK_CMD(CMD_BL_STATUS) | ||
160 | #define CYAPA_SMBUS_BL_HEAD SMBUS_BLOCK_CMD(CMD_BL_HEAD) | ||
161 | #define CYAPA_SMBUS_BL_CMD SMBUS_BLOCK_CMD(CMD_BL_CMD) | ||
162 | #define CYAPA_SMBUS_BL_DATA SMBUS_BLOCK_CMD(CMD_BL_DATA) | ||
163 | #define CYAPA_SMBUS_BL_ALL SMBUS_BLOCK_CMD(CMD_BL_ALL) | ||
164 | |||
165 | /* register block read/write command in operational mode */ | ||
166 | #define CYAPA_SMBUS_BLK_PRODUCT_ID SMBUS_BLOCK_CMD(CMD_BLK_PRODUCT_ID) | ||
167 | #define CYAPA_SMBUS_BLK_HEAD SMBUS_BLOCK_CMD(CMD_BLK_HEAD) | ||
168 | |||
169 | /* for byte read/write command */ | ||
170 | #define CMD_RESET 0 | ||
171 | #define CMD_POWER_MODE 1 | ||
172 | #define CMD_DEV_STATUS 2 | ||
173 | #define CMD_REPORT_MAX_BASELINE 3 | ||
174 | #define CMD_REPORT_MIN_BASELINE 4 | ||
175 | #define SMBUS_BYTE_CMD(cmd) (((cmd) & 0x3f) << 1) | ||
176 | #define CYAPA_SMBUS_RESET SMBUS_BYTE_CMD(CMD_RESET) | ||
177 | #define CYAPA_SMBUS_POWER_MODE SMBUS_BYTE_CMD(CMD_POWER_MODE) | ||
178 | #define CYAPA_SMBUS_DEV_STATUS SMBUS_BYTE_CMD(CMD_DEV_STATUS) | ||
179 | #define CYAPA_SMBUS_MAX_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MAX_BASELINE) | ||
180 | #define CYAPA_SMBUS_MIN_BASELINE SMBUS_BYTE_CMD(CMD_REPORT_MIN_BASELINE) | ||
181 | |||
182 | /* for group registers read/write command */ | ||
183 | #define REG_GROUP_DATA 0 | ||
184 | #define REG_GROUP_CMD 2 | ||
185 | #define REG_GROUP_QUERY 3 | ||
186 | #define SMBUS_GROUP_CMD(grp) (0x80 | (((grp) & 0x07) << 3)) | ||
187 | #define CYAPA_SMBUS_GROUP_DATA SMBUS_GROUP_CMD(REG_GROUP_DATA) | ||
188 | #define CYAPA_SMBUS_GROUP_CMD SMBUS_GROUP_CMD(REG_GROUP_CMD) | ||
189 | #define CYAPA_SMBUS_GROUP_QUERY SMBUS_GROUP_CMD(REG_GROUP_QUERY) | ||
190 | |||
191 | /* for register block read/write command */ | ||
192 | #define CMD_BL_STATUS 0 | ||
193 | #define CMD_BL_HEAD 1 | ||
194 | #define CMD_BL_CMD 2 | ||
195 | #define CMD_BL_DATA 3 | ||
196 | #define CMD_BL_ALL 4 | ||
197 | #define CMD_BLK_PRODUCT_ID 5 | ||
198 | #define CMD_BLK_HEAD 6 | ||
199 | #define SMBUS_BLOCK_CMD(cmd) (0xc0 | (((cmd) & 0x1f) << 1)) | ||
200 | |||
201 | /* register block read/write command in bootloader mode */ | ||
202 | #define CYAPA_SMBUS_BL_STATUS SMBUS_BLOCK_CMD(CMD_BL_STATUS) | ||
203 | #define CYAPA_SMBUS_BL_HEAD SMBUS_BLOCK_CMD(CMD_BL_HEAD) | ||
204 | #define CYAPA_SMBUS_BL_CMD SMBUS_BLOCK_CMD(CMD_BL_CMD) | ||
205 | #define CYAPA_SMBUS_BL_DATA SMBUS_BLOCK_CMD(CMD_BL_DATA) | ||
206 | #define CYAPA_SMBUS_BL_ALL SMBUS_BLOCK_CMD(CMD_BL_ALL) | ||
207 | |||
208 | /* register block read/write command in operational mode */ | ||
209 | #define CYAPA_SMBUS_BLK_PRODUCT_ID SMBUS_BLOCK_CMD(CMD_BLK_PRODUCT_ID) | ||
210 | #define CYAPA_SMBUS_BLK_HEAD SMBUS_BLOCK_CMD(CMD_BLK_HEAD) | ||
211 | |||
212 | struct cyapa_cmd_len { | ||
213 | u8 cmd; | ||
214 | u8 len; | ||
215 | }; | ||
216 | |||
217 | /* maps generic CYAPA_CMD_* code to the I2C equivalent */ | ||
218 | static const struct cyapa_cmd_len cyapa_i2c_cmds[] = { | ||
219 | { CYAPA_OFFSET_SOFT_RESET, 1 }, /* CYAPA_CMD_SOFT_RESET */ | ||
220 | { REG_OFFSET_COMMAND_BASE + 1, 1 }, /* CYAPA_CMD_POWER_MODE */ | ||
221 | { REG_OFFSET_DATA_BASE, 1 }, /* CYAPA_CMD_DEV_STATUS */ | ||
222 | { REG_OFFSET_DATA_BASE, sizeof(struct cyapa_reg_data) }, | ||
223 | /* CYAPA_CMD_GROUP_DATA */ | ||
224 | { REG_OFFSET_COMMAND_BASE, 0 }, /* CYAPA_CMD_GROUP_CMD */ | ||
225 | { REG_OFFSET_QUERY_BASE, QUERY_DATA_SIZE }, /* CYAPA_CMD_GROUP_QUERY */ | ||
226 | { BL_HEAD_OFFSET, 3 }, /* CYAPA_CMD_BL_STATUS */ | ||
227 | { BL_HEAD_OFFSET, 16 }, /* CYAPA_CMD_BL_HEAD */ | ||
228 | { BL_HEAD_OFFSET, 16 }, /* CYAPA_CMD_BL_CMD */ | ||
229 | { BL_DATA_OFFSET, 16 }, /* CYAPA_CMD_BL_DATA */ | ||
230 | { BL_HEAD_OFFSET, 32 }, /* CYAPA_CMD_BL_ALL */ | ||
231 | { REG_OFFSET_QUERY_BASE, PRODUCT_ID_SIZE }, | ||
232 | /* CYAPA_CMD_BLK_PRODUCT_ID */ | ||
233 | { REG_OFFSET_DATA_BASE, 32 }, /* CYAPA_CMD_BLK_HEAD */ | ||
234 | { REG_OFFSET_MAX_BASELINE, 1 }, /* CYAPA_CMD_MAX_BASELINE */ | ||
235 | { REG_OFFSET_MIN_BASELINE, 1 }, /* CYAPA_CMD_MIN_BASELINE */ | ||
236 | }; | ||
237 | |||
238 | static const struct cyapa_cmd_len cyapa_smbus_cmds[] = { | ||
239 | { CYAPA_SMBUS_RESET, 1 }, /* CYAPA_CMD_SOFT_RESET */ | ||
240 | { CYAPA_SMBUS_POWER_MODE, 1 }, /* CYAPA_CMD_POWER_MODE */ | ||
241 | { CYAPA_SMBUS_DEV_STATUS, 1 }, /* CYAPA_CMD_DEV_STATUS */ | ||
242 | { CYAPA_SMBUS_GROUP_DATA, sizeof(struct cyapa_reg_data) }, | ||
243 | /* CYAPA_CMD_GROUP_DATA */ | ||
244 | { CYAPA_SMBUS_GROUP_CMD, 2 }, /* CYAPA_CMD_GROUP_CMD */ | ||
245 | { CYAPA_SMBUS_GROUP_QUERY, QUERY_DATA_SIZE }, | ||
246 | /* CYAPA_CMD_GROUP_QUERY */ | ||
247 | { CYAPA_SMBUS_BL_STATUS, 3 }, /* CYAPA_CMD_BL_STATUS */ | ||
248 | { CYAPA_SMBUS_BL_HEAD, 16 }, /* CYAPA_CMD_BL_HEAD */ | ||
249 | { CYAPA_SMBUS_BL_CMD, 16 }, /* CYAPA_CMD_BL_CMD */ | ||
250 | { CYAPA_SMBUS_BL_DATA, 16 }, /* CYAPA_CMD_BL_DATA */ | ||
251 | { CYAPA_SMBUS_BL_ALL, 32 }, /* CYAPA_CMD_BL_ALL */ | ||
252 | { CYAPA_SMBUS_BLK_PRODUCT_ID, PRODUCT_ID_SIZE }, | ||
253 | /* CYAPA_CMD_BLK_PRODUCT_ID */ | ||
254 | { CYAPA_SMBUS_BLK_HEAD, 16 }, /* CYAPA_CMD_BLK_HEAD */ | ||
255 | { CYAPA_SMBUS_MAX_BASELINE, 1 }, /* CYAPA_CMD_MAX_BASELINE */ | ||
256 | { CYAPA_SMBUS_MIN_BASELINE, 1 }, /* CYAPA_CMD_MIN_BASELINE */ | ||
257 | }; | ||
258 | |||
259 | |||
260 | /* | ||
261 | * cyapa_smbus_read_block - perform smbus block read command | ||
262 | * @cyapa - private data structure of the driver | ||
263 | * @cmd - the properly encoded smbus command | ||
264 | * @len - expected length of smbus command result | ||
265 | * @values - buffer to store smbus command result | ||
266 | * | ||
267 | * Returns negative errno, else the number of bytes written. | ||
268 | * | ||
269 | * Note: | ||
270 | * In trackpad device, the memory block allocated for I2C register map | ||
271 | * is 256 bytes, so the max read block for I2C bus is 256 bytes. | ||
272 | */ | ||
273 | ssize_t cyapa_smbus_read_block(struct cyapa *cyapa, u8 cmd, size_t len, | ||
274 | u8 *values) | ||
275 | { | ||
276 | ssize_t ret; | ||
277 | u8 index; | ||
278 | u8 smbus_cmd; | ||
279 | u8 *buf; | ||
280 | struct i2c_client *client = cyapa->client; | ||
281 | |||
282 | if (!(SMBUS_BYTE_BLOCK_CMD_MASK & cmd)) | ||
283 | return -EINVAL; | ||
284 | |||
285 | if (SMBUS_GROUP_BLOCK_CMD_MASK & cmd) { | ||
286 | /* read specific block registers command. */ | ||
287 | smbus_cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ); | ||
288 | ret = i2c_smbus_read_block_data(client, smbus_cmd, values); | ||
289 | goto out; | ||
290 | } | ||
291 | |||
292 | ret = 0; | ||
293 | for (index = 0; index * I2C_SMBUS_BLOCK_MAX < len; index++) { | ||
294 | smbus_cmd = SMBUS_ENCODE_IDX(cmd, index); | ||
295 | smbus_cmd = SMBUS_ENCODE_RW(smbus_cmd, SMBUS_READ); | ||
296 | buf = values + I2C_SMBUS_BLOCK_MAX * index; | ||
297 | ret = i2c_smbus_read_block_data(client, smbus_cmd, buf); | ||
298 | if (ret < 0) | ||
299 | goto out; | ||
300 | } | ||
301 | |||
302 | out: | ||
303 | return ret > 0 ? len : ret; | ||
304 | } | ||
305 | |||
306 | static s32 cyapa_read_byte(struct cyapa *cyapa, u8 cmd_idx) | ||
307 | { | ||
308 | u8 cmd; | ||
309 | |||
310 | if (cyapa->smbus) { | ||
311 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; | ||
312 | cmd = SMBUS_ENCODE_RW(cmd, SMBUS_READ); | ||
313 | } else { | ||
314 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; | ||
315 | } | ||
316 | return i2c_smbus_read_byte_data(cyapa->client, cmd); | ||
317 | } | ||
318 | |||
319 | static s32 cyapa_write_byte(struct cyapa *cyapa, u8 cmd_idx, u8 value) | ||
320 | { | ||
321 | u8 cmd; | ||
322 | |||
323 | if (cyapa->smbus) { | ||
324 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; | ||
325 | cmd = SMBUS_ENCODE_RW(cmd, SMBUS_WRITE); | ||
326 | } else { | ||
327 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; | ||
328 | } | ||
329 | return i2c_smbus_write_byte_data(cyapa->client, cmd, value); | ||
330 | } | ||
331 | |||
332 | ssize_t cyapa_i2c_reg_read_block(struct cyapa *cyapa, u8 reg, size_t len, | ||
333 | u8 *values) | ||
334 | { | ||
335 | return i2c_smbus_read_i2c_block_data(cyapa->client, reg, len, values); | ||
336 | } | ||
337 | |||
338 | static ssize_t cyapa_i2c_reg_write_block(struct cyapa *cyapa, u8 reg, | ||
339 | size_t len, const u8 *values) | ||
340 | { | ||
341 | return i2c_smbus_write_i2c_block_data(cyapa->client, reg, len, values); | ||
342 | } | ||
343 | |||
344 | ssize_t cyapa_read_block(struct cyapa *cyapa, u8 cmd_idx, u8 *values) | ||
345 | { | ||
346 | u8 cmd; | ||
347 | size_t len; | ||
348 | |||
349 | if (cyapa->smbus) { | ||
350 | cmd = cyapa_smbus_cmds[cmd_idx].cmd; | ||
351 | len = cyapa_smbus_cmds[cmd_idx].len; | ||
352 | return cyapa_smbus_read_block(cyapa, cmd, len, values); | ||
353 | } | ||
354 | cmd = cyapa_i2c_cmds[cmd_idx].cmd; | ||
355 | len = cyapa_i2c_cmds[cmd_idx].len; | ||
356 | return cyapa_i2c_reg_read_block(cyapa, cmd, len, values); | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | * Determine the Gen3 trackpad device's current operating state. | ||
361 | * | ||
362 | */ | ||
363 | static int cyapa_gen3_state_parse(struct cyapa *cyapa, u8 *reg_data, int len) | ||
364 | { | ||
365 | cyapa->state = CYAPA_STATE_NO_DEVICE; | ||
366 | |||
367 | /* Parse based on Gen3 characteristic registers and bits */ | ||
368 | if (reg_data[REG_BL_FILE] == BL_FILE && | ||
369 | reg_data[REG_BL_ERROR] == BL_ERROR_NO_ERR_IDLE && | ||
370 | (reg_data[REG_BL_STATUS] == | ||
371 | (BL_STATUS_RUNNING | BL_STATUS_CSUM_VALID) || | ||
372 | reg_data[REG_BL_STATUS] == BL_STATUS_RUNNING)) { | ||
373 | /* | ||
374 | * Normal state after power on or reset, | ||
375 | * REG_BL_STATUS == 0x11, firmware image checksum is valid. | ||
376 | * REG_BL_STATUS == 0x10, firmware image checksum is invalid. | ||
377 | */ | ||
378 | cyapa->gen = CYAPA_GEN3; | ||
379 | cyapa->state = CYAPA_STATE_BL_IDLE; | ||
380 | } else if (reg_data[REG_BL_FILE] == BL_FILE && | ||
381 | (reg_data[REG_BL_STATUS] & BL_STATUS_RUNNING) == | ||
382 | BL_STATUS_RUNNING) { | ||
383 | cyapa->gen = CYAPA_GEN3; | ||
384 | if (reg_data[REG_BL_STATUS] & BL_STATUS_BUSY) { | ||
385 | cyapa->state = CYAPA_STATE_BL_BUSY; | ||
386 | } else { | ||
387 | if ((reg_data[REG_BL_ERROR] & BL_ERROR_BOOTLOADING) == | ||
388 | BL_ERROR_BOOTLOADING) | ||
389 | cyapa->state = CYAPA_STATE_BL_ACTIVE; | ||
390 | else | ||
391 | cyapa->state = CYAPA_STATE_BL_IDLE; | ||
392 | } | ||
393 | } else if ((reg_data[REG_OP_STATUS] & OP_STATUS_SRC) && | ||
394 | (reg_data[REG_OP_DATA1] & OP_DATA_VALID)) { | ||
395 | /* | ||
396 | * Normal state when running in operational mode, | ||
397 | * may also not in full power state or | ||
398 | * busying in command process. | ||
399 | */ | ||
400 | if (GEN3_FINGER_NUM(reg_data[REG_OP_DATA1]) <= | ||
401 | GEN3_MAX_FINGERS) { | ||
402 | /* Finger number data is valid. */ | ||
403 | cyapa->gen = CYAPA_GEN3; | ||
404 | cyapa->state = CYAPA_STATE_OP; | ||
405 | } | ||
406 | } else if (reg_data[REG_OP_STATUS] == 0x0C && | ||
407 | reg_data[REG_OP_DATA1] == 0x08) { | ||
408 | /* Op state when first two registers overwritten with 0x00 */ | ||
409 | cyapa->gen = CYAPA_GEN3; | ||
410 | cyapa->state = CYAPA_STATE_OP; | ||
411 | } else if (reg_data[REG_BL_STATUS] & | ||
412 | (BL_STATUS_RUNNING | BL_STATUS_BUSY)) { | ||
413 | cyapa->gen = CYAPA_GEN3; | ||
414 | cyapa->state = CYAPA_STATE_BL_BUSY; | ||
415 | } | ||
416 | |||
417 | if (cyapa->gen == CYAPA_GEN3 && (cyapa->state == CYAPA_STATE_OP || | ||
418 | cyapa->state == CYAPA_STATE_BL_IDLE || | ||
419 | cyapa->state == CYAPA_STATE_BL_ACTIVE || | ||
420 | cyapa->state == CYAPA_STATE_BL_BUSY)) | ||
421 | return 0; | ||
422 | |||
423 | return -EAGAIN; | ||
424 | } | ||
425 | |||
426 | static int cyapa_gen3_bl_deactivate(struct cyapa *cyapa) | ||
427 | { | ||
428 | int error; | ||
429 | |||
430 | error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_deactivate), | ||
431 | bl_deactivate); | ||
432 | if (error) | ||
433 | return error; | ||
434 | |||
435 | /* Wait for bootloader to switch to idle state; should take < 100ms */ | ||
436 | msleep(100); | ||
437 | error = cyapa_poll_state(cyapa, 500); | ||
438 | if (error) | ||
439 | return error; | ||
440 | if (cyapa->state != CYAPA_STATE_BL_IDLE) | ||
441 | return -EAGAIN; | ||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * Exit bootloader | ||
447 | * | ||
448 | * Send bl_exit command, then wait 50 - 100 ms to let device transition to | ||
449 | * operational mode. If this is the first time the device's firmware is | ||
450 | * running, it can take up to 2 seconds to calibrate its sensors. So, poll | ||
451 | * the device's new state for up to 2 seconds. | ||
452 | * | ||
453 | * Returns: | ||
454 | * -EIO failure while reading from device | ||
455 | * -EAGAIN device is stuck in bootloader, b/c it has invalid firmware | ||
456 | * 0 device is supported and in operational mode | ||
457 | */ | ||
458 | static int cyapa_gen3_bl_exit(struct cyapa *cyapa) | ||
459 | { | ||
460 | int error; | ||
461 | |||
462 | error = cyapa_i2c_reg_write_block(cyapa, 0, sizeof(bl_exit), bl_exit); | ||
463 | if (error) | ||
464 | return error; | ||
465 | |||
466 | /* | ||
467 | * Wait for bootloader to exit, and operation mode to start. | ||
468 | * Normally, this takes at least 50 ms. | ||
469 | */ | ||
470 | usleep_range(50000, 100000); | ||
471 | /* | ||
472 | * In addition, when a device boots for the first time after being | ||
473 | * updated to new firmware, it must first calibrate its sensors, which | ||
474 | * can take up to an additional 2 seconds. If the device power is | ||
475 | * running low, this may take even longer. | ||
476 | */ | ||
477 | error = cyapa_poll_state(cyapa, 4000); | ||
478 | if (error < 0) | ||
479 | return error; | ||
480 | if (cyapa->state != CYAPA_STATE_OP) | ||
481 | return -EAGAIN; | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | /* | ||
487 | * cyapa_get_wait_time_for_pwr_cmd | ||
488 | * | ||
489 | * Compute the amount of time we need to wait after updating the touchpad | ||
490 | * power mode. The touchpad needs to consume the incoming power mode set | ||
491 | * command at the current clock rate. | ||
492 | */ | ||
493 | |||
494 | static u16 cyapa_get_wait_time_for_pwr_cmd(u8 pwr_mode) | ||
495 | { | ||
496 | switch (pwr_mode) { | ||
497 | case PWR_MODE_FULL_ACTIVE: return 20; | ||
498 | case PWR_MODE_BTN_ONLY: return 20; | ||
499 | case PWR_MODE_OFF: return 20; | ||
500 | default: return cyapa_pwr_cmd_to_sleep_time(pwr_mode) + 50; | ||
501 | } | ||
502 | } | ||
503 | |||
504 | /* | ||
505 | * Set device power mode | ||
506 | * | ||
507 | * Write to the field to configure power state. Power states include : | ||
508 | * Full : Max scans and report rate. | ||
509 | * Idle : Report rate set by user specified time. | ||
510 | * ButtonOnly : No scans for fingers. When the button is triggered, | ||
511 | * a slave interrupt is asserted to notify host to wake up. | ||
512 | * Off : Only awake for i2c commands from host. No function for button | ||
513 | * or touch sensors. | ||
514 | * | ||
515 | * The power_mode command should conform to the following : | ||
516 | * Full : 0x3f | ||
517 | * Idle : Configurable from 20 to 1000ms. See note below for | ||
518 | * cyapa_sleep_time_to_pwr_cmd and cyapa_pwr_cmd_to_sleep_time | ||
519 | * ButtonOnly : 0x01 | ||
520 | * Off : 0x00 | ||
521 | * | ||
522 | * Device power mode can only be set when device is in operational mode. | ||
523 | */ | ||
524 | static int cyapa_gen3_set_power_mode(struct cyapa *cyapa, u8 power_mode, | ||
525 | u16 always_unused) | ||
526 | { | ||
527 | int ret; | ||
528 | u8 power; | ||
529 | int tries; | ||
530 | u16 sleep_time; | ||
531 | |||
532 | always_unused = 0; | ||
533 | if (cyapa->state != CYAPA_STATE_OP) | ||
534 | return 0; | ||
535 | |||
536 | tries = SET_POWER_MODE_TRIES; | ||
537 | while (tries--) { | ||
538 | ret = cyapa_read_byte(cyapa, CYAPA_CMD_POWER_MODE); | ||
539 | if (ret >= 0) | ||
540 | break; | ||
541 | usleep_range(SET_POWER_MODE_DELAY, 2 * SET_POWER_MODE_DELAY); | ||
542 | } | ||
543 | if (ret < 0) | ||
544 | return ret; | ||
545 | |||
546 | /* | ||
547 | * Return early if the power mode to set is the same as the current | ||
548 | * one. | ||
549 | */ | ||
550 | if ((ret & PWR_MODE_MASK) == power_mode) | ||
551 | return 0; | ||
552 | |||
553 | sleep_time = cyapa_get_wait_time_for_pwr_cmd(ret & PWR_MODE_MASK); | ||
554 | power = ret; | ||
555 | power &= ~PWR_MODE_MASK; | ||
556 | power |= power_mode & PWR_MODE_MASK; | ||
557 | tries = SET_POWER_MODE_TRIES; | ||
558 | while (tries--) { | ||
559 | ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power); | ||
560 | if (!ret) | ||
561 | break; | ||
562 | usleep_range(SET_POWER_MODE_DELAY, 2 * SET_POWER_MODE_DELAY); | ||
563 | } | ||
564 | |||
565 | /* | ||
566 | * Wait for the newly set power command to go in at the previous | ||
567 | * clock speed (scanrate) used by the touchpad firmware. Not | ||
568 | * doing so before issuing the next command may result in errors | ||
569 | * depending on the command's content. | ||
570 | */ | ||
571 | msleep(sleep_time); | ||
572 | return ret; | ||
573 | } | ||
574 | |||
575 | static int cyapa_gen3_get_query_data(struct cyapa *cyapa) | ||
576 | { | ||
577 | u8 query_data[QUERY_DATA_SIZE]; | ||
578 | int ret; | ||
579 | |||
580 | if (cyapa->state != CYAPA_STATE_OP) | ||
581 | return -EBUSY; | ||
582 | |||
583 | ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_QUERY, query_data); | ||
584 | if (ret != QUERY_DATA_SIZE) | ||
585 | return (ret < 0) ? ret : -EIO; | ||
586 | |||
587 | memcpy(&cyapa->product_id[0], &query_data[0], 5); | ||
588 | cyapa->product_id[5] = '-'; | ||
589 | memcpy(&cyapa->product_id[6], &query_data[5], 6); | ||
590 | cyapa->product_id[12] = '-'; | ||
591 | memcpy(&cyapa->product_id[13], &query_data[11], 2); | ||
592 | cyapa->product_id[15] = '\0'; | ||
593 | |||
594 | cyapa->fw_maj_ver = query_data[15]; | ||
595 | cyapa->fw_min_ver = query_data[16]; | ||
596 | |||
597 | cyapa->btn_capability = query_data[19] & CAPABILITY_BTN_MASK; | ||
598 | |||
599 | cyapa->gen = query_data[20] & 0x0f; | ||
600 | |||
601 | cyapa->max_abs_x = ((query_data[21] & 0xf0) << 4) | query_data[22]; | ||
602 | cyapa->max_abs_y = ((query_data[21] & 0x0f) << 8) | query_data[23]; | ||
603 | |||
604 | cyapa->physical_size_x = | ||
605 | ((query_data[24] & 0xf0) << 4) | query_data[25]; | ||
606 | cyapa->physical_size_y = | ||
607 | ((query_data[24] & 0x0f) << 8) | query_data[26]; | ||
608 | |||
609 | cyapa->max_z = 255; | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static int cyapa_gen3_bl_query_data(struct cyapa *cyapa) | ||
615 | { | ||
616 | u8 bl_data[CYAPA_CMD_LEN]; | ||
617 | int ret; | ||
618 | |||
619 | ret = cyapa_i2c_reg_read_block(cyapa, 0, CYAPA_CMD_LEN, bl_data); | ||
620 | if (ret != CYAPA_CMD_LEN) | ||
621 | return (ret < 0) ? ret : -EIO; | ||
622 | |||
623 | /* | ||
624 | * This value will be updated again when entered application mode. | ||
625 | * If TP failed to enter application mode, this fw version values | ||
626 | * can be used as a reference. | ||
627 | * This firmware version valid when fw image checksum is valid. | ||
628 | */ | ||
629 | if (bl_data[REG_BL_STATUS] == | ||
630 | (BL_STATUS_RUNNING | BL_STATUS_CSUM_VALID)) { | ||
631 | cyapa->fw_maj_ver = bl_data[GEN3_BL_IDLE_FW_MAJ_VER_OFFSET]; | ||
632 | cyapa->fw_min_ver = bl_data[GEN3_BL_IDLE_FW_MIN_VER_OFFSET]; | ||
633 | } | ||
634 | |||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | /* | ||
639 | * Check if device is operational. | ||
640 | * | ||
641 | * An operational device is responding, has exited bootloader, and has | ||
642 | * firmware supported by this driver. | ||
643 | * | ||
644 | * Returns: | ||
645 | * -EBUSY no device or in bootloader | ||
646 | * -EIO failure while reading from device | ||
647 | * -EAGAIN device is still in bootloader | ||
648 | * if ->state = CYAPA_STATE_BL_IDLE, device has invalid firmware | ||
649 | * -EINVAL device is in operational mode, but not supported by this driver | ||
650 | * 0 device is supported | ||
651 | */ | ||
652 | static int cyapa_gen3_do_operational_check(struct cyapa *cyapa) | ||
653 | { | ||
654 | struct device *dev = &cyapa->client->dev; | ||
655 | int error; | ||
656 | |||
657 | switch (cyapa->state) { | ||
658 | case CYAPA_STATE_BL_ACTIVE: | ||
659 | error = cyapa_gen3_bl_deactivate(cyapa); | ||
660 | if (error) { | ||
661 | dev_err(dev, "failed to bl_deactivate: %d\n", error); | ||
662 | return error; | ||
663 | } | ||
664 | |||
665 | /* Fallthrough state */ | ||
666 | case CYAPA_STATE_BL_IDLE: | ||
667 | /* Try to get firmware version in bootloader mode. */ | ||
668 | cyapa_gen3_bl_query_data(cyapa); | ||
669 | |||
670 | error = cyapa_gen3_bl_exit(cyapa); | ||
671 | if (error) { | ||
672 | dev_err(dev, "failed to bl_exit: %d\n", error); | ||
673 | return error; | ||
674 | } | ||
675 | |||
676 | /* Fallthrough state */ | ||
677 | case CYAPA_STATE_OP: | ||
678 | /* | ||
679 | * Reading query data before going back to the full mode | ||
680 | * may cause problems, so we set the power mode first here. | ||
681 | */ | ||
682 | error = cyapa_gen3_set_power_mode(cyapa, | ||
683 | PWR_MODE_FULL_ACTIVE, 0); | ||
684 | if (error) | ||
685 | dev_err(dev, "%s: set full power mode failed: %d\n", | ||
686 | __func__, error); | ||
687 | error = cyapa_gen3_get_query_data(cyapa); | ||
688 | if (error < 0) | ||
689 | return error; | ||
690 | |||
691 | /* Only support firmware protocol gen3 */ | ||
692 | if (cyapa->gen != CYAPA_GEN3) { | ||
693 | dev_err(dev, "unsupported protocol version (%d)", | ||
694 | cyapa->gen); | ||
695 | return -EINVAL; | ||
696 | } | ||
697 | |||
698 | /* Only support product ID starting with CYTRA */ | ||
699 | if (memcmp(cyapa->product_id, product_id, | ||
700 | strlen(product_id)) != 0) { | ||
701 | dev_err(dev, "unsupported product ID (%s)\n", | ||
702 | cyapa->product_id); | ||
703 | return -EINVAL; | ||
704 | } | ||
705 | |||
706 | return 0; | ||
707 | |||
708 | default: | ||
709 | return -EIO; | ||
710 | } | ||
711 | return 0; | ||
712 | } | ||
713 | |||
714 | /* | ||
715 | * Return false, do not continue process | ||
716 | * Return true, continue process. | ||
717 | */ | ||
718 | static bool cyapa_gen3_irq_cmd_handler(struct cyapa *cyapa) | ||
719 | { | ||
720 | /* Not gen3 irq command response, skip for continue. */ | ||
721 | if (cyapa->gen != CYAPA_GEN3) | ||
722 | return true; | ||
723 | |||
724 | if (cyapa->operational) | ||
725 | return true; | ||
726 | |||
727 | /* | ||
728 | * Driver in detecting or other interface function processing, | ||
729 | * so, stop cyapa_gen3_irq_handler to continue process to | ||
730 | * avoid unwanted to error detecting and processing. | ||
731 | * | ||
732 | * And also, avoid the periodicly accerted interrupts to be processed | ||
733 | * as touch inputs when gen3 failed to launch into application mode, | ||
734 | * which will cause gen3 stays in bootloader mode. | ||
735 | */ | ||
736 | return false; | ||
737 | } | ||
738 | |||
739 | static int cyapa_gen3_irq_handler(struct cyapa *cyapa) | ||
740 | { | ||
741 | struct input_dev *input = cyapa->input; | ||
742 | struct device *dev = &cyapa->client->dev; | ||
743 | struct cyapa_reg_data data; | ||
744 | int num_fingers; | ||
745 | int ret; | ||
746 | int i; | ||
747 | |||
748 | ret = cyapa_read_block(cyapa, CYAPA_CMD_GROUP_DATA, (u8 *)&data); | ||
749 | if (ret != sizeof(data)) { | ||
750 | dev_err(dev, "failed to read report data, (%d)\n", ret); | ||
751 | return -EINVAL; | ||
752 | } | ||
753 | |||
754 | if ((data.device_status & OP_STATUS_SRC) != OP_STATUS_SRC || | ||
755 | (data.device_status & OP_STATUS_DEV) != CYAPA_DEV_NORMAL || | ||
756 | (data.finger_btn & OP_DATA_VALID) != OP_DATA_VALID) { | ||
757 | dev_err(dev, "invalid device state bytes, %02x %02x\n", | ||
758 | data.device_status, data.finger_btn); | ||
759 | return -EINVAL; | ||
760 | } | ||
761 | |||
762 | num_fingers = (data.finger_btn >> 4) & 0x0f; | ||
763 | for (i = 0; i < num_fingers; i++) { | ||
764 | const struct cyapa_touch *touch = &data.touches[i]; | ||
765 | /* Note: touch->id range is 1 to 15; slots are 0 to 14. */ | ||
766 | int slot = touch->id - 1; | ||
767 | |||
768 | input_mt_slot(input, slot); | ||
769 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); | ||
770 | input_report_abs(input, ABS_MT_POSITION_X, | ||
771 | ((touch->xy_hi & 0xf0) << 4) | touch->x_lo); | ||
772 | input_report_abs(input, ABS_MT_POSITION_Y, | ||
773 | ((touch->xy_hi & 0x0f) << 8) | touch->y_lo); | ||
774 | input_report_abs(input, ABS_MT_PRESSURE, touch->pressure); | ||
775 | } | ||
776 | |||
777 | input_mt_sync_frame(input); | ||
778 | |||
779 | if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK) | ||
780 | input_report_key(input, BTN_LEFT, | ||
781 | !!(data.finger_btn & OP_DATA_LEFT_BTN)); | ||
782 | if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK) | ||
783 | input_report_key(input, BTN_MIDDLE, | ||
784 | !!(data.finger_btn & OP_DATA_MIDDLE_BTN)); | ||
785 | if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK) | ||
786 | input_report_key(input, BTN_RIGHT, | ||
787 | !!(data.finger_btn & OP_DATA_RIGHT_BTN)); | ||
788 | input_sync(input); | ||
789 | |||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | static int cyapa_gen3_initialize(struct cyapa *cyapa) { return 0; } | ||
794 | static int cyapa_gen3_empty_output_data(struct cyapa *cyapa, | ||
795 | u8 *buf, int *len, cb_sort func) { return 0; } | ||
796 | |||
797 | const struct cyapa_dev_ops cyapa_gen3_ops = { | ||
798 | .initialize = cyapa_gen3_initialize, | ||
799 | |||
800 | .state_parse = cyapa_gen3_state_parse, | ||
801 | .operational_check = cyapa_gen3_do_operational_check, | ||
802 | |||
803 | .irq_handler = cyapa_gen3_irq_handler, | ||
804 | .irq_cmd_handler = cyapa_gen3_irq_cmd_handler, | ||
805 | .sort_empty_output_data = cyapa_gen3_empty_output_data, | ||
806 | .set_power_mode = cyapa_gen3_set_power_mode, | ||
807 | }; | ||