cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

elan_i2c_smbus.c (13569B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Elan I2C/SMBus Touchpad driver - SMBus interface
      4 *
      5 * Copyright (c) 2013 ELAN Microelectronics Corp.
      6 *
      7 * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
      8 *
      9 * Based on cyapa driver:
     10 * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
     11 * copyright (c) 2011-2012 Google, Inc.
     12 *
     13 * Trademarks are the property of their respective owners.
     14 */
     15
     16#include <linux/delay.h>
     17#include <linux/i2c.h>
     18#include <linux/init.h>
     19#include <linux/kernel.h>
     20
     21#include "elan_i2c.h"
     22
     23/* Elan SMbus commands */
     24#define ETP_SMBUS_IAP_CMD		0x00
     25#define ETP_SMBUS_ENABLE_TP		0x20
     26#define ETP_SMBUS_SLEEP_CMD		0x21
     27#define ETP_SMBUS_IAP_PASSWORD_WRITE	0x29
     28#define ETP_SMBUS_IAP_PASSWORD_READ	0x80
     29#define ETP_SMBUS_WRITE_FW_BLOCK	0x2A
     30#define ETP_SMBUS_IAP_RESET_CMD		0x2B
     31#define ETP_SMBUS_RANGE_CMD		0xA0
     32#define ETP_SMBUS_FW_VERSION_CMD	0xA1
     33#define ETP_SMBUS_XY_TRACENUM_CMD	0xA2
     34#define ETP_SMBUS_SM_VERSION_CMD	0xA3
     35#define ETP_SMBUS_UNIQUEID_CMD		0xA3
     36#define ETP_SMBUS_RESOLUTION_CMD	0xA4
     37#define ETP_SMBUS_HELLOPACKET_CMD	0xA7
     38#define ETP_SMBUS_PACKET_QUERY		0xA8
     39#define ETP_SMBUS_IAP_VERSION_CMD	0xAC
     40#define ETP_SMBUS_IAP_CTRL_CMD		0xAD
     41#define ETP_SMBUS_IAP_CHECKSUM_CMD	0xAE
     42#define ETP_SMBUS_FW_CHECKSUM_CMD	0xAF
     43#define ETP_SMBUS_MAX_BASELINE_CMD	0xC3
     44#define ETP_SMBUS_MIN_BASELINE_CMD	0xC4
     45#define ETP_SMBUS_CALIBRATE_QUERY	0xC5
     46
     47#define ETP_SMBUS_REPORT_LEN		32
     48#define ETP_SMBUS_REPORT_LEN2		7
     49#define ETP_SMBUS_REPORT_OFFSET		2
     50#define ETP_SMBUS_HELLOPACKET_LEN	5
     51#define ETP_SMBUS_IAP_PASSWORD		0x1234
     52#define ETP_SMBUS_IAP_MODE_ON		(1 << 6)
     53
     54static int elan_smbus_initialize(struct i2c_client *client)
     55{
     56	u8 check[ETP_SMBUS_HELLOPACKET_LEN] = { 0x55, 0x55, 0x55, 0x55, 0x55 };
     57	u8 values[I2C_SMBUS_BLOCK_MAX] = {0};
     58	int len, error;
     59
     60	/* Get hello packet */
     61	len = i2c_smbus_read_block_data(client,
     62					ETP_SMBUS_HELLOPACKET_CMD, values);
     63	if (len != ETP_SMBUS_HELLOPACKET_LEN) {
     64		dev_err(&client->dev, "hello packet length fail: %d\n", len);
     65		error = len < 0 ? len : -EIO;
     66		return error;
     67	}
     68
     69	/* compare hello packet */
     70	if (memcmp(values, check, ETP_SMBUS_HELLOPACKET_LEN)) {
     71		dev_err(&client->dev, "hello packet fail [%*ph]\n",
     72			ETP_SMBUS_HELLOPACKET_LEN, values);
     73		return -ENXIO;
     74	}
     75
     76	/* enable tp */
     77	error = i2c_smbus_write_byte(client, ETP_SMBUS_ENABLE_TP);
     78	if (error) {
     79		dev_err(&client->dev, "failed to enable touchpad: %d\n", error);
     80		return error;
     81	}
     82
     83	return 0;
     84}
     85
     86static int elan_smbus_set_mode(struct i2c_client *client, u8 mode)
     87{
     88	u8 cmd[4] = { 0x00, 0x07, 0x00, mode };
     89
     90	return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
     91					  sizeof(cmd), cmd);
     92}
     93
     94static int elan_smbus_sleep_control(struct i2c_client *client, bool sleep)
     95{
     96	if (sleep)
     97		return i2c_smbus_write_byte(client, ETP_SMBUS_SLEEP_CMD);
     98	else
     99		return 0; /* XXX should we send ETP_SMBUS_ENABLE_TP here? */
    100}
    101
    102static int elan_smbus_power_control(struct i2c_client *client, bool enable)
    103{
    104	return 0; /* A no-op */
    105}
    106
    107static int elan_smbus_calibrate(struct i2c_client *client)
    108{
    109	u8 cmd[4] = { 0x00, 0x08, 0x00, 0x01 };
    110
    111	return i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
    112					  sizeof(cmd), cmd);
    113}
    114
    115static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val)
    116{
    117	int error;
    118	u8 buf[I2C_SMBUS_BLOCK_MAX] = {0};
    119
    120	BUILD_BUG_ON(ETP_CALIBRATE_MAX_LEN > sizeof(buf));
    121
    122	error = i2c_smbus_read_block_data(client,
    123					  ETP_SMBUS_CALIBRATE_QUERY, buf);
    124	if (error < 0)
    125		return error;
    126
    127	memcpy(val, buf, ETP_CALIBRATE_MAX_LEN);
    128	return 0;
    129}
    130
    131static int elan_smbus_get_baseline_data(struct i2c_client *client,
    132					bool max_baseline, u8 *value)
    133{
    134	int error;
    135	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
    136
    137	error = i2c_smbus_read_block_data(client,
    138					  max_baseline ?
    139						ETP_SMBUS_MAX_BASELINE_CMD :
    140						ETP_SMBUS_MIN_BASELINE_CMD,
    141					  val);
    142	if (error < 0)
    143		return error;
    144
    145	*value = be16_to_cpup((__be16 *)val);
    146
    147	return 0;
    148}
    149
    150static int elan_smbus_get_version(struct i2c_client *client,
    151				  u8 pattern, bool iap, u8 *version)
    152{
    153	int error;
    154	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
    155
    156	error = i2c_smbus_read_block_data(client,
    157					  iap ? ETP_SMBUS_IAP_VERSION_CMD :
    158						ETP_SMBUS_FW_VERSION_CMD,
    159					  val);
    160	if (error < 0) {
    161		dev_err(&client->dev, "failed to get %s version: %d\n",
    162			iap ? "IAP" : "FW", error);
    163		return error;
    164	}
    165
    166	*version = val[2];
    167	return 0;
    168}
    169
    170static int elan_smbus_get_sm_version(struct i2c_client *client, u8 pattern,
    171				     u16 *ic_type, u8 *version, u8 *clickpad)
    172{
    173	int error;
    174	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
    175
    176	error = i2c_smbus_read_block_data(client,
    177					  ETP_SMBUS_SM_VERSION_CMD, val);
    178	if (error < 0) {
    179		dev_err(&client->dev, "failed to get SM version: %d\n", error);
    180		return error;
    181	}
    182
    183	*version = val[0];
    184	*ic_type = val[1];
    185	*clickpad = val[0] & 0x10;
    186	return 0;
    187}
    188
    189static int elan_smbus_get_product_id(struct i2c_client *client, u16 *id)
    190{
    191	int error;
    192	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
    193
    194	error = i2c_smbus_read_block_data(client,
    195					  ETP_SMBUS_UNIQUEID_CMD, val);
    196	if (error < 0) {
    197		dev_err(&client->dev, "failed to get product ID: %d\n", error);
    198		return error;
    199	}
    200
    201	*id = be16_to_cpup((__be16 *)val);
    202	return 0;
    203}
    204
    205static int elan_smbus_get_checksum(struct i2c_client *client,
    206				   bool iap, u16 *csum)
    207{
    208	int error;
    209	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
    210
    211	error = i2c_smbus_read_block_data(client,
    212					  iap ? ETP_SMBUS_FW_CHECKSUM_CMD :
    213						ETP_SMBUS_IAP_CHECKSUM_CMD,
    214					  val);
    215	if (error < 0) {
    216		dev_err(&client->dev, "failed to get %s checksum: %d\n",
    217			iap ? "IAP" : "FW", error);
    218		return error;
    219	}
    220
    221	*csum = be16_to_cpup((__be16 *)val);
    222	return 0;
    223}
    224
    225static int elan_smbus_get_max(struct i2c_client *client,
    226			      unsigned int *max_x, unsigned int *max_y)
    227{
    228	int ret;
    229	int error;
    230	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
    231
    232	ret = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val);
    233	if (ret != 3) {
    234		error = ret < 0 ? ret : -EIO;
    235		dev_err(&client->dev, "failed to get dimensions: %d\n", error);
    236		return error;
    237	}
    238
    239	*max_x = (0x0f & val[0]) << 8 | val[1];
    240	*max_y = (0xf0 & val[0]) << 4 | val[2];
    241
    242	return 0;
    243}
    244
    245static int elan_smbus_get_resolution(struct i2c_client *client,
    246				     u8 *hw_res_x, u8 *hw_res_y)
    247{
    248	int ret;
    249	int error;
    250	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
    251
    252	ret = i2c_smbus_read_block_data(client, ETP_SMBUS_RESOLUTION_CMD, val);
    253	if (ret != 3) {
    254		error = ret < 0 ? ret : -EIO;
    255		dev_err(&client->dev, "failed to get resolution: %d\n", error);
    256		return error;
    257	}
    258
    259	*hw_res_x = val[1] & 0x0F;
    260	*hw_res_y = (val[1] & 0xF0) >> 4;
    261
    262	return 0;
    263}
    264
    265static int elan_smbus_get_num_traces(struct i2c_client *client,
    266				     unsigned int *x_traces,
    267				     unsigned int *y_traces)
    268{
    269	int ret;
    270	int error;
    271	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
    272
    273	ret = i2c_smbus_read_block_data(client, ETP_SMBUS_XY_TRACENUM_CMD, val);
    274	if (ret != 3) {
    275		error = ret < 0 ? ret : -EIO;
    276		dev_err(&client->dev, "failed to get trace info: %d\n", error);
    277		return error;
    278	}
    279
    280	*x_traces = val[1];
    281	*y_traces = val[2];
    282
    283	return 0;
    284}
    285
    286static int elan_smbus_get_pressure_adjustment(struct i2c_client *client,
    287					      int *adjustment)
    288{
    289	*adjustment = ETP_PRESSURE_OFFSET;
    290	return 0;
    291}
    292
    293static int elan_smbus_iap_get_mode(struct i2c_client *client,
    294				   enum tp_mode *mode)
    295{
    296	int error;
    297	u16 constant;
    298	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
    299
    300	error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val);
    301	if (error < 0) {
    302		dev_err(&client->dev, "failed to read iap ctrol register: %d\n",
    303			error);
    304		return error;
    305	}
    306
    307	constant = be16_to_cpup((__be16 *)val);
    308	dev_dbg(&client->dev, "iap control reg: 0x%04x.\n", constant);
    309
    310	*mode = (constant & ETP_SMBUS_IAP_MODE_ON) ? IAP_MODE : MAIN_MODE;
    311
    312	return 0;
    313}
    314
    315static int elan_smbus_iap_reset(struct i2c_client *client)
    316{
    317	int error;
    318
    319	error = i2c_smbus_write_byte(client, ETP_SMBUS_IAP_RESET_CMD);
    320	if (error) {
    321		dev_err(&client->dev, "cannot reset IC: %d\n", error);
    322		return error;
    323	}
    324
    325	return 0;
    326}
    327
    328static int elan_smbus_set_flash_key(struct i2c_client *client)
    329{
    330	int error;
    331	u8 cmd[4] = { 0x00, 0x0B, 0x00, 0x5A };
    332
    333	error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
    334					   sizeof(cmd), cmd);
    335	if (error) {
    336		dev_err(&client->dev, "cannot set flash key: %d\n", error);
    337		return error;
    338	}
    339
    340	return 0;
    341}
    342
    343static int elan_smbus_prepare_fw_update(struct i2c_client *client, u16 ic_type,
    344					u8 iap_version, u16 fw_page_size)
    345{
    346	struct device *dev = &client->dev;
    347	int len;
    348	int error;
    349	enum tp_mode mode;
    350	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
    351	u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06};
    352	u16 password;
    353
    354	/* Get FW in which mode	(IAP_MODE/MAIN_MODE)  */
    355	error = elan_smbus_iap_get_mode(client, &mode);
    356	if (error)
    357		return error;
    358
    359	if (mode == MAIN_MODE) {
    360
    361		/* set flash key */
    362		error = elan_smbus_set_flash_key(client);
    363		if (error)
    364			return error;
    365
    366		/* write iap password */
    367		if (i2c_smbus_write_byte(client,
    368					 ETP_SMBUS_IAP_PASSWORD_WRITE) < 0) {
    369			dev_err(dev, "cannot write iap password\n");
    370			return -EIO;
    371		}
    372
    373		error = i2c_smbus_write_block_data(client, ETP_SMBUS_IAP_CMD,
    374						   sizeof(cmd), cmd);
    375		if (error) {
    376			dev_err(dev, "failed to write iap password: %d\n",
    377				error);
    378			return error;
    379		}
    380
    381		/*
    382		 * Read back password to make sure we enabled flash
    383		 * successfully.
    384		 */
    385		len = i2c_smbus_read_block_data(client,
    386						ETP_SMBUS_IAP_PASSWORD_READ,
    387						val);
    388		if (len < (int)sizeof(u16)) {
    389			error = len < 0 ? len : -EIO;
    390			dev_err(dev, "failed to read iap password: %d\n",
    391				error);
    392			return error;
    393		}
    394
    395		password = be16_to_cpup((__be16 *)val);
    396		if (password != ETP_SMBUS_IAP_PASSWORD) {
    397			dev_err(dev, "wrong iap password = 0x%X\n", password);
    398			return -EIO;
    399		}
    400
    401		/* Wait 30ms for MAIN_MODE change to IAP_MODE */
    402		msleep(30);
    403	}
    404
    405	error = elan_smbus_set_flash_key(client);
    406	if (error)
    407		return error;
    408
    409	/* Reset IC */
    410	error = elan_smbus_iap_reset(client);
    411	if (error)
    412		return error;
    413
    414	return 0;
    415}
    416
    417
    418static int elan_smbus_write_fw_block(struct i2c_client *client, u16 fw_page_size,
    419				     const u8 *page, u16 checksum, int idx)
    420{
    421	struct device *dev = &client->dev;
    422	int error;
    423	u16 result;
    424	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
    425
    426	/*
    427	 * Due to the limitation of smbus protocol limiting
    428	 * transfer to 32 bytes at a time, we must split block
    429	 * in 2 transfers.
    430	 */
    431	error = i2c_smbus_write_block_data(client,
    432					   ETP_SMBUS_WRITE_FW_BLOCK,
    433					   fw_page_size / 2,
    434					   page);
    435	if (error) {
    436		dev_err(dev, "Failed to write page %d (part %d): %d\n",
    437			idx, 1, error);
    438		return error;
    439	}
    440
    441	error = i2c_smbus_write_block_data(client,
    442					   ETP_SMBUS_WRITE_FW_BLOCK,
    443					   fw_page_size / 2,
    444					   page + fw_page_size / 2);
    445	if (error) {
    446		dev_err(dev, "Failed to write page %d (part %d): %d\n",
    447			idx, 2, error);
    448		return error;
    449	}
    450
    451
    452	/* Wait for F/W to update one page ROM data. */
    453	usleep_range(8000, 10000);
    454
    455	error = i2c_smbus_read_block_data(client,
    456					  ETP_SMBUS_IAP_CTRL_CMD, val);
    457	if (error < 0) {
    458		dev_err(dev, "Failed to read IAP write result: %d\n",
    459			error);
    460		return error;
    461	}
    462
    463	result = be16_to_cpup((__be16 *)val);
    464	if (result & (ETP_FW_IAP_PAGE_ERR | ETP_FW_IAP_INTF_ERR)) {
    465		dev_err(dev, "IAP reports failed write: %04hx\n",
    466			result);
    467		return -EIO;
    468	}
    469
    470	return 0;
    471}
    472
    473static int elan_smbus_get_report_features(struct i2c_client *client, u8 pattern,
    474					  unsigned int *features,
    475					  unsigned int *report_len)
    476{
    477	/*
    478	 * SMBus controllers with pattern 2 lack area info, as newer
    479	 * high-precision packets use that space for coordinates.
    480	 */
    481	*features = pattern <= 0x01 ? ETP_FEATURE_REPORT_MK : 0;
    482	*report_len = ETP_SMBUS_REPORT_LEN;
    483	return 0;
    484}
    485
    486static int elan_smbus_get_report(struct i2c_client *client,
    487				 u8 *report, unsigned int report_len)
    488{
    489	int len;
    490
    491	BUILD_BUG_ON(I2C_SMBUS_BLOCK_MAX > ETP_SMBUS_REPORT_LEN);
    492
    493	len = i2c_smbus_read_block_data(client,
    494					ETP_SMBUS_PACKET_QUERY,
    495					&report[ETP_SMBUS_REPORT_OFFSET]);
    496	if (len < 0) {
    497		dev_err(&client->dev, "failed to read report data: %d\n", len);
    498		return len;
    499	}
    500
    501	if (report[ETP_REPORT_ID_OFFSET] == ETP_TP_REPORT_ID2)
    502		report_len = ETP_SMBUS_REPORT_LEN2;
    503
    504	if (len != report_len) {
    505		dev_err(&client->dev,
    506			"wrong report length (%d vs %d expected)\n",
    507			len, report_len);
    508		return -EIO;
    509	}
    510
    511	return 0;
    512}
    513
    514static int elan_smbus_finish_fw_update(struct i2c_client *client,
    515				       struct completion *fw_completion)
    516{
    517	/* No special handling unlike I2C transport */
    518	return 0;
    519}
    520
    521static int elan_smbus_get_pattern(struct i2c_client *client, u8 *pattern)
    522{
    523	*pattern = 0;
    524	return 0;
    525}
    526
    527const struct elan_transport_ops elan_smbus_ops = {
    528	.initialize		= elan_smbus_initialize,
    529	.sleep_control		= elan_smbus_sleep_control,
    530	.power_control		= elan_smbus_power_control,
    531	.set_mode		= elan_smbus_set_mode,
    532
    533	.calibrate		= elan_smbus_calibrate,
    534	.calibrate_result	= elan_smbus_calibrate_result,
    535
    536	.get_baseline_data	= elan_smbus_get_baseline_data,
    537
    538	.get_version		= elan_smbus_get_version,
    539	.get_sm_version		= elan_smbus_get_sm_version,
    540	.get_product_id		= elan_smbus_get_product_id,
    541	.get_checksum		= elan_smbus_get_checksum,
    542	.get_pressure_adjustment = elan_smbus_get_pressure_adjustment,
    543
    544	.get_max		= elan_smbus_get_max,
    545	.get_resolution		= elan_smbus_get_resolution,
    546	.get_num_traces		= elan_smbus_get_num_traces,
    547
    548	.iap_get_mode		= elan_smbus_iap_get_mode,
    549	.iap_reset		= elan_smbus_iap_reset,
    550
    551	.prepare_fw_update	= elan_smbus_prepare_fw_update,
    552	.write_fw_block		= elan_smbus_write_fw_block,
    553	.finish_fw_update	= elan_smbus_finish_fw_update,
    554
    555	.get_report_features	= elan_smbus_get_report_features,
    556	.get_report		= elan_smbus_get_report,
    557	.get_pattern		= elan_smbus_get_pattern,
    558};