ptp: ptp_clockmatrix: use i2c_master_send for i2c write

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 <min.li.xe@renesas.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Min Li 2020-08-18 10:41:22 -04:00 committed by David S. Miller
parent d1fb555929
commit 957ff4278e
2 changed files with 45 additions and 13 deletions

View File

@ -142,16 +142,15 @@ static int idtcm_strverscmp(const char *ver1, const char *ver2)
return result; return result;
} }
static int idtcm_xfer(struct idtcm *idtcm, static int idtcm_xfer_read(struct idtcm *idtcm,
u8 regaddr, u8 regaddr,
u8 *buf, u8 *buf,
u16 count, u16 count)
bool write)
{ {
struct i2c_client *client = idtcm->client; struct i2c_client *client = idtcm->client;
struct i2c_msg msg[2]; struct i2c_msg msg[2];
int cnt; 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].addr = client->addr;
msg[0].flags = 0; msg[0].flags = 0;
@ -159,7 +158,7 @@ static int idtcm_xfer(struct idtcm *idtcm,
msg[0].buf = &regaddr; msg[0].buf = &regaddr;
msg[1].addr = client->addr; 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].len = count;
msg[1].buf = buf; msg[1].buf = buf;
@ -170,7 +169,6 @@ static int idtcm_xfer(struct idtcm *idtcm,
fmt, fmt,
__LINE__, __LINE__,
__func__, __func__,
write ? "write" : "read",
regaddr); regaddr);
return cnt; return cnt;
} else if (cnt != 2) { } else if (cnt != 2) {
@ -182,6 +180,37 @@ static int idtcm_xfer(struct idtcm *idtcm,
return 0; 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) static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
{ {
u8 buf[4]; u8 buf[4];
@ -195,7 +224,7 @@ static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
buf[2] = 0x10; buf[2] = 0x10;
buf[3] = 0x20; 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) { if (err) {
idtcm->page_offset = 0xff; idtcm->page_offset = 0xff;
@ -223,11 +252,12 @@ static int _idtcm_rdwr(struct idtcm *idtcm,
err = idtcm_page_offset(idtcm, hi); err = idtcm_page_offset(idtcm, hi);
if (err) if (err)
goto out; return err;
err = idtcm_xfer(idtcm, lo, buf, count, write); if (write)
out: return idtcm_xfer_write(idtcm, lo, buf, count);
return err;
return idtcm_xfer_read(idtcm, lo, buf, count);
} }
static int idtcm_read(struct idtcm *idtcm, static int idtcm_read(struct idtcm *idtcm,

View File

@ -55,6 +55,8 @@
#define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef) #define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef)
#define IDTCM_MAX_WRITE_COUNT (512)
/* Values of DPLL_N.DPLL_MODE.PLL_MODE */ /* Values of DPLL_N.DPLL_MODE.PLL_MODE */
enum pll_mode { enum pll_mode {
PLL_MODE_MIN = 0, PLL_MODE_MIN = 0,