Commit 918e2844 authored by Michał Mirosław's avatar Michał Mirosław Committed by Dmitry Torokhov
Browse files

Input: elants - refactor elants_i2c_execute_command()



Apply some DRY-ing to elants_i2c_execute_command() callers.  This pulls
polling and error printk()s into a single function.

Signed-off-by: default avatarMichał Mirosław <mirq-linux@rere.qmqm.pl>
Link: https://lore.kernel.org/r/6c576f688b385235c65b461410a917080d27e825.1587923061.git.mirq-linux@rere.qmqm.pl


Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 68334dba
Loading
Loading
Loading
Loading
+99 −101
Original line number Diff line number Diff line
@@ -192,7 +192,8 @@ static int elants_i2c_read(struct i2c_client *client, void *data, size_t size)

static int elants_i2c_execute_command(struct i2c_client *client,
				      const u8 *cmd, size_t cmd_size,
				      u8 *resp, size_t resp_size)
				      u8 *resp, size_t resp_size,
				      int retries, const char *cmd_name)
{
	struct i2c_msg msgs[2];
	int ret;
@@ -212,31 +213,56 @@ static int elants_i2c_execute_command(struct i2c_client *client,
		break;

	default:
		dev_err(&client->dev, "%s: invalid command %*ph\n",
			__func__, (int)cmd_size, cmd);
		dev_err(&client->dev, "(%s): invalid command: %*ph\n",
			cmd_name, (int)cmd_size, cmd);
		return -EINVAL;
	}

	for (;;) {
		msgs[0].addr = client->addr;
		msgs[0].flags = client->flags & I2C_M_TEN;
		msgs[0].len = cmd_size;
		msgs[0].buf = (u8 *)cmd;

		msgs[1].addr = client->addr;
	msgs[1].flags = client->flags & I2C_M_TEN;
		msgs[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
		msgs[1].flags |= I2C_M_RD;
		msgs[1].len = resp_size;
		msgs[1].buf = resp;

		ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
	if (ret < 0)
		if (ret < 0) {
			if (--retries > 0) {
				dev_dbg(&client->dev,
					"(%s) I2C transfer failed: %pe (retrying)\n",
					cmd_name, ERR_PTR(ret));
				continue;
			}

			dev_err(&client->dev,
				"(%s) I2C transfer failed: %pe\n",
				cmd_name, ERR_PTR(ret));
			return ret;
		}

		if (ret != ARRAY_SIZE(msgs) ||
		    resp[FW_HDR_TYPE] != expected_response) {
			if (--retries > 0) {
				dev_dbg(&client->dev,
					"(%s) unexpected response: %*ph (retrying)\n",
					cmd_name, ret, resp);
				continue;
			}

	if (ret != ARRAY_SIZE(msgs) || resp[FW_HDR_TYPE] != expected_response)
			dev_err(&client->dev,
				"(%s) unexpected response: %*ph\n",
				cmd_name, ret, resp);
			return -EIO;
		}

		return 0;
	}
}

static int elants_i2c_calibrate(struct elants_data *ts)
{
@@ -308,29 +334,23 @@ static u16 elants_i2c_parse_version(u8 *buf)
static int elants_i2c_query_hw_version(struct elants_data *ts)
{
	struct i2c_client *client = ts->client;
	int error, retry_cnt;
	int retry_cnt = MAX_RETRIES;
	const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_ID, 0x00, 0x01 };
	u8 resp[HEADER_SIZE];
	int error;

	for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
	while (retry_cnt--) {
		error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
						   resp, sizeof(resp));
		if (!error) {
						   resp, sizeof(resp), 1,
						   "read fw id");
		if (error)
			return error;

		ts->hw_version = elants_i2c_parse_version(resp);
		if (ts->hw_version != 0xffff)
			return 0;
	}

		dev_dbg(&client->dev, "read fw id error=%d, buf=%*phC\n",
			error, (int)sizeof(resp), resp);
	}

	if (error) {
		dev_err(&client->dev,
			"Failed to read fw id: %d\n", error);
		return error;
	}

	dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version);

	return -EINVAL;
