// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Goodix "Berlin" Touchscreen IC driver
 * Copyright (C) 2020 - 2021 Goodix, Inc.
 * Copyright (C) 2023 Linaro Ltd.
 *
 * Based on goodix_ts_berlin driver.
 *
 * This driver is distinct from goodix.c since hardware interface
 * is different enough to require a new driver.
 * None of the register address or data structure are close enough
 * to the previous generations.
 *
 * Currently the driver only handles Multitouch events with already
 * programmed firmware and "config" for "Revision D" Berlin IC.
 *
 * Support is missing for:
 * - ESD Management
 * - Firmware update/flashing
 * - "Config" update/flashing
 * - Stylus Events
 * - Gesture Events
 * - Support for older revisions (A & B)
 */

#include <linux/bitfield.h>
#include <linux/gpio/consumer.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/sizes.h>
#include <asm/unaligned.h>

#include "goodix_berlin.h"

#define GOODIX_BERLIN_MAX_TOUCH			10

#define GOODIX_BERLIN_NORMAL_RESET_DELAY_MS	100

#define GOODIX_BERLIN_TOUCH_EVENT		BIT(7)
#define GOODIX_BERLIN_REQUEST_EVENT		BIT(6)
#define GOODIX_BERLIN_TOUCH_COUNT_MASK		GENMASK(3, 0)

#define GOODIX_BERLIN_REQUEST_CODE_RESET	3

#define GOODIX_BERLIN_POINT_TYPE_MASK		GENMASK(3, 0)
#define GOODIX_BERLIN_POINT_TYPE_STYLUS_HOVER	1
#define GOODIX_BERLIN_POINT_TYPE_STYLUS		3

#define GOODIX_BERLIN_TOUCH_ID_MASK		GENMASK(7, 4)

#define GOODIX_BERLIN_DEV_CONFIRM_VAL		0xAA
#define GOODIX_BERLIN_BOOTOPTION_ADDR		0x10000
#define GOODIX_BERLIN_FW_VERSION_INFO_ADDR	0x10014

#define GOODIX_BERLIN_IC_INFO_MAX_LEN		SZ_1K
#define GOODIX_BERLIN_IC_INFO_ADDR		0x10070

#define GOODIX_BERLIN_CHECKSUM_SIZE		sizeof(u16)

struct goodix_berlin_fw_version {
	u8 rom_pid[6];
	u8 rom_vid[3];
	u8 rom_vid_reserved;
	u8 patch_pid[8];
	u8 patch_vid[4];
	u8 patch_vid_reserved;
	u8 sensor_id;
	u8 reserved[2];
	__le16 checksum;
};

struct goodix_berlin_ic_info_version {
	u8 info_customer_id;
	u8 info_version_id;
	u8 ic_die_id;
	u8 ic_version_id;
	__le32 config_id;
	u8 config_version;
	u8 frame_data_customer_id;
	u8 frame_data_version_id;
	u8 touch_data_customer_id;
	u8 touch_data_version_id;
	u8 reserved[3];
} __packed;

struct goodix_berlin_ic_info_feature {
	__le16 freqhop_feature;
	__le16 calibration_feature;
	__le16 gesture_feature;
	__le16 side_touch_feature;
	__le16 stylus_feature;
} __packed;

struct goodix_berlin_ic_info_misc {
	__le32 cmd_addr;
	__le16 cmd_max_len;
	__le32 cmd_reply_addr;
	__le16 cmd_reply_len;
	__le32 fw_state_addr;
	__le16 fw_state_len;
	__le32 fw_buffer_addr;
	__le16 fw_buffer_max_len;
	__le32 frame_data_addr;
	__le16 frame_data_head_len;
	__le16 fw_attr_len;
	__le16 fw_log_len;
	u8 pack_max_num;
	u8 pack_compress_version;
	__le16 stylus_struct_len;
	__le16 mutual_struct_len;
	__le16 self_struct_len;
	__le16 noise_struct_len;
	__le32 touch_data_addr;
	__le16 touch_data_head_len;
	__le16 point_struct_len;
	__le16 reserved1;
	__le16 reserved2;
	__le32 mutual_rawdata_addr;
	__le32 mutual_diffdata_addr;
	__le32 mutual_refdata_addr;
	__le32 self_rawdata_addr;
	__le32 self_diffdata_addr;
	__le32 self_refdata_addr;
	__le32 iq_rawdata_addr;
	__le32 iq_refdata_addr;
	__le32 im_rawdata_addr;
	__le16 im_readata_len;
	__le32 noise_rawdata_addr;
	__le16 noise_rawdata_len;
	__le32 stylus_rawdata_addr;
	__le16 stylus_rawdata_len;
	__le32 noise_data_addr;
	__le32 esd_addr;
} __packed;

