diff options
Diffstat (limited to 'drivers/media/common/tuners/xc4000.c')
-rw-r--r-- | drivers/media/common/tuners/xc4000.c | 86 |
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 | ||
491 | static int xc_get_signal_level(struct xc4000_priv *priv, u16 *signal) | ||
492 | { | ||
493 | return xc4000_readreg(priv, XREG_SIGNAL_LEVEL, signal); | ||
494 | } | ||
495 | |||
496 | static int xc_get_noise_level(struct xc4000_priv *priv, u16 *noise) | ||
497 | { | ||
498 | return xc4000_readreg(priv, XREG_NOISE_LEVEL, noise); | ||
499 | } | ||
500 | |||
489 | static u16 xc_wait_for_lock(struct xc4000_priv *priv) | 501 | static 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 | ||
1124 | static int xc4000_set_params(struct dvb_frontend *fe) | 1144 | static int xc4000_set_params(struct dvb_frontend *fe) |
@@ -1432,6 +1452,71 @@ fail: | |||
1432 | return ret; | 1452 | return ret; |
1433 | } | 1453 | } |
1434 | 1454 | ||
1455 | static 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 | */ | ||
1503 | digital: | ||
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 | |||
1514 | ret: | ||
1515 | *strength = value; | ||
1516 | |||
1517 | return rc; | ||
1518 | } | ||
1519 | |||
1435 | static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq) | 1520 | static 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 | }; |