aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/tuners
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-04-07 19:32:55 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-16 21:24:10 -0300
commit7a5ef30dc3363ae1ab7243397be7dd8449063999 (patch)
treebb2f1df796de7f2942a6ff1a5e93dedd9daa673a /drivers/media/tuners
parent9e30edd8907e5a7e92b04b1d05de5619c4a35d47 (diff)
[media] r820t: proper lock and set the I2C gate
As this tuner can be used by analog and digital parts of the driver, be sure that all ops that access the hardware will be be properly locked. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> Tested-by: Antti Palosaari <crope@iki.fi>
Diffstat (limited to 'drivers/media/tuners')
-rw-r--r--drivers/media/tuners/r820t.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c
index 0fa355d1737..5cd8256a203 100644
--- a/drivers/media/tuners/r820t.c
+++ b/drivers/media/tuners/r820t.c
@@ -1193,8 +1193,6 @@ static int generic_set_freq(struct dvb_frontend *fe,
tuner_dbg("should set frequency to %d kHz, bw %d MHz\n",
freq / 1000, bw);
- mutex_lock(&priv->lock);
-
if ((type == V4L2_TUNER_ANALOG_TV) && (std == V4L2_STD_SECAM_LC))
lo_freq = freq - priv->int_freq;
else
@@ -1218,7 +1216,6 @@ static int generic_set_freq(struct dvb_frontend *fe,
rc = r820t_sysfreq_sel(priv, freq, type, std, delsys);
err:
- mutex_unlock(&priv->lock);
if (rc < 0)
tuner_dbg("%s: failed=%d\n", __func__, rc);
@@ -1335,6 +1332,8 @@ static int r820t_xtal_check(struct r820t_priv *priv)
/*
* r820t frontend operations and tuner attach code
+ *
+ * All driver locks and i2c control are only in this part of the code
*/
static int r820t_init(struct dvb_frontend *fe)
@@ -1345,11 +1344,10 @@ static int r820t_init(struct dvb_frontend *fe)
tuner_dbg("%s:\n", __func__);
+ mutex_lock(&priv->lock);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- mutex_lock(&priv->lock);
-
if ((priv->cfg->rafael_chip == CHIP_R820T) ||
(priv->cfg->rafael_chip == CHIP_R828S) ||
(priv->cfg->rafael_chip == CHIP_R820C)) {
@@ -1369,17 +1367,13 @@ static int r820t_init(struct dvb_frontend *fe)
rc = r820t_write(priv, 0x05,
r820t_init_array, sizeof(r820t_init_array));
- mutex_unlock(&priv->lock);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0);
-
- return rc;
err:
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
+ mutex_unlock(&priv->lock);
- tuner_dbg("%s: failed=%d\n", __func__, rc);
+ if (rc < 0)
+ tuner_dbg("%s: failed=%d\n", __func__, rc);
return rc;
}
@@ -1390,15 +1384,15 @@ static int r820t_sleep(struct dvb_frontend *fe)
tuner_dbg("%s:\n", __func__);
+ mutex_lock(&priv->lock);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- mutex_lock(&priv->lock);
rc = r820t_standby(priv);
- mutex_unlock(&priv->lock);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
+ mutex_unlock(&priv->lock);
tuner_dbg("%s: failed=%d\n", __func__, rc);
return rc;
@@ -1409,6 +1403,7 @@ static int r820t_set_analog_freq(struct dvb_frontend *fe,
{
struct r820t_priv *priv = fe->tuner_priv;
unsigned bw;
+ int rc;
tuner_dbg("%s called\n", __func__);
@@ -1421,8 +1416,18 @@ static int r820t_set_analog_freq(struct dvb_frontend *fe,
else
bw = 8;
- return generic_set_freq(fe, 62500l * p->frequency, bw,
- V4L2_TUNER_ANALOG_TV, p->std, SYS_UNDEFINED);
+ mutex_lock(&priv->lock);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ rc = generic_set_freq(fe, 62500l * p->frequency, bw,
+ V4L2_TUNER_ANALOG_TV, p->std, SYS_UNDEFINED);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ mutex_unlock(&priv->lock);
+
+ return rc;
}
static int r820t_set_params(struct dvb_frontend *fe)
@@ -1435,6 +1440,7 @@ static int r820t_set_params(struct dvb_frontend *fe)
tuner_dbg("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
__func__, c->delivery_system, c->frequency, c->bandwidth_hz);
+ mutex_lock(&priv->lock);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -1447,6 +1453,7 @@ static int r820t_set_params(struct dvb_frontend *fe)
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
+ mutex_unlock(&priv->lock);
if (rc)
tuner_dbg("%s: failed=%d\n", __func__, rc);
@@ -1458,10 +1465,14 @@ static int r820t_signal(struct dvb_frontend *fe, u16 *strength)
struct r820t_priv *priv = fe->tuner_priv;
int rc = 0;
+ mutex_lock(&priv->lock);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
if (priv->has_lock) {
rc = r820t_read_gain(priv);
if (rc < 0)
- return rc;
+ goto err;
/* A higher gain at LNA means a lower signal strength */
*strength = (45 - rc) << 4 | 0xff;
@@ -1469,6 +1480,11 @@ static int r820t_signal(struct dvb_frontend *fe, u16 *strength)
*strength = 0;
}
+err:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ mutex_unlock(&priv->lock);
+
tuner_dbg("%s: %s, gain=%d strength=%d\n",
__func__,
priv->has_lock ? "PLL locked" : "no signal",