struct goodix_berlin_touch {
	u8 status;
	u8 reserved;
	__le16 x;
	__le16 y;
	__le16 w;
};
#define GOODIX_BERLIN_TOUCH_SIZE	sizeof(struct goodix_berlin_touch)

struct goodix_berlin_header {
	u8 status;
	u8 reserved1;
	u8 request_type;
	u8 reserved2[3];
	__le16 checksum;
};
#define GOODIX_BERLIN_HEADER_SIZE	sizeof(struct goodix_berlin_header)

struct goodix_berlin_event {
	struct goodix_berlin_header hdr;
	/* The data below is u16/__le16 aligned */
	u8 data[GOODIX_BERLIN_TOUCH_SIZE * GOODIX_BERLIN_MAX_TOUCH +
		GOODIX_BERLIN_CHECKSUM_SIZE];
};

struct goodix_berlin_core {
	struct device *dev;
	struct regmap *regmap;
	struct regulator *avdd;
	struct regulator *iovdd;
	struct gpio_desc *reset_gpio;
	struct touchscreen_properties props;
	struct goodix_berlin_fw_version fw_version;
	struct input_dev *input_dev;
	int irq;

	/* Runtime parameters extracted from IC_INFO buffer  */
	u32 touch_data_addr;

	struct goodix_berlin_event event;
};

static bool goodix_berlin_checksum_valid(const u8 *data, int size)
{
	u32 cal_checksum = 0;
	u16 r_checksum;
	int i;

	if (size < GOODIX_BERLIN_CHECKSUM_SIZE)
		return false;

	for (i = 0; i < size - GOODIX_BERLIN_CHECKSUM_SIZE; i++)
		cal_checksum += data[i];

	r_checksum = get_unaligned_le16(&data[i]);

	return (u16)cal_checksum == r_checksum;
}

static bool goodix_berlin_is_dummy_data(struct goodix_berlin_core *cd,
					const u8 *data, int size)
{
	int i;

	/*
	 * If the device is missing or doesn't respond the buffer
	 * could be filled with bus default line state, 0x00 or 0xff,
	 * so declare success the first time we encounter neither.
	 */
	for (i = 0; i < size; i++)
		if (data[i] > 0 && data[i] < 0xff)
			return false;

	return true;
}

static int goodix_berlin_dev_confirm(struct goodix_berlin_core *cd)
{
	u8 tx_buf[8], rx_buf[8];
	int retry = 3;
	int error;

	memset(tx_buf, GOODIX_BERLIN_DEV_CONFIRM_VAL, sizeof(tx_buf));
	while (retry--) {
		error = regmap_raw_write(cd->regmap,
					 GOODIX_BERLIN_BOOTOPTION_ADDR,
					 tx_buf, sizeof(tx_buf));
		if (error)
			return error;

		error = regmap_raw_read(cd->regmap,
					GOODIX_BERLIN_BOOTOPTION_ADDR,
					rx_buf, sizeof(rx_buf));
		if (error)
			return error;

		if (!memcmp(tx_buf, rx_buf, sizeof(tx_buf)))
			return 0;

		usleep_range(5000, 5100);
	}

	dev_err(cd->dev, "device confirm failed, rx_buf: %*ph\n",
		(int)sizeof(rx_buf), rx_buf);

	return -EINVAL;
}

