summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends/stv0367.c
diff options
context:
space:
mode:
authorDaniel Scheller <d.scheller@gmx.net>2017-03-29 18:43:01 +0200
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2017-06-20 14:18:16 +0200
commitf61c2991e6ee6753be35193aa46ed6fd4a77dc25 (patch)
tree4733f7d7e5bfa51d8215f023caa1fbafd69e397e /drivers/media/dvb-frontends/stv0367.c
parent[media] s5p-cec: update MAINTAINERS entry (diff)
downloadlinux-f61c2991e6ee6753be35193aa46ed6fd4a77dc25.tar.xz
linux-f61c2991e6ee6753be35193aa46ed6fd4a77dc25.zip
[media] dvb-frontends/stv0367: add flag to make i2c_gatectrl optional
Some hardware and bridges (namely ddbridge) require that tuner access is limited to one concurrent access and wrap i2c gate control with a mutex_lock when attaching frontends. According to vendor information, this is required as concurrent tuner reconfiguration can interfere each other and at worst cause tuning fails or bad reception quality. If the demod driver does gate_ctrl before setting up tuner parameters, and the tuner does another I2C enable, it will deadlock forever when gate_ctrl is wrapped into the mutex_lock. This adds a flag and a conditional before triggering gate_ctrl in the demodulator driver. Signed-off-by: Daniel Scheller <d.scheller@gmx.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/dvb-frontends/stv0367.c')
-rw-r--r--drivers/media/dvb-frontends/stv0367.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
index fd49c436a36d..fc80934387dd 100644
--- a/drivers/media/dvb-frontends/stv0367.c
+++ b/drivers/media/dvb-frontends/stv0367.c
@@ -89,6 +89,8 @@ struct stv0367_state {
struct stv0367cab_state *cab_state;
/* DVB-T */
struct stv0367ter_state *ter_state;
+ /* flags for operation control */
+ u8 use_i2c_gatectrl;
};
struct st_register {
@@ -1827,10 +1829,10 @@ static int stv0367ter_set_frontend(struct dvb_frontend *fe)
stv0367ter_init(fe);
if (fe->ops.tuner_ops.set_params) {
- if (fe->ops.i2c_gate_ctrl)
+ if (state->use_i2c_gatectrl && fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
fe->ops.tuner_ops.set_params(fe);
- if (fe->ops.i2c_gate_ctrl)
+ if (state->use_i2c_gatectrl && fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
}
@@ -2321,6 +2323,9 @@ struct dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
state->fe.demodulator_priv = state;
state->chip_id = stv0367_readreg(state, 0xf000);
+ /* demod operation options */
+ state->use_i2c_gatectrl = 1;
+
dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
/* check if the demod is there */
@@ -3120,10 +3125,10 @@ static int stv0367cab_set_frontend(struct dvb_frontend *fe)
/* Tuner Frequency Setting */
if (fe->ops.tuner_ops.set_params) {
- if (fe->ops.i2c_gate_ctrl)
+ if (state->use_i2c_gatectrl && fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
fe->ops.tuner_ops.set_params(fe);
- if (fe->ops.i2c_gate_ctrl)
+ if (state->use_i2c_gatectrl && fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
}
@@ -3437,6 +3442,9 @@ struct dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
state->fe.demodulator_priv = state;
state->chip_id = stv0367_readreg(state, 0xf000);
+ /* demod operation options */
+ state->use_i2c_gatectrl = 1;
+
dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
/* check if the demod is there */