aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/dvb-usb
diff options
context:
space:
mode:
authorOlivier Grenie <olivier.grenie@parrot.com>2012-12-31 08:17:44 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-22 16:15:07 -0400
commit5e9c85d983375fd84a4ba98b34f8fc38d4ec8766 (patch)
tree3af7bc434e572f2bccf33b71509207bd99a0a723 /drivers/media/usb/dvb-usb
parentaedabf7a5402cd46df6ca33e87d77762c08599b0 (diff)
[media] dib8096: enhancement
The intend of this patch is to improve the support of the dib8096. The PLL parameters are not automatically computed. The limit to set/unset external diode for attenuation has been updated. The TFE8096P board is using the new I2C API. Signed-off-by: Olivier Grenie <olivier.grenie@parrot.com> Signed-off-by: Patrick Boettcher <patrick.boettcher@parrot.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/dvb-usb')
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_devices.c208
1 files changed, 175 insertions, 33 deletions
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
index 5a4175ef3524..d0916c88d9c1 100644
--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
@@ -1431,13 +1431,22 @@ static int dib8090_get_adc_power(struct dvb_frontend *fe)
1431 return dib8000_get_adc_power(fe, 1); 1431 return dib8000_get_adc_power(fe, 1);
1432} 1432}
1433 1433
1434static void dib8090_agc_control(struct dvb_frontend *fe, u8 restart)
1435{
1436 deb_info("AGC control callback: %i\n", restart);
1437 dib0090_dcc_freq(fe, restart);
1438
1439 if (restart == 0) /* before AGC startup */
1440 dib0090_set_dc_servo(fe, 1);
1441}
1442
1434static struct dib8000_config dib809x_dib8000_config[2] = { 1443static struct dib8000_config dib809x_dib8000_config[2] = {
1435 { 1444 {
1436 .output_mpeg2_in_188_bytes = 1, 1445 .output_mpeg2_in_188_bytes = 1,
1437 1446
1438 .agc_config_count = 2, 1447 .agc_config_count = 2,
1439 .agc = dib8090_agc_config, 1448 .agc = dib8090_agc_config,
1440 .agc_control = dib0090_dcc_freq, 1449 .agc_control = dib8090_agc_control,
1441 .pll = &dib8090_pll_config_12mhz, 1450 .pll = &dib8090_pll_config_12mhz,
1442 .tuner_is_baseband = 1, 1451 .tuner_is_baseband = 1,
1443 1452
@@ -1456,7 +1465,7 @@ static struct dib8000_config dib809x_dib8000_config[2] = {
1456 1465
1457 .agc_config_count = 2, 1466 .agc_config_count = 2,
1458 .agc = dib8090_agc_config, 1467 .agc = dib8090_agc_config,
1459 .agc_control = dib0090_dcc_freq, 1468 .agc_control = dib8090_agc_control,
1460 .pll = &dib8090_pll_config_12mhz, 1469 .pll = &dib8090_pll_config_12mhz,
1461 .tuner_is_baseband = 1, 1470 .tuner_is_baseband = 1,
1462 1471
@@ -1504,28 +1513,89 @@ static struct dib0090_config dib809x_dib0090_config = {
1504 .fref_clock_ratio = 6, 1513 .fref_clock_ratio = 6,
1505}; 1514};
1506 1515
1516static u8 dib8090_compute_pll_parameters(struct dvb_frontend *fe)
1517{
1518 u8 optimal_pll_ratio = 20;
1519 u32 freq_adc, ratio, rest, max = 0;
1520 u8 pll_ratio;
1521
1522 for (pll_ratio = 17; pll_ratio <= 20; pll_ratio++) {
1523 freq_adc = 12 * pll_ratio * (1 << 8) / 16;
1524 ratio = ((fe->dtv_property_cache.frequency / 1000) * (1 << 8) / 1000) / freq_adc;
1525 rest = ((fe->dtv_property_cache.frequency / 1000) * (1 << 8) / 1000) - ratio * freq_adc;
1526
1527 if (rest > freq_adc / 2)
1528 rest = freq_adc - rest;
1529 deb_info("PLL ratio=%i rest=%i\n", pll_ratio, rest);
1530 if ((rest > max) && (rest > 717)) {
1531 optimal_pll_ratio = pll_ratio;
1532 max = rest;
1533 }
1534 }
1535 deb_info("optimal PLL ratio=%i\n", optimal_pll_ratio);
1536
1537 return optimal_pll_ratio;
1538}
1539
1507static int dib8096_set_param_override(struct dvb_frontend *fe) 1540static int dib8096_set_param_override(struct dvb_frontend *fe)
1508{ 1541{
1509 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1510 struct dvb_usb_adapter *adap = fe->dvb->priv; 1542 struct dvb_usb_adapter *adap = fe->dvb->priv;
1511 struct dib0700_adapter_state *state = adap->priv; 1543 struct dib0700_adapter_state *state = adap->priv;
1512 u8 band = BAND_OF_FREQUENCY(p->frequency/1000); 1544 u8 pll_ratio, band = BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
1513 u16 target; 1545 u16 target, ltgain, rf_gain_limit;
1546 u32 timf;
1514 int ret = 0; 1547 int ret = 0;
1515 enum frontend_tune_state tune_state = CT_SHUTDOWN; 1548 enum frontend_tune_state tune_state = CT_SHUTDOWN;
1516 u16 ltgain, rf_gain_limit; 1549
1550 switch (band) {
1551 default:
1552 deb_info("Warning : Rf frequency (%iHz) is not in the supported range, using VHF switch ", fe->dtv_property_cache.frequency);
1553 case BAND_VHF:
1554 dib8000_set_gpio(fe, 3, 0, 1);
1555 break;
1556 case BAND_UHF:
1557 dib8000_set_gpio(fe, 3, 0, 0);
1558 break;
1559 }
1517 1560
1518 ret = state->set_param_save(fe); 1561 ret = state->set_param_save(fe);
1519 if (ret < 0) 1562 if (ret < 0)
1520 return ret; 1563 return ret;
1521 1564
1522 target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2; 1565 if (fe->dtv_property_cache.bandwidth_hz != 6000000) {
1523 dib8000_set_wbd_ref(fe, target); 1566 deb_info("only 6MHz bandwidth is supported\n");
1567 return -EINVAL;
1568 }
1524 1569
1570 /** Update PLL if needed ratio **/
1571 dib8000_update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, 0);
1572
1573 /** Get optimize PLL ratio to remove spurious **/
1574 pll_ratio = dib8090_compute_pll_parameters(fe);
1575 if (pll_ratio == 17)
1576 timf = 21387946;
1577 else if (pll_ratio == 18)
1578 timf = 20199727;
1579 else if (pll_ratio == 19)
1580 timf = 19136583;
1581 else
1582 timf = 18179756;
1583
1584 /** Update ratio **/
1585 dib8000_update_pll(fe, &dib8090_pll_config_12mhz, fe->dtv_property_cache.bandwidth_hz / 1000, pll_ratio);
1586
1587 dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, timf);
1588
1589 if (band != BAND_CBAND) {
1590 /* dib0090_get_wbd_target is returning any possible temperature compensated wbd-target */
1591 target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2;
1592 dib8000_set_wbd_ref(fe, target);
1593 }
1525 1594
1526 if (band == BAND_CBAND) { 1595 if (band == BAND_CBAND) {
1527 deb_info("tuning in CBAND - soft-AGC startup\n"); 1596 deb_info("tuning in CBAND - soft-AGC startup\n");
1528 dib0090_set_tune_state(fe, CT_AGC_START); 1597 dib0090_set_tune_state(fe, CT_AGC_START);
1598
1529 do { 1599 do {
1530 ret = dib0090_gain_control(fe); 1600 ret = dib0090_gain_control(fe);
1531 msleep(ret); 1601 msleep(ret);
@@ -1534,14 +1604,17 @@ static int dib8096_set_param_override(struct dvb_frontend *fe)
1534 dib8000_set_gpio(fe, 6, 0, 1); 1604 dib8000_set_gpio(fe, 6, 0, 1);
1535 else if (tune_state == CT_AGC_STEP_1) { 1605 else if (tune_state == CT_AGC_STEP_1) {
1536 dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain); 1606 dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
1537 if (rf_gain_limit == 0) 1607 if (rf_gain_limit < 2000) /* activate the external attenuator in case of very high input power */
1538 dib8000_set_gpio(fe, 6, 0, 0); 1608 dib8000_set_gpio(fe, 6, 0, 0);
1539 } 1609 }
1540 } while (tune_state < CT_AGC_STOP); 1610 } while (tune_state < CT_AGC_STOP);
1611
1612 deb_info("switching to PWM AGC\n");
1541 dib0090_pwm_gain_reset(fe); 1613 dib0090_pwm_gain_reset(fe);
1542 dib8000_pwm_agc_reset(fe); 1614 dib8000_pwm_agc_reset(fe);
1543 dib8000_set_tune_state(fe, CT_DEMOD_START); 1615 dib8000_set_tune_state(fe, CT_DEMOD_START);
1544 } else { 1616 } else {
1617 /* for everything else than CBAND we are using standard AGC */
1545 deb_info("not tuning in CBAND - standard AGC startup\n"); 1618 deb_info("not tuning in CBAND - standard AGC startup\n");
1546 dib0090_pwm_gain_reset(fe); 1619 dib0090_pwm_gain_reset(fe);
1547 } 1620 }
@@ -1814,21 +1887,92 @@ struct dibx090p_adc {
1814 u32 pll_prediv; /* New loopdiv */ 1887 u32 pll_prediv; /* New loopdiv */
1815}; 1888};
1816 1889
1817struct dibx090p_adc dib8090p_adc_tab[] = { 1890struct dibx090p_best_adc {
1818 { 50000, 17043521, 16, 3}, /* 64 MHz */ 1891 u32 timf;
1819 {878000, 20199729, 9, 1}, /* 60 MHz */ 1892 u32 pll_loopdiv;
1820 {0xffffffff, 0, 0, 0}, /* 60 MHz */ 1893 u32 pll_prediv;
1821}; 1894};
1822 1895
1896static int dib8096p_get_best_sampling(struct dvb_frontend *fe, struct dibx090p_best_adc *adc)
1897{
1898 u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
1899 u16 xtal = 12000;
1900 u16 fcp_min = 1900; /* PLL, Minimum Frequency of phase comparator (KHz) */
1901 u16 fcp_max = 20000; /* PLL, Maximum Frequency of phase comparator (KHz) */
1902 u32 fmem_max = 140000; /* 140MHz max SDRAM freq */
1903 u32 fdem_min = 66000;
1904 u32 fcp = 0, fs = 0, fdem = 0, fmem = 0;
1905 u32 harmonic_id = 0;
1906
1907 adc->timf = 0;
1908 adc->pll_loopdiv = loopdiv;
1909 adc->pll_prediv = prediv;
1910
1911 deb_info("bandwidth = %d", fe->dtv_property_cache.bandwidth_hz);
1912
1913 /* Find Min and Max prediv */
1914 while ((xtal / max_prediv) >= fcp_min)
1915 max_prediv++;
1916
1917 max_prediv--;
1918 min_prediv = max_prediv;
1919 while ((xtal / min_prediv) <= fcp_max) {
1920 min_prediv--;
1921 if (min_prediv == 1)
1922 break;
1923 }
1924 deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv);
1925
1926 min_prediv = 1;
1927
1928 for (prediv = min_prediv; prediv < max_prediv; prediv++) {
1929 fcp = xtal / prediv;
1930 if (fcp > fcp_min && fcp < fcp_max) {
1931 for (loopdiv = 1; loopdiv < 64; loopdiv++) {
1932 fmem = ((xtal/prediv) * loopdiv);
1933 fdem = fmem / 2;
1934 fs = fdem / 4;
1935
1936 /* test min/max system restrictions */
1937 if ((fdem >= fdem_min) && (fmem <= fmem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz / 1000)) {
1938 spur = 0;
1939 /* test fs harmonics positions */
1940 for (harmonic_id = (fe->dtv_property_cache.frequency / (1000 * fs)); harmonic_id <= ((fe->dtv_property_cache.frequency / (1000 * fs)) + 1); harmonic_id++) {
1941 if (((fs * harmonic_id) >= (fe->dtv_property_cache.frequency / 1000 - (fe->dtv_property_cache.bandwidth_hz / 2000))) && ((fs * harmonic_id) <= (fe->dtv_property_cache.frequency / 1000 + (fe->dtv_property_cache.bandwidth_hz / 2000)))) {
1942 spur = 1;
1943 break;
1944 }
1945 }
1946
1947 if (!spur) {
1948 adc->pll_loopdiv = loopdiv;
1949 adc->pll_prediv = prediv;
1950 adc->timf = (4260880253U / fdem) * (1 << 8);
1951 adc->timf += ((4260880253U % fdem) << 8) / fdem;
1952
1953 deb_info("RF %6d; BW %6d; Xtal %6d; Fmem %6d; Fdem %6d; Fs %6d; Prediv %2d; Loopdiv %2d; Timf %8d;", fe->dtv_property_cache.frequency, fe->dtv_property_cache.bandwidth_hz, xtal, fmem, fdem, fs, prediv, loopdiv, adc->timf);
1954 break;
1955 }
1956 }
1957 }
1958 }
1959 if (!spur)
1960 break;
1961 }
1962
1963 if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0)
1964 return -EINVAL;
1965 return 0;
1966}
1967
1823static int dib8096p_agc_startup(struct dvb_frontend *fe) 1968static int dib8096p_agc_startup(struct dvb_frontend *fe)
1824{ 1969{
1825 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1826 struct dvb_usb_adapter *adap = fe->dvb->priv; 1970 struct dvb_usb_adapter *adap = fe->dvb->priv;
1827 struct dib0700_adapter_state *state = adap->priv; 1971 struct dib0700_adapter_state *state = adap->priv;
1828 struct dibx000_bandwidth_config pll; 1972 struct dibx000_bandwidth_config pll;
1973 struct dibx090p_best_adc adc;
1829 u16 target; 1974 u16 target;
1830 int better_sampling_freq = 0, ret; 1975 int ret;
1831 struct dibx090p_adc *adc_table = &dib8090p_adc_tab[0];
1832 1976
1833 ret = state->set_param_save(fe); 1977 ret = state->set_param_save(fe);
1834 if (ret < 0) 1978 if (ret < 0)
@@ -1841,23 +1985,27 @@ static int dib8096p_agc_startup(struct dvb_frontend *fe)
1841 target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2; 1985 target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
1842 dib8000_set_wbd_ref(fe, target); 1986 dib8000_set_wbd_ref(fe, target);
1843 1987
1988 if (dib8096p_get_best_sampling(fe, &adc) == 0) {
1989 pll.pll_ratio = adc.pll_loopdiv;
1990 pll.pll_prediv = adc.pll_prediv;
1844 1991
1845 while (p->frequency / 1000 > adc_table->freq) { 1992 dib0700_set_i2c_speed(adap->dev, 200);
1846 better_sampling_freq = 1;
1847 adc_table++;
1848 }
1849
1850 if ((adc_table->freq != 0xffffffff) && better_sampling_freq) {
1851 pll.pll_ratio = adc_table->pll_loopdiv;
1852 pll.pll_prediv = adc_table->pll_prediv;
1853 dib8000_update_pll(fe, &pll, fe->dtv_property_cache.bandwidth_hz / 1000, 0); 1993 dib8000_update_pll(fe, &pll, fe->dtv_property_cache.bandwidth_hz / 1000, 0);
1854 dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc_table->timf); 1994 dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
1995 dib0700_set_i2c_speed(adap->dev, 1000);
1855 } 1996 }
1856 return 0; 1997 return 0;
1857} 1998}
1858 1999
1859static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap) 2000static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap)
1860{ 2001{
2002 struct dib0700_state *st = adap->dev->priv;
2003 u32 fw_version;
2004
2005 dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
2006 if (fw_version >= 0x10200)
2007 st->fw_use_new_i2c_api = 1;
2008
1861 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); 2009 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1862 msleep(20); 2010 msleep(20);
1863 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); 2011 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
@@ -2242,13 +2390,7 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap)
2242} 2390}
2243 2391
2244/* NIM7090 */ 2392/* NIM7090 */
2245struct dib7090p_best_adc { 2393static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dibx090p_best_adc *adc)
2246 u32 timf;
2247 u32 pll_loopdiv;
2248 u32 pll_prediv;
2249};
2250
2251static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_best_adc *adc)
2252{ 2394{
2253 u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1; 2395 u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
2254 2396
@@ -2327,7 +2469,7 @@ static int dib7090_agc_startup(struct dvb_frontend *fe)
2327 struct dib0700_adapter_state *state = adap->priv; 2469 struct dib0700_adapter_state *state = adap->priv;
2328 struct dibx000_bandwidth_config pll; 2470 struct dibx000_bandwidth_config pll;
2329 u16 target; 2471 u16 target;
2330 struct dib7090p_best_adc adc; 2472 struct dibx090p_best_adc adc;
2331 int ret; 2473 int ret;
2332 2474
2333 ret = state->set_param_save(fe); 2475 ret = state->set_param_save(fe);