From d83886ff118cd93d85617362a582beec20c9e92d Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 12 Jun 2017 17:06:19 -0300 Subject: [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: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/af9015.c | 153 ++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 74 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index ea16b627cb0b..49aec2f940e9 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -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 af9015_state *state = d_to_priv(d); - int ret = 0, i = 0; + int ret; u16 addr; - u8 uninitialized_var(mbox), addr_len; + u8 mbox, addr_len; struct req_t req; /* @@ -233,84 +233,89 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. | addr 0x3a | | addr 0xc6 | |____________| |____________| */ - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - while (i < num) { - if (msg[i].addr == state->af9013_config[0].i2c_addr || - msg[i].addr == state->af9013_config[1].i2c_addr) { - addr = msg[i].buf[0] << 8; - addr += msg[i].buf[1]; - mbox = msg[i].buf[2]; - addr_len = 3; - } else { - addr = msg[i].buf[0]; - addr_len = 1; - /* mbox is don't care in that case */ - } + if (msg[0].len == 0 || msg[0].flags & I2C_M_RD) { + addr = 0x0000; + mbox = 0; + addr_len = 0; + } else if (msg[0].len == 1) { + addr = msg[0].buf[0]; + mbox = 0; + addr_len = 1; + } else if (msg[0].len == 2) { + addr = msg[0].buf[0] << 8|msg[0].buf[1] << 0; + 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 (msg[i].len > 3 || msg[i+1].len > 61) { - ret = -EOPNOTSUPP; - goto error; - } - if (msg[i].addr == state->af9013_config[0].i2c_addr) - req.cmd = READ_MEMORY; - else - req.cmd = READ_I2C; - req.i2c_addr = msg[i].addr; - req.addr = addr; - req.mbox = mbox; - req.addr_len = addr_len; - req.data_len = msg[i+1].len; - req.data = &msg[i+1].buf[0]; - ret = af9015_ctrl_msg(d, &req); - i += 2; - } else if (msg[i].flags & I2C_M_RD) { - if (msg[i].len > 61) { - ret = -EOPNOTSUPP; - goto error; - } - if (msg[i].addr == state->af9013_config[0].i2c_addr) { - ret = -EINVAL; - goto error; - } + if (num == 1 && !(msg[0].flags & I2C_M_RD)) { + /* i2c write */ + if (msg[0].len > 21) { + ret = -EOPNOTSUPP; + goto err; + } + if (msg[0].addr == state->af9013_config[0].i2c_addr) + req.cmd = WRITE_MEMORY; + else + req.cmd = WRITE_I2C; + req.i2c_addr = msg[0].addr; + req.addr = addr; + req.mbox = mbox; + req.addr_len = addr_len; + req.data_len = msg[0].len-addr_len; + req.data = &msg[0].buf[addr_len]; + ret = af9015_ctrl_msg(d, &req); + } else if (num == 2 && !(msg[0].flags & I2C_M_RD) && + (msg[1].flags & I2C_M_RD)) { + /* i2c write + read */ + if (msg[0].len > 3 || msg[1].len > 61) { + ret = -EOPNOTSUPP; + goto err; + } + if (msg[0].addr == state->af9013_config[0].i2c_addr) + req.cmd = READ_MEMORY; + else req.cmd = READ_I2C; - req.i2c_addr = msg[i].addr; - req.addr = addr; - req.mbox = mbox; - req.addr_len = addr_len; - req.data_len = msg[i].len; - req.data = &msg[i].buf[0]; - ret = af9015_ctrl_msg(d, &req); - i += 1; - } else { - if (msg[i].len > 21) { - ret = -EOPNOTSUPP; - goto error; - } - 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; + req.i2c_addr = msg[0].addr; + req.addr = addr; + req.mbox = mbox; + req.addr_len = addr_len; + req.data_len = msg[1].len; + req.data = &msg[1].buf[0]; + ret = af9015_ctrl_msg(d, &req); + } else if (num == 1 && (msg[0].flags & I2C_M_RD)) { + /* i2c read */ + if (msg[0].len > 61) { + ret = -EOPNOTSUPP; + goto err; } - if (ret) - goto error; - + if (msg[0].addr == state->af9013_config[0].i2c_addr) { + 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; - -error: - mutex_unlock(&d->i2c_mutex); + if (ret) + goto err; + return num; +err: + dev_dbg(&d->udev->dev, "%s: failed %d\n", __func__, ret); return ret; } -- cgit v1.2.3-59-g8ed1b