Skip to content

Commit 3e03ee3

Browse files
6by9gregkh
authored andcommitted
media: tc358743: Check I2C succeeded during probe
[ Upstream commit 303d816 ] The probe for the TC358743 reads the CHIPID register from the device and compares it to the expected value of 0. If the I2C request fails then that also returns 0, so the driver loads thinking that the device is there. Generally I2C communications are reliable so there is limited need to check the return value on every transfer, therefore only amend the one read during probe to check for I2C errors. Signed-off-by: Dave Stevenson <[email protected]> Signed-off-by: Hans Verkuil <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent e6f36f5 commit 3e03ee3

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

drivers/media/i2c/tc358743.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ static inline struct tc358743_state *to_state(struct v4l2_subdev *sd)
110110

111111
/* --------------- I2C --------------- */
112112

113-
static void i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
113+
static int i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
114114
{
115115
struct tc358743_state *state = to_state(sd);
116116
struct i2c_client *client = state->i2c_client;
@@ -136,6 +136,7 @@ static void i2c_rd(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
136136
v4l2_err(sd, "%s: reading register 0x%x from 0x%x failed: %d\n",
137137
__func__, reg, client->addr, err);
138138
}
139+
return err != ARRAY_SIZE(msgs);
139140
}
140141

141142
static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
@@ -192,15 +193,24 @@ static void i2c_wr(struct v4l2_subdev *sd, u16 reg, u8 *values, u32 n)
192193
}
193194
}
194195

195-
static noinline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n)
196+
static noinline u32 i2c_rdreg_err(struct v4l2_subdev *sd, u16 reg, u32 n,
197+
int *err)
196198
{
199+
int error;
197200
__le32 val = 0;
198201

199-
i2c_rd(sd, reg, (u8 __force *)&val, n);
202+
error = i2c_rd(sd, reg, (u8 __force *)&val, n);
203+
if (err)
204+
*err = error;
200205

201206
return le32_to_cpu(val);
202207
}
203208

209+
static inline u32 i2c_rdreg(struct v4l2_subdev *sd, u16 reg, u32 n)
210+
{
211+
return i2c_rdreg_err(sd, reg, n, NULL);
212+
}
213+
204214
static noinline void i2c_wrreg(struct v4l2_subdev *sd, u16 reg, u32 val, u32 n)
205215
{
206216
__le32 raw = cpu_to_le32(val);
@@ -229,6 +239,13 @@ static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg)
229239
return i2c_rdreg(sd, reg, 2);
230240
}
231241

242+
static int i2c_rd16_err(struct v4l2_subdev *sd, u16 reg, u16 *value)
243+
{
244+
int err;
245+
*value = i2c_rdreg_err(sd, reg, 2, &err);
246+
return err;
247+
}
248+
232249
static void i2c_wr16(struct v4l2_subdev *sd, u16 reg, u16 val)
233250
{
234251
i2c_wrreg(sd, reg, val, 2);
@@ -2030,6 +2047,7 @@ static int tc358743_probe(struct i2c_client *client)
20302047
struct tc358743_platform_data *pdata = client->dev.platform_data;
20312048
struct v4l2_subdev *sd;
20322049
u16 irq_mask = MASK_HDMI_MSK | MASK_CSI_MSK;
2050+
u16 chipid;
20332051
int err;
20342052

20352053
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -2061,7 +2079,8 @@ static int tc358743_probe(struct i2c_client *client)
20612079
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
20622080

20632081
/* i2c access */
2064-
if ((i2c_rd16(sd, CHIPID) & MASK_CHIPID) != 0) {
2082+
if (i2c_rd16_err(sd, CHIPID, &chipid) ||
2083+
(chipid & MASK_CHIPID) != 0) {
20652084
v4l2_info(sd, "not a TC358743 on address 0x%x\n",
20662085
client->addr << 1);
20672086
return -ENODEV;

0 commit comments

Comments
 (0)