static int goodix_berlin_power_on(struct goodix_berlin_core *cd)
{
	int error;

	error = regulator_enable(cd->iovdd);
	if (error) {
		dev_err(cd->dev, "Failed to enable iovdd: %d\n", error);
		return error;
	}

	/* Vendor waits 3ms for IOVDD to settle */
	usleep_range(3000, 3100);

	error = regulator_enable(cd->avdd);
	if (error) {
		dev_err(cd->dev, "Failed to enable avdd: %d\n", error);
		goto err_iovdd_disable;
	}

	/* Vendor waits 15ms for IOVDD to settle */
	usleep_range(15000, 15100);

	gpiod_set_value_cansleep(cd->reset_gpio, 0);

	/* Vendor waits 4ms for Firmware to initialize */
	usleep_range(4000, 4100);

	error = goodix_berlin_dev_confirm(cd);
	if (error)
		goto err_dev_reset;

	/* Vendor waits 100ms for Firmware to fully boot */
	msleep(GOODIX_BERLIN_NORMAL_RESET_DELAY_MS);

	return 0;

err_dev_reset:
	gpiod_set_value_cansleep(cd->reset_gpio, 1);
	regulator_disable(cd->avdd);
err_iovdd_disable:
	regulator_disable(cd->iovdd);
	return error;
}

static void goodix_berlin_power_off(struct goodix_berlin_core *cd)
{
	gpiod_set_value_cansleep(cd->reset_gpio, 1);
	regulator_disable(cd->avdd);
	regulator_disable(cd->iovdd);
}

static int goodix_berlin_read_version(struct goodix_berlin_core *cd)
{
	int error;

	error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_FW_VERSION_INFO_ADDR,
				&cd->fw_version, sizeof(cd->fw_version));
	if (error) {
		dev_err(cd->dev, "error reading fw version, %d\n", error);
		return error;
	}

	if (!goodix_berlin_checksum_valid((u8 *)&cd->fw_version,
					  sizeof(cd->fw_version))) {
		dev_err(cd->dev, "invalid fw version: checksum error\n");
		return -EINVAL;
	}

	return 0;
}

/* Only extract necessary data for runtime */
static int goodix_berlin_parse_ic_info(struct goodix_berlin_core *cd,
				       const u8 *data, u16 length)
{
	struct goodix_berlin_ic_info_misc *misc;
	unsigned int offset = 0;

	offset += sizeof(__le16); /* length */
	offset += sizeof(struct goodix_berlin_ic_info_version);
	offset += sizeof(struct goodix_berlin_ic_info_feature);

	/* IC_INFO Parameters, variable width structure */
	offset += 4 * sizeof(u8); /* drv_num, sen_num, button_num, force_num */
	if (offset >= length)
		goto invalid_offset;

#define ADVANCE_LE16_PARAMS()				\
	do {						\
		u8 param_num = data[offset++];		\
		offset += param_num * sizeof(__le16);	\
		if (offset >= length)			\
			goto invalid_offset;		\
	} while (0)
	ADVANCE_LE16_PARAMS(); /* active_scan_rate_num */
	ADVANCE_LE16_PARAMS(); /* mutual_freq_num*/
	ADVANCE_LE16_PARAMS(); /* self_tx_freq_num */
	ADVANCE_LE16_PARAMS(); /* self_rx_freq_num */
	ADVANCE_LE16_PARAMS(); /* stylus_freq_num */
#undef ADVANCE_LE16_PARAMS

	misc = (struct goodix_berlin_ic_info_misc *)&data[offset];
	cd->touch_data_addr = le32_to_cpu(misc->touch_data_addr);

	return 0;

invalid_offset:
	dev_err(cd->dev, "ic_info length is invalid (offset %d length %d)\n",
		offset, length);
	return -EINVAL;
}

static int goodix_berlin_get_ic_info(struct goodix_berlin_core *cd)
{
	u8 *afe_data __free(kfree) = NULL;
	__le16 length_raw;
	u16 length;
	int error;

	afe_data = kzalloc(GOODIX_BERLIN_IC_INFO_MAX_LEN, GFP_KERNEL);
	if (!afe_data)
		return -ENOMEM;

	error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_IC_INFO_ADDR,
				&length_raw, sizeof(length_raw));
	if (error) {
		dev_err(cd->dev, "failed get ic info length, %d\n", error);
		return error;
	}

	length = le16_to_cpu(length_raw);
	if (length >= GOODIX_BERLIN_IC_INFO_MAX_LEN) {
		dev_err(cd->dev, "invalid ic info length %d\n", length);
		return -EINVAL;
	}

	error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_IC_INFO_ADDR,
				afe_data, length);
	if (error) {
		dev_err(cd->dev, "failed get ic info data, %d\n", error);
		return error;
	}

	/* check whether the data is valid (ex. bus default values) */
	if (goodix_berlin_is_dummy_data(cd, afe_data, length)) {
		dev_err(cd->dev, "fw info data invalid\n");
		return -EINVAL;
	}

	if (!goodix_berlin_checksum_valid(afe_data, length)) {
		dev_err(cd->dev, "fw info checksum error\n");
		return -EINVAL;
	}

	error = goodix_berlin_parse_ic_info(cd, afe_data, length);
	if (error)
		return error;

	/* check some key info */
	if (!cd->touch_data_addr) {
		dev_err(cd->dev, "touch_data_addr is null\n");
		return -EINVAL;
	}

	return 0;
}

static int goodix_berlin_get_remaining_contacts(struct goodix_berlin_core *cd,
						int n)
{
	size_t offset = 2 * GOODIX_BERLIN_TOUCH_SIZE +
				GOODIX_BERLIN_CHECKSUM_SIZE;
	u32 addr = cd->touch_data_addr + GOODIX_BERLIN_HEADER_SIZE + offset;
	int error;

	error = regmap_raw_read(cd->regmap, addr,
				&cd->event.data[offset],
				(n - 2) * GOODIX_BERLIN_TOUCH_SIZE);
	if (error) {
		dev_err_ratelimited(cd->dev, "failed to get touch data, %d\n",
				    error);
		return error;
	}

	return 0;
}

static void goodix_berlin_report_state(struct goodix_berlin_core *cd, int n)
{
	struct goodix_berlin_touch *touch_data =
			(struct goodix_berlin_touch *)cd->event.data;
	struct goodix_berlin_touch *t;
	int i;
	u8 type, id;

	for (i = 0; i < n; i++) {
		t = &touch_data[i];

		type = FIELD_GET(GOODIX_BERLIN_POINT_TYPE_MASK, t->status);
		if (type == GOODIX_BERLIN_POINT_TYPE_STYLUS ||
		    type == GOODIX_BERLIN_POINT_TYPE_STYLUS_HOVER) {
			dev_warn_once(cd->dev, "Stylus event type not handled\n");
			continue;
		}

		id = FIELD_GET(GOODIX_BERLIN_TOUCH_ID_MASK, t->status);
		if (id >= GOODIX_BERLIN_MAX_TOUCH) {
			dev_warn_ratelimited(cd->dev, "invalid finger id %d\n", id);
			continue;
		}

		input_mt_slot(cd->input_dev, id);
		input_mt_report_slot_state(cd->input_dev, MT_TOOL_FINGER, true);

		touchscreen_report_pos(cd->input_dev, &cd->props,
				       __le16_to_cpu(t->x), __le16_to_cpu(t->y),
				       true);
		input_report_abs(cd->input_dev, ABS_MT_TOUCH_MAJOR,
				 __le16_to_cpu(t->w));
	}

	input_mt_sync_frame(cd->input_dev);
	input_sync(cd->input_dev);
}

static void goodix_berlin_touch_handler(struct goodix_berlin_core *cd)
{
	u8 touch_num;
	int error;

	touch_num = FIELD_GET(GOODIX_BERLIN_TOUCH_COUNT_MASK,
			      cd->event.hdr.request_type);
	if (touch_num > GOODIX_BERLIN_MAX_TOUCH) {
		dev_warn(cd->dev, "invalid touch num %d\n", touch_num);
		return;
	}

	if (touch_num > 2) {
		/* read additional contact data if more than 2 touch events */
		error = goodix_berlin_get_remaining_contacts(cd, touch_num);
		if (error)
			return;
	}

	if (touch_num) {
		int len = touch_num * GOODIX_BERLIN_TOUCH_SIZE +
			  GOODIX_BERLIN_CHECKSUM_SIZE;
		if (!goodix_berlin_checksum_valid(cd->event.data, len)) {
			dev_err(cd->dev, "touch data checksum error: %*ph\n",
				len, cd->event.data);
			return;
		}
	}

	goodix_berlin_report_state(cd, touch_num);
}

