Commit d83886ff authored by Antti Palosaari's avatar Antti Palosaari Committed by Mauro Carvalho Chehab

[media] af9015: fix and refactor i2c adapter algo logic

* fix write+read when write has more than one byte
* remove lock, not needed on that case
* remove useless i2c msg send loop, as we support only write, read and
write+read as one go and nothing more
Signed-off-by: default avatarAntti Palosaari <crope@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent d029799b
...@@ -206,9 +206,9 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], ...@@ -206,9 +206,9 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
{ {
struct dvb_usb_device *d = i2c_get_adapdata(adap); struct dvb_usb_device *d = i2c_get_adapdata(adap);
struct af9015_state *state = d_to_priv(d); struct af9015_state *state = d_to_priv(d);
int ret = 0, i = 0; int ret;
u16 addr; u16 addr;
u8 uninitialized_var(mbox), addr_len; u8 mbox, addr_len;
struct req_t req; struct req_t req;
/* /*
...@@ -233,84 +233,89 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ...@@ -233,84 +233,89 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate.
| addr 0x3a | | addr 0xc6 | | addr 0x3a | | addr 0xc6 |
|____________| |____________| |____________| |____________|
*/ */
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
while (i < num) { if (msg[0].len == 0 || msg[0].flags & I2C_M_RD) {
if (msg[i].addr == state->af9013_config[0].i2c_addr || addr = 0x0000;
msg[i].addr == state->af9013_config[1].i2c_addr) { mbox = 0;
addr = msg[i].buf[0] << 8; addr_len = 0;
addr += msg[i].buf[1]; } else if (msg[0].len == 1) {
mbox = msg[i].buf[2]; addr = msg[0].buf[0];
addr_len = 3; mbox = 0;
} else { addr_len = 1;
addr = msg[i].buf[0]; } else if (msg[0].len == 2) {
addr_len = 1; addr = msg[0].buf[0] << 8|msg[0].buf[1] << 0;
/* mbox is don't care in that case */ mbox = 0;
} addr_len = 2;
} else {
addr = msg[0].buf[0] << 8|msg[0].buf[1] << 0;
mbox = msg[0].buf[2];
addr_len = 3;
}
if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
if (msg[i].len > 3 || msg[i+1].len > 61) { /* i2c write */
ret = -EOPNOTSUPP; if (msg[0].len > 21) {
goto error; ret = -EOPNOTSUPP;
} goto err;
if (msg[i].addr == state->af9013_config[0].i2c_addr) }
req.cmd = READ_MEMORY; if (msg[0].addr == state->af9013_config[0].i2c_addr)
else req.cmd = WRITE_MEMORY;
req.cmd = READ_I2C; else
req.i2c_addr = msg[i].addr; req.cmd = WRITE_I2C;
req.addr = addr; req.i2c_addr = msg[0].addr;
req.mbox = mbox; req.addr = addr;
req.addr_len = addr_len; req.mbox = mbox;
req.data_len = msg[i+1].len; req.addr_len = addr_len;
req.data = &msg[i+1].buf[0]; req.data_len = msg[0].len-addr_len;
ret = af9015_ctrl_msg(d, &req); req.data = &msg[0].buf[addr_len];
i += 2; ret = af9015_ctrl_msg(d, &req);
} else if (msg[i].flags & I2C_M_RD) { } else if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
if (msg[i].len > 61) { (msg[1].flags & I2C_M_RD)) {
ret = -EOPNOTSUPP; /* i2c write + read */
goto error; if (msg[0].len > 3 || msg[1].len > 61) {
} ret = -EOPNOTSUPP;
if (msg[i].addr == state->af9013_config[0].i2c_addr) { goto err;
ret = -EINVAL; }
goto error; if (msg[0].addr == state->af9013_config[0].i2c_addr)
} req.cmd = READ_MEMORY;
else
req.cmd = READ_I2C; req.cmd = READ_I2C;
req.i2c_addr = msg[i].addr; req.i2c_addr = msg[0].addr;
req.addr = addr; req.addr = addr;
req.mbox = mbox; req.mbox = mbox;
req.addr_len = addr_len; req.addr_len = addr_len;
req.data_len = msg[i].len; req.data_len = msg[1].len;
req.data = &msg[i].buf[0]; req.data = &msg[1].buf[0];
ret = af9015_ctrl_msg(d, &req); ret = af9015_ctrl_msg(d, &req);
i += 1; } else if (num == 1 && (msg[0].flags & I2C_M_RD)) {
} else { /* i2c read */
if (msg[i].len > 21) { if (msg[0].len > 61) {
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
goto error; goto err;
}
if (msg[i].addr == state->af9013_config[0].i2c_addr)
req.cmd = WRITE_MEMORY;
else
req.cmd = WRITE_I2C;
req.i2c_addr = msg[i].addr;
req.addr = addr;
req.mbox = mbox;
req.addr_len = addr_len;
req.data_len = msg[i].len-addr_len;
req.data = &msg[i].buf[addr_len];
ret = af9015_ctrl_msg(d, &req);
i += 1;
} }
if (ret) if (msg[0].addr == state->af9013_config[0].i2c_addr) {
goto error; ret = -EINVAL;
goto err;
}
req.cmd = READ_I2C;
req.i2c_addr = msg[0].addr;
req.addr = addr;
req.mbox = mbox;
req.addr_len = addr_len;
req.data_len = msg[0].len;
req.data = &msg[0].buf[0];
ret = af9015_ctrl_msg(d, &req);
} else {
ret = -EOPNOTSUPP;
dev_dbg(&d->udev->dev, "%s: unknown msg, num %u\n",
__func__, num);
} }
ret = i; if (ret)
goto err;
error:
mutex_unlock(&d->i2c_mutex);
return num;
err:
dev_dbg(&d->udev->dev, "%s: failed %d\n", __func__, ret);
return ret; return ret;
} }
......
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