Skip to content

Commit 957ff42

Browse files
Min Lidavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d1fb555 commit 957ff42

File tree

2 files changed

+45
-13
lines changed

2 files changed

+45
-13
lines changed

drivers/ptp/ptp_clockmatrix.c

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -142,24 +142,23 @@ static int idtcm_strverscmp(const char *ver1, const char *ver2)
142142
return result;
143143
}
144144

145-
static int idtcm_xfer(struct idtcm *idtcm,
146-
u8 regaddr,
147-
u8 *buf,
148-
u16 count,
149-
bool write)
145+
static int idtcm_xfer_read(struct idtcm *idtcm,
146+
u8 regaddr,
147+
u8 *buf,
148+
u16 count)
150149
{
151150
struct i2c_client *client = idtcm->client;
152151
struct i2c_msg msg[2];
153152
int cnt;
154-
char *fmt = "i2c_transfer failed at %d in %s for %s, at addr: %04X!\n";
153+
char *fmt = "i2c_transfer failed at %d in %s, at addr: %04X!\n";
155154

156155
msg[0].addr = client->addr;
157156
msg[0].flags = 0;
158157
msg[0].len = 1;
159158
msg[0].buf = &regaddr;
160159

161160
msg[1].addr = client->addr;
162-
msg[1].flags = write ? 0 : I2C_M_RD;
161+
msg[1].flags = I2C_M_RD;
163162
msg[1].len = count;
164163
msg[1].buf = buf;
165164

@@ -170,7 +169,6 @@ static int idtcm_xfer(struct idtcm *idtcm,
170169
fmt,
171170
__LINE__,
172171
__func__,
173-
write ? "write" : "read",
174172
regaddr);
175173
return cnt;
176174
} else if (cnt != 2) {
@@ -182,6 +180,37 @@ static int idtcm_xfer(struct idtcm *idtcm,
182180
return 0;
183181
}
184182

183+
static int idtcm_xfer_write(struct idtcm *idtcm,
184+
u8 regaddr,
185+
u8 *buf,
186+
u16 count)
187+
{
188+
struct i2c_client *client = idtcm->client;
189+
/* we add 1 byte for device register */
190+
u8 msg[IDTCM_MAX_WRITE_COUNT + 1];
191+
int cnt;
192+
char *fmt = "i2c_master_send failed at %d in %s, at addr: %04X!\n";
193+
194+
if (count > IDTCM_MAX_WRITE_COUNT)
195+
return -EINVAL;
196+
197+
msg[0] = regaddr;
198+
memcpy(&msg[1], buf, count);
199+
200+
cnt = i2c_master_send(client, msg, count + 1);
201+
202+
if (cnt < 0) {
203+
dev_err(&client->dev,
204+
fmt,
205+
__LINE__,
206+
__func__,
207+
regaddr);
208+
return cnt;
209+
}
210+
211+
return 0;
212+
}
213+
185214
static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
186215
{
187216
u8 buf[4];
@@ -195,7 +224,7 @@ static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
195224
buf[2] = 0x10;
196225
buf[3] = 0x20;
197226

198-
err = idtcm_xfer(idtcm, PAGE_ADDR, buf, sizeof(buf), 1);
227+
err = idtcm_xfer_write(idtcm, PAGE_ADDR, buf, sizeof(buf));
199228

200229
if (err) {
201230
idtcm->page_offset = 0xff;
@@ -223,11 +252,12 @@ static int _idtcm_rdwr(struct idtcm *idtcm,
223252
err = idtcm_page_offset(idtcm, hi);
224253

225254
if (err)
226-
goto out;
255+
return err;
227256

228-
err = idtcm_xfer(idtcm, lo, buf, count, write);
229-
out:
230-
return err;
257+
if (write)
258+
return idtcm_xfer_write(idtcm, lo, buf, count);
259+
260+
return idtcm_xfer_read(idtcm, lo, buf, count);
231261
}
232262

233263
static int idtcm_read(struct idtcm *idtcm,

drivers/ptp/ptp_clockmatrix.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555

5656
#define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef)
5757

58+
#define IDTCM_MAX_WRITE_COUNT (512)
59+
5860
/* Values of DPLL_N.DPLL_MODE.PLL_MODE */
5961
enum pll_mode {
6062
PLL_MODE_MIN = 0,

0 commit comments

Comments
 (0)