[media] af9015: fix and refactor i2c adapter algo logic
authorAntti Palosaari <crope@iki.fi>
Mon, 12 Jun 2017 20:06:19 +0000 (17:06 -0300)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Tue, 20 Jun 2017 13:23:51 +0000 (10:23 -0300)
* 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 <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/usb/dvb-usb-v2/af9015.c

index ea16b627cb0be6ef78830733fbb8fe93eb99a159..49aec2f940e98c9a00446441ac13e6f0ec9d4285 100644 (file)
@@ -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;
 }