1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Goodix "Berlin" Touchscreen IC driver |
4 | * Copyright (C) 2020 - 2021 Goodix, Inc. |
5 | * Copyright (C) 2023 Linaro Ltd. |
6 | * |
7 | * Based on goodix_ts_berlin driver. |
8 | * |
9 | * This driver is distinct from goodix.c since hardware interface |
10 | * is different enough to require a new driver. |
11 | * None of the register address or data structure are close enough |
12 | * to the previous generations. |
13 | * |
14 | * Currently the driver only handles Multitouch events with already |
15 | * programmed firmware and "config" for "Revision A/D" Berlin IC. |
16 | * |
17 | * Support is missing for: |
18 | * - ESD Management |
19 | * - Firmware update/flashing |
20 | * - "Config" update/flashing |
21 | * - Stylus Events |
22 | * - Gesture Events |
23 | * - Support for revision B |
24 | */ |
25 | |
26 | #include <linux/bitfield.h> |
27 | #include <linux/gpio/consumer.h> |
28 | #include <linux/input.h> |
29 | #include <linux/input/mt.h> |
30 | #include <linux/input/touchscreen.h> |
31 | #include <linux/property.h> |
32 | #include <linux/regmap.h> |
33 | #include <linux/regulator/consumer.h> |
34 | #include <linux/sizes.h> |
35 | #include <linux/unaligned.h> |
36 | |
37 | #include "goodix_berlin.h" |
38 | |
39 | #define GOODIX_BERLIN_MAX_TOUCH 10 |
40 | |
41 | #define GOODIX_BERLIN_NORMAL_RESET_DELAY_MS 100 |
42 | |
43 | #define GOODIX_BERLIN_TOUCH_EVENT BIT(7) |
44 | #define GOODIX_BERLIN_REQUEST_EVENT BIT(6) |
45 | #define GOODIX_BERLIN_TOUCH_COUNT_MASK GENMASK(3, 0) |
46 | |
47 | #define GOODIX_BERLIN_REQUEST_CODE_RESET 3 |
48 | |
49 | #define GOODIX_BERLIN_POINT_TYPE_MASK GENMASK(3, 0) |
50 | #define GOODIX_BERLIN_POINT_TYPE_STYLUS_HOVER 1 |
51 | #define GOODIX_BERLIN_POINT_TYPE_STYLUS 3 |
52 | |
53 | #define GOODIX_BERLIN_TOUCH_ID_MASK GENMASK(7, 4) |
54 | |
55 | #define GOODIX_BERLIN_DEV_CONFIRM_VAL 0xAA |
56 | #define GOODIX_BERLIN_BOOTOPTION_ADDR 0x10000 |
57 | |
58 | #define GOODIX_BERLIN_IC_INFO_MAX_LEN SZ_1K |
59 | |
60 | #define GOODIX_BERLIN_CHECKSUM_SIZE sizeof(u16) |
61 | |
62 | struct goodix_berlin_fw_version { |
63 | u8 rom_pid[6]; |
64 | u8 rom_vid[3]; |
65 | u8 rom_vid_reserved; |
66 | u8 patch_pid[8]; |
67 | u8 patch_vid[4]; |
68 | u8 patch_vid_reserved; |
69 | u8 sensor_id; |
70 | u8 reserved[2]; |
71 | __le16 checksum; |
72 | }; |
73 | |
74 | struct goodix_berlin_ic_info_version { |
75 | u8 info_customer_id; |
76 | u8 info_version_id; |
77 | u8 ic_die_id; |
78 | u8 ic_version_id; |
79 | __le32 config_id; |
80 | u8 config_version; |
81 | u8 frame_data_customer_id; |
82 | u8 frame_data_version_id; |
83 | u8 touch_data_customer_id; |
84 | u8 touch_data_version_id; |
85 | u8 reserved[3]; |
86 | } __packed; |
87 | |
88 | struct goodix_berlin_ic_info_feature { |
89 | __le16 freqhop_feature; |
90 | __le16 calibration_feature; |
91 | __le16 gesture_feature; |
92 | __le16 side_touch_feature; |
93 | __le16 stylus_feature; |
94 | } __packed; |
95 | |
96 | struct goodix_berlin_ic_info_misc { |
97 | __le32 cmd_addr; |
98 | __le16 cmd_max_len; |
99 | __le32 cmd_reply_addr; |
100 | __le16 cmd_reply_len; |
101 | __le32 fw_state_addr; |
102 | __le16 fw_state_len; |
103 | __le32 fw_buffer_addr; |
104 | __le16 fw_buffer_max_len; |
105 | __le32 frame_data_addr; |
106 | __le16 frame_data_head_len; |
107 | __le16 fw_attr_len; |
108 | __le16 fw_log_len; |
109 | u8 pack_max_num; |
110 | u8 pack_compress_version; |
111 | __le16 stylus_struct_len; |
112 | __le16 mutual_struct_len; |
113 | __le16 self_struct_len; |
114 | __le16 noise_struct_len; |
115 | __le32 touch_data_addr; |
116 | __le16 touch_data_head_len; |
117 | __le16 point_struct_len; |
118 | __le16 reserved1; |
119 | __le16 reserved2; |
120 | __le32 mutual_rawdata_addr; |
121 | __le32 mutual_diffdata_addr; |
122 | __le32 mutual_refdata_addr; |
123 | __le32 self_rawdata_addr; |
124 | __le32 self_diffdata_addr; |
125 | __le32 self_refdata_addr; |
126 | __le32 iq_rawdata_addr; |
127 | __le32 iq_refdata_addr; |
128 | __le32 im_rawdata_addr; |
129 | __le16 im_readata_len; |
130 | __le32 noise_rawdata_addr; |
131 | __le16 noise_rawdata_len; |
132 | __le32 stylus_rawdata_addr; |
133 | __le16 stylus_rawdata_len; |
134 | __le32 noise_data_addr; |
135 | __le32 esd_addr; |
136 | } __packed; |
137 | |
138 | struct goodix_berlin_touch { |
139 | u8 status; |
140 | u8 reserved; |
141 | __le16 x; |
142 | __le16 y; |
143 | __le16 w; |
144 | }; |
145 | #define GOODIX_BERLIN_TOUCH_SIZE sizeof(struct goodix_berlin_touch) |
146 | |
147 | struct { |
148 | u8 ; |
149 | u8 ; |
150 | u8 ; |
151 | u8 [3]; |
152 | __le16 ; |
153 | }; |
154 | #define sizeof(struct goodix_berlin_header) |
155 | |
156 | struct goodix_berlin_event { |
157 | struct goodix_berlin_header hdr; |
158 | /* The data below is u16/__le16 aligned */ |
159 | u8 data[GOODIX_BERLIN_TOUCH_SIZE * GOODIX_BERLIN_MAX_TOUCH + |
160 | GOODIX_BERLIN_CHECKSUM_SIZE]; |
161 | }; |
162 | |
163 | struct goodix_berlin_core { |
164 | struct device *dev; |
165 | struct regmap *regmap; |
166 | struct regulator *avdd; |
167 | struct regulator *vddio; |
168 | struct gpio_desc *reset_gpio; |
169 | struct touchscreen_properties props; |
170 | struct goodix_berlin_fw_version fw_version; |
171 | struct input_dev *input_dev; |
172 | int irq; |
173 | |
174 | /* Runtime parameters extracted from IC_INFO buffer */ |
175 | u32 touch_data_addr; |
176 | |
177 | const struct goodix_berlin_ic_data *ic_data; |
178 | |
179 | struct goodix_berlin_event event; |
180 | }; |
181 | |
182 | static bool goodix_berlin_checksum_valid(const u8 *data, int size) |
183 | { |
184 | u32 cal_checksum = 0; |
185 | u16 r_checksum; |
186 | int i; |
187 | |
188 | if (size < GOODIX_BERLIN_CHECKSUM_SIZE) |
189 | return false; |
190 | |
191 | for (i = 0; i < size - GOODIX_BERLIN_CHECKSUM_SIZE; i++) |
192 | cal_checksum += data[i]; |
193 | |
194 | r_checksum = get_unaligned_le16(p: &data[i]); |
195 | |
196 | return (u16)cal_checksum == r_checksum; |
197 | } |
198 | |
199 | static bool goodix_berlin_is_dummy_data(struct goodix_berlin_core *cd, |
200 | const u8 *data, int size) |
201 | { |
202 | int i; |
203 | |
204 | /* |
205 | * If the device is missing or doesn't respond the buffer |
206 | * could be filled with bus default line state, 0x00 or 0xff, |
207 | * so declare success the first time we encounter neither. |
208 | */ |
209 | for (i = 0; i < size; i++) |
210 | if (data[i] > 0 && data[i] < 0xff) |
211 | return false; |
212 | |
213 | return true; |
214 | } |
215 | |
216 | static int goodix_berlin_dev_confirm(struct goodix_berlin_core *cd) |
217 | { |
218 | u8 tx_buf[8], rx_buf[8]; |
219 | int retry = 3; |
220 | int error; |
221 | |
222 | memset(tx_buf, GOODIX_BERLIN_DEV_CONFIRM_VAL, sizeof(tx_buf)); |
223 | while (retry--) { |
224 | error = regmap_raw_write(map: cd->regmap, |
225 | GOODIX_BERLIN_BOOTOPTION_ADDR, |
226 | val: tx_buf, val_len: sizeof(tx_buf)); |
227 | if (error) |
228 | return error; |
229 | |
230 | error = regmap_raw_read(map: cd->regmap, |
231 | GOODIX_BERLIN_BOOTOPTION_ADDR, |
232 | val: rx_buf, val_len: sizeof(rx_buf)); |
233 | if (error) |
234 | return error; |
235 | |
236 | if (!memcmp(p: tx_buf, q: rx_buf, size: sizeof(tx_buf))) |
237 | return 0; |
238 | |
239 | usleep_range(min: 5000, max: 5100); |
240 | } |
241 | |
242 | dev_err(cd->dev, "device confirm failed, rx_buf: %*ph\n" , |
243 | (int)sizeof(rx_buf), rx_buf); |
244 | |
245 | return -EINVAL; |
246 | } |
247 | |
248 | static int goodix_berlin_power_on(struct goodix_berlin_core *cd) |
249 | { |
250 | int error; |
251 | |
252 | error = regulator_enable(regulator: cd->vddio); |
253 | if (error) { |
254 | dev_err(cd->dev, "Failed to enable vddio: %d\n" , error); |
255 | return error; |
256 | } |
257 | |
258 | /* Vendor waits 3ms for VDDIO to settle */ |
259 | usleep_range(min: 3000, max: 3100); |
260 | |
261 | error = regulator_enable(regulator: cd->avdd); |
262 | if (error) { |
263 | dev_err(cd->dev, "Failed to enable avdd: %d\n" , error); |
264 | goto err_vddio_disable; |
265 | } |
266 | |
267 | /* Vendor waits 15ms for AVDD to settle */ |
268 | usleep_range(min: 15000, max: 15100); |
269 | |
270 | gpiod_set_value_cansleep(desc: cd->reset_gpio, value: 0); |
271 | |
272 | /* Vendor waits 4ms for Firmware to initialize */ |
273 | usleep_range(min: 4000, max: 4100); |
274 | |
275 | error = goodix_berlin_dev_confirm(cd); |
276 | if (error) |
277 | goto err_dev_reset; |
278 | |
279 | /* Vendor waits 100ms for Firmware to fully boot */ |
280 | msleep(GOODIX_BERLIN_NORMAL_RESET_DELAY_MS); |
281 | |
282 | return 0; |
283 | |
284 | err_dev_reset: |
285 | gpiod_set_value_cansleep(desc: cd->reset_gpio, value: 1); |
286 | regulator_disable(regulator: cd->avdd); |
287 | err_vddio_disable: |
288 | regulator_disable(regulator: cd->vddio); |
289 | return error; |
290 | } |
291 | |
292 | static void goodix_berlin_power_off(struct goodix_berlin_core *cd) |
293 | { |
294 | gpiod_set_value_cansleep(desc: cd->reset_gpio, value: 1); |
295 | regulator_disable(regulator: cd->avdd); |
296 | regulator_disable(regulator: cd->vddio); |
297 | } |
298 | |
299 | static int goodix_berlin_read_version(struct goodix_berlin_core *cd) |
300 | { |
301 | int error; |
302 | |
303 | error = regmap_raw_read(map: cd->regmap, reg: cd->ic_data->fw_version_info_addr, |
304 | val: &cd->fw_version, val_len: sizeof(cd->fw_version)); |
305 | if (error) { |
306 | dev_err(cd->dev, "error reading fw version, %d\n" , error); |
307 | return error; |
308 | } |
309 | |
310 | if (!goodix_berlin_checksum_valid(data: (u8 *)&cd->fw_version, |
311 | size: sizeof(cd->fw_version))) { |
312 | dev_err(cd->dev, "invalid fw version: checksum error\n" ); |
313 | return -EINVAL; |
314 | } |
315 | |
316 | return 0; |
317 | } |
318 | |
319 | /* Only extract necessary data for runtime */ |
320 | static int goodix_berlin_parse_ic_info(struct goodix_berlin_core *cd, |
321 | const u8 *data, u16 length) |
322 | { |
323 | struct goodix_berlin_ic_info_misc *misc; |
324 | unsigned int offset = 0; |
325 | |
326 | offset += sizeof(__le16); /* length */ |
327 | offset += sizeof(struct goodix_berlin_ic_info_version); |
328 | offset += sizeof(struct goodix_berlin_ic_info_feature); |
329 | |
330 | /* IC_INFO Parameters, variable width structure */ |
331 | offset += 4 * sizeof(u8); /* drv_num, sen_num, button_num, force_num */ |
332 | if (offset >= length) |
333 | goto invalid_offset; |
334 | |
335 | #define ADVANCE_LE16_PARAMS() \ |
336 | do { \ |
337 | u8 param_num = data[offset++]; \ |
338 | offset += param_num * sizeof(__le16); \ |
339 | if (offset >= length) \ |
340 | goto invalid_offset; \ |
341 | } while (0) |
342 | ADVANCE_LE16_PARAMS(); /* active_scan_rate_num */ |
343 | ADVANCE_LE16_PARAMS(); /* mutual_freq_num*/ |
344 | ADVANCE_LE16_PARAMS(); /* self_tx_freq_num */ |
345 | ADVANCE_LE16_PARAMS(); /* self_rx_freq_num */ |
346 | ADVANCE_LE16_PARAMS(); /* stylus_freq_num */ |
347 | #undef ADVANCE_LE16_PARAMS |
348 | |
349 | misc = (struct goodix_berlin_ic_info_misc *)&data[offset]; |
350 | cd->touch_data_addr = le32_to_cpu(misc->touch_data_addr); |
351 | |
352 | return 0; |
353 | |
354 | invalid_offset: |
355 | dev_err(cd->dev, "ic_info length is invalid (offset %d length %d)\n" , |
356 | offset, length); |
357 | return -EINVAL; |
358 | } |
359 | |
360 | static int goodix_berlin_get_ic_info(struct goodix_berlin_core *cd) |
361 | { |
362 | u8 *afe_data __free(kfree) = NULL; |
363 | __le16 length_raw; |
364 | u16 length; |
365 | int error; |
366 | |
367 | afe_data = kzalloc(GOODIX_BERLIN_IC_INFO_MAX_LEN, GFP_KERNEL); |
368 | if (!afe_data) |
369 | return -ENOMEM; |
370 | |
371 | error = regmap_raw_read(map: cd->regmap, reg: cd->ic_data->ic_info_addr, |
372 | val: &length_raw, val_len: sizeof(length_raw)); |
373 | if (error) { |
374 | dev_err(cd->dev, "failed get ic info length, %d\n" , error); |
375 | return error; |
376 | } |
377 | |
378 | length = le16_to_cpu(length_raw); |
379 | if (length >= GOODIX_BERLIN_IC_INFO_MAX_LEN) { |
380 | dev_err(cd->dev, "invalid ic info length %d\n" , length); |
381 | return -EINVAL; |
382 | } |
383 | |
384 | error = regmap_raw_read(map: cd->regmap, reg: cd->ic_data->ic_info_addr, val: afe_data, |
385 | val_len: length); |
386 | if (error) { |
387 | dev_err(cd->dev, "failed get ic info data, %d\n" , error); |
388 | return error; |
389 | } |
390 | |
391 | /* check whether the data is valid (ex. bus default values) */ |
392 | if (goodix_berlin_is_dummy_data(cd, data: afe_data, size: length)) { |
393 | dev_err(cd->dev, "fw info data invalid\n" ); |
394 | return -EINVAL; |
395 | } |
396 | |
397 | if (!goodix_berlin_checksum_valid(data: afe_data, size: length)) { |
398 | dev_err(cd->dev, "fw info checksum error\n" ); |
399 | return -EINVAL; |
400 | } |
401 | |
402 | error = goodix_berlin_parse_ic_info(cd, data: afe_data, length); |
403 | if (error) |
404 | return error; |
405 | |
406 | /* check some key info */ |
407 | if (!cd->touch_data_addr) { |
408 | dev_err(cd->dev, "touch_data_addr is null\n" ); |
409 | return -EINVAL; |
410 | } |
411 | |
412 | return 0; |
413 | } |
414 | |
415 | static int goodix_berlin_get_remaining_contacts(struct goodix_berlin_core *cd, |
416 | int n) |
417 | { |
418 | size_t offset = 2 * GOODIX_BERLIN_TOUCH_SIZE + |
419 | GOODIX_BERLIN_CHECKSUM_SIZE; |
420 | u32 addr = cd->touch_data_addr + GOODIX_BERLIN_HEADER_SIZE + offset; |
421 | int error; |
422 | |
423 | error = regmap_raw_read(map: cd->regmap, reg: addr, |
424 | val: &cd->event.data[offset], |
425 | val_len: (n - 2) * GOODIX_BERLIN_TOUCH_SIZE); |
426 | if (error) { |
427 | dev_err_ratelimited(cd->dev, "failed to get touch data, %d\n" , |
428 | error); |
429 | return error; |
430 | } |
431 | |
432 | return 0; |
433 | } |
434 | |
435 | static void goodix_berlin_report_state(struct goodix_berlin_core *cd, int n) |
436 | { |
437 | struct goodix_berlin_touch *touch_data = |
438 | (struct goodix_berlin_touch *)cd->event.data; |
439 | struct goodix_berlin_touch *t; |
440 | int i; |
441 | u8 type, id; |
442 | |
443 | for (i = 0; i < n; i++) { |
444 | t = &touch_data[i]; |
445 | |
446 | type = FIELD_GET(GOODIX_BERLIN_POINT_TYPE_MASK, t->status); |
447 | if (type == GOODIX_BERLIN_POINT_TYPE_STYLUS || |
448 | type == GOODIX_BERLIN_POINT_TYPE_STYLUS_HOVER) { |
449 | dev_warn_once(cd->dev, "Stylus event type not handled\n" ); |
450 | continue; |
451 | } |
452 | |
453 | id = FIELD_GET(GOODIX_BERLIN_TOUCH_ID_MASK, t->status); |
454 | if (id >= GOODIX_BERLIN_MAX_TOUCH) { |
455 | dev_warn_ratelimited(cd->dev, "invalid finger id %d\n" , id); |
456 | continue; |
457 | } |
458 | |
459 | input_mt_slot(dev: cd->input_dev, slot: id); |
460 | input_mt_report_slot_state(dev: cd->input_dev, MT_TOOL_FINGER, active: true); |
461 | |
462 | touchscreen_report_pos(input: cd->input_dev, prop: &cd->props, |
463 | __le16_to_cpu(t->x), __le16_to_cpu(t->y), |
464 | multitouch: true); |
465 | input_report_abs(dev: cd->input_dev, ABS_MT_TOUCH_MAJOR, |
466 | __le16_to_cpu(t->w)); |
467 | } |
468 | |
469 | input_mt_sync_frame(dev: cd->input_dev); |
470 | input_sync(dev: cd->input_dev); |
471 | } |
472 | |
473 | static void goodix_berlin_touch_handler(struct goodix_berlin_core *cd) |
474 | { |
475 | u8 touch_num; |
476 | int error; |
477 | |
478 | touch_num = FIELD_GET(GOODIX_BERLIN_TOUCH_COUNT_MASK, |
479 | cd->event.hdr.request_type); |
480 | if (touch_num > GOODIX_BERLIN_MAX_TOUCH) { |
481 | dev_warn(cd->dev, "invalid touch num %d\n" , touch_num); |
482 | return; |
483 | } |
484 | |
485 | if (touch_num > 2) { |
486 | /* read additional contact data if more than 2 touch events */ |
487 | error = goodix_berlin_get_remaining_contacts(cd, n: touch_num); |
488 | if (error) |
489 | return; |
490 | } |
491 | |
492 | if (touch_num) { |
493 | int len = touch_num * GOODIX_BERLIN_TOUCH_SIZE + |
494 | GOODIX_BERLIN_CHECKSUM_SIZE; |
495 | if (!goodix_berlin_checksum_valid(data: cd->event.data, size: len)) { |
496 | dev_err(cd->dev, "touch data checksum error: %*ph\n" , |
497 | len, cd->event.data); |
498 | return; |
499 | } |
500 | } |
501 | |
502 | goodix_berlin_report_state(cd, n: touch_num); |
503 | } |
504 | |
505 | static int goodix_berlin_request_handle_reset(struct goodix_berlin_core *cd) |
506 | { |
507 | gpiod_set_value_cansleep(desc: cd->reset_gpio, value: 1); |
508 | usleep_range(min: 2000, max: 2100); |
509 | gpiod_set_value_cansleep(desc: cd->reset_gpio, value: 0); |
510 | |
511 | msleep(GOODIX_BERLIN_NORMAL_RESET_DELAY_MS); |
512 | |
513 | return 0; |
514 | } |
515 | |
516 | static irqreturn_t goodix_berlin_irq(int irq, void *data) |
517 | { |
518 | struct goodix_berlin_core *cd = data; |
519 | int error; |
520 | |
521 | /* |
522 | * First, read buffer with space for 2 touch events: |
523 | * - GOODIX_BERLIN_HEADER_SIZE = 8 bytes |
524 | * - GOODIX_BERLIN_TOUCH_SIZE * 2 = 16 bytes |
525 | * - GOODIX_BERLIN_CHECKLSUM_SIZE = 2 bytes |
526 | * For a total of 26 bytes. |
527 | * |
528 | * If only a single finger is reported, we will read 8 bytes more than |
529 | * needed: |
530 | * - bytes 0-7: Header (GOODIX_BERLIN_HEADER_SIZE) |
531 | * - bytes 8-15: Finger 0 Data |
532 | * - bytes 24-25: Checksum |
533 | * - bytes 18-25: Unused 8 bytes |
534 | * |
535 | * If 2 fingers are reported, we would have read the exact needed |
536 | * amount of data and checksum would be at the end of the buffer: |
537 | * - bytes 0-7: Header (GOODIX_BERLIN_HEADER_SIZE) |
538 | * - bytes 8-15: Finger 0 Bytes 0-7 |
539 | * - bytes 16-23: Finger 1 Bytes 0-7 |
540 | * - bytes 24-25: Checksum |
541 | * |
542 | * If more than 2 fingers were reported, the "Checksum" bytes would |
543 | * in fact contain part of the next finger data, and then |
544 | * goodix_berlin_get_remaining_contacts() would complete the buffer |
545 | * with the missing bytes, including the trailing checksum. |
546 | * For example, if 3 fingers are reported, then we would do: |
547 | * Read 1: |
548 | * - bytes 0-7: Header (GOODIX_BERLIN_HEADER_SIZE) |
549 | * - bytes 8-15: Finger 0 Bytes 0-7 |
550 | * - bytes 16-23: Finger 1 Bytes 0-7 |
551 | * - bytes 24-25: Finger 2 Bytes 0-1 |
552 | * Read 2 (with length of (3 - 2) * 8 = 8 bytes): |
553 | * - bytes 26-31: Finger 2 Bytes 2-7 |
554 | * - bytes 32-33: Checksum |
555 | */ |
556 | error = regmap_raw_read(map: cd->regmap, reg: cd->touch_data_addr, |
557 | val: &cd->event, |
558 | GOODIX_BERLIN_HEADER_SIZE + |
559 | 2 * GOODIX_BERLIN_TOUCH_SIZE + |
560 | GOODIX_BERLIN_CHECKSUM_SIZE); |
561 | if (error) { |
562 | dev_warn_ratelimited(cd->dev, |
563 | "failed get event head data: %d\n" , error); |
564 | goto out; |
565 | } |
566 | |
567 | if (cd->event.hdr.status == 0) |
568 | goto out; |
569 | |
570 | if (!goodix_berlin_checksum_valid(data: (u8 *)&cd->event.hdr, |
571 | GOODIX_BERLIN_HEADER_SIZE)) { |
572 | dev_warn_ratelimited(cd->dev, |
573 | "touch head checksum error: %*ph\n" , |
574 | (int)GOODIX_BERLIN_HEADER_SIZE, |
575 | &cd->event.hdr); |
576 | goto out_clear; |
577 | } |
578 | |
579 | if (cd->event.hdr.status & GOODIX_BERLIN_TOUCH_EVENT) |
580 | goodix_berlin_touch_handler(cd); |
581 | |
582 | if (cd->event.hdr.status & GOODIX_BERLIN_REQUEST_EVENT) { |
583 | switch (cd->event.hdr.request_type) { |
584 | case GOODIX_BERLIN_REQUEST_CODE_RESET: |
585 | if (cd->reset_gpio) |
586 | goodix_berlin_request_handle_reset(cd); |
587 | break; |
588 | |
589 | default: |
590 | dev_warn(cd->dev, "unsupported request code 0x%x\n" , |
591 | cd->event.hdr.request_type); |
592 | } |
593 | } |
594 | |
595 | |
596 | out_clear: |
597 | /* Clear up status field */ |
598 | regmap_write(map: cd->regmap, reg: cd->touch_data_addr, val: 0); |
599 | |
600 | out: |
601 | return IRQ_HANDLED; |
602 | } |
603 | |
604 | static int goodix_berlin_input_dev_config(struct goodix_berlin_core *cd, |
605 | const struct input_id *id) |
606 | { |
607 | struct input_dev *input_dev; |
608 | int error; |
609 | |
610 | input_dev = devm_input_allocate_device(cd->dev); |
611 | if (!input_dev) |
612 | return -ENOMEM; |
613 | |
614 | cd->input_dev = input_dev; |
615 | input_set_drvdata(dev: input_dev, data: cd); |
616 | |
617 | input_dev->name = "Goodix Berlin Capacitive TouchScreen" ; |
618 | input_dev->phys = "input/ts" ; |
619 | |
620 | input_dev->id = *id; |
621 | |
622 | input_set_abs_params(dev: cd->input_dev, ABS_MT_POSITION_X, |
623 | min: 0, SZ_64K - 1, fuzz: 0, flat: 0); |
624 | input_set_abs_params(dev: cd->input_dev, ABS_MT_POSITION_Y, |
625 | min: 0, SZ_64K - 1, fuzz: 0, flat: 0); |
626 | input_set_abs_params(dev: cd->input_dev, ABS_MT_TOUCH_MAJOR, min: 0, max: 255, fuzz: 0, flat: 0); |
627 | |
628 | touchscreen_parse_properties(input: cd->input_dev, multitouch: true, prop: &cd->props); |
629 | |
630 | error = input_mt_init_slots(dev: cd->input_dev, GOODIX_BERLIN_MAX_TOUCH, |
631 | INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); |
632 | if (error) |
633 | return error; |
634 | |
635 | error = input_register_device(cd->input_dev); |
636 | if (error) |
637 | return error; |
638 | |
639 | return 0; |
640 | } |
641 | |
642 | static int goodix_berlin_suspend(struct device *dev) |
643 | { |
644 | struct goodix_berlin_core *cd = dev_get_drvdata(dev); |
645 | |
646 | disable_irq(irq: cd->irq); |
647 | goodix_berlin_power_off(cd); |
648 | |
649 | return 0; |
650 | } |
651 | |
652 | static int goodix_berlin_resume(struct device *dev) |
653 | { |
654 | struct goodix_berlin_core *cd = dev_get_drvdata(dev); |
655 | int error; |
656 | |
657 | error = goodix_berlin_power_on(cd); |
658 | if (error) |
659 | return error; |
660 | |
661 | enable_irq(irq: cd->irq); |
662 | |
663 | return 0; |
664 | } |
665 | |
666 | EXPORT_GPL_SIMPLE_DEV_PM_OPS(goodix_berlin_pm_ops, |
667 | goodix_berlin_suspend, goodix_berlin_resume); |
668 | |
669 | static void goodix_berlin_power_off_act(void *data) |
670 | { |
671 | struct goodix_berlin_core *cd = data; |
672 | |
673 | goodix_berlin_power_off(cd); |
674 | } |
675 | |
676 | static ssize_t registers_read(struct file *filp, struct kobject *kobj, |
677 | const struct bin_attribute *bin_attr, |
678 | char *buf, loff_t off, size_t count) |
679 | { |
680 | struct device *dev = kobj_to_dev(kobj); |
681 | struct goodix_berlin_core *cd = dev_get_drvdata(dev); |
682 | int error; |
683 | |
684 | error = regmap_raw_read(map: cd->regmap, reg: off, val: buf, val_len: count); |
685 | |
686 | return error ? error : count; |
687 | } |
688 | |
689 | static ssize_t registers_write(struct file *filp, struct kobject *kobj, |
690 | const struct bin_attribute *bin_attr, |
691 | char *buf, loff_t off, size_t count) |
692 | { |
693 | struct device *dev = kobj_to_dev(kobj); |
694 | struct goodix_berlin_core *cd = dev_get_drvdata(dev); |
695 | int error; |
696 | |
697 | error = regmap_raw_write(map: cd->regmap, reg: off, val: buf, val_len: count); |
698 | |
699 | return error ? error : count; |
700 | } |
701 | |
702 | static const BIN_ATTR_ADMIN_RW(registers, 0); |
703 | |
704 | static const struct bin_attribute *const goodix_berlin_bin_attrs[] = { |
705 | &bin_attr_registers, |
706 | NULL, |
707 | }; |
708 | |
709 | static const struct attribute_group goodix_berlin_attr_group = { |
710 | .bin_attrs_new = goodix_berlin_bin_attrs, |
711 | }; |
712 | |
713 | const struct attribute_group *goodix_berlin_groups[] = { |
714 | &goodix_berlin_attr_group, |
715 | NULL, |
716 | }; |
717 | EXPORT_SYMBOL_GPL(goodix_berlin_groups); |
718 | |
719 | int goodix_berlin_probe(struct device *dev, int irq, const struct input_id *id, |
720 | struct regmap *regmap, |
721 | const struct goodix_berlin_ic_data *ic_data) |
722 | { |
723 | struct goodix_berlin_core *cd; |
724 | int error; |
725 | |
726 | if (irq <= 0) { |
727 | dev_err(dev, "Missing interrupt number\n" ); |
728 | return -EINVAL; |
729 | } |
730 | |
731 | cd = devm_kzalloc(dev, size: sizeof(*cd), GFP_KERNEL); |
732 | if (!cd) |
733 | return -ENOMEM; |
734 | |
735 | cd->dev = dev; |
736 | cd->regmap = regmap; |
737 | cd->irq = irq; |
738 | cd->ic_data = ic_data; |
739 | |
740 | cd->reset_gpio = devm_gpiod_get_optional(dev, con_id: "reset" , flags: GPIOD_OUT_HIGH); |
741 | if (IS_ERR(ptr: cd->reset_gpio)) |
742 | return dev_err_probe(dev, err: PTR_ERR(ptr: cd->reset_gpio), |
743 | fmt: "Failed to request reset gpio\n" ); |
744 | |
745 | cd->avdd = devm_regulator_get(dev, id: "avdd" ); |
746 | if (IS_ERR(ptr: cd->avdd)) |
747 | return dev_err_probe(dev, err: PTR_ERR(ptr: cd->avdd), |
748 | fmt: "Failed to request avdd regulator\n" ); |
749 | |
750 | cd->vddio = devm_regulator_get(dev, id: "vddio" ); |
751 | if (IS_ERR(ptr: cd->vddio)) |
752 | return dev_err_probe(dev, err: PTR_ERR(ptr: cd->vddio), |
753 | fmt: "Failed to request vddio regulator\n" ); |
754 | |
755 | error = goodix_berlin_power_on(cd); |
756 | if (error) { |
757 | dev_err(dev, "failed power on" ); |
758 | return error; |
759 | } |
760 | |
761 | error = devm_add_action_or_reset(dev, goodix_berlin_power_off_act, cd); |
762 | if (error) |
763 | return error; |
764 | |
765 | error = goodix_berlin_read_version(cd); |
766 | if (error) { |
767 | dev_err(dev, "failed to get version info" ); |
768 | return error; |
769 | } |
770 | |
771 | error = goodix_berlin_get_ic_info(cd); |
772 | if (error) { |
773 | dev_err(dev, "invalid ic info, abort" ); |
774 | return error; |
775 | } |
776 | |
777 | error = goodix_berlin_input_dev_config(cd, id); |
778 | if (error) { |
779 | dev_err(dev, "failed set input device" ); |
780 | return error; |
781 | } |
782 | |
783 | error = devm_request_threaded_irq(dev, irq: cd->irq, NULL, thread_fn: goodix_berlin_irq, |
784 | IRQF_ONESHOT, devname: "goodix-berlin" , dev_id: cd); |
785 | if (error) { |
786 | dev_err(dev, "request threaded irq failed: %d\n" , error); |
787 | return error; |
788 | } |
789 | |
790 | dev_set_drvdata(dev, data: cd); |
791 | |
792 | dev_dbg(dev, "Goodix Berlin %s Touchscreen Controller" , |
793 | cd->fw_version.patch_pid); |
794 | |
795 | return 0; |
796 | } |
797 | EXPORT_SYMBOL_GPL(goodix_berlin_probe); |
798 | |
799 | MODULE_LICENSE("GPL" ); |
800 | MODULE_DESCRIPTION("Goodix Berlin Core Touchscreen driver" ); |
801 | MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>" ); |
802 | |