diff options
Diffstat (limited to 'drivers/media/dvb-frontends/tc90522.c')
-rw-r--r-- | drivers/media/dvb-frontends/tc90522.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/media/dvb-frontends/tc90522.c b/drivers/media/dvb-frontends/tc90522.c index 849d63dbc279..e83836b29715 100644 --- a/drivers/media/dvb-frontends/tc90522.c +++ b/drivers/media/dvb-frontends/tc90522.c @@ -685,10 +685,33 @@ tc90522_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) p += new_msgs[j].len; } - if (i < num) + if (i < num) { ret = -ENOMEM; - else + } else if (!state->cfg.split_tuner_read_i2c || rd_num == 0) { ret = i2c_transfer(state->i2c_client->adapter, new_msgs, j); + } else { + /* + * Split transactions at each I2C_M_RD message. + * Some of the parent device require this, + * such as Friio (see. dvb-usb-gl861). + */ + int from, to; + + ret = 0; + from = 0; + do { + int r; + + to = from + 1; + while (to < j && !(new_msgs[to].flags & I2C_M_RD)) + to++; + r = i2c_transfer(state->i2c_client->adapter, + &new_msgs[from], to - from); + ret = (r <= 0) ? r : ret + r; + from = to; + } while (from < j && ret > 0); + } + if (ret >= 0 && ret < j) ret = -EIO; kfree(new_msgs); |