aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/dvb-frontends/tc90522.c
diff options
context:
space:
mode:
authorGravatar Akihiro Tsukada <tskd08@gmail.com> 2019-08-29 05:38:21 -0300
committerGravatar Mauro Carvalho Chehab <mchehab+samsung@kernel.org> 2019-10-07 07:50:41 -0300
commitecf20d28ff7730d8d446c989eb1cf641ec6e28ce (patch)
tree9407cc36efd4906c4cff3ea93fe9028ec48c94f3 /drivers/media/dvb-frontends/tc90522.c
parentmedia: dvb-usb-v2/gl861: remove an un-used header file (diff)
downloadlinux-ecf20d28ff7730d8d446c989eb1cf641ec6e28ce.tar.gz
linux-ecf20d28ff7730d8d446c989eb1cf641ec6e28ce.tar.bz2
linux-ecf20d28ff7730d8d446c989eb1cf641ec6e28ce.zip
media: dvb-frontends/tc90522: extend i2c algo to support some devices
This demod implements an i2c adapter for attached tuner and relays i2c messages from users (dvb adapters / bridge chips). Some of them, such as Friio dvb card using gl861, require each pair of i2c messages for one read to be issued as two separate transactions. This patch adds a configuration option to enable this split. Signed-off-by: Akihiro Tsukada <tskd08@gmail.com> Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/dvb-frontends/tc90522.c')
-rw-r--r--drivers/media/dvb-frontends/tc90522.c27
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);