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