aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-04-07 18:32:55 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-16 20:24:10 -0400
commit7a5ef30dc3363ae1ab7243397be7dd8449063999 (patch)
treebb2f1df796de7f2942a6ff1a5e93dedd9daa673a /drivers/media
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')
-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 0fa355d1737c..5cd8256a203e 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,
1193 tuner_dbg("should set frequency to %d kHz, bw %d MHz\n", 1193 tuner_dbg("should set frequency to %d kHz, bw %d MHz\n",
1194 freq / 1000, bw); 1194 freq / 1000, bw);
1195 1195
1196 mutex_lock(&priv->lock);
1197
1198 if ((type == V4L2_TUNER_ANALOG_TV) && (std == V4L2_STD_SECAM_LC)) 1196 if ((type == V4L2_TUNER_ANALOG_TV) && (std == V4L2_STD_SECAM_LC))
1199 lo_freq = freq - priv->int_freq; 1197 lo_freq = freq - priv->int_freq;
1200 else 1198 else
@@ -1218,7 +1216,6 @@ static int generic_set_freq(struct dvb_frontend *fe,
1218 1216
1219 rc = r820t_sysfreq_sel(priv, freq, type, std, delsys); 1217 rc = r820t_sysfreq_sel(priv, freq, type, std, delsys);
1220err: 1218err:
1221 mutex_unlock(&priv->lock);
1222 1219
1223 if (rc < 0) 1220 if (rc < 0)
1224 tuner_dbg("%s: failed=%d\n", __func__, rc); 1221 tuner_dbg("%s: failed=%d\n", __func__, rc);
@@ -1335,6 +1332,8 @@ static int r820t_xtal_check(struct r820t_priv *priv)
1335 1332
1336/* 1333/*
1337 * r820t frontend operations and tuner attach code 1334 * r820t frontend operations and tuner attach code
1335 *
1336 * All driver locks and i2c control are only in this part of the code
1338 */ 1337 */
1339 1338
1340static int r820t_init(struct dvb_frontend *fe) 1339static int r820t_init(struct dvb_frontend *fe)
@@ -1345,11 +1344,10 @@ static int r820t_init(struct dvb_frontend *fe)
1345 1344
1346 tuner_dbg("%s:\n", __func__); 1345 tuner_dbg("%s:\n", __func__);
1347 1346
1347 mutex_lock(&priv->lock);
1348 if (fe->ops.i2c_gate_ctrl) 1348 if (fe->ops.i2c_gate_ctrl)
1349 fe->ops.i2c_gate_ctrl(fe, 1); 1349 fe->ops.i2c_gate_ctrl(fe, 1);
1350 1350
1351 mutex_lock(&priv->lock);
1352
1353 if ((priv->cfg->rafael_chip == CHIP_R820T) || 1351 if ((priv->cfg->rafael_chip == CHIP_R820T) ||
1354 (priv->cfg->rafael_chip == CHIP_R828S) || 1352 (priv->cfg->rafael_chip == CHIP_R828S) ||
1355 (priv->cfg->rafael_chip == CHIP_R820C)) { 1353 (priv->cfg->rafael_chip == CHIP_R820C)) {
@@ -1369,17 +1367,13 @@ static int r820t_init(struct dvb_frontend *fe)
1369 rc = r820t_write(priv, 0x05, 1367 rc = r820t_write(priv, 0x05,
1370 r820t_init_array, sizeof(r820t_init_array)); 1368 r820t_init_array, sizeof(r820t_init_array));
1371 1369
1372 mutex_unlock(&priv->lock);
1373
1374 if (fe->ops.i2c_gate_ctrl)
1375 fe->ops.i2c_gate_ctrl(fe, 0);
1376
1377 return rc;
1378err: 1370err:
1379 if (fe->ops.i2c_gate_ctrl) 1371 if (fe->ops.i2c_gate_ctrl)
1380 fe->ops.i2c_gate_ctrl(fe, 0); 1372 fe->ops.i2c_gate_ctrl(fe, 0);
1373 mutex_unlock(&priv->lock);
1381 1374
1382 tuner_dbg("%s: failed=%d\n", __func__, rc); 1375 if (rc < 0)
1376 tuner_dbg("%s: failed=%d\n", __func__, rc);
1383 return rc; 1377 return rc;
1384} 1378}
1385 1379
@@ -1390,15 +1384,15 @@ static int r820t_sleep(struct dvb_frontend *fe)
1390 1384
1391 tuner_dbg("%s:\n", __func__); 1385 tuner_dbg("%s:\n", __func__);
1392 1386
1387 mutex_lock(&priv->lock);
1393 if (fe->ops.i2c_gate_ctrl) 1388 if (fe->ops.i2c_gate_ctrl)
1394 fe->ops.i2c_gate_ctrl(fe, 1); 1389 fe->ops.i2c_gate_ctrl(fe, 1);
1395 1390
1396 mutex_lock(&priv->lock);
1397 rc = r820t_standby(priv); 1391 rc = r820t_standby(priv);
1398 mutex_unlock(&priv->lock);
1399 1392
1400 if (fe->ops.i2c_gate_ctrl) 1393 if (fe->ops.i2c_gate_ctrl)
1401 fe->ops.i2c_gate_ctrl(fe, 0); 1394 fe->ops.i2c_gate_ctrl(fe, 0);
1395 mutex_unlock(&priv->lock);
1402 1396
1403 tuner_dbg("%s: failed=%d\n", __func__, rc); 1397 tuner_dbg("%s: failed=%d\n", __func__, rc);
1404 return rc; 1398 return rc;
@@ -1409,6 +1403,7 @@ static int r820t_set_analog_freq(struct dvb_frontend *fe,
1409{ 1403{
1410 struct r820t_priv *priv = fe->tuner_priv; 1404 struct r820t_priv *priv = fe->tuner_priv;
1411 unsigned bw; 1405 unsigned bw;
1406 int rc;
1412 1407
1413 tuner_dbg("%s called\n", __func__); 1408 tuner_dbg("%s called\n", __func__);
1414 1409
@@ -1421,8 +1416,18 @@ static int r820t_set_analog_freq(struct dvb_frontend *fe,
1421 else 1416 else
1422 bw = 8; 1417 bw = 8;
1423 1418
1424 return generic_set_freq(fe, 62500l * p->frequency, bw, 1419 mutex_lock(&priv->lock);
1425 V4L2_TUNER_ANALOG_TV, p->std, SYS_UNDEFINED); 1420 if (fe->ops.i2c_gate_ctrl)
1421 fe->ops.i2c_gate_ctrl(fe, 1);
1422
1423 rc = generic_set_freq(fe, 62500l * p->frequency, bw,
1424 V4L2_TUNER_ANALOG_TV, p->std, SYS_UNDEFINED);
1425
1426 if (fe->ops.i2c_gate_ctrl)
1427 fe->ops.i2c_gate_ctrl(fe, 0);
1428 mutex_unlock(&priv->lock);
1429
1430 return rc;
1426} 1431}
1427 1432
1428static int r820t_set_params(struct dvb_frontend *fe) 1433static int r820t_set_params(struct dvb_frontend *fe)
@@ -1435,6 +1440,7 @@ static int r820t_set_params(struct dvb_frontend *fe)
1435 tuner_dbg("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n", 1440 tuner_dbg("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
1436 __func__, c->delivery_system, c->frequency, c->bandwidth_hz); 1441 __func__, c->delivery_system, c->frequency, c->bandwidth_hz);
1437 1442
1443 mutex_lock(&priv->lock);
1438 if (fe->ops.i2c_gate_ctrl) 1444 if (fe->ops.i2c_gate_ctrl)
1439 fe->ops.i2c_gate_ctrl(fe, 1); 1445 fe->ops.i2c_gate_ctrl(fe, 1);
1440 1446
@@ -1447,6 +1453,7 @@ static int r820t_set_params(struct dvb_frontend *fe)
1447 1453
1448 if (fe->ops.i2c_gate_ctrl) 1454 if (fe->ops.i2c_gate_ctrl)
1449 fe->ops.i2c_gate_ctrl(fe, 0); 1455 fe->ops.i2c_gate_ctrl(fe, 0);
1456 mutex_unlock(&priv->lock);
1450 1457
1451 if (rc) 1458 if (rc)
1452 tuner_dbg("%s: failed=%d\n", __func__, rc); 1459 tuner_dbg("%s: failed=%d\n", __func__, rc);
@@ -1458,10 +1465,14 @@ static int r820t_signal(struct dvb_frontend *fe, u16 *strength)
1458 struct r820t_priv *priv = fe->tuner_priv; 1465 struct r820t_priv *priv = fe->tuner_priv;
1459 int rc = 0; 1466 int rc = 0;
1460 1467
1468 mutex_lock(&priv->lock);
1469 if (fe->ops.i2c_gate_ctrl)
1470 fe->ops.i2c_gate_ctrl(fe, 1);
1471
1461 if (priv->has_lock) { 1472 if (priv->has_lock) {
1462 rc = r820t_read_gain(priv); 1473 rc = r820t_read_gain(priv);
1463 if (rc < 0) 1474 if (rc < 0)
1464 return rc; 1475 goto err;
1465 1476
1466 /* A higher gain at LNA means a lower signal strength */ 1477 /* A higher gain at LNA means a lower signal strength */
1467 *strength = (45 - rc) << 4 | 0xff; 1478 *strength = (45 - rc) << 4 | 0xff;
@@ -1469,6 +1480,11 @@ static int r820t_signal(struct dvb_frontend *fe, u16 *strength)
1469 *strength = 0; 1480 *strength = 0;
1470 } 1481 }
1471 1482
1483err:
1484 if (fe->ops.i2c_gate_ctrl)
1485 fe->ops.i2c_gate_ctrl(fe, 0);
1486 mutex_unlock(&priv->lock);
1487
1472 tuner_dbg("%s: %s, gain=%d strength=%d\n", 1488 tuner_dbg("%s: %s, gain=%d strength=%d\n",
1473 __func__, 1489 __func__,
1474 priv->has_lock ? "PLL locked" : "no signal", 1490 priv->has_lock ? "PLL locked" : "no signal",