aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common/tuners/xc4000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/common/tuners/xc4000.c')
-rw-r--r--drivers/media/common/tuners/xc4000.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/common/tuners/xc4000.c
index d218c1d68c3..68397110b7d 100644
--- a/drivers/media/common/tuners/xc4000.c
+++ b/drivers/media/common/tuners/xc4000.c
@@ -154,6 +154,8 @@ struct xc4000_priv {
154#define XREG_SNR 0x06 154#define XREG_SNR 0x06
155#define XREG_VERSION 0x07 155#define XREG_VERSION 0x07
156#define XREG_PRODUCT_ID 0x08 156#define XREG_PRODUCT_ID 0x08
157#define XREG_SIGNAL_LEVEL 0x0A
158#define XREG_NOISE_LEVEL 0x0B
157 159
158/* 160/*
159 Basic firmware description. This will remain with 161 Basic firmware description. This will remain with
@@ -486,6 +488,16 @@ static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
486 return xc4000_readreg(priv, XREG_QUALITY, quality); 488 return xc4000_readreg(priv, XREG_QUALITY, quality);
487} 489}
488 490
491static int xc_get_signal_level(struct xc4000_priv *priv, u16 *signal)
492{
493 return xc4000_readreg(priv, XREG_SIGNAL_LEVEL, signal);
494}
495
496static int xc_get_noise_level(struct xc4000_priv *priv, u16 *noise)
497{
498 return xc4000_readreg(priv, XREG_NOISE_LEVEL, noise);
499}
500
489static u16 xc_wait_for_lock(struct xc4000_priv *priv) 501static u16 xc_wait_for_lock(struct xc4000_priv *priv)
490{ 502{
491 u16 lock_state = 0; 503 u16 lock_state = 0;
@@ -1089,6 +1101,8 @@ static void xc_debug_dump(struct xc4000_priv *priv)
1089 u32 hsync_freq_hz = 0; 1101 u32 hsync_freq_hz = 0;
1090 u16 frame_lines; 1102 u16 frame_lines;
1091 u16 quality; 1103 u16 quality;
1104 u16 signal = 0;
1105 u16 noise = 0;
1092 u8 hw_majorversion = 0, hw_minorversion = 0; 1106 u8 hw_majorversion = 0, hw_minorversion = 0;
1093 u8 fw_majorversion = 0, fw_minorversion = 0; 1107 u8 fw_majorversion = 0, fw_minorversion = 0;
1094 1108
@@ -1119,6 +1133,12 @@ static void xc_debug_dump(struct xc4000_priv *priv)
1119 1133
1120 xc_get_quality(priv, &quality); 1134 xc_get_quality(priv, &quality);
1121 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality); 1135 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
1136
1137 xc_get_signal_level(priv, &signal);
1138 dprintk(1, "*** Signal level = -%ddB (%d)\n", signal >> 8, signal);
1139
1140 xc_get_noise_level(priv, &noise);
1141 dprintk(1, "*** Noise level = %ddB (%d)\n", noise >> 8, noise);
1122} 1142}
1123 1143
1124static int xc4000_set_params(struct dvb_frontend *fe) 1144static int xc4000_set_params(struct dvb_frontend *fe)
@@ -1432,6 +1452,71 @@ fail:
1432 return ret; 1452 return ret;
1433} 1453}
1434 1454
1455static int xc4000_get_signal(struct dvb_frontend *fe, u16 *strength)
1456{
1457 struct xc4000_priv *priv = fe->tuner_priv;
1458 u16 value = 0;
1459 int rc;
1460
1461 mutex_lock(&priv->lock);
1462 rc = xc4000_readreg(priv, XREG_SIGNAL_LEVEL, &value);
1463 mutex_unlock(&priv->lock);
1464
1465 if (rc < 0)
1466 goto ret;
1467
1468 /* Informations from real testing of DVB-T and radio part,
1469 coeficient for one dB is 0xff.
1470 */
1471 tuner_dbg("Signal strength: -%ddB (%05d)\n", value >> 8, value);
1472
1473 /* all known digital modes */
1474 if ((priv->video_standard == XC4000_DTV6) ||
1475 (priv->video_standard == XC4000_DTV7) ||
1476 (priv->video_standard == XC4000_DTV7_8) ||
1477 (priv->video_standard == XC4000_DTV8))
1478 goto digital;
1479
1480 /* Analog mode has NOISE LEVEL important, signal
1481 depends only on gain of antenna and amplifiers,
1482 but it doesn't tell anything about real quality
1483 of reception.
1484 */
1485 mutex_lock(&priv->lock);
1486 rc = xc4000_readreg(priv, XREG_NOISE_LEVEL, &value);
1487 mutex_unlock(&priv->lock);
1488
1489 tuner_dbg("Noise level: %ddB (%05d)\n", value >> 8, value);
1490
1491 /* highest noise level: 32dB */
1492 if (value >= 0x2000) {
1493 value = 0;
1494 } else {
1495 value = ~value << 3;
1496 }
1497
1498 goto ret;
1499
1500 /* Digital mode has SIGNAL LEVEL important and real
1501 noise level is stored in demodulator registers.
1502 */
1503digital:
1504 /* best signal: -50dB */
1505 if (value <= 0x3200) {
1506 value = 0xffff;
1507 /* minimum: -114dB - should be 0x7200 but real zero is 0x713A */
1508 } else if (value >= 0x713A) {
1509 value = 0;
1510 } else {
1511 value = ~(value - 0x3200) << 2;
1512 }
1513
1514ret:
1515 *strength = value;
1516
1517 return rc;
1518}
1519
1435static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq) 1520static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
1436{ 1521{
1437 struct xc4000_priv *priv = fe->tuner_priv; 1522 struct xc4000_priv *priv = fe->tuner_priv;
@@ -1559,6 +1644,7 @@ static const struct dvb_tuner_ops xc4000_tuner_ops = {
1559 .set_params = xc4000_set_params, 1644 .set_params = xc4000_set_params,
1560 .set_analog_params = xc4000_set_analog_params, 1645 .set_analog_params = xc4000_set_analog_params,
1561 .get_frequency = xc4000_get_frequency, 1646 .get_frequency = xc4000_get_frequency,
1647 .get_rf_strength = xc4000_get_signal,
1562 .get_bandwidth = xc4000_get_bandwidth, 1648 .get_bandwidth = xc4000_get_bandwidth,
1563 .get_status = xc4000_get_status 1649 .get_status = xc4000_get_status
1564}; 1650};