lkml.org 
[lkml]   [2020]   [Apr]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH v3 5/9] 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: Michał Mirosław <mirq-linux@rere.qmqm.pl>
    ---
    drivers/input/touchscreen/elants_i2c.c | 189 +++++++++++++------------
    1 file changed, 96 insertions(+), 93 deletions(-)

    diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
    index 87d686ce08f2..b0f083f7f2a9 100644
    --- a/drivers/input/touchscreen/elants_i2c.c
    +++ b/drivers/input/touchscreen/elants_i2c.c
    @@ -205,7 +205,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;
    @@ -225,30 +226,55 @@ 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;
    }

    - msgs[0].addr = client->addr;
    - msgs[0].flags = client->flags & I2C_M_TEN;
    - msgs[0].len = cmd_size;
    - msgs[0].buf = (u8 *)cmd;
    + 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 |= I2C_M_RD;
    - msgs[1].len = resp_size;
    - msgs[1].buf = resp;
    + msgs[1].addr = client->addr;
    + msgs[1].flags = client->flags & I2C_M_TEN;
    + 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)
    - return ret;
    + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
    + if (ret < 0) {
    + if (--retries > 0) {
    + dev_dbg(&client->dev,
    + "(%s) I2C transfer failed: %d (retrying)\n",
    + cmd_name, ret);
    + continue;
    + }

    - if (ret != ARRAY_SIZE(msgs) || resp[FW_HDR_TYPE] != expected_response)
    - return -EIO;
    + dev_err(&client->dev,
    + "(%s) I2C transfer failed: %d\n",
    + cmd_name, ret);
    + return ret;
    + }

    - return 0;
    + 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;
    + }
    +
    + dev_err(&client->dev,
    + "(%s) unexpected response: %*ph\n",
    + cmd_name, ret, resp);
    + return -EIO;
    + }
    +
    + return --retries;
    + }
    }

    static int elants_i2c_calibrate(struct elants_data *ts)
    @@ -321,27 +347,20 @@ 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];

    - for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
    - error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
    - resp, sizeof(resp));
    - if (!error) {
    - ts->hw_version = elants_i2c_parse_version(resp);
    - if (ts->hw_version != 0xffff)
    - return 0;
    - }
    + while (retry_cnt) {
    + retry_cnt = elants_i2c_execute_command(client, cmd, sizeof(cmd),
    + resp, sizeof(resp),
    + retry_cnt, "read fw id");
    + if (retry_cnt < 0)
    + return retry_cnt;

    - 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;
    + ts->hw_version = elants_i2c_parse_version(resp);
    + if (ts->hw_version != 0xffff)
    + return 0;
    }

    dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version);
    @@ -352,26 +371,28 @@ 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];

    - for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
    - error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
    - resp, sizeof(resp));
    - if (!error) {
    - ts->fw_version = elants_i2c_parse_version(resp);
    - if (ts->fw_version != 0x0000 &&
    - ts->fw_version != 0xffff)
    - return 0;
    - }
    + while (retry_cnt) {
    + retry_cnt = elants_i2c_execute_command(client, cmd,
    + sizeof(cmd),
    + resp, sizeof(resp),
    + retry_cnt,
    + "read fw version");
    + if (retry_cnt < 0)
    + return retry_cnt;

    - dev_dbg(&client->dev, "read fw version error=%d, buf=%*phC\n",
    - error, (int)sizeof(resp), resp);
    + 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) 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;
    }
    @@ -379,25 +400,20 @@ 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) {
    - version = elants_i2c_parse_version(resp);
    - ts->test_version = version >> 8;
    - ts->solution_version = version & 0xff;
    + error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
    + resp, sizeof(resp), MAX_RETRIES,
    + "read test version");
    + if (error >= 0) {
    + version = elants_i2c_parse_version(resp);
    + ts->test_version = version >> 8;
    + 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);
    + return 0;
    }

    dev_err(&client->dev, "Failed to read test version\n");
    @@ -414,13 +430,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;
    @@ -452,12 +465,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];
    @@ -465,36 +476,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]);

    @@ -649,11 +653,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 < 0)
    return error;
    - }

    ts_remark_id = get_unaligned_be16(&resp[3]);

    --
    2.20.1
    \
     
     \ /
      Last update: 2020-04-13 15:33    [W:4.559 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site