Commit | Line | Data |
---|---|---|
17fb1563 FY |
1 | /* |
2 | * cyttsp4_core.h | |
3 | * Cypress TrueTouch(TM) Standard Product V4 Core driver module. | |
4 | * For use with Cypress Txx4xx parts. | |
5 | * Supported parts include: | |
6 | * TMA4XX | |
7 | * TMA1036 | |
8 | * | |
9 | * Copyright (C) 2012 Cypress Semiconductor | |
10 | * | |
11 | * This program is free software; you can redistribute it and/or | |
12 | * modify it under the terms of the GNU General Public License | |
13 | * version 2, and only version 2, as published by the | |
14 | * Free Software Foundation. | |
15 | * | |
16 | * This program is distributed in the hope that it will be useful, | |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | * GNU General Public License for more details. | |
20 | * | |
21 | * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com> | |
22 | * | |
23 | */ | |
24 | ||
25 | #ifndef _LINUX_CYTTSP4_CORE_H | |
26 | #define _LINUX_CYTTSP4_CORE_H | |
27 | ||
28 | #include <linux/device.h> | |
29 | #include <linux/err.h> | |
30 | #include <linux/input.h> | |
31 | #include <linux/kernel.h> | |
32 | #include <linux/limits.h> | |
33 | #include <linux/module.h> | |
34 | #include <linux/stringify.h> | |
35 | #include <linux/types.h> | |
36 | #include <linux/platform_data/cyttsp4.h> | |
37 | ||
38 | #define CY_REG_BASE 0x00 | |
39 | ||
40 | #define CY_POST_CODEL_WDG_RST 0x01 | |
41 | #define CY_POST_CODEL_CFG_DATA_CRC_FAIL 0x02 | |
42 | #define CY_POST_CODEL_PANEL_TEST_FAIL 0x04 | |
43 | ||
44 | #define CY_NUM_BTN_PER_REG 4 | |
45 | ||
46 | /* touch record system information offset masks and shifts */ | |
47 | #define CY_BYTE_OFS_MASK 0x1F | |
48 | #define CY_BOFS_MASK 0xE0 | |
49 | #define CY_BOFS_SHIFT 5 | |
50 | ||
51 | #define CY_TMA1036_TCH_REC_SIZE 6 | |
52 | #define CY_TMA4XX_TCH_REC_SIZE 9 | |
53 | #define CY_TMA1036_MAX_TCH 0x0E | |
54 | #define CY_TMA4XX_MAX_TCH 0x1E | |
55 | ||
56 | #define CY_NORMAL_ORIGIN 0 /* upper, left corner */ | |
57 | #define CY_INVERT_ORIGIN 1 /* lower, right corner */ | |
58 | ||
59 | /* helpers */ | |
60 | #define GET_NUM_TOUCHES(x) ((x) & 0x1F) | |
61 | #define IS_LARGE_AREA(x) ((x) & 0x20) | |
62 | #define IS_BAD_PKT(x) ((x) & 0x20) | |
63 | #define IS_BOOTLOADER(hst_mode, reset_detect) \ | |
64 | ((hst_mode) & 0x01 || (reset_detect) != 0) | |
65 | #define IS_TMO(t) ((t) == 0) | |
66 | ||
67 | ||
68 | enum cyttsp_cmd_bits { | |
69 | CY_CMD_COMPLETE = (1 << 6), | |
70 | }; | |
71 | ||
72 | /* Timeout in ms. */ | |
73 | #define CY_WATCHDOG_TIMEOUT 1000 | |
74 | ||
75 | #define CY_MAX_PRINT_SIZE 512 | |
76 | #ifdef VERBOSE_DEBUG | |
77 | #define CY_MAX_PRBUF_SIZE PIPE_BUF | |
78 | #define CY_PR_TRUNCATED " truncated..." | |
79 | #endif | |
80 | ||
81 | enum cyttsp4_ic_grpnum { | |
82 | CY_IC_GRPNUM_RESERVED, | |
83 | CY_IC_GRPNUM_CMD_REGS, | |
84 | CY_IC_GRPNUM_TCH_REP, | |
85 | CY_IC_GRPNUM_DATA_REC, | |
86 | CY_IC_GRPNUM_TEST_REC, | |
87 | CY_IC_GRPNUM_PCFG_REC, | |
88 | CY_IC_GRPNUM_TCH_PARM_VAL, | |
89 | CY_IC_GRPNUM_TCH_PARM_SIZE, | |
90 | CY_IC_GRPNUM_RESERVED1, | |
91 | CY_IC_GRPNUM_RESERVED2, | |
92 | CY_IC_GRPNUM_OPCFG_REC, | |
93 | CY_IC_GRPNUM_DDATA_REC, | |
94 | CY_IC_GRPNUM_MDATA_REC, | |
95 | CY_IC_GRPNUM_TEST_REGS, | |
96 | CY_IC_GRPNUM_BTN_KEYS, | |
97 | CY_IC_GRPNUM_TTHE_REGS, | |
98 | CY_IC_GRPNUM_NUM | |
99 | }; | |
100 | ||
101 | enum cyttsp4_int_state { | |
102 | CY_INT_NONE, | |
103 | CY_INT_IGNORE = (1 << 0), | |
104 | CY_INT_MODE_CHANGE = (1 << 1), | |
105 | CY_INT_EXEC_CMD = (1 << 2), | |
106 | CY_INT_AWAKE = (1 << 3), | |
107 | }; | |
108 | ||
109 | enum cyttsp4_mode { | |
110 | CY_MODE_UNKNOWN, | |
111 | CY_MODE_BOOTLOADER = (1 << 1), | |
112 | CY_MODE_OPERATIONAL = (1 << 2), | |
113 | CY_MODE_SYSINFO = (1 << 3), | |
114 | CY_MODE_CAT = (1 << 4), | |
115 | CY_MODE_STARTUP = (1 << 5), | |
116 | CY_MODE_LOADER = (1 << 6), | |
117 | CY_MODE_CHANGE_MODE = (1 << 7), | |
118 | CY_MODE_CHANGED = (1 << 8), | |
119 | CY_MODE_CMD_COMPLETE = (1 << 9), | |
120 | }; | |
121 | ||
122 | enum cyttsp4_sleep_state { | |
123 | SS_SLEEP_OFF, | |
124 | SS_SLEEP_ON, | |
125 | SS_SLEEPING, | |
126 | SS_WAKING, | |
127 | }; | |
128 | ||
129 | enum cyttsp4_startup_state { | |
130 | STARTUP_NONE, | |
131 | STARTUP_QUEUED, | |
132 | STARTUP_RUNNING, | |
133 | }; | |
134 | ||
135 | #define CY_NUM_REVCTRL 8 | |
136 | struct cyttsp4_cydata { | |
137 | u8 ttpidh; | |
138 | u8 ttpidl; | |
139 | u8 fw_ver_major; | |
140 | u8 fw_ver_minor; | |
141 | u8 revctrl[CY_NUM_REVCTRL]; | |
142 | u8 blver_major; | |
143 | u8 blver_minor; | |
144 | u8 jtag_si_id3; | |
145 | u8 jtag_si_id2; | |
146 | u8 jtag_si_id1; | |
147 | u8 jtag_si_id0; | |
148 | u8 mfgid_sz; | |
149 | u8 cyito_idh; | |
150 | u8 cyito_idl; | |
151 | u8 cyito_verh; | |
152 | u8 cyito_verl; | |
153 | u8 ttsp_ver_major; | |
154 | u8 ttsp_ver_minor; | |
155 | u8 device_info; | |
156 | u8 mfg_id[]; | |
157 | } __packed; | |
158 | ||
159 | struct cyttsp4_test { | |
160 | u8 post_codeh; | |
161 | u8 post_codel; | |
162 | } __packed; | |
163 | ||
164 | struct cyttsp4_pcfg { | |
165 | u8 electrodes_x; | |
166 | u8 electrodes_y; | |
167 | u8 len_xh; | |
168 | u8 len_xl; | |
169 | u8 len_yh; | |
170 | u8 len_yl; | |
171 | u8 res_xh; | |
172 | u8 res_xl; | |
173 | u8 res_yh; | |
174 | u8 res_yl; | |
175 | u8 max_zh; | |
176 | u8 max_zl; | |
177 | u8 panel_info0; | |
178 | } __packed; | |
179 | ||
180 | struct cyttsp4_tch_rec_params { | |
181 | u8 loc; | |
182 | u8 size; | |
183 | } __packed; | |
184 | ||
185 | #define CY_NUM_TCH_FIELDS 7 | |
186 | #define CY_NUM_EXT_TCH_FIELDS 3 | |
187 | struct cyttsp4_opcfg { | |
188 | u8 cmd_ofs; | |
189 | u8 rep_ofs; | |
190 | u8 rep_szh; | |
191 | u8 rep_szl; | |
192 | u8 num_btns; | |
193 | u8 tt_stat_ofs; | |
194 | u8 obj_cfg0; | |
195 | u8 max_tchs; | |
196 | u8 tch_rec_size; | |
197 | struct cyttsp4_tch_rec_params tch_rec_old[CY_NUM_TCH_FIELDS]; | |
198 | u8 btn_rec_size; /* btn record size (in bytes) */ | |
199 | u8 btn_diff_ofs; /* btn data loc, diff counts */ | |
200 | u8 btn_diff_size; /* btn size of diff counts (in bits) */ | |
201 | struct cyttsp4_tch_rec_params tch_rec_new[CY_NUM_EXT_TCH_FIELDS]; | |
202 | } __packed; | |
203 | ||
204 | struct cyttsp4_sysinfo_ptr { | |
205 | struct cyttsp4_cydata *cydata; | |
206 | struct cyttsp4_test *test; | |
207 | struct cyttsp4_pcfg *pcfg; | |
208 | struct cyttsp4_opcfg *opcfg; | |
209 | struct cyttsp4_ddata *ddata; | |
210 | struct cyttsp4_mdata *mdata; | |
211 | } __packed; | |
212 | ||
213 | struct cyttsp4_sysinfo_data { | |
214 | u8 hst_mode; | |
215 | u8 reserved; | |
216 | u8 map_szh; | |
217 | u8 map_szl; | |
218 | u8 cydata_ofsh; | |
219 | u8 cydata_ofsl; | |
220 | u8 test_ofsh; | |
221 | u8 test_ofsl; | |
222 | u8 pcfg_ofsh; | |
223 | u8 pcfg_ofsl; | |
224 | u8 opcfg_ofsh; | |
225 | u8 opcfg_ofsl; | |
226 | u8 ddata_ofsh; | |
227 | u8 ddata_ofsl; | |
228 | u8 mdata_ofsh; | |
229 | u8 mdata_ofsl; | |
230 | } __packed; | |
231 | ||
232 | enum cyttsp4_tch_abs { /* for ordering within the extracted touch data array */ | |
233 | CY_TCH_X, /* X */ | |
234 | CY_TCH_Y, /* Y */ | |
235 | CY_TCH_P, /* P (Z) */ | |
236 | CY_TCH_T, /* TOUCH ID */ | |
237 | CY_TCH_E, /* EVENT ID */ | |
238 | CY_TCH_O, /* OBJECT ID */ | |
239 | CY_TCH_W, /* SIZE */ | |
240 | CY_TCH_MAJ, /* TOUCH_MAJOR */ | |
241 | CY_TCH_MIN, /* TOUCH_MINOR */ | |
242 | CY_TCH_OR, /* ORIENTATION */ | |
243 | CY_TCH_NUM_ABS | |
244 | }; | |
245 | ||
246 | static const char * const cyttsp4_tch_abs_string[] = { | |
247 | [CY_TCH_X] = "X", | |
248 | [CY_TCH_Y] = "Y", | |
249 | [CY_TCH_P] = "P", | |
250 | [CY_TCH_T] = "T", | |
251 | [CY_TCH_E] = "E", | |
252 | [CY_TCH_O] = "O", | |
253 | [CY_TCH_W] = "W", | |
254 | [CY_TCH_MAJ] = "MAJ", | |
255 | [CY_TCH_MIN] = "MIN", | |
256 | [CY_TCH_OR] = "OR", | |
257 | [CY_TCH_NUM_ABS] = "INVALID" | |
258 | }; | |
259 | ||
260 | struct cyttsp4_touch { | |
261 | int abs[CY_TCH_NUM_ABS]; | |
262 | }; | |
263 | ||
264 | struct cyttsp4_tch_abs_params { | |
265 | size_t ofs; /* abs byte offset */ | |
266 | size_t size; /* size in bits */ | |
267 | size_t max; /* max value */ | |
268 | size_t bofs; /* bit offset */ | |
269 | }; | |
270 | ||
271 | struct cyttsp4_sysinfo_ofs { | |
272 | size_t chip_type; | |
273 | size_t cmd_ofs; | |
274 | size_t rep_ofs; | |
275 | size_t rep_sz; | |
276 | size_t num_btns; | |
277 | size_t num_btn_regs; /* ceil(num_btns/4) */ | |
278 | size_t tt_stat_ofs; | |
279 | size_t tch_rec_size; | |
280 | size_t obj_cfg0; | |
281 | size_t max_tchs; | |
282 | size_t mode_size; | |
283 | size_t data_size; | |
284 | size_t map_sz; | |
285 | size_t max_x; | |
286 | size_t x_origin; /* left or right corner */ | |
287 | size_t max_y; | |
288 | size_t y_origin; /* upper or lower corner */ | |
289 | size_t max_p; | |
290 | size_t cydata_ofs; | |
291 | size_t test_ofs; | |
292 | size_t pcfg_ofs; | |
293 | size_t opcfg_ofs; | |
294 | size_t ddata_ofs; | |
295 | size_t mdata_ofs; | |
296 | size_t cydata_size; | |
297 | size_t test_size; | |
298 | size_t pcfg_size; | |
299 | size_t opcfg_size; | |
300 | size_t ddata_size; | |
301 | size_t mdata_size; | |
302 | size_t btn_keys_size; | |
303 | struct cyttsp4_tch_abs_params tch_abs[CY_TCH_NUM_ABS]; | |
304 | size_t btn_rec_size; /* btn record size (in bytes) */ | |
305 | size_t btn_diff_ofs;/* btn data loc ,diff counts, (Op-Mode byte ofs) */ | |
306 | size_t btn_diff_size;/* btn size of diff counts (in bits) */ | |
307 | }; | |
308 | ||
309 | enum cyttsp4_btn_state { | |
310 | CY_BTN_RELEASED, | |
311 | CY_BTN_PRESSED, | |
312 | CY_BTN_NUM_STATE | |
313 | }; | |
314 | ||
315 | struct cyttsp4_btn { | |
316 | bool enabled; | |
317 | int state; /* CY_BTN_PRESSED, CY_BTN_RELEASED */ | |
318 | int key_code; | |
319 | }; | |
320 | ||
321 | struct cyttsp4_sysinfo { | |
322 | bool ready; | |
323 | struct cyttsp4_sysinfo_data si_data; | |
324 | struct cyttsp4_sysinfo_ptr si_ptrs; | |
325 | struct cyttsp4_sysinfo_ofs si_ofs; | |
326 | struct cyttsp4_btn *btn; /* button states */ | |
327 | u8 *btn_rec_data; /* button diff count data */ | |
328 | u8 *xy_mode; /* operational mode and status regs */ | |
329 | u8 *xy_data; /* operational touch regs */ | |
330 | }; | |
331 | ||
332 | struct cyttsp4_mt_data { | |
333 | struct cyttsp4_mt_platform_data *pdata; | |
334 | struct cyttsp4_sysinfo *si; | |
335 | struct input_dev *input; | |
336 | struct mutex report_lock; | |
337 | bool is_suspended; | |
338 | char phys[NAME_MAX]; | |
339 | int num_prv_tch; | |
340 | }; | |
341 | ||
342 | struct cyttsp4 { | |
343 | struct device *dev; | |
344 | struct mutex system_lock; | |
345 | struct mutex adap_lock; | |
346 | enum cyttsp4_mode mode; | |
347 | enum cyttsp4_sleep_state sleep_state; | |
348 | enum cyttsp4_startup_state startup_state; | |
349 | int int_status; | |
350 | wait_queue_head_t wait_q; | |
351 | int irq; | |
352 | struct work_struct startup_work; | |
353 | struct work_struct watchdog_work; | |
354 | struct timer_list watchdog_timer; | |
355 | struct cyttsp4_sysinfo sysinfo; | |
356 | void *exclusive_dev; | |
357 | int exclusive_waits; | |
358 | atomic_t ignore_irq; | |
359 | bool invalid_touch_app; | |
360 | struct cyttsp4_mt_data md; | |
361 | struct cyttsp4_platform_data *pdata; | |
362 | struct cyttsp4_core_platform_data *cpdata; | |
363 | const struct cyttsp4_bus_ops *bus_ops; | |
364 | u8 *xfer_buf; | |
365 | #ifdef VERBOSE_DEBUG | |
366 | u8 pr_buf[CY_MAX_PRBUF_SIZE]; | |
367 | #endif | |
368 | }; | |
369 | ||
370 | struct cyttsp4_bus_ops { | |
371 | u16 bustype; | |
62f548d0 | 372 | int (*write)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length, |
17fb1563 | 373 | const void *values); |
62f548d0 | 374 | int (*read)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length, |
17fb1563 FY |
375 | void *values); |
376 | }; | |
377 | ||
378 | enum cyttsp4_hst_mode_bits { | |
379 | CY_HST_TOGGLE = (1 << 7), | |
380 | CY_HST_MODE_CHANGE = (1 << 3), | |
381 | CY_HST_MODE = (7 << 4), | |
382 | CY_HST_OPERATE = (0 << 4), | |
383 | CY_HST_SYSINFO = (1 << 4), | |
384 | CY_HST_CAT = (2 << 4), | |
385 | CY_HST_LOWPOW = (1 << 2), | |
386 | CY_HST_SLEEP = (1 << 1), | |
387 | CY_HST_RESET = (1 << 0), | |
388 | }; | |
389 | ||
390 | /* abs settings */ | |
391 | #define CY_IGNORE_VALUE 0xFFFF | |
392 | ||
393 | /* abs signal capabilities offsets in the frameworks array */ | |
394 | enum cyttsp4_sig_caps { | |
395 | CY_SIGNAL_OST, | |
396 | CY_MIN_OST, | |
397 | CY_MAX_OST, | |
398 | CY_FUZZ_OST, | |
399 | CY_FLAT_OST, | |
400 | CY_NUM_ABS_SET /* number of signal capability fields */ | |
401 | }; | |
402 | ||
403 | /* abs axis signal offsets in the framworks array */ | |
404 | enum cyttsp4_sig_ost { | |
405 | CY_ABS_X_OST, | |
406 | CY_ABS_Y_OST, | |
407 | CY_ABS_P_OST, | |
408 | CY_ABS_W_OST, | |
409 | CY_ABS_ID_OST, | |
410 | CY_ABS_MAJ_OST, | |
411 | CY_ABS_MIN_OST, | |
412 | CY_ABS_OR_OST, | |
413 | CY_NUM_ABS_OST /* number of abs signals */ | |
414 | }; | |
415 | ||
416 | enum cyttsp4_flags { | |
417 | CY_FLAG_NONE = 0x00, | |
418 | CY_FLAG_HOVER = 0x04, | |
419 | CY_FLAG_FLIP = 0x08, | |
420 | CY_FLAG_INV_X = 0x10, | |
421 | CY_FLAG_INV_Y = 0x20, | |
422 | CY_FLAG_VKEYS = 0x40, | |
423 | }; | |
424 | ||
425 | enum cyttsp4_object_id { | |
426 | CY_OBJ_STANDARD_FINGER, | |
427 | CY_OBJ_LARGE_OBJECT, | |
428 | CY_OBJ_STYLUS, | |
429 | CY_OBJ_HOVER, | |
430 | }; | |
431 | ||
432 | enum cyttsp4_event_id { | |
433 | CY_EV_NO_EVENT, | |
434 | CY_EV_TOUCHDOWN, | |
435 | CY_EV_MOVE, /* significant displacement (> act dist) */ | |
436 | CY_EV_LIFTOFF, /* record reports last position */ | |
437 | }; | |
438 | ||
439 | /* x-axis resolution of panel in pixels */ | |
440 | #define CY_PCFG_RESOLUTION_X_MASK 0x7F | |
441 | ||
442 | /* y-axis resolution of panel in pixels */ | |
443 | #define CY_PCFG_RESOLUTION_Y_MASK 0x7F | |
444 | ||
445 | /* x-axis, 0:origin is on left side of panel, 1: right */ | |
446 | #define CY_PCFG_ORIGIN_X_MASK 0x80 | |
447 | ||
448 | /* y-axis, 0:origin is on top side of panel, 1: bottom */ | |
449 | #define CY_PCFG_ORIGIN_Y_MASK 0x80 | |
450 | ||
62f548d0 | 451 | static inline int cyttsp4_adap_read(struct cyttsp4 *ts, u16 addr, int size, |
17fb1563 FY |
452 | void *buf) |
453 | { | |
454 | return ts->bus_ops->read(ts->dev, ts->xfer_buf, addr, size, buf); | |
455 | } | |
456 | ||
62f548d0 | 457 | static inline int cyttsp4_adap_write(struct cyttsp4 *ts, u16 addr, int size, |
17fb1563 FY |
458 | const void *buf) |
459 | { | |
460 | return ts->bus_ops->write(ts->dev, ts->xfer_buf, addr, size, buf); | |
461 | } | |
462 | ||
463 | extern struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops, | |
464 | struct device *dev, u16 irq, size_t xfer_buf_size); | |
465 | extern int cyttsp4_remove(struct cyttsp4 *ts); | |
62f548d0 | 466 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u16 addr, |
17fb1563 | 467 | u8 length, const void *values); |
62f548d0 | 468 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u16 addr, |
17fb1563 FY |
469 | u8 length, void *values); |
470 | extern const struct dev_pm_ops cyttsp4_pm_ops; | |
471 | ||
472 | #endif /* _LINUX_CYTTSP4_CORE_H */ |