mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 16:41:58 +00:00
[media] cx24120: i2c-max-write-size is now configurable
Some i2c-hosts are quite limited regarding maximum i2c-burst-write-sizes. This patch makes the previously hardcoded field configurable by users of the driver. Signed-off-by: Patrick Boettcher <patrick.boettcher@posteo.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
c5fb0f5f54
commit
f7a77ebf08
@ -630,6 +630,7 @@ static const struct cx24120_config skystar2_rev3_3_cx24120_config = {
|
||||
.xtal_khz = 10111,
|
||||
.initial_mpeg_config = { 0xa1, 0x76, 0x07 },
|
||||
.request_firmware = flexcop_fe_request_firmware,
|
||||
.i2c_wr_max = 4,
|
||||
};
|
||||
|
||||
static int skystarS2_rev33_attach(struct flexcop_device *fc,
|
||||
|
@ -209,24 +209,28 @@ static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data)
|
||||
}
|
||||
|
||||
|
||||
/* Write multiple registers */
|
||||
/* Write multiple registers in chunks of i2c_wr_max-sized buffers */
|
||||
static int cx24120_writeregN(struct cx24120_state *state,
|
||||
u8 reg, const u8 *values, u16 len, u8 incr)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[5]; /* maximum 4 data bytes at once - flexcop limitation
|
||||
(very limited i2c-interface this one) */
|
||||
u16 max = state->config->i2c_wr_max > 0 ?
|
||||
state->config->i2c_wr_max :
|
||||
len;
|
||||
|
||||
struct i2c_msg msg = {
|
||||
.addr = state->config->i2c_addr,
|
||||
.flags = 0,
|
||||
.buf = buf,
|
||||
.len = len };
|
||||
};
|
||||
|
||||
msg.buf = kmalloc(max + 1, GFP_KERNEL);
|
||||
if (msg.buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
while (len) {
|
||||
buf[0] = reg;
|
||||
msg.len = len > 4 ? 4 : len;
|
||||
memcpy(&buf[1], values, msg.len);
|
||||
msg.buf[0] = reg;
|
||||
msg.len = len > max ? max : len;
|
||||
memcpy(&msg.buf[1], values, msg.len);
|
||||
|
||||
len -= msg.len; /* data length revers counter */
|
||||
values += msg.len; /* incr data pointer */
|
||||
@ -238,17 +242,20 @@ static int cx24120_writeregN(struct cx24120_state *state,
|
||||
ret = i2c_transfer(state->i2c, &msg, 1);
|
||||
if (ret != 1) {
|
||||
err("i2c_write error(err == %i, 0x%02x)\n", ret, reg);
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev_dbg(&state->i2c->dev,
|
||||
"%s: reg=0x%02x; data=0x%02x,0x%02x,0x%02x,0x%02x\n",
|
||||
__func__, reg,
|
||||
buf[1], buf[2], buf[3], buf[4]);
|
||||
|
||||
msg.buf[1], msg.buf[2], msg.buf[3], msg.buf[4]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
kfree(msg.buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -1434,7 +1441,6 @@ int cx24120_init(struct dvb_frontend *fe)
|
||||
}
|
||||
info("FW version %i.%i.%i.%i\n", vers[0], vers[1], vers[2], vers[3]);
|
||||
|
||||
|
||||
state->cold_init = 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -37,6 +37,9 @@ struct cx24120_config {
|
||||
|
||||
int (*request_firmware)(struct dvb_frontend *fe,
|
||||
const struct firmware **fw, char *name);
|
||||
|
||||
/* max bytes I2C provider can write at once */
|
||||
u16 i2c_wr_max;
|
||||
};
|
||||
|
||||
#if IS_REACHABLE(CONFIG_DVB_CX24120)
|
||||
|
Loading…
Reference in New Issue
Block a user