static int goodix_berlin_request_handle_reset(struct goodix_berlin_core *cd)
{
	gpiod_set_value_cansleep(cd->reset_gpio, 1);
	usleep_range(2000, 2100);
	gpiod_set_value_cansleep(cd->reset_gpio, 0);

	msleep(GOODIX_BERLIN_NORMAL_RESET_DELAY_MS);

	return 0;
}

static irqreturn_t goodix_berlin_irq(int irq, void *data)
{
	struct goodix_berlin_core *cd = data;
	int error;

	/*
	 * First, read buffer with space for 2 touch events:
	 * - GOODIX_BERLIN_HEADER_SIZE = 8 bytes
	 * - GOODIX_BERLIN_TOUCH_SIZE * 2 = 16 bytes
	 * - GOODIX_BERLIN_CHECKLSUM_SIZE = 2 bytes
	 * For a total of 26 bytes.
	 *
	 * If only a single finger is reported, we will read 8 bytes more than
	 * needed:
	 * - bytes 0-7:   Header (GOODIX_BERLIN_HEADER_SIZE)
	 * - bytes 8-15:  Finger 0 Data
	 * - bytes 24-25: Checksum
	 * - bytes 18-25: Unused 8 bytes
	 *
	 * If 2 fingers are reported, we would have read the exact needed
	 * amount of data and checksum would be at the end of the buffer:
	 * - bytes 0-7:   Header (GOODIX_BERLIN_HEADER_SIZE)
	 * - bytes 8-15:  Finger 0 Bytes 0-7
	 * - bytes 16-23: Finger 1 Bytes 0-7
	 * - bytes 24-25: Checksum
	 *
	 * If more than 2 fingers were reported, the "Checksum" bytes would
	 * in fact contain part of the next finger data, and then
	 * goodix_berlin_get_remaining_contacts() would complete the buffer
	 * with the missing bytes, including the trailing checksum.
	 * For example, if 3 fingers are reported, then we would do:
	 * Read 1:
	 * - bytes 0-7:   Header (GOODIX_BERLIN_HEADER_SIZE)
	 * - bytes 8-15:  Finger 0 Bytes 0-7
	 * - bytes 16-23: Finger 1 Bytes 0-7
	 * - bytes 24-25: Finger 2 Bytes 0-1
	 * Read 2 (with length of (3 - 2) * 8 = 8 bytes):
	 * - bytes 26-31: Finger 2 Bytes 2-7
	 * - bytes 32-33: Checksum
	 */
	error = regmap_raw_read(cd->regmap, cd->touch_data_addr,
				&cd->event,
				GOODIX_BERLIN_HEADER_SIZE +
					2 * GOODIX_BERLIN_TOUCH_SIZE +
					GOODIX_BERLIN_CHECKSUM_SIZE);
	if (error) {
		dev_warn_ratelimited(cd->dev,
				     "failed get event head data: %d\n", error);
		goto out;
	}

	if (cd->event.hdr.status == 0)
		goto out;

	if (!goodix_berlin_checksum_valid((u8 *)&cd->event.hdr,
					  GOODIX_BERLIN_HEADER_SIZE)) {
		dev_warn_ratelimited(cd->dev,
				     "touch head checksum error: %*ph\n",
				     (int)GOODIX_BERLIN_HEADER_SIZE,
				     &cd->event.hdr);
		goto out_clear;
	}

	if (cd->event.hdr.status & GOODIX_BERLIN_TOUCH_EVENT)
		goodix_berlin_touch_handler(cd);

	if (cd->event.hdr.status & GOODIX_BERLIN_REQUEST_EVENT) {
		switch (cd->event.hdr.request_type) {
		case GOODIX_BERLIN_REQUEST_CODE_RESET:
			if (cd->reset_gpio)
				goodix_berlin_request_handle_reset(cd);
			break;

		default:
			dev_warn(cd->dev, "unsupported request code 0x%x\n",
				 cd->event.hdr.request_type);
		}
	}


out_clear:
	/* Clear up status field */
	regmap_write(cd->regmap, cd->touch_data_addr, 0);

out:
	return IRQ_HANDLED;
}

