Commit 7e8f15c5 authored by Andrzej Hajda's avatar Andrzej Hajda Committed by Mauro Carvalho Chehab

[media] s5k5baf: allow to handle arbitrary long i2c sequences

Using variable length array in s5k5baf_write_arr_seq caused
an implicit assumption that i2c sequences should be short.
The patch rewrites the function so it can handle sequences
of any length and does not use variable length array.
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarAndrzej Hajda <a.hajda@samsung.com>
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent c29b8f31
......@@ -478,25 +478,33 @@ static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr,
u16 count, const u16 *seq)
{
struct i2c_client *c = v4l2_get_subdevdata(&state->sd);
__be16 buf[count + 1];
int ret, n;
__be16 buf[65];
s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr);
if (state->error)
return;
v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count,
min(2 * count, 64), seq);
buf[0] = __constant_cpu_to_be16(REG_CMD_BUF);
for (n = 1; n <= count; ++n)
buf[n] = cpu_to_be16(*seq++);
n *= 2;
ret = i2c_master_send(c, (char *)buf, n);
v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count,
min(2 * count, 64), seq - count);
while (count > 0) {
int n = min_t(int, count, ARRAY_SIZE(buf) - 1);
int ret, i;
if (ret != n) {
v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret);
state->error = ret;
for (i = 1; i <= n; ++i)
buf[i] = cpu_to_be16(*seq++);
i *= 2;
ret = i2c_master_send(c, (char *)buf, i);
if (ret != i) {
v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret);
state->error = ret;
break;
}
count -= n;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment