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

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.plSigned-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 68334dba
...@@ -192,7 +192,8 @@ static int elants_i2c_read(struct i2c_client *client, void *data, size_t size) ...@@ -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, static int elants_i2c_execute_command(struct i2c_client *client,
const u8 *cmd, size_t cmd_size, 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]; struct i2c_msg msgs[2];
int ret; int ret;
...@@ -212,30 +213,55 @@ static int elants_i2c_execute_command(struct i2c_client *client, ...@@ -212,30 +213,55 @@ static int elants_i2c_execute_command(struct i2c_client *client,
break; break;
default: default:
dev_err(&client->dev, "%s: invalid command %*ph\n", dev_err(&client->dev, "(%s): invalid command: %*ph\n",
__func__, (int)cmd_size, cmd); cmd_name, (int)cmd_size, cmd);
return -EINVAL; return -EINVAL;
} }
msgs[0].addr = client->addr; for (;;) {
msgs[0].flags = client->flags & I2C_M_TEN; msgs[0].addr = client->addr;
msgs[0].len = cmd_size; msgs[0].flags = client->flags & I2C_M_TEN;
msgs[0].buf = (u8 *)cmd; msgs[0].len = cmd_size;
msgs[0].buf = (u8 *)cmd;
msgs[1].addr = client->addr;
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 (--retries > 0) {
dev_dbg(&client->dev,
"(%s) I2C transfer failed: %pe (retrying)\n",
cmd_name, ERR_PTR(ret));
continue;
}
msgs[1].addr = client->addr; dev_err(&client->dev,
msgs[1].flags = client->flags & I2C_M_TEN; "(%s) I2C transfer failed: %pe\n",
msgs[1].flags |= I2C_M_RD; cmd_name, ERR_PTR(ret));
msgs[1].len = resp_size; return ret;
msgs[1].buf = resp; }
ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); if (ret != ARRAY_SIZE(msgs) ||
if (ret < 0) resp[FW_HDR_TYPE] != expected_response) {
return ret; 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,
return -EIO; "(%s) unexpected response: %*ph\n",
cmd_name, ret, resp);
return -EIO;
}
return 0; return 0;
}
} }
static int elants_i2c_calibrate(struct elants_data *ts) static int elants_i2c_calibrate(struct elants_data *ts)
...@@ -308,27 +334,21 @@ static u16 elants_i2c_parse_version(u8 *buf) ...@@ -308,27 +334,21 @@ static u16 elants_i2c_parse_version(u8 *buf)
static int elants_i2c_query_hw_version(struct elants_data *ts) static int elants_i2c_query_hw_version(struct elants_data *ts)
{ {
struct i2c_client *client = ts->client; 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 }; const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_ID, 0x00, 0x01 };
u8 resp[HEADER_SIZE]; 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), error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
resp, sizeof(resp)); resp, sizeof(resp), 1,
if (!error) { "read fw id");
ts->hw_version = elants_i2c_parse_version(resp); if (error)
if (ts->hw_version != 0xffff) return error;
return 0;
}
dev_dbg(&client->dev, "read fw id error=%d, buf=%*phC\n",
error, (int)sizeof(resp), resp);
}
if (error) { ts->hw_version = elants_i2c_parse_version(resp);
dev_err(&client->dev, if (ts->hw_version != 0xffff)
"Failed to read fw id: %d\n", error); return 0;
return error;
} }
dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version); dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version);
...@@ -339,26 +359,27 @@ static int elants_i2c_query_hw_version(struct elants_data *ts) ...@@ -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) static int elants_i2c_query_fw_version(struct elants_data *ts)
{ {
struct i2c_client *client = ts->client; 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 }; const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_VER, 0x00, 0x01 };
u8 resp[HEADER_SIZE]; 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), error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
resp, sizeof(resp)); resp, sizeof(resp), 1,
if (!error) { "read fw version");
ts->fw_version = elants_i2c_parse_version(resp); if (error)
if (ts->fw_version != 0x0000 && return error;
ts->fw_version != 0xffff)
return 0; ts->fw_version = elants_i2c_parse_version(resp);
} if (ts->fw_version != 0x0000 && ts->fw_version != 0xffff)
return 0;
dev_dbg(&client->dev, "read fw version error=%d, buf=%*phC\n", dev_dbg(&client->dev, "(read fw version) resp %*phC\n",
error, (int)sizeof(resp), resp); (int)sizeof(resp), resp);
} }
dev_err(&client->dev, dev_err(&client->dev, "Invalid fw ver: %#04x\n", ts->fw_version);
"Failed to read fw version or fw version is invalid\n");
return -EINVAL; return -EINVAL;
} }
...@@ -366,30 +387,24 @@ static int elants_i2c_query_fw_version(struct elants_data *ts) ...@@ -366,30 +387,24 @@ static int elants_i2c_query_fw_version(struct elants_data *ts)
static int elants_i2c_query_test_version(struct elants_data *ts) static int elants_i2c_query_test_version(struct elants_data *ts)
{ {
struct i2c_client *client = ts->client; struct i2c_client *client = ts->client;
int error, retry_cnt; int error;
u16 version; u16 version;
const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_TEST_VER, 0x00, 0x01 }; const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_TEST_VER, 0x00, 0x01 };
u8 resp[HEADER_SIZE]; u8 resp[HEADER_SIZE];
for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) { error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
error = elants_i2c_execute_command(client, cmd, sizeof(cmd), resp, sizeof(resp), MAX_RETRIES,
resp, sizeof(resp)); "read test version");
if (!error) { if (error) {
version = elants_i2c_parse_version(resp); dev_err(&client->dev, "Failed to read test version\n");
ts->test_version = version >> 8; return error;
ts->solution_version = version & 0xff;
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"); version = elants_i2c_parse_version(resp);
ts->test_version = version >> 8;
ts->solution_version = version & 0xff;
return -EINVAL; return 0;
} }
static int elants_i2c_query_bc_version(struct elants_data *ts) static int elants_i2c_query_bc_version(struct elants_data *ts)
...@@ -401,13 +416,10 @@ static int elants_i2c_query_bc_version(struct elants_data *ts) ...@@ -401,13 +416,10 @@ static int elants_i2c_query_bc_version(struct elants_data *ts)
int error; int error;
error = elants_i2c_execute_command(client, cmd, sizeof(cmd), error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
resp, sizeof(resp)); resp, sizeof(resp), 1,
if (error) { "read BC version");
dev_err(&client->dev, if (error)
"read BC version error=%d, buf=%*phC\n",
error, (int)sizeof(resp), resp);
return error; return error;
}
version = elants_i2c_parse_version(resp); version = elants_i2c_parse_version(resp);
ts->bc_version = version >> 8; ts->bc_version = version >> 8;
...@@ -439,12 +451,10 @@ static int elants_i2c_query_ts_info(struct elants_data *ts) ...@@ -439,12 +451,10 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
error = elants_i2c_execute_command(client, error = elants_i2c_execute_command(client,
get_resolution_cmd, get_resolution_cmd,
sizeof(get_resolution_cmd), sizeof(get_resolution_cmd),
resp, sizeof(resp)); resp, sizeof(resp), 1,
if (error) { "get resolution");
dev_err(&client->dev, "get resolution command failed: %d\n", if (error)
error);
return error; return error;
}
rows = resp[2] + resp[6] + resp[10]; rows = resp[2] + resp[6] + resp[10];
cols = resp[3] + resp[7] + resp[11]; cols = resp[3] + resp[7] + resp[11];
...@@ -452,36 +462,29 @@ static int elants_i2c_query_ts_info(struct elants_data *ts) ...@@ -452,36 +462,29 @@ static int elants_i2c_query_ts_info(struct elants_data *ts)
/* Process mm_to_pixel information */ /* Process mm_to_pixel information */
error = elants_i2c_execute_command(client, error = elants_i2c_execute_command(client,
get_osr_cmd, sizeof(get_osr_cmd), get_osr_cmd, sizeof(get_osr_cmd),
resp, sizeof(resp)); resp, sizeof(resp), 1, "get osr");
if (error) { if (error)
dev_err(&client->dev, "get osr command failed: %d\n",
error);
return error; return error;
}
osr = resp[3]; osr = resp[3];
error = elants_i2c_execute_command(client, error = elants_i2c_execute_command(client,
get_physical_scan_cmd, get_physical_scan_cmd,
sizeof(get_physical_scan_cmd), sizeof(get_physical_scan_cmd),
resp, sizeof(resp)); resp, sizeof(resp), 1,
if (error) { "get physical scan");
dev_err(&client->dev, "get physical scan command failed: %d\n", if (error)
error);
return error; return error;
}
phy_x = get_unaligned_be16(&resp[2]); phy_x = get_unaligned_be16(&resp[2]);
error = elants_i2c_execute_command(client, error = elants_i2c_execute_command(client,
get_physical_drive_cmd, get_physical_drive_cmd,
sizeof(get_physical_drive_cmd), sizeof(get_physical_drive_cmd),
resp, sizeof(resp)); resp, sizeof(resp), 1,
if (error) { "get physical drive");
dev_err(&client->dev, "get physical drive command failed: %d\n", if (error)
error);
return error; return error;
}
phy_y = get_unaligned_be16(&resp[2]); phy_y = get_unaligned_be16(&resp[2]);
...@@ -636,11 +639,10 @@ static int elants_i2c_validate_remark_id(struct elants_data *ts, ...@@ -636,11 +639,10 @@ static int elants_i2c_validate_remark_id(struct elants_data *ts,
/* Compare TS Remark ID and FW Remark ID */ /* Compare TS Remark ID and FW Remark ID */
error = elants_i2c_execute_command(client, cmd, sizeof(cmd), error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
resp, sizeof(resp)); resp, sizeof(resp),
if (error) { 1, "read Remark ID");
dev_err(&client->dev, "failed to query Remark ID: %d\n", error); if (error)
return error; return error;
}
ts_remark_id = get_unaligned_be16(&resp[3]); ts_remark_id = get_unaligned_be16(&resp[3]);
...@@ -1075,16 +1077,12 @@ static ssize_t show_calibration_count(struct device *dev, ...@@ -1075,16 +1077,12 @@ static ssize_t show_calibration_count(struct device *dev,
int error; int error;
error = elants_i2c_execute_command(client, cmd, sizeof(cmd), error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
resp, sizeof(resp)); resp, sizeof(resp), 1,
if (error) { "read ReK status");
dev_err(&client->dev, if (error)
"read ReK status error=%d, buf=%*phC\n",
error, (int)sizeof(resp), resp);
return sprintf(buf, "%d\n", error); return sprintf(buf, "%d\n", error);
}
rek_count = get_unaligned_be16(&resp[2]); rek_count = get_unaligned_be16(&resp[2]);
return sprintf(buf, "0x%04x\n", rek_count); return sprintf(buf, "0x%04x\n", rek_count);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment