Linux Audio

Check our new training course

Embedded Linux training

Mar 10-20, 2025, special US time zones
Register
Loading...
Note: File does not exist in v3.15.
   1/*
   2 * Weida HiTech WDT87xx TouchScreen I2C driver
   3 *
   4 * Copyright (c) 2015  Weida Hi-Tech Co., Ltd.
   5 * HN Chen <hn.chen@weidahitech.com>
   6 *
   7 * This software is licensed under the terms of the GNU General Public
   8 * License, as published by the Free Software Foundation, and
   9 * may be copied, distributed, and modified under those terms.
  10 */
  11
  12#include <linux/i2c.h>
  13#include <linux/input.h>
  14#include <linux/interrupt.h>
  15#include <linux/delay.h>
  16#include <linux/irq.h>
  17#include <linux/io.h>
  18#include <linux/module.h>
  19#include <linux/slab.h>
  20#include <linux/firmware.h>
  21#include <linux/input/mt.h>
  22#include <linux/acpi.h>
  23#include <asm/unaligned.h>
  24
  25#define WDT87XX_NAME		"wdt87xx_i2c"
  26#define WDT87XX_DRV_VER		"0.9.8"
  27#define WDT87XX_FW_NAME		"wdt87xx_fw.bin"
  28#define WDT87XX_CFG_NAME	"wdt87xx_cfg.bin"
  29
  30#define MODE_ACTIVE			0x01
  31#define MODE_READY			0x02
  32#define MODE_IDLE			0x03
  33#define MODE_SLEEP			0x04
  34#define MODE_STOP			0xFF
  35
  36#define WDT_MAX_FINGER			10
  37#define WDT_RAW_BUF_COUNT		54
  38#define WDT_V1_RAW_BUF_COUNT		74
  39#define WDT_FIRMWARE_ID			0xa9e368f5
  40
  41#define PG_SIZE				0x1000
  42#define MAX_RETRIES			3
  43
  44#define MAX_UNIT_AXIS			0x7FFF
  45
  46#define PKT_READ_SIZE			72
  47#define PKT_WRITE_SIZE			80
  48
  49/* the finger definition of the report event */
  50#define FINGER_EV_OFFSET_ID		0
  51#define FINGER_EV_OFFSET_X		1
  52#define FINGER_EV_OFFSET_Y		3
  53#define FINGER_EV_SIZE			5
  54
  55#define FINGER_EV_V1_OFFSET_ID		0
  56#define FINGER_EV_V1_OFFSET_W		1
  57#define FINGER_EV_V1_OFFSET_P		2
  58#define FINGER_EV_V1_OFFSET_X		3
  59#define FINGER_EV_V1_OFFSET_Y		5
  60#define FINGER_EV_V1_SIZE		7
  61
  62/* The definition of a report packet */
  63#define TOUCH_PK_OFFSET_REPORT_ID	0
  64#define TOUCH_PK_OFFSET_EVENT		1
  65#define TOUCH_PK_OFFSET_SCAN_TIME	51
  66#define TOUCH_PK_OFFSET_FNGR_NUM	53
  67
  68#define TOUCH_PK_V1_OFFSET_REPORT_ID	0
  69#define TOUCH_PK_V1_OFFSET_EVENT	1
  70#define TOUCH_PK_V1_OFFSET_SCAN_TIME	71
  71#define TOUCH_PK_V1_OFFSET_FNGR_NUM	73
  72
  73/* The definition of the controller parameters */
  74#define CTL_PARAM_OFFSET_FW_ID		0
  75#define CTL_PARAM_OFFSET_PLAT_ID	2
  76#define CTL_PARAM_OFFSET_XMLS_ID1	4
  77#define CTL_PARAM_OFFSET_XMLS_ID2	6
  78#define CTL_PARAM_OFFSET_PHY_CH_X	8
  79#define CTL_PARAM_OFFSET_PHY_CH_Y	10
  80#define CTL_PARAM_OFFSET_PHY_X0		12
  81#define CTL_PARAM_OFFSET_PHY_X1		14
  82#define CTL_PARAM_OFFSET_PHY_Y0		16
  83#define CTL_PARAM_OFFSET_PHY_Y1		18
  84#define CTL_PARAM_OFFSET_PHY_W		22
  85#define CTL_PARAM_OFFSET_PHY_H		24
  86#define CTL_PARAM_OFFSET_FACTOR		32
  87
  88/* The definition of the device descriptor */
  89#define WDT_GD_DEVICE			1
  90#define DEV_DESC_OFFSET_VID		8
  91#define DEV_DESC_OFFSET_PID		10
  92
  93/* Communication commands */
  94#define PACKET_SIZE			56
  95#define VND_REQ_READ			0x06
  96#define VND_READ_DATA			0x07
  97#define VND_REQ_WRITE			0x08
  98
  99#define VND_CMD_START			0x00
 100#define VND_CMD_STOP			0x01
 101#define VND_CMD_RESET			0x09
 102
 103#define VND_CMD_ERASE			0x1A
 104
 105#define VND_GET_CHECKSUM		0x66
 106
 107#define VND_SET_DATA			0x83
 108#define VND_SET_COMMAND_DATA		0x84
 109#define VND_SET_CHECKSUM_CALC		0x86
 110#define VND_SET_CHECKSUM_LENGTH		0x87
 111
 112#define VND_CMD_SFLCK			0xFC
 113#define VND_CMD_SFUNL			0xFD
 114
 115#define CMD_SFLCK_KEY			0xC39B
 116#define CMD_SFUNL_KEY			0x95DA
 117
 118#define STRIDX_PLATFORM_ID		0x80
 119#define STRIDX_PARAMETERS		0x81
 120
 121#define CMD_BUF_SIZE			8
 122#define PKT_BUF_SIZE			64
 123
 124/* The definition of the command packet */
 125#define CMD_REPORT_ID_OFFSET		0x0
 126#define CMD_TYPE_OFFSET			0x1
 127#define CMD_INDEX_OFFSET		0x2
 128#define CMD_KEY_OFFSET			0x3
 129#define CMD_LENGTH_OFFSET		0x4
 130#define CMD_DATA_OFFSET			0x8
 131
 132/* The definition of firmware chunk tags */
 133#define FOURCC_ID_RIFF			0x46464952
 134#define FOURCC_ID_WHIF			0x46494857
 135#define FOURCC_ID_FRMT			0x544D5246
 136#define FOURCC_ID_FRWR			0x52575246
 137#define FOURCC_ID_CNFG			0x47464E43
 138
 139#define CHUNK_ID_FRMT			FOURCC_ID_FRMT
 140#define CHUNK_ID_FRWR			FOURCC_ID_FRWR
 141#define CHUNK_ID_CNFG			FOURCC_ID_CNFG
 142
 143#define FW_FOURCC1_OFFSET		0
 144#define FW_SIZE_OFFSET			4
 145#define FW_FOURCC2_OFFSET		8
 146#define FW_PAYLOAD_OFFSET		40
 147
 148#define FW_CHUNK_ID_OFFSET		0
 149#define FW_CHUNK_SIZE_OFFSET		4
 150#define FW_CHUNK_TGT_START_OFFSET	8
 151#define FW_CHUNK_PAYLOAD_LEN_OFFSET	12
 152#define FW_CHUNK_SRC_START_OFFSET	16
 153#define FW_CHUNK_VERSION_OFFSET		20
 154#define FW_CHUNK_ATTR_OFFSET		24
 155#define FW_CHUNK_PAYLOAD_OFFSET		32
 156
 157/* Controller requires minimum 300us between commands */
 158#define WDT_COMMAND_DELAY_MS		2
 159#define WDT_FLASH_WRITE_DELAY_MS	4
 160#define WDT_FLASH_ERASE_DELAY_MS	200
 161#define WDT_FW_RESET_TIME		2500
 162
 163struct wdt87xx_sys_param {
 164	u16	fw_id;
 165	u16	plat_id;
 166	u16	xmls_id1;
 167	u16	xmls_id2;
 168	u16	phy_ch_x;
 169	u16	phy_ch_y;
 170	u16	phy_w;
 171	u16	phy_h;
 172	u16	scaling_factor;
 173	u32	max_x;
 174	u32	max_y;
 175	u16	vendor_id;
 176	u16	product_id;
 177};
 178
 179struct wdt87xx_data {
 180	struct i2c_client		*client;
 181	struct input_dev		*input;
 182	/* Mutex for fw update to prevent concurrent access */
 183	struct mutex			fw_mutex;
 184	struct wdt87xx_sys_param	param;
 185	u8				phys[32];
 186};
 187
 188static int wdt87xx_i2c_xfer(struct i2c_client *client,
 189			    void *txdata, size_t txlen,
 190			    void *rxdata, size_t rxlen)
 191{
 192	struct i2c_msg msgs[] = {
 193		{
 194			.addr	= client->addr,
 195			.flags	= 0,
 196			.len	= txlen,
 197			.buf	= txdata,
 198		},
 199		{
 200			.addr	= client->addr,
 201			.flags	= I2C_M_RD,
 202			.len	= rxlen,
 203			.buf	= rxdata,
 204		},
 205	};
 206	int error;
 207	int ret;
 208
 209	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
 210	if (ret != ARRAY_SIZE(msgs)) {
 211		error = ret < 0 ? ret : -EIO;
 212		dev_err(&client->dev, "%s: i2c transfer failed: %d\n",
 213			__func__, error);
 214		return error;
 215	}
 216
 217	return 0;
 218}
 219
 220static int wdt87xx_get_desc(struct i2c_client *client, u8 desc_idx,
 221			    u8 *buf, size_t len)
 222{
 223	u8 tx_buf[] = { 0x22, 0x00, 0x10, 0x0E, 0x23, 0x00 };
 224	int error;
 225
 226	tx_buf[2] |= desc_idx & 0xF;
 227
 228	error = wdt87xx_i2c_xfer(client, tx_buf, sizeof(tx_buf),
 229				 buf, len);
 230	if (error) {
 231		dev_err(&client->dev, "get desc failed: %d\n", error);
 232		return error;
 233	}
 234
 235	if (buf[0] != len) {
 236		dev_err(&client->dev, "unexpected response to get desc: %d\n",
 237			buf[0]);
 238		return -EINVAL;
 239	}
 240
 241	mdelay(WDT_COMMAND_DELAY_MS);
 242
 243	return 0;
 244}
 245
 246static int wdt87xx_get_string(struct i2c_client *client, u8 str_idx,
 247			      u8 *buf, size_t len)
 248{
 249	u8 tx_buf[] = { 0x22, 0x00, 0x13, 0x0E, str_idx, 0x23, 0x00 };
 250	u8 rx_buf[PKT_WRITE_SIZE];
 251	size_t rx_len = len + 2;
 252	int error;
 253
 254	if (rx_len > sizeof(rx_buf))
 255		return -EINVAL;
 256
 257	error = wdt87xx_i2c_xfer(client, tx_buf, sizeof(tx_buf),
 258				 rx_buf, rx_len);
 259	if (error) {
 260		dev_err(&client->dev, "get string failed: %d\n", error);
 261		return error;
 262	}
 263
 264	if (rx_buf[1] != 0x03) {
 265		dev_err(&client->dev, "unexpected response to get string: %d\n",
 266			rx_buf[1]);
 267		return -EINVAL;
 268	}
 269
 270	rx_len = min_t(size_t, len, rx_buf[0]);
 271	memcpy(buf, &rx_buf[2], rx_len);
 272
 273	mdelay(WDT_COMMAND_DELAY_MS);
 274
 275	return 0;
 276}
 277
 278static int wdt87xx_get_feature(struct i2c_client *client,
 279			       u8 *buf, size_t buf_size)
 280{
 281	u8 tx_buf[8];
 282	u8 rx_buf[PKT_WRITE_SIZE];
 283	size_t tx_len = 0;
 284	size_t rx_len = buf_size + 2;
 285	int error;
 286
 287	if (rx_len > sizeof(rx_buf))
 288		return -EINVAL;
 289
 290	/* Get feature command packet */
 291	tx_buf[tx_len++] = 0x22;
 292	tx_buf[tx_len++] = 0x00;
 293	if (buf[CMD_REPORT_ID_OFFSET] > 0xF) {
 294		tx_buf[tx_len++] = 0x30;
 295		tx_buf[tx_len++] = 0x02;
 296		tx_buf[tx_len++] = buf[CMD_REPORT_ID_OFFSET];
 297	} else {
 298		tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
 299		tx_buf[tx_len++] = 0x02;
 300	}
 301	tx_buf[tx_len++] = 0x23;
 302	tx_buf[tx_len++] = 0x00;
 303
 304	error = wdt87xx_i2c_xfer(client, tx_buf, tx_len, rx_buf, rx_len);
 305	if (error) {
 306		dev_err(&client->dev, "get feature failed: %d\n", error);
 307		return error;
 308	}
 309
 310	rx_len = min_t(size_t, buf_size, get_unaligned_le16(rx_buf));
 311	memcpy(buf, &rx_buf[2], rx_len);
 312
 313	mdelay(WDT_COMMAND_DELAY_MS);
 314
 315	return 0;
 316}
 317
 318static int wdt87xx_set_feature(struct i2c_client *client,
 319			       const u8 *buf, size_t buf_size)
 320{
 321	u8 tx_buf[PKT_WRITE_SIZE];
 322	int tx_len = 0;
 323	int error;
 324
 325	/* Set feature command packet */
 326	tx_buf[tx_len++] = 0x22;
 327	tx_buf[tx_len++] = 0x00;
 328	if (buf[CMD_REPORT_ID_OFFSET] > 0xF) {
 329		tx_buf[tx_len++] = 0x30;
 330		tx_buf[tx_len++] = 0x03;
 331		tx_buf[tx_len++] = buf[CMD_REPORT_ID_OFFSET];
 332	} else {
 333		tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
 334		tx_buf[tx_len++] = 0x03;
 335	}
 336	tx_buf[tx_len++] = 0x23;
 337	tx_buf[tx_len++] = 0x00;
 338	tx_buf[tx_len++] = (buf_size & 0xFF);
 339	tx_buf[tx_len++] = ((buf_size & 0xFF00) >> 8);
 340
 341	if (tx_len + buf_size > sizeof(tx_buf))
 342		return -EINVAL;
 343
 344	memcpy(&tx_buf[tx_len], buf, buf_size);
 345	tx_len += buf_size;
 346
 347	error = i2c_master_send(client, tx_buf, tx_len);
 348	if (error < 0) {
 349		dev_err(&client->dev, "set feature failed: %d\n", error);
 350		return error;
 351	}
 352
 353	mdelay(WDT_COMMAND_DELAY_MS);
 354
 355	return 0;
 356}
 357
 358static int wdt87xx_send_command(struct i2c_client *client, int cmd, int value)
 359{
 360	u8 cmd_buf[CMD_BUF_SIZE];
 361
 362	/* Set the command packet */
 363	cmd_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_WRITE;
 364	cmd_buf[CMD_TYPE_OFFSET] = VND_SET_COMMAND_DATA;
 365	put_unaligned_le16((u16)cmd, &cmd_buf[CMD_INDEX_OFFSET]);
 366
 367	switch (cmd) {
 368	case VND_CMD_START:
 369	case VND_CMD_STOP:
 370	case VND_CMD_RESET:
 371		/* Mode selector */
 372		put_unaligned_le32((value & 0xFF), &cmd_buf[CMD_LENGTH_OFFSET]);
 373		break;
 374
 375	case VND_CMD_SFLCK:
 376		put_unaligned_le16(CMD_SFLCK_KEY, &cmd_buf[CMD_KEY_OFFSET]);
 377		break;
 378
 379	case VND_CMD_SFUNL:
 380		put_unaligned_le16(CMD_SFUNL_KEY, &cmd_buf[CMD_KEY_OFFSET]);
 381		break;
 382
 383	case VND_CMD_ERASE:
 384	case VND_SET_CHECKSUM_CALC:
 385	case VND_SET_CHECKSUM_LENGTH:
 386		put_unaligned_le32(value, &cmd_buf[CMD_KEY_OFFSET]);
 387		break;
 388
 389	default:
 390		cmd_buf[CMD_REPORT_ID_OFFSET] = 0;
 391		dev_err(&client->dev, "Invalid command: %d\n", cmd);
 392		return -EINVAL;
 393	}
 394
 395	return wdt87xx_set_feature(client, cmd_buf, sizeof(cmd_buf));
 396}
 397
 398static int wdt87xx_sw_reset(struct i2c_client *client)
 399{
 400	int error;
 401
 402	dev_dbg(&client->dev, "resetting device now\n");
 403
 404	error = wdt87xx_send_command(client, VND_CMD_RESET, 0);
 405	if (error) {
 406		dev_err(&client->dev, "reset failed\n");
 407		return error;
 408	}
 409
 410	/* Wait the device to be ready */
 411	msleep(WDT_FW_RESET_TIME);
 412
 413	return 0;
 414}
 415
 416static const void *wdt87xx_get_fw_chunk(const struct firmware *fw, u32 id)
 417{
 418	size_t pos = FW_PAYLOAD_OFFSET;
 419	u32 chunk_id, chunk_size;
 420
 421	while (pos < fw->size) {
 422		chunk_id = get_unaligned_le32(fw->data +
 423					      pos + FW_CHUNK_ID_OFFSET);
 424		if (chunk_id == id)
 425			return fw->data + pos;
 426
 427		chunk_size = get_unaligned_le32(fw->data +
 428						pos + FW_CHUNK_SIZE_OFFSET);
 429		pos += chunk_size + 2 * sizeof(u32); /* chunk ID + size */
 430	}
 431
 432	return NULL;
 433}
 434
 435static int wdt87xx_get_sysparam(struct i2c_client *client,
 436				struct wdt87xx_sys_param *param)
 437{
 438	u8 buf[PKT_READ_SIZE];
 439	int error;
 440
 441	error = wdt87xx_get_desc(client, WDT_GD_DEVICE, buf, 18);
 442	if (error) {
 443		dev_err(&client->dev, "failed to get device desc\n");
 444		return error;
 445	}
 446
 447	param->vendor_id = get_unaligned_le16(buf + DEV_DESC_OFFSET_VID);
 448	param->product_id = get_unaligned_le16(buf + DEV_DESC_OFFSET_PID);
 449
 450	error = wdt87xx_get_string(client, STRIDX_PARAMETERS, buf, 34);
 451	if (error) {
 452		dev_err(&client->dev, "failed to get parameters\n");
 453		return error;
 454	}
 455
 456	param->xmls_id1 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID1);
 457	param->xmls_id2 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID2);
 458	param->phy_ch_x = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_X);
 459	param->phy_ch_y = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_Y);
 460	param->phy_w = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_W) / 10;
 461	param->phy_h = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_H) / 10;
 462
 463	/* Get the scaling factor of pixel to logical coordinate */
 464	param->scaling_factor =
 465			get_unaligned_le16(buf + CTL_PARAM_OFFSET_FACTOR);
 466
 467	param->max_x = MAX_UNIT_AXIS;
 468	param->max_y = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS * param->phy_h,
 469					 param->phy_w);
 470
 471	error = wdt87xx_get_string(client, STRIDX_PLATFORM_ID, buf, 8);
 472	if (error) {
 473		dev_err(&client->dev, "failed to get platform id\n");
 474		return error;
 475	}
 476
 477	param->plat_id = buf[1];
 478
 479	buf[0] = 0xf2;
 480	error = wdt87xx_get_feature(client, buf, 16);
 481	if (error) {
 482		dev_err(&client->dev, "failed to get firmware id\n");
 483		return error;
 484	}
 485
 486	if (buf[0] != 0xf2) {
 487		dev_err(&client->dev, "wrong id of fw response: 0x%x\n",
 488			buf[0]);
 489		return -EINVAL;
 490	}
 491
 492	param->fw_id = get_unaligned_le16(&buf[1]);
 493
 494	dev_info(&client->dev,
 495		 "fw_id: 0x%x, plat_id: 0x%x, xml_id1: %04x, xml_id2: %04x\n",
 496		 param->fw_id, param->plat_id,
 497		 param->xmls_id1, param->xmls_id2);
 498
 499	return 0;
 500}
 501
 502static int wdt87xx_validate_firmware(struct wdt87xx_data *wdt,
 503				     const struct firmware *fw)
 504{
 505	const void *fw_chunk;
 506	u32 data1, data2;
 507	u32 size;
 508	u8 fw_chip_id;
 509	u8 chip_id;
 510
 511	data1 = get_unaligned_le32(fw->data + FW_FOURCC1_OFFSET);
 512	data2 = get_unaligned_le32(fw->data + FW_FOURCC2_OFFSET);
 513	if (data1 != FOURCC_ID_RIFF || data2 != FOURCC_ID_WHIF) {
 514		dev_err(&wdt->client->dev, "check fw tag failed\n");
 515		return -EINVAL;
 516	}
 517
 518	size = get_unaligned_le32(fw->data + FW_SIZE_OFFSET);
 519	if (size != fw->size) {
 520		dev_err(&wdt->client->dev,
 521			"fw size mismatch: expected %d, actual %zu\n",
 522			size, fw->size);
 523		return -EINVAL;
 524	}
 525
 526	/*
 527	 * Get the chip_id from the firmware. Make sure that it is the
 528	 * right controller to do the firmware and config update.
 529	 */
 530	fw_chunk = wdt87xx_get_fw_chunk(fw, CHUNK_ID_FRWR);
 531	if (!fw_chunk) {
 532		dev_err(&wdt->client->dev,
 533			"unable to locate firmware chunk\n");
 534		return -EINVAL;
 535	}
 536
 537	fw_chip_id = (get_unaligned_le32(fw_chunk +
 538					 FW_CHUNK_VERSION_OFFSET) >> 12) & 0xF;
 539	chip_id = (wdt->param.fw_id >> 12) & 0xF;
 540
 541	if (fw_chip_id != chip_id) {
 542		dev_err(&wdt->client->dev,
 543			"fw version mismatch: fw %d vs. chip %d\n",
 544			fw_chip_id, chip_id);
 545		return -ENODEV;
 546	}
 547
 548	return 0;
 549}
 550
 551static int wdt87xx_validate_fw_chunk(const void *data, int id)
 552{
 553	if (id == CHUNK_ID_FRWR) {
 554		u32 fw_id;
 555
 556		fw_id = get_unaligned_le32(data + FW_CHUNK_PAYLOAD_OFFSET);
 557		if (fw_id != WDT_FIRMWARE_ID)
 558			return -EINVAL;
 559	}
 560
 561	return 0;
 562}
 563
 564static int wdt87xx_write_data(struct i2c_client *client, const char *data,
 565			      u32 address, int length)
 566{
 567	u16 packet_size;
 568	int count = 0;
 569	int error;
 570	u8 pkt_buf[PKT_BUF_SIZE];
 571
 572	/* Address and length should be 4 bytes aligned */
 573	if ((address & 0x3) != 0 || (length & 0x3) != 0) {
 574		dev_err(&client->dev,
 575			"addr & len must be 4 bytes aligned %x, %x\n",
 576			address, length);
 577		return -EINVAL;
 578	}
 579
 580	while (length) {
 581		packet_size = min(length, PACKET_SIZE);
 582
 583		pkt_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_WRITE;
 584		pkt_buf[CMD_TYPE_OFFSET] = VND_SET_DATA;
 585		put_unaligned_le16(packet_size, &pkt_buf[CMD_INDEX_OFFSET]);
 586		put_unaligned_le32(address, &pkt_buf[CMD_LENGTH_OFFSET]);
 587		memcpy(&pkt_buf[CMD_DATA_OFFSET], data, packet_size);
 588
 589		error = wdt87xx_set_feature(client, pkt_buf, sizeof(pkt_buf));
 590		if (error)
 591			return error;
 592
 593		length -= packet_size;
 594		data += packet_size;
 595		address += packet_size;
 596
 597		/* Wait for the controller to finish the write */
 598		mdelay(WDT_FLASH_WRITE_DELAY_MS);
 599
 600		if ((++count % 32) == 0) {
 601			/* Delay for fw to clear watch dog */
 602			msleep(20);
 603		}
 604	}
 605
 606	return 0;
 607}
 608
 609static u16 misr(u16 cur_value, u8 new_value)
 610{
 611	u32 a, b;
 612	u32 bit0;
 613	u32 y;
 614
 615	a = cur_value;
 616	b = new_value;
 617	bit0 = a ^ (b & 1);
 618	bit0 ^= a >> 1;
 619	bit0 ^= a >> 2;
 620	bit0 ^= a >> 4;
 621	bit0 ^= a >> 5;
 622	bit0 ^= a >> 7;
 623	bit0 ^= a >> 11;
 624	bit0 ^= a >> 15;
 625	y = (a << 1) ^ b;
 626	y = (y & ~1) | (bit0 & 1);
 627
 628	return (u16)y;
 629}
 630
 631static u16 wdt87xx_calculate_checksum(const u8 *data, size_t length)
 632{
 633	u16 checksum = 0;
 634	size_t i;
 635
 636	for (i = 0; i < length; i++)
 637		checksum = misr(checksum, data[i]);
 638
 639	return checksum;
 640}
 641
 642static int wdt87xx_get_checksum(struct i2c_client *client, u16 *checksum,
 643				u32 address, int length)
 644{
 645	int error;
 646	int time_delay;
 647	u8 pkt_buf[PKT_BUF_SIZE];
 648	u8 cmd_buf[CMD_BUF_SIZE];
 649
 650	error = wdt87xx_send_command(client, VND_SET_CHECKSUM_LENGTH, length);
 651	if (error) {
 652		dev_err(&client->dev, "failed to set checksum length\n");
 653		return error;
 654	}
 655
 656	error = wdt87xx_send_command(client, VND_SET_CHECKSUM_CALC, address);
 657	if (error) {
 658		dev_err(&client->dev, "failed to set checksum address\n");
 659		return error;
 660	}
 661
 662	/* Wait the operation to complete */
 663	time_delay = DIV_ROUND_UP(length, 1024);
 664	msleep(time_delay * 30);
 665
 666	memset(cmd_buf, 0, sizeof(cmd_buf));
 667	cmd_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_READ;
 668	cmd_buf[CMD_TYPE_OFFSET] = VND_GET_CHECKSUM;
 669	error = wdt87xx_set_feature(client, cmd_buf, sizeof(cmd_buf));
 670	if (error) {
 671		dev_err(&client->dev, "failed to request checksum\n");
 672		return error;
 673	}
 674
 675	memset(pkt_buf, 0, sizeof(pkt_buf));
 676	pkt_buf[CMD_REPORT_ID_OFFSET] = VND_READ_DATA;
 677	error = wdt87xx_get_feature(client, pkt_buf, sizeof(pkt_buf));
 678	if (error) {
 679		dev_err(&client->dev, "failed to read checksum\n");
 680		return error;
 681	}
 682
 683	*checksum = get_unaligned_le16(&pkt_buf[CMD_DATA_OFFSET]);
 684	return 0;
 685}
 686
 687static int wdt87xx_write_firmware(struct i2c_client *client, const void *chunk)
 688{
 689	u32 start_addr = get_unaligned_le32(chunk + FW_CHUNK_TGT_START_OFFSET);
 690	u32 size = get_unaligned_le32(chunk + FW_CHUNK_PAYLOAD_LEN_OFFSET);
 691	const void *data = chunk + FW_CHUNK_PAYLOAD_OFFSET;
 692	int error;
 693	int err1;
 694	int page_size;
 695	int retry = 0;
 696	u16 device_checksum, firmware_checksum;
 697
 698	dev_dbg(&client->dev, "start 4k page program\n");
 699
 700	error = wdt87xx_send_command(client, VND_CMD_STOP, MODE_STOP);
 701	if (error) {
 702		dev_err(&client->dev, "stop report mode failed\n");
 703		return error;
 704	}
 705
 706	error = wdt87xx_send_command(client, VND_CMD_SFUNL, 0);
 707	if (error) {
 708		dev_err(&client->dev, "unlock failed\n");
 709		goto out_enable_reporting;
 710	}
 711
 712	mdelay(10);
 713
 714	while (size) {
 715		dev_dbg(&client->dev, "%s: %x, %x\n", __func__,
 716			start_addr, size);
 717
 718		page_size = min_t(u32, size, PG_SIZE);
 719		size -= page_size;
 720
 721		for (retry = 0; retry < MAX_RETRIES; retry++) {
 722			error = wdt87xx_send_command(client, VND_CMD_ERASE,
 723						     start_addr);
 724			if (error) {
 725				dev_err(&client->dev,
 726					"erase failed at %#08x\n", start_addr);
 727				break;
 728			}
 729
 730			msleep(WDT_FLASH_ERASE_DELAY_MS);
 731
 732			error = wdt87xx_write_data(client, data, start_addr,
 733						   page_size);
 734			if (error) {
 735				dev_err(&client->dev,
 736					"write failed at %#08x (%d bytes)\n",
 737					start_addr, page_size);
 738				break;
 739			}
 740
 741			error = wdt87xx_get_checksum(client, &device_checksum,
 742						     start_addr, page_size);
 743			if (error) {
 744				dev_err(&client->dev,
 745					"failed to retrieve checksum for %#08x (len: %d)\n",
 746					start_addr, page_size);
 747				break;
 748			}
 749
 750			firmware_checksum =
 751				wdt87xx_calculate_checksum(data, page_size);
 752
 753			if (device_checksum == firmware_checksum)
 754				break;
 755
 756			dev_err(&client->dev,
 757				"checksum fail: %d vs %d, retry %d\n",
 758				device_checksum, firmware_checksum, retry);
 759		}
 760
 761		if (retry == MAX_RETRIES) {
 762			dev_err(&client->dev, "page write failed\n");
 763			error = -EIO;
 764			goto out_lock_device;
 765		}
 766
 767		start_addr = start_addr + page_size;
 768		data = data + page_size;
 769	}
 770
 771out_lock_device:
 772	err1 = wdt87xx_send_command(client, VND_CMD_SFLCK, 0);
 773	if (err1)
 774		dev_err(&client->dev, "lock failed\n");
 775
 776	mdelay(10);
 777
 778out_enable_reporting:
 779	err1 = wdt87xx_send_command(client, VND_CMD_START, 0);
 780	if (err1)
 781		dev_err(&client->dev, "start to report failed\n");
 782
 783	return error ? error : err1;
 784}
 785
 786static int wdt87xx_load_chunk(struct i2c_client *client,
 787			      const struct firmware *fw, u32 ck_id)
 788{
 789	const void *chunk;
 790	int error;
 791
 792	chunk = wdt87xx_get_fw_chunk(fw, ck_id);
 793	if (!chunk) {
 794		dev_err(&client->dev, "unable to locate chunk (type %d)\n",
 795			ck_id);
 796		return -EINVAL;
 797	}
 798
 799	error = wdt87xx_validate_fw_chunk(chunk, ck_id);
 800	if (error) {
 801		dev_err(&client->dev, "invalid chunk (type %d): %d\n",
 802			ck_id, error);
 803		return error;
 804	}
 805
 806	error = wdt87xx_write_firmware(client, chunk);
 807	if (error) {
 808		dev_err(&client->dev,
 809			"failed to write fw chunk (type %d): %d\n",
 810			ck_id, error);
 811		return error;
 812	}
 813
 814	return 0;
 815}
 816
 817static int wdt87xx_do_update_firmware(struct i2c_client *client,
 818				      const struct firmware *fw,
 819				      unsigned int chunk_id)
 820{
 821	struct wdt87xx_data *wdt = i2c_get_clientdata(client);
 822	int error;
 823
 824	error = wdt87xx_validate_firmware(wdt, fw);
 825	if (error)
 826		return error;
 827
 828	error = mutex_lock_interruptible(&wdt->fw_mutex);
 829	if (error)
 830		return error;
 831
 832	disable_irq(client->irq);
 833
 834	error = wdt87xx_load_chunk(client, fw, chunk_id);
 835	if (error) {
 836		dev_err(&client->dev,
 837			"firmware load failed (type: %d): %d\n",
 838			chunk_id, error);
 839		goto out;
 840	}
 841
 842	error = wdt87xx_sw_reset(client);
 843	if (error) {
 844		dev_err(&client->dev, "soft reset failed: %d\n", error);
 845		goto out;
 846	}
 847
 848	/* Refresh the parameters */
 849	error = wdt87xx_get_sysparam(client, &wdt->param);
 850	if (error)
 851		dev_err(&client->dev,
 852			"failed to refresh system parameters: %d\n", error);
 853out:
 854	enable_irq(client->irq);
 855	mutex_unlock(&wdt->fw_mutex);
 856
 857	return error ? error : 0;
 858}
 859
 860static int wdt87xx_update_firmware(struct device *dev,
 861				   const char *fw_name, unsigned int chunk_id)
 862{
 863	struct i2c_client *client = to_i2c_client(dev);
 864	const struct firmware *fw;
 865	int error;
 866
 867	error = request_firmware(&fw, fw_name, dev);
 868	if (error) {
 869		dev_err(&client->dev, "unable to retrieve firmware %s: %d\n",
 870			fw_name, error);
 871		return error;
 872	}
 873
 874	error = wdt87xx_do_update_firmware(client, fw, chunk_id);
 875
 876	release_firmware(fw);
 877
 878	return error ? error : 0;
 879}
 880
 881static ssize_t config_csum_show(struct device *dev,
 882				struct device_attribute *attr, char *buf)
 883{
 884	struct i2c_client *client = to_i2c_client(dev);
 885	struct wdt87xx_data *wdt = i2c_get_clientdata(client);
 886	u32 cfg_csum;
 887
 888	cfg_csum = wdt->param.xmls_id1;
 889	cfg_csum = (cfg_csum << 16) | wdt->param.xmls_id2;
 890
 891	return scnprintf(buf, PAGE_SIZE, "%x\n", cfg_csum);
 892}
 893
 894static ssize_t fw_version_show(struct device *dev,
 895			       struct device_attribute *attr, char *buf)
 896{
 897	struct i2c_client *client = to_i2c_client(dev);
 898	struct wdt87xx_data *wdt = i2c_get_clientdata(client);
 899
 900	return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.fw_id);
 901}
 902
 903static ssize_t plat_id_show(struct device *dev,
 904			    struct device_attribute *attr, char *buf)
 905{
 906	struct i2c_client *client = to_i2c_client(dev);
 907	struct wdt87xx_data *wdt = i2c_get_clientdata(client);
 908
 909	return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.plat_id);
 910}
 911
 912static ssize_t update_config_store(struct device *dev,
 913				   struct device_attribute *attr,
 914				   const char *buf, size_t count)
 915{
 916	int error;
 917
 918	error = wdt87xx_update_firmware(dev, WDT87XX_CFG_NAME, CHUNK_ID_CNFG);
 919
 920	return error ? error : count;
 921}
 922
 923static ssize_t update_fw_store(struct device *dev,
 924			       struct device_attribute *attr,
 925			       const char *buf, size_t count)
 926{
 927	int error;
 928
 929	error = wdt87xx_update_firmware(dev, WDT87XX_FW_NAME, CHUNK_ID_FRWR);
 930
 931	return error ? error : count;
 932}
 933
 934static DEVICE_ATTR_RO(config_csum);
 935static DEVICE_ATTR_RO(fw_version);
 936static DEVICE_ATTR_RO(plat_id);
 937static DEVICE_ATTR_WO(update_config);
 938static DEVICE_ATTR_WO(update_fw);
 939
 940static struct attribute *wdt87xx_attrs[] = {
 941	&dev_attr_config_csum.attr,
 942	&dev_attr_fw_version.attr,
 943	&dev_attr_plat_id.attr,
 944	&dev_attr_update_config.attr,
 945	&dev_attr_update_fw.attr,
 946	NULL
 947};
 948
 949static const struct attribute_group wdt87xx_attr_group = {
 950	.attrs = wdt87xx_attrs,
 951};
 952
 953static void wdt87xx_report_contact(struct input_dev *input,
 954				   struct wdt87xx_sys_param *param,
 955				   u8 *buf)
 956{
 957	int finger_id;
 958	u32 x, y, w;
 959	u8 p;
 960
 961	finger_id = (buf[FINGER_EV_V1_OFFSET_ID] >> 3) - 1;
 962	if (finger_id < 0)
 963		return;
 964
 965	/* Check if this is an active contact */
 966	if (!(buf[FINGER_EV_V1_OFFSET_ID] & 0x1))
 967		return;
 968
 969	w = buf[FINGER_EV_V1_OFFSET_W];
 970	w *= param->scaling_factor;
 971
 972	p = buf[FINGER_EV_V1_OFFSET_P];
 973
 974	x = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_X);
 975
 976	y = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_Y);
 977	y = DIV_ROUND_CLOSEST(y * param->phy_h, param->phy_w);
 978
 979	/* Refuse incorrect coordinates */
 980	if (x > param->max_x || y > param->max_y)
 981		return;
 982
 983	dev_dbg(input->dev.parent, "tip on (%d), x(%d), y(%d)\n",
 984		finger_id, x, y);
 985
 986	input_mt_slot(input, finger_id);
 987	input_mt_report_slot_state(input, MT_TOOL_FINGER, 1);
 988	input_report_abs(input, ABS_MT_TOUCH_MAJOR, w);
 989	input_report_abs(input, ABS_MT_PRESSURE, p);
 990	input_report_abs(input, ABS_MT_POSITION_X, x);
 991	input_report_abs(input, ABS_MT_POSITION_Y, y);
 992}
 993
 994static irqreturn_t wdt87xx_ts_interrupt(int irq, void *dev_id)
 995{
 996	struct wdt87xx_data *wdt = dev_id;
 997	struct i2c_client *client = wdt->client;
 998	int i, fingers;
 999	int error;
1000	u8 raw_buf[WDT_V1_RAW_BUF_COUNT] = {0};
1001
1002	error = i2c_master_recv(client, raw_buf, WDT_V1_RAW_BUF_COUNT);
1003	if (error < 0) {
1004		dev_err(&client->dev, "read v1 raw data failed: %d\n", error);
1005		goto irq_exit;
1006	}
1007
1008	fingers = raw_buf[TOUCH_PK_V1_OFFSET_FNGR_NUM];
1009	if (!fingers)
1010		goto irq_exit;
1011
1012	for (i = 0; i < WDT_MAX_FINGER; i++)
1013		wdt87xx_report_contact(wdt->input,
1014				       &wdt->param,
1015				       &raw_buf[TOUCH_PK_V1_OFFSET_EVENT +
1016						i * FINGER_EV_V1_SIZE]);
1017
1018	input_mt_sync_frame(wdt->input);
1019	input_sync(wdt->input);
1020
1021irq_exit:
1022	return IRQ_HANDLED;
1023}
1024
1025static int wdt87xx_ts_create_input_device(struct wdt87xx_data *wdt)
1026{
1027	struct device *dev = &wdt->client->dev;
1028	struct input_dev *input;
1029	unsigned int res = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS, wdt->param.phy_w);
1030	int error;
1031
1032	input = devm_input_allocate_device(dev);
1033	if (!input) {
1034		dev_err(dev, "failed to allocate input device\n");
1035		return -ENOMEM;
1036	}
1037	wdt->input = input;
1038
1039	input->name = "WDT87xx Touchscreen";
1040	input->id.bustype = BUS_I2C;
1041	input->id.vendor = wdt->param.vendor_id;
1042	input->id.product = wdt->param.product_id;
1043	input->phys = wdt->phys;
1044
1045	input_set_abs_params(input, ABS_MT_POSITION_X, 0,
1046			     wdt->param.max_x, 0, 0);
1047	input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
1048			     wdt->param.max_y, 0, 0);
1049	input_abs_set_res(input, ABS_MT_POSITION_X, res);
1050	input_abs_set_res(input, ABS_MT_POSITION_Y, res);
1051
1052	input_set_abs_params(input, ABS_MT_TOUCH_MAJOR,
1053			     0, wdt->param.max_x, 0, 0);
1054	input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xFF, 0, 0);
1055
1056	input_mt_init_slots(input, WDT_MAX_FINGER,
1057			    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
1058
1059	error = input_register_device(input);
1060	if (error) {
1061		dev_err(dev, "failed to register input device: %d\n", error);
1062		return error;
1063	}
1064
1065	return 0;
1066}
1067
1068static int wdt87xx_ts_probe(struct i2c_client *client,
1069			    const struct i2c_device_id *id)
1070{
1071	struct wdt87xx_data *wdt;
1072	int error;
1073
1074	dev_dbg(&client->dev, "adapter=%d, client irq: %d\n",
1075		client->adapter->nr, client->irq);
1076
1077	/* Check if the I2C function is ok in this adaptor */
1078	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
1079		return -ENXIO;
1080
1081	wdt = devm_kzalloc(&client->dev, sizeof(*wdt), GFP_KERNEL);
1082	if (!wdt)
1083		return -ENOMEM;
1084
1085	wdt->client = client;
1086	mutex_init(&wdt->fw_mutex);
1087	i2c_set_clientdata(client, wdt);
1088
1089	snprintf(wdt->phys, sizeof(wdt->phys), "i2c-%u-%04x/input0",
1090		 client->adapter->nr, client->addr);
1091
1092	error = wdt87xx_get_sysparam(client, &wdt->param);
1093	if (error)
1094		return error;
1095
1096	error = wdt87xx_ts_create_input_device(wdt);
1097	if (error)
1098		return error;
1099
1100	error = devm_request_threaded_irq(&client->dev, client->irq,
1101					  NULL, wdt87xx_ts_interrupt,
1102					  IRQF_ONESHOT,
1103					  client->name, wdt);
1104	if (error) {
1105		dev_err(&client->dev, "request irq failed: %d\n", error);
1106		return error;
1107	}
1108
1109	error = sysfs_create_group(&client->dev.kobj, &wdt87xx_attr_group);
1110	if (error) {
1111		dev_err(&client->dev, "create sysfs failed: %d\n", error);
1112		return error;
1113	}
1114
1115	return 0;
1116}
1117
1118static int wdt87xx_ts_remove(struct i2c_client *client)
1119{
1120	sysfs_remove_group(&client->dev.kobj, &wdt87xx_attr_group);
1121
1122	return 0;
1123}
1124
1125static int __maybe_unused wdt87xx_suspend(struct device *dev)
1126{
1127	struct i2c_client *client = to_i2c_client(dev);
1128	int error;
1129
1130	disable_irq(client->irq);
1131
1132	error = wdt87xx_send_command(client, VND_CMD_STOP, MODE_IDLE);
1133	if (error) {
1134		enable_irq(client->irq);
1135		dev_err(&client->dev,
1136			"failed to stop device when suspending: %d\n",
1137			error);
1138		return error;
1139	}
1140
1141	return 0;
1142}
1143
1144static int __maybe_unused wdt87xx_resume(struct device *dev)
1145{
1146	struct i2c_client *client = to_i2c_client(dev);
1147	int error;
1148
1149	/*
1150	 * The chip may have been reset while system is resuming,
1151	 * give it some time to settle.
1152	 */
1153	mdelay(100);
1154
1155	error = wdt87xx_send_command(client, VND_CMD_START, 0);
1156	if (error)
1157		dev_err(&client->dev,
1158			"failed to start device when resuming: %d\n",
1159			error);
1160
1161	enable_irq(client->irq);
1162
1163	return 0;
1164}
1165
1166static SIMPLE_DEV_PM_OPS(wdt87xx_pm_ops, wdt87xx_suspend, wdt87xx_resume);
1167
1168static const struct i2c_device_id wdt87xx_dev_id[] = {
1169	{ WDT87XX_NAME, 0 },
1170	{ }
1171};
1172MODULE_DEVICE_TABLE(i2c, wdt87xx_dev_id);
1173
1174static const struct acpi_device_id wdt87xx_acpi_id[] = {
1175	{ "WDHT0001", 0 },
1176	{ }
1177};
1178MODULE_DEVICE_TABLE(acpi, wdt87xx_acpi_id);
1179
1180static struct i2c_driver wdt87xx_driver = {
1181	.probe		= wdt87xx_ts_probe,
1182	.remove		= wdt87xx_ts_remove,
1183	.id_table	= wdt87xx_dev_id,
1184	.driver	= {
1185		.name	= WDT87XX_NAME,
1186		.pm     = &wdt87xx_pm_ops,
1187		.acpi_match_table = ACPI_PTR(wdt87xx_acpi_id),
1188	},
1189};
1190module_i2c_driver(wdt87xx_driver);
1191
1192MODULE_AUTHOR("HN Chen <hn.chen@weidahitech.com>");
1193MODULE_DESCRIPTION("WeidaHiTech WDT87XX Touchscreen driver");
1194MODULE_VERSION(WDT87XX_DRV_VER);
1195MODULE_LICENSE("GPL");