File Index
Files and directories
Sign in
FILE

goodix_berlin_core.c

File preview with syntax highlighting.

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