static int goodix_berlin_input_dev_config(struct goodix_berlin_core *cd,
					  const struct input_id *id)
{
	struct input_dev *input_dev;
	int error;

	input_dev = devm_input_allocate_device(cd->dev);
	if (!input_dev)
		return -ENOMEM;

	cd->input_dev = input_dev;
	input_set_drvdata(input_dev, cd);

	input_dev->name = "Goodix Berlin Capacitive TouchScreen";
	input_dev->phys = "input/ts";

	input_dev->id = *id;

	input_set_abs_params(cd->input_dev, ABS_MT_POSITION_X,
			     0, SZ_64K - 1, 0, 0);
	input_set_abs_params(cd->input_dev, ABS_MT_POSITION_Y,
			     0, SZ_64K - 1, 0, 0);
	input_set_abs_params(cd->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);

	touchscreen_parse_properties(cd->input_dev, true, &cd->props);

	error = input_mt_init_slots(cd->input_dev, GOODIX_BERLIN_MAX_TOUCH,
				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
	if (error)
		return error;

	error = input_register_device(cd->input_dev);
	if (error)
		return error;

	return 0;
}

static int goodix_berlin_suspend(struct device *dev)
{
	struct goodix_berlin_core *cd = dev_get_drvdata(dev);

	disable_irq(cd->irq);
	goodix_berlin_power_off(cd);

	return 0;
}

static int goodix_berlin_resume(struct device *dev)
{
	struct goodix_berlin_core *cd = dev_get_drvdata(dev);
	int error;

	error = goodix_berlin_power_on(cd);
	if (error)
		return error;

	enable_irq(cd->irq);

	return 0;
}

EXPORT_GPL_SIMPLE_DEV_PM_OPS(goodix_berlin_pm_ops,
			     goodix_berlin_suspend, goodix_berlin_resume);

static void goodix_berlin_power_off_act(void *data)
{
	struct goodix_berlin_core *cd = data;

	goodix_berlin_power_off(cd);
}

int goodix_berlin_probe(struct device *dev, int irq, const struct input_id *id,
			struct regmap *regmap)
{
	struct goodix_berlin_core *cd;
	int error;

	if (irq <= 0) {
		dev_err(dev, "Missing interrupt number\n");
		return -EINVAL;
	}

	cd = devm_kzalloc(dev, sizeof(*cd), GFP_KERNEL);
	if (!cd)
		return -ENOMEM;

	cd->dev = dev;
	cd->regmap = regmap;
	cd->irq = irq;

	cd->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
	if (IS_ERR(cd->reset_gpio))
		return dev_err_probe(dev, PTR_ERR(cd->reset_gpio),
				     "Failed to request reset gpio\n");

	cd->avdd = devm_regulator_get(dev, "avdd");
	if (IS_ERR(cd->avdd))
		return dev_err_probe(dev, PTR_ERR(cd->avdd),
				     "Failed to request avdd regulator\n");

	cd->iovdd = devm_regulator_get(dev, "iovdd");
	if (IS_ERR(cd->iovdd))
		return dev_err_probe(dev, PTR_ERR(cd->iovdd),
				     "Failed to request iovdd regulator\n");

	error = goodix_berlin_power_on(cd);
	if (error) {
		dev_err(dev, "failed power on");
		return error;
	}

	error = devm_add_action_or_reset(dev, goodix_berlin_power_off_act, cd);
	if (error)
		return error;

	error = goodix_berlin_read_version(cd);
	if (error) {
		dev_err(dev, "failed to get version info");
		return error;
	}

	error = goodix_berlin_get_ic_info(cd);
	if (error) {
		dev_err(dev, "invalid ic info, abort");
		return error;
	}

	error = goodix_berlin_input_dev_config(cd, id);
	if (error) {
		dev_err(dev, "failed set input device");
		return error;
	}

	error = devm_request_threaded_irq(dev, cd->irq, NULL, goodix_berlin_irq,
					  IRQF_ONESHOT, "goodix-berlin", cd);
	if (error) {
		dev_err(dev, "request threaded irq failed: %d\n", error);
		return error;
	}

	dev_set_drvdata(dev, cd);

	dev_dbg(dev, "Goodix Berlin %s Touchscreen Controller",
		cd->fw_version.patch_pid);

	return 0;
}
EXPORT_SYMBOL_GPL(goodix_berlin_probe);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Goodix Berlin Core Touchscreen driver");
MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