@@ -339,26 +359,27 @@ static int elants_i2c_query_hw_version(struct elants_data *ts)
static int elants_i2c_query_fw_version(struct elants_data *ts)
{
	struct i2c_client *client = ts->client;
	int error, retry_cnt;
	int retry_cnt = MAX_RETRIES;
	const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_VER, 0x00, 0x01 };
	u8 resp[HEADER_SIZE];
	int error;

	for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
	while (retry_cnt--) {
		error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
						   resp, sizeof(resp));
		if (!error) {
						   resp, sizeof(resp), 1,
						   "read fw version");
		if (error)
			return error;

		ts->fw_version = elants_i2c_parse_version(resp);
			if (ts->fw_version != 0x0000 &&
			    ts->fw_version != 0xffff)
		if (ts->fw_version != 0x0000 && ts->fw_version != 0xffff)
			return 0;
		}

		dev_dbg(&client->dev, "read fw version error=%d, buf=%*phC\n",
			error, (int)sizeof(resp), resp);
		dev_dbg(&client->dev, "(read fw version) resp %*phC\n",
			(int)sizeof(resp), resp);
	}

	dev_err(&client->dev,
		"Failed to read fw version or fw version is invalid\n");
	dev_err(&client->dev, "Invalid fw ver: %#04x\n", ts->fw_version);

	return -EINVAL;
}
@@ -366,15 +387,19 @@ static int elants_i2c_query_fw_version(struct elants_data *ts)
static int elants_i2c_query_test_version(struct elants_data *ts)
{
	struct i2c_client *client = ts->client;
	int error, retry_cnt;
	int error;
	u16 version;
	const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_TEST_VER, 0x00, 0x01 };
	u8 resp[HEADER_SIZE];

	for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
	error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
						   resp, sizeof(resp));
		if (!error) {
					   resp, sizeof(resp), MAX_RETRIES,
					   "read test version");
	if (error) {
		dev_err(&client->dev, "Failed to read test version\n");
		return error;
	}

	version = elants_i2c_parse_version(resp);
	ts->test_version = version >> 8;
	ts->solution_version = version & 0xff;
@@ -382,16 +407,6 @@ static int elants_i2c_query_test_version(struct elants_data *ts)
	return 0;
}

		dev_dbg(&client->dev,
			"read test version error rc=%d, buf=%*phC\n",
			error, (int)sizeof(resp), resp);
	}

	dev_err(&client->dev, "Failed to read test version\n");

	return -EINVAL;
}

static int elants_i2c_query_bc_version(struct elants_data *ts)
{
	struct i2c_client *client = ts->client;
@@ -401,13 +416,10 @@ static int elants_i2c_query_bc_version(struct elants_data *ts)
	int error;

	error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
					   resp, sizeof(resp));
	if (error) {
		dev_err(&client->dev,
			"read BC version error=%d, buf=%*phC\n",
			error, (int)sizeof(resp), resp);
					   resp, sizeof(resp), 1,
					   "read BC version");
	if (error)
		return error;
	}

	version = elants_i2c_parse_version(resp);
	ts->bc_version = version >> 8;
@@ -439,12 +451,10 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
	error = elants_i2c_execute_command(client,
					   get_resolution_cmd,
					   sizeof(get_resolution_cmd),
					   resp, sizeof(resp));
	if (error) {
		dev_err(&client->dev, "get resolution command failed: %d\n",
			error);
					   resp, sizeof(resp), 1,
					   "get resolution");
	if (error)
		return error;
	}

	rows = resp[2] + resp[6] + resp[10];
	cols = resp[3] + resp[7] + resp[11];
@@ -452,36 +462,29 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
	/* Process mm_to_pixel information */
	error = elants_i2c_execute_command(client,
					   get_osr_cmd, sizeof(get_osr_cmd),
					   resp, sizeof(resp));
	if (error) {
		dev_err(&client->dev, "get osr command failed: %d\n",
			error);
					   resp, sizeof(resp), 1, "get osr");
	if (error)
		return error;
	}

	osr = resp[3];

	error = elants_i2c_execute_command(client,
					   get_physical_scan_cmd,
					   sizeof(get_physical_scan_cmd),
					   resp, sizeof(resp));
	if (error) {
		dev_err(&client->dev, "get physical scan command failed: %d\n",
			error);
					   resp, sizeof(resp), 1,
					   "get physical scan");
	if (error)
		return error;
	}

	phy_x = get_unaligned_be16(&resp[2]);

	error = elants_i2c_execute_command(client,
					   get_physical_drive_cmd,
					   sizeof(get_physical_drive_cmd),
					   resp, sizeof(resp));
	if (error) {
		dev_err(&client->dev, "get physical drive command failed: %d\n",
			error);
					   resp, sizeof(resp), 1,
					   "get physical drive");
	if (error)
		return error;
	}

	phy_y = get_unaligned_be16(&resp[2]);

@@ -636,11 +639,10 @@ static int elants_i2c_validate_remark_id(struct elants_data *ts,

	/* Compare TS Remark ID and FW Remark ID */
	error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
					resp, sizeof(resp));
	if (error) {
		dev_err(&client->dev, "failed to query Remark ID: %d\n", error);
					   resp, sizeof(resp),
					   1, "read Remark ID");
	if (error)
		return error;
	}

	ts_remark_id = get_unaligned_be16(&resp[3]);

@@ -1075,16 +1077,12 @@ static ssize_t show_calibration_count(struct device *dev,
	int error;

	error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
						resp, sizeof(resp));
	if (error) {
		dev_err(&client->dev,
			"read ReK status error=%d, buf=%*phC\n",
			error, (int)sizeof(resp), resp);
					   resp, sizeof(resp), 1,
					   "read ReK status");
	if (error)
		return sprintf(buf, "%d\n", error);
	}

	rek_count = get_unaligned_be16(&resp[2]);

	return sprintf(buf, "0x%04x\n", rek_count);
}