Skip to content

Commit

Permalink
ptp: ptp_clockmatrix: use i2c_master_send for i2c write
Browse files Browse the repository at this point in the history
The old code for i2c write would break on some controllers, which fails
at handling Repeated Start Condition. So we will just use i2c_master_send
to handle write in one transanction.

Changes since v1:
- Remove indentation change

Signed-off-by: Min Li <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Min Li authored and davem330 committed Aug 19, 2020
1 parent d1fb555 commit 957ff42
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 13 deletions.
56 changes: 43 additions & 13 deletions drivers/ptp/ptp_clockmatrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,24 +142,23 @@ static int idtcm_strverscmp(const char *ver1, const char *ver2)
return result;
}

static int idtcm_xfer(struct idtcm *idtcm,
u8 regaddr,
u8 *buf,
u16 count,
bool write)
static int idtcm_xfer_read(struct idtcm *idtcm,
u8 regaddr,
u8 *buf,
u16 count)
{
struct i2c_client *client = idtcm->client;
struct i2c_msg msg[2];
int cnt;
char *fmt = "i2c_transfer failed at %d in %s for %s, at addr: %04X!\n";
char *fmt = "i2c_transfer failed at %d in %s, at addr: %04X!\n";

msg[0].addr = client->addr;
msg[0].flags = 0;
msg[0].len = 1;
msg[0].buf = &regaddr;

msg[1].addr = client->addr;
msg[1].flags = write ? 0 : I2C_M_RD;
msg[1].flags = I2C_M_RD;
msg[1].len = count;
msg[1].buf = buf;

Expand All @@ -170,7 +169,6 @@ static int idtcm_xfer(struct idtcm *idtcm,
fmt,
__LINE__,
__func__,
write ? "write" : "read",
regaddr);
return cnt;
} else if (cnt != 2) {
Expand All @@ -182,6 +180,37 @@ static int idtcm_xfer(struct idtcm *idtcm,
return 0;
}

static int idtcm_xfer_write(struct idtcm *idtcm,
u8 regaddr,
u8 *buf,
u16 count)
{
struct i2c_client *client = idtcm->client;
/* we add 1 byte for device register */
u8 msg[IDTCM_MAX_WRITE_COUNT + 1];
int cnt;
char *fmt = "i2c_master_send failed at %d in %s, at addr: %04X!\n";

if (count > IDTCM_MAX_WRITE_COUNT)
return -EINVAL;

msg[0] = regaddr;
memcpy(&msg[1], buf, count);

cnt = i2c_master_send(client, msg, count + 1);

if (cnt < 0) {
dev_err(&client->dev,
fmt,
__LINE__,
__func__,
regaddr);
return cnt;
}

return 0;
}

static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
{
u8 buf[4];
Expand All @@ -195,7 +224,7 @@ static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
buf[2] = 0x10;
buf[3] = 0x20;

err = idtcm_xfer(idtcm, PAGE_ADDR, buf, sizeof(buf), 1);
err = idtcm_xfer_write(idtcm, PAGE_ADDR, buf, sizeof(buf));

if (err) {
idtcm->page_offset = 0xff;
Expand Down Expand Up @@ -223,11 +252,12 @@ static int _idtcm_rdwr(struct idtcm *idtcm,
err = idtcm_page_offset(idtcm, hi);

if (err)
goto out;
return err;

err = idtcm_xfer(idtcm, lo, buf, count, write);
out:
return err;
if (write)
return idtcm_xfer_write(idtcm, lo, buf, count);

return idtcm_xfer_read(idtcm, lo, buf, count);
}

static int idtcm_read(struct idtcm *idtcm,
Expand Down
2 changes: 2 additions & 0 deletions drivers/ptp/ptp_clockmatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@

#define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef)

#define IDTCM_MAX_WRITE_COUNT (512)

/* Values of DPLL_N.DPLL_MODE.PLL_MODE */
enum pll_mode {
PLL_MODE_MIN = 0,
Expand Down

0 comments on commit 957ff42

Please sign in to comment.