631 lines · 15.2 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only #include <linux/delay.h>#include <linux/i2c.h>#include <linux/input.h>#include <linux/input/mt.h>#include <linux/input/touchscreen.h>#include <linux/interrupt.h>#include <linux/irq.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/of.h>#include <linux/regulator/consumer.h>#include <linux/slab.h> /* Register Map */ #define ZINITIX_SWRESET_CMD			0x0000#define ZINITIX_WAKEUP_CMD			0x0001 #define ZINITIX_IDLE_CMD			0x0004#define ZINITIX_SLEEP_CMD			0x0005 #define ZINITIX_CLEAR_INT_STATUS_CMD		0x0003#define ZINITIX_CALIBRATE_CMD			0x0006#define ZINITIX_SAVE_STATUS_CMD			0x0007#define ZINITIX_SAVE_CALIBRATION_CMD		0x0008#define ZINITIX_RECALL_FACTORY_CMD		0x000f #define ZINITIX_THRESHOLD			0x0020 #define ZINITIX_LARGE_PALM_REJECT_AREA_TH	0x003F #define ZINITIX_DEBUG_REG			0x0115 /* 0~7 */ #define ZINITIX_TOUCH_MODE			0x0010#define ZINITIX_CHIP_REVISION			0x0011#define ZINITIX_FIRMWARE_VERSION		0x0012 #define ZINITIX_USB_DETECT			0x116 #define ZINITIX_MINOR_FW_VERSION		0x0121 #define ZINITIX_VENDOR_ID			0x001C#define ZINITIX_HW_ID				0x0014 #define ZINITIX_DATA_VERSION_REG		0x0013#define ZINITIX_SUPPORTED_FINGER_NUM		0x0015#define ZINITIX_EEPROM_INFO			0x0018#define ZINITIX_INITIAL_TOUCH_MODE		0x0019 #define ZINITIX_TOTAL_NUMBER_OF_X		0x0060#define ZINITIX_TOTAL_NUMBER_OF_Y		0x0061 #define ZINITIX_DELAY_RAW_FOR_HOST		0x007f #define ZINITIX_BUTTON_SUPPORTED_NUM		0x00B0#define ZINITIX_BUTTON_SENSITIVITY		0x00B2#define ZINITIX_DUMMY_BUTTON_SENSITIVITY	0X00C8 #define ZINITIX_X_RESOLUTION			0x00C0#define ZINITIX_Y_RESOLUTION			0x00C1 #define ZINITIX_POINT_STATUS_REG		0x0080#define ZINITIX_ICON_STATUS_REG			0x00AA #define ZINITIX_POINT_COORD_REG			(ZINITIX_POINT_STATUS_REG + 2) #define ZINITIX_AFE_FREQUENCY			0x0100#define ZINITIX_DND_N_COUNT			0x0122#define ZINITIX_DND_U_COUNT			0x0135 #define ZINITIX_RAWDATA_REG			0x0200 #define ZINITIX_EEPROM_INFO_REG			0x0018 #define ZINITIX_INT_ENABLE_FLAG			0x00f0#define ZINITIX_PERIODICAL_INTERRUPT_INTERVAL	0x00f1 #define ZINITIX_BTN_WIDTH			0x016d #define ZINITIX_CHECKSUM_RESULT			0x012c #define ZINITIX_INIT_FLASH			0x01d0#define ZINITIX_WRITE_FLASH			0x01d1#define ZINITIX_READ_FLASH			0x01d2 #define ZINITIX_INTERNAL_FLAG_02		0x011e#define ZINITIX_INTERNAL_FLAG_03		0x011f #define ZINITIX_I2C_CHECKSUM_WCNT		0x016a#define ZINITIX_I2C_CHECKSUM_RESULT		0x016c /* Interrupt & status register flags */ #define BIT_PT_CNT_CHANGE			BIT(0)#define BIT_DOWN				BIT(1)#define BIT_MOVE				BIT(2)#define BIT_UP					BIT(3)#define BIT_PALM				BIT(4)#define BIT_PALM_REJECT				BIT(5)#define BIT_RESERVED_0				BIT(6)#define BIT_RESERVED_1				BIT(7)#define BIT_WEIGHT_CHANGE			BIT(8)#define BIT_PT_NO_CHANGE			BIT(9)#define BIT_REJECT				BIT(10)#define BIT_PT_EXIST				BIT(11)#define BIT_RESERVED_2				BIT(12)#define BIT_ERROR				BIT(13)#define BIT_DEBUG				BIT(14)#define BIT_ICON_EVENT				BIT(15) #define SUB_BIT_EXIST				BIT(0)#define SUB_BIT_DOWN				BIT(1)#define SUB_BIT_MOVE				BIT(2)#define SUB_BIT_UP				BIT(3)#define SUB_BIT_UPDATE				BIT(4)#define SUB_BIT_WAIT				BIT(5) #define DEFAULT_TOUCH_POINT_MODE		2#define MAX_SUPPORTED_FINGER_NUM		5 #define CHIP_ON_DELAY				15 // ms#define FIRMWARE_ON_DELAY			40 // ms struct point_coord {	__le16	x;	__le16	y;	u8	width;	u8	sub_status;	// currently unused, but needed as padding:	u8	minor_width;	u8	angle;}; struct touch_event {	__le16	status;	u8	finger_mask;	u8	time_stamp;	struct point_coord point_coord[MAX_SUPPORTED_FINGER_NUM];}; struct bt541_ts_data {	struct i2c_client *client;	struct input_dev *input_dev;	struct touchscreen_properties prop;	struct regulator_bulk_data supplies[2];	u32 zinitix_mode;}; static int zinitix_read_data(struct i2c_client *client,			     u16 reg, void *values, size_t length){	__le16 reg_le = cpu_to_le16(reg);	int ret; 	/* A single i2c_transfer() transaction does not work here. */	ret = i2c_master_send(client, (u8 *)&reg_le, sizeof(reg_le));	if (ret != sizeof(reg_le))		return ret < 0 ? ret : -EIO; 	ret = i2c_master_recv(client, (u8 *)values, length);	if (ret != length)		return ret < 0 ? ret : -EIO; 	return 0;} static int zinitix_write_u16(struct i2c_client *client, u16 reg, u16 value){	__le16 packet[2] = {cpu_to_le16(reg), cpu_to_le16(value)};	int ret; 	ret = i2c_master_send(client, (u8 *)packet, sizeof(packet));	if (ret != sizeof(packet))		return ret < 0 ? ret : -EIO; 	return 0;} static int zinitix_write_cmd(struct i2c_client *client, u16 reg){	__le16 reg_le = cpu_to_le16(reg);	int ret; 	ret = i2c_master_send(client, (u8 *)&reg_le, sizeof(reg_le));	if (ret != sizeof(reg_le))		return ret < 0 ? ret : -EIO; 	return 0;} static int zinitix_init_touch(struct bt541_ts_data *bt541){	struct i2c_client *client = bt541->client;	int i;	int error; 	error = zinitix_write_cmd(client, ZINITIX_SWRESET_CMD);	if (error) {		dev_err(&client->dev, "Failed to write reset command\n");		return error;	} 	error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, 0x0);	if (error) {		dev_err(&client->dev,			"Failed to reset interrupt enable flag\n");		return error;	} 	/* initialize */	error = zinitix_write_u16(client, ZINITIX_X_RESOLUTION,				  bt541->prop.max_x);	if (error)		return error; 	error = zinitix_write_u16(client, ZINITIX_Y_RESOLUTION,				  bt541->prop.max_y);	if (error)		return error; 	error = zinitix_write_u16(client, ZINITIX_SUPPORTED_FINGER_NUM,				  MAX_SUPPORTED_FINGER_NUM);	if (error)		return error; 	error = zinitix_write_u16(client, ZINITIX_INITIAL_TOUCH_MODE,				  bt541->zinitix_mode);	if (error)		return error; 	error = zinitix_write_u16(client, ZINITIX_TOUCH_MODE,				  bt541->zinitix_mode);	if (error)		return error; 	error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG,				  BIT_PT_CNT_CHANGE | BIT_DOWN | BIT_MOVE |					BIT_UP);	if (error)		return error; 	/* clear queue */	for (i = 0; i < 10; i++) {		zinitix_write_cmd(client, ZINITIX_CLEAR_INT_STATUS_CMD);		udelay(10);	} 	return 0;} static int zinitix_init_regulators(struct bt541_ts_data *bt541){	struct device *dev = &bt541->client->dev;	int error; 	/*	 * Some older device trees have erroneous names for the regulators,	 * so check if "vddo" is present and in that case use these names.	 * Else use the proper supply names on the component.	 */	if (of_find_property(dev->of_node, "vddo-supply", NULL)) {		bt541->supplies[0].supply = "vdd";		bt541->supplies[1].supply = "vddo";	} else {		/* Else use the proper supply names */		bt541->supplies[0].supply = "vcca";		bt541->supplies[1].supply = "vdd";	}	error = devm_regulator_bulk_get(dev,					ARRAY_SIZE(bt541->supplies),					bt541->supplies);	if (error < 0) {		dev_err(dev, "Failed to get regulators: %d\n", error);		return error;	} 	return 0;} static int zinitix_send_power_on_sequence(struct bt541_ts_data *bt541){	int error;	struct i2c_client *client = bt541->client; 	error = zinitix_write_u16(client, 0xc000, 0x0001);	if (error) {		dev_err(&client->dev,			"Failed to send power sequence(vendor cmd enable)\n");		return error;	}	udelay(10); 	error = zinitix_write_cmd(client, 0xc004);	if (error) {		dev_err(&client->dev,			"Failed to send power sequence (intn clear)\n");		return error;	}	udelay(10); 	error = zinitix_write_u16(client, 0xc002, 0x0001);	if (error) {		dev_err(&client->dev,			"Failed to send power sequence (nvm init)\n");		return error;	}	mdelay(2); 	error = zinitix_write_u16(client, 0xc001, 0x0001);	if (error) {		dev_err(&client->dev,			"Failed to send power sequence (program start)\n");		return error;	}	msleep(FIRMWARE_ON_DELAY); 	return 0;} static void zinitix_report_finger(struct bt541_ts_data *bt541, int slot,				  const struct point_coord *p){	u16 x, y; 	if (unlikely(!(p->sub_status &		       (SUB_BIT_UP | SUB_BIT_DOWN | SUB_BIT_MOVE)))) {		dev_dbg(&bt541->client->dev, "unknown finger event %#02x\n",			p->sub_status);		return;	} 	x = le16_to_cpu(p->x);	y = le16_to_cpu(p->y); 	input_mt_slot(bt541->input_dev, slot);	if (input_mt_report_slot_state(bt541->input_dev, MT_TOOL_FINGER,				       !(p->sub_status & SUB_BIT_UP))) {		touchscreen_report_pos(bt541->input_dev,				       &bt541->prop, x, y, true);		input_report_abs(bt541->input_dev,				 ABS_MT_TOUCH_MAJOR, p->width);		dev_dbg(&bt541->client->dev, "finger %d %s (%u, %u)\n",			slot, p->sub_status & SUB_BIT_DOWN ? "down" : "move",			x, y);	} else {		dev_dbg(&bt541->client->dev, "finger %d up (%u, %u)\n",			slot, x, y);	}} static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler){	struct bt541_ts_data *bt541 = bt541_handler;	struct i2c_client *client = bt541->client;	struct touch_event touch_event;	unsigned long finger_mask;	int error;	int i; 	memset(&touch_event, 0, sizeof(struct touch_event)); 	error = zinitix_read_data(bt541->client, ZINITIX_POINT_STATUS_REG,				  &touch_event, sizeof(struct touch_event));	if (error) {		dev_err(&client->dev, "Failed to read in touchpoint struct\n");		goto out;	} 	finger_mask = touch_event.finger_mask;	for_each_set_bit(i, &finger_mask, MAX_SUPPORTED_FINGER_NUM) {		const struct point_coord *p = &touch_event.point_coord[i]; 		/* Only process contacts that are actually reported */		if (p->sub_status & SUB_BIT_EXIST)			zinitix_report_finger(bt541, i, p);	} 	input_mt_sync_frame(bt541->input_dev);	input_sync(bt541->input_dev); out:	zinitix_write_cmd(bt541->client, ZINITIX_CLEAR_INT_STATUS_CMD);	return IRQ_HANDLED;} static int zinitix_start(struct bt541_ts_data *bt541){	int error; 	error = regulator_bulk_enable(ARRAY_SIZE(bt541->supplies),				      bt541->supplies);	if (error) {		dev_err(&bt541->client->dev,			"Failed to enable regulators: %d\n", error);		return error;	} 	msleep(CHIP_ON_DELAY); 	error = zinitix_send_power_on_sequence(bt541);	if (error) {		dev_err(&bt541->client->dev,			"Error while sending power-on sequence: %d\n", error);		return error;	} 	error = zinitix_init_touch(bt541);	if (error) {		dev_err(&bt541->client->dev,			"Error while configuring touch IC\n");		return error;	} 	enable_irq(bt541->client->irq); 	return 0;} static int zinitix_stop(struct bt541_ts_data *bt541){	int error; 	disable_irq(bt541->client->irq); 	error = regulator_bulk_disable(ARRAY_SIZE(bt541->supplies),				       bt541->supplies);	if (error) {		dev_err(&bt541->client->dev,			"Failed to disable regulators: %d\n", error);		return error;	} 	return 0;} static int zinitix_input_open(struct input_dev *dev){	struct bt541_ts_data *bt541 = input_get_drvdata(dev); 	return zinitix_start(bt541);} static void zinitix_input_close(struct input_dev *dev){	struct bt541_ts_data *bt541 = input_get_drvdata(dev); 	zinitix_stop(bt541);} static int zinitix_init_input_dev(struct bt541_ts_data *bt541){	struct input_dev *input_dev;	int error; 	input_dev = devm_input_allocate_device(&bt541->client->dev);	if (!input_dev) {		dev_err(&bt541->client->dev,			"Failed to allocate input device.");		return -ENOMEM;	} 	input_set_drvdata(input_dev, bt541);	bt541->input_dev = input_dev; 	input_dev->name = "Zinitix Capacitive TouchScreen";	input_dev->phys = "input/ts";	input_dev->id.bustype = BUS_I2C;	input_dev->open = zinitix_input_open;	input_dev->close = zinitix_input_close; 	input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);	input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);	input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); 	touchscreen_parse_properties(input_dev, true, &bt541->prop);	if (!bt541->prop.max_x || !bt541->prop.max_y) {		dev_err(&bt541->client->dev,			"Touchscreen-size-x and/or touchscreen-size-y not set in dts\n");		return -EINVAL;	} 	error = input_mt_init_slots(input_dev, MAX_SUPPORTED_FINGER_NUM,				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);	if (error) {		dev_err(&bt541->client->dev,			"Failed to initialize MT slots: %d", error);		return error;	} 	error = input_register_device(input_dev);	if (error) {		dev_err(&bt541->client->dev,			"Failed to register input device: %d", error);		return error;	} 	return 0;

Lines 1–500 of 631.