18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci STV0900/0903 Multistandard Broadcast Frontend driver 48c2ecf20Sopenharmony_ci Copyright (C) Manu Abraham <abraham.manu@gmail.com> 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci Copyright (C) ST Microelectronics 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci*/ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/init.h> 118c2ecf20Sopenharmony_ci#include <linux/kernel.h> 128c2ecf20Sopenharmony_ci#include <linux/module.h> 138c2ecf20Sopenharmony_ci#include <linux/string.h> 148c2ecf20Sopenharmony_ci#include <linux/slab.h> 158c2ecf20Sopenharmony_ci#include <linux/mutex.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <linux/dvb/frontend.h> 188c2ecf20Sopenharmony_ci#include <media/dvb_frontend.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#include "stv6110x.h" /* for demodulator internal modes */ 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include "stv090x_reg.h" 238c2ecf20Sopenharmony_ci#include "stv090x.h" 248c2ecf20Sopenharmony_ci#include "stv090x_priv.h" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* Max transfer size done by I2C transfer functions */ 278c2ecf20Sopenharmony_ci#define MAX_XFER_SIZE 64 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistatic unsigned int verbose; 308c2ecf20Sopenharmony_cimodule_param(verbose, int, 0644); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* internal params node */ 338c2ecf20Sopenharmony_cistruct stv090x_dev { 348c2ecf20Sopenharmony_ci /* pointer for internal params, one for each pair of demods */ 358c2ecf20Sopenharmony_ci struct stv090x_internal *internal; 368c2ecf20Sopenharmony_ci struct stv090x_dev *next_dev; 378c2ecf20Sopenharmony_ci}; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/* first internal params */ 408c2ecf20Sopenharmony_cistatic struct stv090x_dev *stv090x_first_dev; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* find chip by i2c adapter and i2c address */ 438c2ecf20Sopenharmony_cistatic struct stv090x_dev *find_dev(struct i2c_adapter *i2c_adap, 448c2ecf20Sopenharmony_ci u8 i2c_addr) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci struct stv090x_dev *temp_dev = stv090x_first_dev; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci /* 498c2ecf20Sopenharmony_ci Search of the last stv0900 chip or 508c2ecf20Sopenharmony_ci find it by i2c adapter and i2c address */ 518c2ecf20Sopenharmony_ci while ((temp_dev != NULL) && 528c2ecf20Sopenharmony_ci ((temp_dev->internal->i2c_adap != i2c_adap) || 538c2ecf20Sopenharmony_ci (temp_dev->internal->i2c_addr != i2c_addr))) { 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci temp_dev = temp_dev->next_dev; 568c2ecf20Sopenharmony_ci } 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci return temp_dev; 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* deallocating chip */ 628c2ecf20Sopenharmony_cistatic void remove_dev(struct stv090x_internal *internal) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci struct stv090x_dev *prev_dev = stv090x_first_dev; 658c2ecf20Sopenharmony_ci struct stv090x_dev *del_dev = find_dev(internal->i2c_adap, 668c2ecf20Sopenharmony_ci internal->i2c_addr); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci if (del_dev != NULL) { 698c2ecf20Sopenharmony_ci if (del_dev == stv090x_first_dev) { 708c2ecf20Sopenharmony_ci stv090x_first_dev = del_dev->next_dev; 718c2ecf20Sopenharmony_ci } else { 728c2ecf20Sopenharmony_ci while (prev_dev->next_dev != del_dev) 738c2ecf20Sopenharmony_ci prev_dev = prev_dev->next_dev; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci prev_dev->next_dev = del_dev->next_dev; 768c2ecf20Sopenharmony_ci } 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci kfree(del_dev); 798c2ecf20Sopenharmony_ci } 808c2ecf20Sopenharmony_ci} 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci/* allocating new chip */ 838c2ecf20Sopenharmony_cistatic struct stv090x_dev *append_internal(struct stv090x_internal *internal) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci struct stv090x_dev *new_dev; 868c2ecf20Sopenharmony_ci struct stv090x_dev *temp_dev; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci new_dev = kmalloc(sizeof(struct stv090x_dev), GFP_KERNEL); 898c2ecf20Sopenharmony_ci if (new_dev != NULL) { 908c2ecf20Sopenharmony_ci new_dev->internal = internal; 918c2ecf20Sopenharmony_ci new_dev->next_dev = NULL; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci /* append to list */ 948c2ecf20Sopenharmony_ci if (stv090x_first_dev == NULL) { 958c2ecf20Sopenharmony_ci stv090x_first_dev = new_dev; 968c2ecf20Sopenharmony_ci } else { 978c2ecf20Sopenharmony_ci temp_dev = stv090x_first_dev; 988c2ecf20Sopenharmony_ci while (temp_dev->next_dev != NULL) 998c2ecf20Sopenharmony_ci temp_dev = temp_dev->next_dev; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci temp_dev->next_dev = new_dev; 1028c2ecf20Sopenharmony_ci } 1038c2ecf20Sopenharmony_ci } 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci return new_dev; 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci/* DVBS1 and DSS C/N Lookup table */ 1108c2ecf20Sopenharmony_cistatic const struct stv090x_tab stv090x_s1cn_tab[] = { 1118c2ecf20Sopenharmony_ci { 0, 8917 }, /* 0.0dB */ 1128c2ecf20Sopenharmony_ci { 5, 8801 }, /* 0.5dB */ 1138c2ecf20Sopenharmony_ci { 10, 8667 }, /* 1.0dB */ 1148c2ecf20Sopenharmony_ci { 15, 8522 }, /* 1.5dB */ 1158c2ecf20Sopenharmony_ci { 20, 8355 }, /* 2.0dB */ 1168c2ecf20Sopenharmony_ci { 25, 8175 }, /* 2.5dB */ 1178c2ecf20Sopenharmony_ci { 30, 7979 }, /* 3.0dB */ 1188c2ecf20Sopenharmony_ci { 35, 7763 }, /* 3.5dB */ 1198c2ecf20Sopenharmony_ci { 40, 7530 }, /* 4.0dB */ 1208c2ecf20Sopenharmony_ci { 45, 7282 }, /* 4.5dB */ 1218c2ecf20Sopenharmony_ci { 50, 7026 }, /* 5.0dB */ 1228c2ecf20Sopenharmony_ci { 55, 6781 }, /* 5.5dB */ 1238c2ecf20Sopenharmony_ci { 60, 6514 }, /* 6.0dB */ 1248c2ecf20Sopenharmony_ci { 65, 6241 }, /* 6.5dB */ 1258c2ecf20Sopenharmony_ci { 70, 5965 }, /* 7.0dB */ 1268c2ecf20Sopenharmony_ci { 75, 5690 }, /* 7.5dB */ 1278c2ecf20Sopenharmony_ci { 80, 5424 }, /* 8.0dB */ 1288c2ecf20Sopenharmony_ci { 85, 5161 }, /* 8.5dB */ 1298c2ecf20Sopenharmony_ci { 90, 4902 }, /* 9.0dB */ 1308c2ecf20Sopenharmony_ci { 95, 4654 }, /* 9.5dB */ 1318c2ecf20Sopenharmony_ci { 100, 4417 }, /* 10.0dB */ 1328c2ecf20Sopenharmony_ci { 105, 4186 }, /* 10.5dB */ 1338c2ecf20Sopenharmony_ci { 110, 3968 }, /* 11.0dB */ 1348c2ecf20Sopenharmony_ci { 115, 3757 }, /* 11.5dB */ 1358c2ecf20Sopenharmony_ci { 120, 3558 }, /* 12.0dB */ 1368c2ecf20Sopenharmony_ci { 125, 3366 }, /* 12.5dB */ 1378c2ecf20Sopenharmony_ci { 130, 3185 }, /* 13.0dB */ 1388c2ecf20Sopenharmony_ci { 135, 3012 }, /* 13.5dB */ 1398c2ecf20Sopenharmony_ci { 140, 2850 }, /* 14.0dB */ 1408c2ecf20Sopenharmony_ci { 145, 2698 }, /* 14.5dB */ 1418c2ecf20Sopenharmony_ci { 150, 2550 }, /* 15.0dB */ 1428c2ecf20Sopenharmony_ci { 160, 2283 }, /* 16.0dB */ 1438c2ecf20Sopenharmony_ci { 170, 2042 }, /* 17.0dB */ 1448c2ecf20Sopenharmony_ci { 180, 1827 }, /* 18.0dB */ 1458c2ecf20Sopenharmony_ci { 190, 1636 }, /* 19.0dB */ 1468c2ecf20Sopenharmony_ci { 200, 1466 }, /* 20.0dB */ 1478c2ecf20Sopenharmony_ci { 210, 1315 }, /* 21.0dB */ 1488c2ecf20Sopenharmony_ci { 220, 1181 }, /* 22.0dB */ 1498c2ecf20Sopenharmony_ci { 230, 1064 }, /* 23.0dB */ 1508c2ecf20Sopenharmony_ci { 240, 960 }, /* 24.0dB */ 1518c2ecf20Sopenharmony_ci { 250, 869 }, /* 25.0dB */ 1528c2ecf20Sopenharmony_ci { 260, 792 }, /* 26.0dB */ 1538c2ecf20Sopenharmony_ci { 270, 724 }, /* 27.0dB */ 1548c2ecf20Sopenharmony_ci { 280, 665 }, /* 28.0dB */ 1558c2ecf20Sopenharmony_ci { 290, 616 }, /* 29.0dB */ 1568c2ecf20Sopenharmony_ci { 300, 573 }, /* 30.0dB */ 1578c2ecf20Sopenharmony_ci { 310, 537 }, /* 31.0dB */ 1588c2ecf20Sopenharmony_ci { 320, 507 }, /* 32.0dB */ 1598c2ecf20Sopenharmony_ci { 330, 483 }, /* 33.0dB */ 1608c2ecf20Sopenharmony_ci { 400, 398 }, /* 40.0dB */ 1618c2ecf20Sopenharmony_ci { 450, 381 }, /* 45.0dB */ 1628c2ecf20Sopenharmony_ci { 500, 377 } /* 50.0dB */ 1638c2ecf20Sopenharmony_ci}; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/* DVBS2 C/N Lookup table */ 1668c2ecf20Sopenharmony_cistatic const struct stv090x_tab stv090x_s2cn_tab[] = { 1678c2ecf20Sopenharmony_ci { -30, 13348 }, /* -3.0dB */ 1688c2ecf20Sopenharmony_ci { -20, 12640 }, /* -2d.0B */ 1698c2ecf20Sopenharmony_ci { -10, 11883 }, /* -1.0dB */ 1708c2ecf20Sopenharmony_ci { 0, 11101 }, /* -0.0dB */ 1718c2ecf20Sopenharmony_ci { 5, 10718 }, /* 0.5dB */ 1728c2ecf20Sopenharmony_ci { 10, 10339 }, /* 1.0dB */ 1738c2ecf20Sopenharmony_ci { 15, 9947 }, /* 1.5dB */ 1748c2ecf20Sopenharmony_ci { 20, 9552 }, /* 2.0dB */ 1758c2ecf20Sopenharmony_ci { 25, 9183 }, /* 2.5dB */ 1768c2ecf20Sopenharmony_ci { 30, 8799 }, /* 3.0dB */ 1778c2ecf20Sopenharmony_ci { 35, 8422 }, /* 3.5dB */ 1788c2ecf20Sopenharmony_ci { 40, 8062 }, /* 4.0dB */ 1798c2ecf20Sopenharmony_ci { 45, 7707 }, /* 4.5dB */ 1808c2ecf20Sopenharmony_ci { 50, 7353 }, /* 5.0dB */ 1818c2ecf20Sopenharmony_ci { 55, 7025 }, /* 5.5dB */ 1828c2ecf20Sopenharmony_ci { 60, 6684 }, /* 6.0dB */ 1838c2ecf20Sopenharmony_ci { 65, 6331 }, /* 6.5dB */ 1848c2ecf20Sopenharmony_ci { 70, 6036 }, /* 7.0dB */ 1858c2ecf20Sopenharmony_ci { 75, 5727 }, /* 7.5dB */ 1868c2ecf20Sopenharmony_ci { 80, 5437 }, /* 8.0dB */ 1878c2ecf20Sopenharmony_ci { 85, 5164 }, /* 8.5dB */ 1888c2ecf20Sopenharmony_ci { 90, 4902 }, /* 9.0dB */ 1898c2ecf20Sopenharmony_ci { 95, 4653 }, /* 9.5dB */ 1908c2ecf20Sopenharmony_ci { 100, 4408 }, /* 10.0dB */ 1918c2ecf20Sopenharmony_ci { 105, 4187 }, /* 10.5dB */ 1928c2ecf20Sopenharmony_ci { 110, 3961 }, /* 11.0dB */ 1938c2ecf20Sopenharmony_ci { 115, 3751 }, /* 11.5dB */ 1948c2ecf20Sopenharmony_ci { 120, 3558 }, /* 12.0dB */ 1958c2ecf20Sopenharmony_ci { 125, 3368 }, /* 12.5dB */ 1968c2ecf20Sopenharmony_ci { 130, 3191 }, /* 13.0dB */ 1978c2ecf20Sopenharmony_ci { 135, 3017 }, /* 13.5dB */ 1988c2ecf20Sopenharmony_ci { 140, 2862 }, /* 14.0dB */ 1998c2ecf20Sopenharmony_ci { 145, 2710 }, /* 14.5dB */ 2008c2ecf20Sopenharmony_ci { 150, 2565 }, /* 15.0dB */ 2018c2ecf20Sopenharmony_ci { 160, 2300 }, /* 16.0dB */ 2028c2ecf20Sopenharmony_ci { 170, 2058 }, /* 17.0dB */ 2038c2ecf20Sopenharmony_ci { 180, 1849 }, /* 18.0dB */ 2048c2ecf20Sopenharmony_ci { 190, 1663 }, /* 19.0dB */ 2058c2ecf20Sopenharmony_ci { 200, 1495 }, /* 20.0dB */ 2068c2ecf20Sopenharmony_ci { 210, 1349 }, /* 21.0dB */ 2078c2ecf20Sopenharmony_ci { 220, 1222 }, /* 22.0dB */ 2088c2ecf20Sopenharmony_ci { 230, 1110 }, /* 23.0dB */ 2098c2ecf20Sopenharmony_ci { 240, 1011 }, /* 24.0dB */ 2108c2ecf20Sopenharmony_ci { 250, 925 }, /* 25.0dB */ 2118c2ecf20Sopenharmony_ci { 260, 853 }, /* 26.0dB */ 2128c2ecf20Sopenharmony_ci { 270, 789 }, /* 27.0dB */ 2138c2ecf20Sopenharmony_ci { 280, 734 }, /* 28.0dB */ 2148c2ecf20Sopenharmony_ci { 290, 690 }, /* 29.0dB */ 2158c2ecf20Sopenharmony_ci { 300, 650 }, /* 30.0dB */ 2168c2ecf20Sopenharmony_ci { 310, 619 }, /* 31.0dB */ 2178c2ecf20Sopenharmony_ci { 320, 593 }, /* 32.0dB */ 2188c2ecf20Sopenharmony_ci { 330, 571 }, /* 33.0dB */ 2198c2ecf20Sopenharmony_ci { 400, 498 }, /* 40.0dB */ 2208c2ecf20Sopenharmony_ci { 450, 484 }, /* 45.0dB */ 2218c2ecf20Sopenharmony_ci { 500, 481 } /* 50.0dB */ 2228c2ecf20Sopenharmony_ci}; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci/* RF level C/N lookup table */ 2258c2ecf20Sopenharmony_cistatic const struct stv090x_tab stv090x_rf_tab[] = { 2268c2ecf20Sopenharmony_ci { -5, 0xcaa1 }, /* -5dBm */ 2278c2ecf20Sopenharmony_ci { -10, 0xc229 }, /* -10dBm */ 2288c2ecf20Sopenharmony_ci { -15, 0xbb08 }, /* -15dBm */ 2298c2ecf20Sopenharmony_ci { -20, 0xb4bc }, /* -20dBm */ 2308c2ecf20Sopenharmony_ci { -25, 0xad5a }, /* -25dBm */ 2318c2ecf20Sopenharmony_ci { -30, 0xa298 }, /* -30dBm */ 2328c2ecf20Sopenharmony_ci { -35, 0x98a8 }, /* -35dBm */ 2338c2ecf20Sopenharmony_ci { -40, 0x8389 }, /* -40dBm */ 2348c2ecf20Sopenharmony_ci { -45, 0x59be }, /* -45dBm */ 2358c2ecf20Sopenharmony_ci { -50, 0x3a14 }, /* -50dBm */ 2368c2ecf20Sopenharmony_ci { -55, 0x2d11 }, /* -55dBm */ 2378c2ecf20Sopenharmony_ci { -60, 0x210d }, /* -60dBm */ 2388c2ecf20Sopenharmony_ci { -65, 0xa14f }, /* -65dBm */ 2398c2ecf20Sopenharmony_ci { -70, 0x07aa } /* -70dBm */ 2408c2ecf20Sopenharmony_ci}; 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_cistatic struct stv090x_reg stv0900_initval[] = { 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci { STV090x_OUTCFG, 0x00 }, 2468c2ecf20Sopenharmony_ci { STV090x_MODECFG, 0xff }, 2478c2ecf20Sopenharmony_ci { STV090x_AGCRF1CFG, 0x11 }, 2488c2ecf20Sopenharmony_ci { STV090x_AGCRF2CFG, 0x13 }, 2498c2ecf20Sopenharmony_ci { STV090x_TSGENERAL1X, 0x14 }, 2508c2ecf20Sopenharmony_ci { STV090x_TSTTNR2, 0x21 }, 2518c2ecf20Sopenharmony_ci { STV090x_TSTTNR4, 0x21 }, 2528c2ecf20Sopenharmony_ci { STV090x_P2_DISTXCTL, 0x22 }, 2538c2ecf20Sopenharmony_ci { STV090x_P2_F22TX, 0xc0 }, 2548c2ecf20Sopenharmony_ci { STV090x_P2_F22RX, 0xc0 }, 2558c2ecf20Sopenharmony_ci { STV090x_P2_DISRXCTL, 0x00 }, 2568c2ecf20Sopenharmony_ci { STV090x_P2_DMDCFGMD, 0xF9 }, 2578c2ecf20Sopenharmony_ci { STV090x_P2_DEMOD, 0x08 }, 2588c2ecf20Sopenharmony_ci { STV090x_P2_DMDCFG3, 0xc4 }, 2598c2ecf20Sopenharmony_ci { STV090x_P2_CARFREQ, 0xed }, 2608c2ecf20Sopenharmony_ci { STV090x_P2_LDT, 0xd0 }, 2618c2ecf20Sopenharmony_ci { STV090x_P2_LDT2, 0xb8 }, 2628c2ecf20Sopenharmony_ci { STV090x_P2_TMGCFG, 0xd2 }, 2638c2ecf20Sopenharmony_ci { STV090x_P2_TMGTHRISE, 0x20 }, 2648c2ecf20Sopenharmony_ci { STV090x_P1_TMGCFG, 0xd2 }, 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci { STV090x_P2_TMGTHFALL, 0x00 }, 2678c2ecf20Sopenharmony_ci { STV090x_P2_FECSPY, 0x88 }, 2688c2ecf20Sopenharmony_ci { STV090x_P2_FSPYDATA, 0x3a }, 2698c2ecf20Sopenharmony_ci { STV090x_P2_FBERCPT4, 0x00 }, 2708c2ecf20Sopenharmony_ci { STV090x_P2_FSPYBER, 0x10 }, 2718c2ecf20Sopenharmony_ci { STV090x_P2_ERRCTRL1, 0x35 }, 2728c2ecf20Sopenharmony_ci { STV090x_P2_ERRCTRL2, 0xc1 }, 2738c2ecf20Sopenharmony_ci { STV090x_P2_CFRICFG, 0xf8 }, 2748c2ecf20Sopenharmony_ci { STV090x_P2_NOSCFG, 0x1c }, 2758c2ecf20Sopenharmony_ci { STV090x_P2_DMDTOM, 0x20 }, 2768c2ecf20Sopenharmony_ci { STV090x_P2_CORRELMANT, 0x70 }, 2778c2ecf20Sopenharmony_ci { STV090x_P2_CORRELABS, 0x88 }, 2788c2ecf20Sopenharmony_ci { STV090x_P2_AGC2O, 0x5b }, 2798c2ecf20Sopenharmony_ci { STV090x_P2_AGC2REF, 0x38 }, 2808c2ecf20Sopenharmony_ci { STV090x_P2_CARCFG, 0xe4 }, 2818c2ecf20Sopenharmony_ci { STV090x_P2_ACLC, 0x1A }, 2828c2ecf20Sopenharmony_ci { STV090x_P2_BCLC, 0x09 }, 2838c2ecf20Sopenharmony_ci { STV090x_P2_CARHDR, 0x08 }, 2848c2ecf20Sopenharmony_ci { STV090x_P2_KREFTMG, 0xc1 }, 2858c2ecf20Sopenharmony_ci { STV090x_P2_SFRUPRATIO, 0xf0 }, 2868c2ecf20Sopenharmony_ci { STV090x_P2_SFRLOWRATIO, 0x70 }, 2878c2ecf20Sopenharmony_ci { STV090x_P2_SFRSTEP, 0x58 }, 2888c2ecf20Sopenharmony_ci { STV090x_P2_TMGCFG2, 0x01 }, 2898c2ecf20Sopenharmony_ci { STV090x_P2_CAR2CFG, 0x26 }, 2908c2ecf20Sopenharmony_ci { STV090x_P2_BCLC2S2Q, 0x86 }, 2918c2ecf20Sopenharmony_ci { STV090x_P2_BCLC2S28, 0x86 }, 2928c2ecf20Sopenharmony_ci { STV090x_P2_SMAPCOEF7, 0x77 }, 2938c2ecf20Sopenharmony_ci { STV090x_P2_SMAPCOEF6, 0x85 }, 2948c2ecf20Sopenharmony_ci { STV090x_P2_SMAPCOEF5, 0x77 }, 2958c2ecf20Sopenharmony_ci { STV090x_P2_TSCFGL, 0x20 }, 2968c2ecf20Sopenharmony_ci { STV090x_P2_DMDCFG2, 0x3b }, 2978c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLST0, 0xff }, 2988c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLST1, 0xff }, 2998c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLST2, 0xff }, 3008c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLST3, 0xff }, 3018c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLST4, 0xff }, 3028c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLST5, 0xff }, 3038c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLST6, 0xff }, 3048c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLST7, 0xcc }, 3058c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLST8, 0xcc }, 3068c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLST9, 0xcc }, 3078c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLSTA, 0xcc }, 3088c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLSTB, 0xcc }, 3098c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLSTC, 0xcc }, 3108c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLSTD, 0xcc }, 3118c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLSTE, 0xcc }, 3128c2ecf20Sopenharmony_ci { STV090x_P2_MODCODLSTF, 0xcf }, 3138c2ecf20Sopenharmony_ci { STV090x_P1_DISTXCTL, 0x22 }, 3148c2ecf20Sopenharmony_ci { STV090x_P1_F22TX, 0xc0 }, 3158c2ecf20Sopenharmony_ci { STV090x_P1_F22RX, 0xc0 }, 3168c2ecf20Sopenharmony_ci { STV090x_P1_DISRXCTL, 0x00 }, 3178c2ecf20Sopenharmony_ci { STV090x_P1_DMDCFGMD, 0xf9 }, 3188c2ecf20Sopenharmony_ci { STV090x_P1_DEMOD, 0x08 }, 3198c2ecf20Sopenharmony_ci { STV090x_P1_DMDCFG3, 0xc4 }, 3208c2ecf20Sopenharmony_ci { STV090x_P1_DMDTOM, 0x20 }, 3218c2ecf20Sopenharmony_ci { STV090x_P1_CARFREQ, 0xed }, 3228c2ecf20Sopenharmony_ci { STV090x_P1_LDT, 0xd0 }, 3238c2ecf20Sopenharmony_ci { STV090x_P1_LDT2, 0xb8 }, 3248c2ecf20Sopenharmony_ci { STV090x_P1_TMGCFG, 0xd2 }, 3258c2ecf20Sopenharmony_ci { STV090x_P1_TMGTHRISE, 0x20 }, 3268c2ecf20Sopenharmony_ci { STV090x_P1_TMGTHFALL, 0x00 }, 3278c2ecf20Sopenharmony_ci { STV090x_P1_SFRUPRATIO, 0xf0 }, 3288c2ecf20Sopenharmony_ci { STV090x_P1_SFRLOWRATIO, 0x70 }, 3298c2ecf20Sopenharmony_ci { STV090x_P1_TSCFGL, 0x20 }, 3308c2ecf20Sopenharmony_ci { STV090x_P1_FECSPY, 0x88 }, 3318c2ecf20Sopenharmony_ci { STV090x_P1_FSPYDATA, 0x3a }, 3328c2ecf20Sopenharmony_ci { STV090x_P1_FBERCPT4, 0x00 }, 3338c2ecf20Sopenharmony_ci { STV090x_P1_FSPYBER, 0x10 }, 3348c2ecf20Sopenharmony_ci { STV090x_P1_ERRCTRL1, 0x35 }, 3358c2ecf20Sopenharmony_ci { STV090x_P1_ERRCTRL2, 0xc1 }, 3368c2ecf20Sopenharmony_ci { STV090x_P1_CFRICFG, 0xf8 }, 3378c2ecf20Sopenharmony_ci { STV090x_P1_NOSCFG, 0x1c }, 3388c2ecf20Sopenharmony_ci { STV090x_P1_CORRELMANT, 0x70 }, 3398c2ecf20Sopenharmony_ci { STV090x_P1_CORRELABS, 0x88 }, 3408c2ecf20Sopenharmony_ci { STV090x_P1_AGC2O, 0x5b }, 3418c2ecf20Sopenharmony_ci { STV090x_P1_AGC2REF, 0x38 }, 3428c2ecf20Sopenharmony_ci { STV090x_P1_CARCFG, 0xe4 }, 3438c2ecf20Sopenharmony_ci { STV090x_P1_ACLC, 0x1A }, 3448c2ecf20Sopenharmony_ci { STV090x_P1_BCLC, 0x09 }, 3458c2ecf20Sopenharmony_ci { STV090x_P1_CARHDR, 0x08 }, 3468c2ecf20Sopenharmony_ci { STV090x_P1_KREFTMG, 0xc1 }, 3478c2ecf20Sopenharmony_ci { STV090x_P1_SFRSTEP, 0x58 }, 3488c2ecf20Sopenharmony_ci { STV090x_P1_TMGCFG2, 0x01 }, 3498c2ecf20Sopenharmony_ci { STV090x_P1_CAR2CFG, 0x26 }, 3508c2ecf20Sopenharmony_ci { STV090x_P1_BCLC2S2Q, 0x86 }, 3518c2ecf20Sopenharmony_ci { STV090x_P1_BCLC2S28, 0x86 }, 3528c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF7, 0x77 }, 3538c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF6, 0x85 }, 3548c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF5, 0x77 }, 3558c2ecf20Sopenharmony_ci { STV090x_P1_DMDCFG2, 0x3b }, 3568c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST0, 0xff }, 3578c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST1, 0xff }, 3588c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST2, 0xff }, 3598c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST3, 0xff }, 3608c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST4, 0xff }, 3618c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST5, 0xff }, 3628c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST6, 0xff }, 3638c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST7, 0xcc }, 3648c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST8, 0xcc }, 3658c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST9, 0xcc }, 3668c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTA, 0xcc }, 3678c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTB, 0xcc }, 3688c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTC, 0xcc }, 3698c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTD, 0xcc }, 3708c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTE, 0xcc }, 3718c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTF, 0xcf }, 3728c2ecf20Sopenharmony_ci { STV090x_GENCFG, 0x1d }, 3738c2ecf20Sopenharmony_ci { STV090x_NBITER_NF4, 0x37 }, 3748c2ecf20Sopenharmony_ci { STV090x_NBITER_NF5, 0x29 }, 3758c2ecf20Sopenharmony_ci { STV090x_NBITER_NF6, 0x37 }, 3768c2ecf20Sopenharmony_ci { STV090x_NBITER_NF7, 0x33 }, 3778c2ecf20Sopenharmony_ci { STV090x_NBITER_NF8, 0x31 }, 3788c2ecf20Sopenharmony_ci { STV090x_NBITER_NF9, 0x2f }, 3798c2ecf20Sopenharmony_ci { STV090x_NBITER_NF10, 0x39 }, 3808c2ecf20Sopenharmony_ci { STV090x_NBITER_NF11, 0x3a }, 3818c2ecf20Sopenharmony_ci { STV090x_NBITER_NF12, 0x29 }, 3828c2ecf20Sopenharmony_ci { STV090x_NBITER_NF13, 0x37 }, 3838c2ecf20Sopenharmony_ci { STV090x_NBITER_NF14, 0x33 }, 3848c2ecf20Sopenharmony_ci { STV090x_NBITER_NF15, 0x2f }, 3858c2ecf20Sopenharmony_ci { STV090x_NBITER_NF16, 0x39 }, 3868c2ecf20Sopenharmony_ci { STV090x_NBITER_NF17, 0x3a }, 3878c2ecf20Sopenharmony_ci { STV090x_NBITERNOERR, 0x04 }, 3888c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF4, 0x0C }, 3898c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF5, 0x0F }, 3908c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF6, 0x11 }, 3918c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF7, 0x14 }, 3928c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF8, 0x17 }, 3938c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF9, 0x19 }, 3948c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF10, 0x20 }, 3958c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF11, 0x21 }, 3968c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF12, 0x0D }, 3978c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF13, 0x0F }, 3988c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF14, 0x13 }, 3998c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF15, 0x1A }, 4008c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF16, 0x1F }, 4018c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF17, 0x21 }, 4028c2ecf20Sopenharmony_ci { STV090x_RCCFGH, 0x20 }, 4038c2ecf20Sopenharmony_ci { STV090x_P1_FECM, 0x01 }, /* disable DSS modes */ 4048c2ecf20Sopenharmony_ci { STV090x_P2_FECM, 0x01 }, /* disable DSS modes */ 4058c2ecf20Sopenharmony_ci { STV090x_P1_PRVIT, 0x2F }, /* disable PR 6/7 */ 4068c2ecf20Sopenharmony_ci { STV090x_P2_PRVIT, 0x2F }, /* disable PR 6/7 */ 4078c2ecf20Sopenharmony_ci}; 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_cistatic struct stv090x_reg stv0903_initval[] = { 4108c2ecf20Sopenharmony_ci { STV090x_OUTCFG, 0x00 }, 4118c2ecf20Sopenharmony_ci { STV090x_AGCRF1CFG, 0x11 }, 4128c2ecf20Sopenharmony_ci { STV090x_STOPCLK1, 0x48 }, 4138c2ecf20Sopenharmony_ci { STV090x_STOPCLK2, 0x14 }, 4148c2ecf20Sopenharmony_ci { STV090x_TSTTNR1, 0x27 }, 4158c2ecf20Sopenharmony_ci { STV090x_TSTTNR2, 0x21 }, 4168c2ecf20Sopenharmony_ci { STV090x_P1_DISTXCTL, 0x22 }, 4178c2ecf20Sopenharmony_ci { STV090x_P1_F22TX, 0xc0 }, 4188c2ecf20Sopenharmony_ci { STV090x_P1_F22RX, 0xc0 }, 4198c2ecf20Sopenharmony_ci { STV090x_P1_DISRXCTL, 0x00 }, 4208c2ecf20Sopenharmony_ci { STV090x_P1_DMDCFGMD, 0xF9 }, 4218c2ecf20Sopenharmony_ci { STV090x_P1_DEMOD, 0x08 }, 4228c2ecf20Sopenharmony_ci { STV090x_P1_DMDCFG3, 0xc4 }, 4238c2ecf20Sopenharmony_ci { STV090x_P1_CARFREQ, 0xed }, 4248c2ecf20Sopenharmony_ci { STV090x_P1_TNRCFG2, 0x82 }, 4258c2ecf20Sopenharmony_ci { STV090x_P1_LDT, 0xd0 }, 4268c2ecf20Sopenharmony_ci { STV090x_P1_LDT2, 0xb8 }, 4278c2ecf20Sopenharmony_ci { STV090x_P1_TMGCFG, 0xd2 }, 4288c2ecf20Sopenharmony_ci { STV090x_P1_TMGTHRISE, 0x20 }, 4298c2ecf20Sopenharmony_ci { STV090x_P1_TMGTHFALL, 0x00 }, 4308c2ecf20Sopenharmony_ci { STV090x_P1_SFRUPRATIO, 0xf0 }, 4318c2ecf20Sopenharmony_ci { STV090x_P1_SFRLOWRATIO, 0x70 }, 4328c2ecf20Sopenharmony_ci { STV090x_P1_TSCFGL, 0x20 }, 4338c2ecf20Sopenharmony_ci { STV090x_P1_FECSPY, 0x88 }, 4348c2ecf20Sopenharmony_ci { STV090x_P1_FSPYDATA, 0x3a }, 4358c2ecf20Sopenharmony_ci { STV090x_P1_FBERCPT4, 0x00 }, 4368c2ecf20Sopenharmony_ci { STV090x_P1_FSPYBER, 0x10 }, 4378c2ecf20Sopenharmony_ci { STV090x_P1_ERRCTRL1, 0x35 }, 4388c2ecf20Sopenharmony_ci { STV090x_P1_ERRCTRL2, 0xc1 }, 4398c2ecf20Sopenharmony_ci { STV090x_P1_CFRICFG, 0xf8 }, 4408c2ecf20Sopenharmony_ci { STV090x_P1_NOSCFG, 0x1c }, 4418c2ecf20Sopenharmony_ci { STV090x_P1_DMDTOM, 0x20 }, 4428c2ecf20Sopenharmony_ci { STV090x_P1_CORRELMANT, 0x70 }, 4438c2ecf20Sopenharmony_ci { STV090x_P1_CORRELABS, 0x88 }, 4448c2ecf20Sopenharmony_ci { STV090x_P1_AGC2O, 0x5b }, 4458c2ecf20Sopenharmony_ci { STV090x_P1_AGC2REF, 0x38 }, 4468c2ecf20Sopenharmony_ci { STV090x_P1_CARCFG, 0xe4 }, 4478c2ecf20Sopenharmony_ci { STV090x_P1_ACLC, 0x1A }, 4488c2ecf20Sopenharmony_ci { STV090x_P1_BCLC, 0x09 }, 4498c2ecf20Sopenharmony_ci { STV090x_P1_CARHDR, 0x08 }, 4508c2ecf20Sopenharmony_ci { STV090x_P1_KREFTMG, 0xc1 }, 4518c2ecf20Sopenharmony_ci { STV090x_P1_SFRSTEP, 0x58 }, 4528c2ecf20Sopenharmony_ci { STV090x_P1_TMGCFG2, 0x01 }, 4538c2ecf20Sopenharmony_ci { STV090x_P1_CAR2CFG, 0x26 }, 4548c2ecf20Sopenharmony_ci { STV090x_P1_BCLC2S2Q, 0x86 }, 4558c2ecf20Sopenharmony_ci { STV090x_P1_BCLC2S28, 0x86 }, 4568c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF7, 0x77 }, 4578c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF6, 0x85 }, 4588c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF5, 0x77 }, 4598c2ecf20Sopenharmony_ci { STV090x_P1_DMDCFG2, 0x3b }, 4608c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST0, 0xff }, 4618c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST1, 0xff }, 4628c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST2, 0xff }, 4638c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST3, 0xff }, 4648c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST4, 0xff }, 4658c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST5, 0xff }, 4668c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST6, 0xff }, 4678c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST7, 0xcc }, 4688c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST8, 0xcc }, 4698c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLST9, 0xcc }, 4708c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTA, 0xcc }, 4718c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTB, 0xcc }, 4728c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTC, 0xcc }, 4738c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTD, 0xcc }, 4748c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTE, 0xcc }, 4758c2ecf20Sopenharmony_ci { STV090x_P1_MODCODLSTF, 0xcf }, 4768c2ecf20Sopenharmony_ci { STV090x_GENCFG, 0x1c }, 4778c2ecf20Sopenharmony_ci { STV090x_NBITER_NF4, 0x37 }, 4788c2ecf20Sopenharmony_ci { STV090x_NBITER_NF5, 0x29 }, 4798c2ecf20Sopenharmony_ci { STV090x_NBITER_NF6, 0x37 }, 4808c2ecf20Sopenharmony_ci { STV090x_NBITER_NF7, 0x33 }, 4818c2ecf20Sopenharmony_ci { STV090x_NBITER_NF8, 0x31 }, 4828c2ecf20Sopenharmony_ci { STV090x_NBITER_NF9, 0x2f }, 4838c2ecf20Sopenharmony_ci { STV090x_NBITER_NF10, 0x39 }, 4848c2ecf20Sopenharmony_ci { STV090x_NBITER_NF11, 0x3a }, 4858c2ecf20Sopenharmony_ci { STV090x_NBITER_NF12, 0x29 }, 4868c2ecf20Sopenharmony_ci { STV090x_NBITER_NF13, 0x37 }, 4878c2ecf20Sopenharmony_ci { STV090x_NBITER_NF14, 0x33 }, 4888c2ecf20Sopenharmony_ci { STV090x_NBITER_NF15, 0x2f }, 4898c2ecf20Sopenharmony_ci { STV090x_NBITER_NF16, 0x39 }, 4908c2ecf20Sopenharmony_ci { STV090x_NBITER_NF17, 0x3a }, 4918c2ecf20Sopenharmony_ci { STV090x_NBITERNOERR, 0x04 }, 4928c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF4, 0x0C }, 4938c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF5, 0x0F }, 4948c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF6, 0x11 }, 4958c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF7, 0x14 }, 4968c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF8, 0x17 }, 4978c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF9, 0x19 }, 4988c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF10, 0x20 }, 4998c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF11, 0x21 }, 5008c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF12, 0x0D }, 5018c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF13, 0x0F }, 5028c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF14, 0x13 }, 5038c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF15, 0x1A }, 5048c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF16, 0x1F }, 5058c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF17, 0x21 }, 5068c2ecf20Sopenharmony_ci { STV090x_RCCFGH, 0x20 }, 5078c2ecf20Sopenharmony_ci { STV090x_P1_FECM, 0x01 }, /*disable the DSS mode */ 5088c2ecf20Sopenharmony_ci { STV090x_P1_PRVIT, 0x2f } /*disable puncture rate 6/7*/ 5098c2ecf20Sopenharmony_ci}; 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_cistatic struct stv090x_reg stv0900_cut20_val[] = { 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci { STV090x_P2_DMDCFG3, 0xe8 }, 5148c2ecf20Sopenharmony_ci { STV090x_P2_DMDCFG4, 0x10 }, 5158c2ecf20Sopenharmony_ci { STV090x_P2_CARFREQ, 0x38 }, 5168c2ecf20Sopenharmony_ci { STV090x_P2_CARHDR, 0x20 }, 5178c2ecf20Sopenharmony_ci { STV090x_P2_KREFTMG, 0x5a }, 5188c2ecf20Sopenharmony_ci { STV090x_P2_SMAPCOEF7, 0x06 }, 5198c2ecf20Sopenharmony_ci { STV090x_P2_SMAPCOEF6, 0x00 }, 5208c2ecf20Sopenharmony_ci { STV090x_P2_SMAPCOEF5, 0x04 }, 5218c2ecf20Sopenharmony_ci { STV090x_P2_NOSCFG, 0x0c }, 5228c2ecf20Sopenharmony_ci { STV090x_P1_DMDCFG3, 0xe8 }, 5238c2ecf20Sopenharmony_ci { STV090x_P1_DMDCFG4, 0x10 }, 5248c2ecf20Sopenharmony_ci { STV090x_P1_CARFREQ, 0x38 }, 5258c2ecf20Sopenharmony_ci { STV090x_P1_CARHDR, 0x20 }, 5268c2ecf20Sopenharmony_ci { STV090x_P1_KREFTMG, 0x5a }, 5278c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF7, 0x06 }, 5288c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF6, 0x00 }, 5298c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF5, 0x04 }, 5308c2ecf20Sopenharmony_ci { STV090x_P1_NOSCFG, 0x0c }, 5318c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF4, 0x21 }, 5328c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF5, 0x21 }, 5338c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF6, 0x20 }, 5348c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF7, 0x1F }, 5358c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF8, 0x1E }, 5368c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF9, 0x1E }, 5378c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF10, 0x1D }, 5388c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF11, 0x1B }, 5398c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF12, 0x20 }, 5408c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF13, 0x20 }, 5418c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF14, 0x20 }, 5428c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF15, 0x20 }, 5438c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF16, 0x20 }, 5448c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF17, 0x21 }, 5458c2ecf20Sopenharmony_ci}; 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_cistatic struct stv090x_reg stv0903_cut20_val[] = { 5488c2ecf20Sopenharmony_ci { STV090x_P1_DMDCFG3, 0xe8 }, 5498c2ecf20Sopenharmony_ci { STV090x_P1_DMDCFG4, 0x10 }, 5508c2ecf20Sopenharmony_ci { STV090x_P1_CARFREQ, 0x38 }, 5518c2ecf20Sopenharmony_ci { STV090x_P1_CARHDR, 0x20 }, 5528c2ecf20Sopenharmony_ci { STV090x_P1_KREFTMG, 0x5a }, 5538c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF7, 0x06 }, 5548c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF6, 0x00 }, 5558c2ecf20Sopenharmony_ci { STV090x_P1_SMAPCOEF5, 0x04 }, 5568c2ecf20Sopenharmony_ci { STV090x_P1_NOSCFG, 0x0c }, 5578c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF4, 0x21 }, 5588c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF5, 0x21 }, 5598c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF6, 0x20 }, 5608c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF7, 0x1F }, 5618c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF8, 0x1E }, 5628c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF9, 0x1E }, 5638c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF10, 0x1D }, 5648c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF11, 0x1B }, 5658c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF12, 0x20 }, 5668c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF13, 0x20 }, 5678c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF14, 0x20 }, 5688c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF15, 0x20 }, 5698c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF16, 0x20 }, 5708c2ecf20Sopenharmony_ci { STV090x_GAINLLR_NF17, 0x21 } 5718c2ecf20Sopenharmony_ci}; 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci/* Cut 2.0 Long Frame Tracking CR loop */ 5748c2ecf20Sopenharmony_cistatic struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = { 5758c2ecf20Sopenharmony_ci /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ 5768c2ecf20Sopenharmony_ci { STV090x_QPSK_12, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x1e }, 5778c2ecf20Sopenharmony_ci { STV090x_QPSK_35, 0x2f, 0x3f, 0x2e, 0x2f, 0x3d, 0x0f, 0x0e, 0x2e, 0x3d, 0x0e }, 5788c2ecf20Sopenharmony_ci { STV090x_QPSK_23, 0x2f, 0x3f, 0x2e, 0x2f, 0x0e, 0x0f, 0x0e, 0x1e, 0x3d, 0x3d }, 5798c2ecf20Sopenharmony_ci { STV090x_QPSK_34, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, 5808c2ecf20Sopenharmony_ci { STV090x_QPSK_45, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, 5818c2ecf20Sopenharmony_ci { STV090x_QPSK_56, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, 5828c2ecf20Sopenharmony_ci { STV090x_QPSK_89, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, 5838c2ecf20Sopenharmony_ci { STV090x_QPSK_910, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d }, 5848c2ecf20Sopenharmony_ci { STV090x_8PSK_35, 0x3c, 0x3e, 0x1c, 0x2e, 0x0c, 0x1e, 0x2b, 0x2d, 0x1b, 0x1d }, 5858c2ecf20Sopenharmony_ci { STV090x_8PSK_23, 0x1d, 0x3e, 0x3c, 0x2e, 0x2c, 0x1e, 0x0c, 0x2d, 0x2b, 0x1d }, 5868c2ecf20Sopenharmony_ci { STV090x_8PSK_34, 0x0e, 0x3e, 0x3d, 0x2e, 0x0d, 0x1e, 0x2c, 0x2d, 0x0c, 0x1d }, 5878c2ecf20Sopenharmony_ci { STV090x_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d }, 5888c2ecf20Sopenharmony_ci { STV090x_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d }, 5898c2ecf20Sopenharmony_ci { STV090x_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d } 5908c2ecf20Sopenharmony_ci}; 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci/* Cut 3.0 Long Frame Tracking CR loop */ 5938c2ecf20Sopenharmony_cistatic struct stv090x_long_frame_crloop stv090x_s2_crl_cut30[] = { 5948c2ecf20Sopenharmony_ci /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ 5958c2ecf20Sopenharmony_ci { STV090x_QPSK_12, 0x3c, 0x2c, 0x0c, 0x2c, 0x1b, 0x2c, 0x1b, 0x1c, 0x0b, 0x3b }, 5968c2ecf20Sopenharmony_ci { STV090x_QPSK_35, 0x0d, 0x0d, 0x0c, 0x0d, 0x1b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b }, 5978c2ecf20Sopenharmony_ci { STV090x_QPSK_23, 0x1d, 0x0d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b }, 5988c2ecf20Sopenharmony_ci { STV090x_QPSK_34, 0x1d, 0x1d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b }, 5998c2ecf20Sopenharmony_ci { STV090x_QPSK_45, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, 6008c2ecf20Sopenharmony_ci { STV090x_QPSK_56, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, 6018c2ecf20Sopenharmony_ci { STV090x_QPSK_89, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, 6028c2ecf20Sopenharmony_ci { STV090x_QPSK_910, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b }, 6038c2ecf20Sopenharmony_ci { STV090x_8PSK_35, 0x39, 0x29, 0x39, 0x19, 0x19, 0x19, 0x19, 0x19, 0x09, 0x19 }, 6048c2ecf20Sopenharmony_ci { STV090x_8PSK_23, 0x2a, 0x39, 0x1a, 0x0a, 0x39, 0x0a, 0x29, 0x39, 0x29, 0x0a }, 6058c2ecf20Sopenharmony_ci { STV090x_8PSK_34, 0x2b, 0x3a, 0x1b, 0x1b, 0x3a, 0x1b, 0x1a, 0x0b, 0x1a, 0x3a }, 6068c2ecf20Sopenharmony_ci { STV090x_8PSK_56, 0x0c, 0x1b, 0x3b, 0x3b, 0x1b, 0x3b, 0x3a, 0x3b, 0x3a, 0x1b }, 6078c2ecf20Sopenharmony_ci { STV090x_8PSK_89, 0x0d, 0x3c, 0x2c, 0x2c, 0x2b, 0x0c, 0x0b, 0x3b, 0x0b, 0x1b }, 6088c2ecf20Sopenharmony_ci { STV090x_8PSK_910, 0x0d, 0x0d, 0x2c, 0x3c, 0x3b, 0x1c, 0x0b, 0x3b, 0x0b, 0x1b } 6098c2ecf20Sopenharmony_ci}; 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci/* Cut 2.0 Long Frame Tracking CR Loop */ 6128c2ecf20Sopenharmony_cistatic struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = { 6138c2ecf20Sopenharmony_ci /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ 6148c2ecf20Sopenharmony_ci { STV090x_16APSK_23, 0x0c, 0x0c, 0x0c, 0x0c, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x0c }, 6158c2ecf20Sopenharmony_ci { STV090x_16APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0c, 0x2d, 0x0c, 0x1d, 0x0c }, 6168c2ecf20Sopenharmony_ci { STV090x_16APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c }, 6178c2ecf20Sopenharmony_ci { STV090x_16APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c }, 6188c2ecf20Sopenharmony_ci { STV090x_16APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c }, 6198c2ecf20Sopenharmony_ci { STV090x_16APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c }, 6208c2ecf20Sopenharmony_ci { STV090x_32APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, 6218c2ecf20Sopenharmony_ci { STV090x_32APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, 6228c2ecf20Sopenharmony_ci { STV090x_32APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, 6238c2ecf20Sopenharmony_ci { STV090x_32APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, 6248c2ecf20Sopenharmony_ci { STV090x_32APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c } 6258c2ecf20Sopenharmony_ci}; 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci/* Cut 3.0 Long Frame Tracking CR Loop */ 6288c2ecf20Sopenharmony_cistatic struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut30[] = { 6298c2ecf20Sopenharmony_ci /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ 6308c2ecf20Sopenharmony_ci { STV090x_16APSK_23, 0x0a, 0x0a, 0x0a, 0x0a, 0x1a, 0x0a, 0x3a, 0x0a, 0x2a, 0x0a }, 6318c2ecf20Sopenharmony_ci { STV090x_16APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x3b, 0x0a, 0x1b, 0x0a }, 6328c2ecf20Sopenharmony_ci { STV090x_16APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a }, 6338c2ecf20Sopenharmony_ci { STV090x_16APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a }, 6348c2ecf20Sopenharmony_ci { STV090x_16APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a }, 6358c2ecf20Sopenharmony_ci { STV090x_16APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a }, 6368c2ecf20Sopenharmony_ci { STV090x_32APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, 6378c2ecf20Sopenharmony_ci { STV090x_32APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, 6388c2ecf20Sopenharmony_ci { STV090x_32APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, 6398c2ecf20Sopenharmony_ci { STV090x_32APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }, 6408c2ecf20Sopenharmony_ci { STV090x_32APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a } 6418c2ecf20Sopenharmony_ci}; 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_cistatic struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = { 6448c2ecf20Sopenharmony_ci /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ 6458c2ecf20Sopenharmony_ci { STV090x_QPSK_14, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x2d, 0x1f, 0x3d, 0x3e }, 6468c2ecf20Sopenharmony_ci { STV090x_QPSK_13, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x3d, 0x0f, 0x3d, 0x2e }, 6478c2ecf20Sopenharmony_ci { STV090x_QPSK_25, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x2e } 6488c2ecf20Sopenharmony_ci}; 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_cistatic struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut30[] = { 6518c2ecf20Sopenharmony_ci /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ 6528c2ecf20Sopenharmony_ci { STV090x_QPSK_14, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x2a, 0x1c, 0x3a, 0x3b }, 6538c2ecf20Sopenharmony_ci { STV090x_QPSK_13, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x3a, 0x0c, 0x3a, 0x2b }, 6548c2ecf20Sopenharmony_ci { STV090x_QPSK_25, 0x1c, 0x3c, 0x1b, 0x3c, 0x3a, 0x1c, 0x3a, 0x3b, 0x3a, 0x2b } 6558c2ecf20Sopenharmony_ci}; 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci/* Cut 2.0 Short Frame Tracking CR Loop */ 6588c2ecf20Sopenharmony_cistatic struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = { 6598c2ecf20Sopenharmony_ci /* MODCOD 2M 5M 10M 20M 30M */ 6608c2ecf20Sopenharmony_ci { STV090x_QPSK, 0x2f, 0x2e, 0x0e, 0x0e, 0x3d }, 6618c2ecf20Sopenharmony_ci { STV090x_8PSK, 0x3e, 0x0e, 0x2d, 0x0d, 0x3c }, 6628c2ecf20Sopenharmony_ci { STV090x_16APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d }, 6638c2ecf20Sopenharmony_ci { STV090x_32APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d } 6648c2ecf20Sopenharmony_ci}; 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci/* Cut 3.0 Short Frame Tracking CR Loop */ 6678c2ecf20Sopenharmony_cistatic struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = { 6688c2ecf20Sopenharmony_ci /* MODCOD 2M 5M 10M 20M 30M */ 6698c2ecf20Sopenharmony_ci { STV090x_QPSK, 0x2C, 0x2B, 0x0B, 0x0B, 0x3A }, 6708c2ecf20Sopenharmony_ci { STV090x_8PSK, 0x3B, 0x0B, 0x2A, 0x0A, 0x39 }, 6718c2ecf20Sopenharmony_ci { STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A }, 6728c2ecf20Sopenharmony_ci { STV090x_32APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A } 6738c2ecf20Sopenharmony_ci}; 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_cistatic inline s32 comp2(s32 __x, s32 __width) 6768c2ecf20Sopenharmony_ci{ 6778c2ecf20Sopenharmony_ci if (__width == 32) 6788c2ecf20Sopenharmony_ci return __x; 6798c2ecf20Sopenharmony_ci else 6808c2ecf20Sopenharmony_ci return (__x >= (1 << (__width - 1))) ? (__x - (1 << __width)) : __x; 6818c2ecf20Sopenharmony_ci} 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_cistatic int stv090x_read_reg(struct stv090x_state *state, unsigned int reg) 6848c2ecf20Sopenharmony_ci{ 6858c2ecf20Sopenharmony_ci const struct stv090x_config *config = state->config; 6868c2ecf20Sopenharmony_ci int ret; 6878c2ecf20Sopenharmony_ci 6888c2ecf20Sopenharmony_ci u8 b0[] = { reg >> 8, reg & 0xff }; 6898c2ecf20Sopenharmony_ci u8 buf; 6908c2ecf20Sopenharmony_ci 6918c2ecf20Sopenharmony_ci struct i2c_msg msg[] = { 6928c2ecf20Sopenharmony_ci { .addr = config->address, .flags = 0, .buf = b0, .len = 2 }, 6938c2ecf20Sopenharmony_ci { .addr = config->address, .flags = I2C_M_RD, .buf = &buf, .len = 1 } 6948c2ecf20Sopenharmony_ci }; 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci ret = i2c_transfer(state->i2c, msg, 2); 6978c2ecf20Sopenharmony_ci if (ret != 2) { 6988c2ecf20Sopenharmony_ci if (ret != -ERESTARTSYS) 6998c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, 7008c2ecf20Sopenharmony_ci "Read error, Reg=[0x%02x], Status=%d", 7018c2ecf20Sopenharmony_ci reg, ret); 7028c2ecf20Sopenharmony_ci 7038c2ecf20Sopenharmony_ci return ret < 0 ? ret : -EREMOTEIO; 7048c2ecf20Sopenharmony_ci } 7058c2ecf20Sopenharmony_ci if (unlikely(*state->verbose >= FE_DEBUGREG)) 7068c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "Reg=[0x%02x], data=%02x", 7078c2ecf20Sopenharmony_ci reg, buf); 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci return (unsigned int) buf; 7108c2ecf20Sopenharmony_ci} 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_cistatic int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 *data, u32 count) 7138c2ecf20Sopenharmony_ci{ 7148c2ecf20Sopenharmony_ci const struct stv090x_config *config = state->config; 7158c2ecf20Sopenharmony_ci int ret; 7168c2ecf20Sopenharmony_ci u8 buf[MAX_XFER_SIZE]; 7178c2ecf20Sopenharmony_ci struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count }; 7188c2ecf20Sopenharmony_ci 7198c2ecf20Sopenharmony_ci if (2 + count > sizeof(buf)) { 7208c2ecf20Sopenharmony_ci printk(KERN_WARNING 7218c2ecf20Sopenharmony_ci "%s: i2c wr reg=%04x: len=%d is too big!\n", 7228c2ecf20Sopenharmony_ci KBUILD_MODNAME, reg, count); 7238c2ecf20Sopenharmony_ci return -EINVAL; 7248c2ecf20Sopenharmony_ci } 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci buf[0] = reg >> 8; 7278c2ecf20Sopenharmony_ci buf[1] = reg & 0xff; 7288c2ecf20Sopenharmony_ci memcpy(&buf[2], data, count); 7298c2ecf20Sopenharmony_ci 7308c2ecf20Sopenharmony_ci dprintk(FE_DEBUGREG, 1, "%s [0x%04x]: %*ph", 7318c2ecf20Sopenharmony_ci __func__, reg, count, data); 7328c2ecf20Sopenharmony_ci 7338c2ecf20Sopenharmony_ci ret = i2c_transfer(state->i2c, &i2c_msg, 1); 7348c2ecf20Sopenharmony_ci if (ret != 1) { 7358c2ecf20Sopenharmony_ci if (ret != -ERESTARTSYS) 7368c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d", 7378c2ecf20Sopenharmony_ci reg, data[0], count, ret); 7388c2ecf20Sopenharmony_ci return ret < 0 ? ret : -EREMOTEIO; 7398c2ecf20Sopenharmony_ci } 7408c2ecf20Sopenharmony_ci 7418c2ecf20Sopenharmony_ci return 0; 7428c2ecf20Sopenharmony_ci} 7438c2ecf20Sopenharmony_ci 7448c2ecf20Sopenharmony_cistatic int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data) 7458c2ecf20Sopenharmony_ci{ 7468c2ecf20Sopenharmony_ci u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ 7478c2ecf20Sopenharmony_ci 7488c2ecf20Sopenharmony_ci return stv090x_write_regs(state, reg, &tmp, 1); 7498c2ecf20Sopenharmony_ci} 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_cistatic int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable) 7528c2ecf20Sopenharmony_ci{ 7538c2ecf20Sopenharmony_ci u32 reg; 7548c2ecf20Sopenharmony_ci 7558c2ecf20Sopenharmony_ci /* 7568c2ecf20Sopenharmony_ci * NOTE! A lock is used as a FSM to control the state in which 7578c2ecf20Sopenharmony_ci * access is serialized between two tuners on the same demod. 7588c2ecf20Sopenharmony_ci * This has nothing to do with a lock to protect a critical section 7598c2ecf20Sopenharmony_ci * which may in some other cases be confused with protecting I/O 7608c2ecf20Sopenharmony_ci * access to the demodulator gate. 7618c2ecf20Sopenharmony_ci * In case of any error, the lock is unlocked and exit within the 7628c2ecf20Sopenharmony_ci * relevant operations themselves. 7638c2ecf20Sopenharmony_ci */ 7648c2ecf20Sopenharmony_ci if (enable) { 7658c2ecf20Sopenharmony_ci if (state->config->tuner_i2c_lock) 7668c2ecf20Sopenharmony_ci state->config->tuner_i2c_lock(&state->frontend, 1); 7678c2ecf20Sopenharmony_ci else 7688c2ecf20Sopenharmony_ci mutex_lock(&state->internal->tuner_lock); 7698c2ecf20Sopenharmony_ci } 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, I2CRPT); 7728c2ecf20Sopenharmony_ci if (enable) { 7738c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Enable Gate"); 7748c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 1); 7758c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) 7768c2ecf20Sopenharmony_ci goto err; 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_ci } else { 7798c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Disable Gate"); 7808c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 0); 7818c2ecf20Sopenharmony_ci if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0) 7828c2ecf20Sopenharmony_ci goto err; 7838c2ecf20Sopenharmony_ci } 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_ci if (!enable) { 7868c2ecf20Sopenharmony_ci if (state->config->tuner_i2c_lock) 7878c2ecf20Sopenharmony_ci state->config->tuner_i2c_lock(&state->frontend, 0); 7888c2ecf20Sopenharmony_ci else 7898c2ecf20Sopenharmony_ci mutex_unlock(&state->internal->tuner_lock); 7908c2ecf20Sopenharmony_ci } 7918c2ecf20Sopenharmony_ci 7928c2ecf20Sopenharmony_ci return 0; 7938c2ecf20Sopenharmony_cierr: 7948c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 7958c2ecf20Sopenharmony_ci if (state->config->tuner_i2c_lock) 7968c2ecf20Sopenharmony_ci state->config->tuner_i2c_lock(&state->frontend, 0); 7978c2ecf20Sopenharmony_ci else 7988c2ecf20Sopenharmony_ci mutex_unlock(&state->internal->tuner_lock); 7998c2ecf20Sopenharmony_ci return -1; 8008c2ecf20Sopenharmony_ci} 8018c2ecf20Sopenharmony_ci 8028c2ecf20Sopenharmony_cistatic void stv090x_get_lock_tmg(struct stv090x_state *state) 8038c2ecf20Sopenharmony_ci{ 8048c2ecf20Sopenharmony_ci switch (state->algo) { 8058c2ecf20Sopenharmony_ci case STV090x_BLIND_SEARCH: 8068c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Blind Search"); 8078c2ecf20Sopenharmony_ci if (state->srate <= 1500000) { /*10Msps< SR <=15Msps*/ 8088c2ecf20Sopenharmony_ci state->DemodTimeout = 1500; 8098c2ecf20Sopenharmony_ci state->FecTimeout = 400; 8108c2ecf20Sopenharmony_ci } else if (state->srate <= 5000000) { /*10Msps< SR <=15Msps*/ 8118c2ecf20Sopenharmony_ci state->DemodTimeout = 1000; 8128c2ecf20Sopenharmony_ci state->FecTimeout = 300; 8138c2ecf20Sopenharmony_ci } else { /*SR >20Msps*/ 8148c2ecf20Sopenharmony_ci state->DemodTimeout = 700; 8158c2ecf20Sopenharmony_ci state->FecTimeout = 100; 8168c2ecf20Sopenharmony_ci } 8178c2ecf20Sopenharmony_ci break; 8188c2ecf20Sopenharmony_ci 8198c2ecf20Sopenharmony_ci case STV090x_COLD_SEARCH: 8208c2ecf20Sopenharmony_ci case STV090x_WARM_SEARCH: 8218c2ecf20Sopenharmony_ci default: 8228c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Normal Search"); 8238c2ecf20Sopenharmony_ci if (state->srate <= 1000000) { /*SR <=1Msps*/ 8248c2ecf20Sopenharmony_ci state->DemodTimeout = 4500; 8258c2ecf20Sopenharmony_ci state->FecTimeout = 1700; 8268c2ecf20Sopenharmony_ci } else if (state->srate <= 2000000) { /*1Msps < SR <= 2Msps */ 8278c2ecf20Sopenharmony_ci state->DemodTimeout = 2500; 8288c2ecf20Sopenharmony_ci state->FecTimeout = 1100; 8298c2ecf20Sopenharmony_ci } else if (state->srate <= 5000000) { /*2Msps < SR <= 5Msps */ 8308c2ecf20Sopenharmony_ci state->DemodTimeout = 1000; 8318c2ecf20Sopenharmony_ci state->FecTimeout = 550; 8328c2ecf20Sopenharmony_ci } else if (state->srate <= 10000000) { /*5Msps < SR <= 10Msps */ 8338c2ecf20Sopenharmony_ci state->DemodTimeout = 700; 8348c2ecf20Sopenharmony_ci state->FecTimeout = 250; 8358c2ecf20Sopenharmony_ci } else if (state->srate <= 20000000) { /*10Msps < SR <= 20Msps */ 8368c2ecf20Sopenharmony_ci state->DemodTimeout = 400; 8378c2ecf20Sopenharmony_ci state->FecTimeout = 130; 8388c2ecf20Sopenharmony_ci } else { /*SR >20Msps*/ 8398c2ecf20Sopenharmony_ci state->DemodTimeout = 300; 8408c2ecf20Sopenharmony_ci state->FecTimeout = 100; 8418c2ecf20Sopenharmony_ci } 8428c2ecf20Sopenharmony_ci break; 8438c2ecf20Sopenharmony_ci } 8448c2ecf20Sopenharmony_ci 8458c2ecf20Sopenharmony_ci if (state->algo == STV090x_WARM_SEARCH) 8468c2ecf20Sopenharmony_ci state->DemodTimeout /= 2; 8478c2ecf20Sopenharmony_ci} 8488c2ecf20Sopenharmony_ci 8498c2ecf20Sopenharmony_cistatic int stv090x_set_srate(struct stv090x_state *state, u32 srate) 8508c2ecf20Sopenharmony_ci{ 8518c2ecf20Sopenharmony_ci u32 sym; 8528c2ecf20Sopenharmony_ci 8538c2ecf20Sopenharmony_ci if (srate > 60000000) { 8548c2ecf20Sopenharmony_ci sym = (srate << 4); /* SR * 2^16 / master_clk */ 8558c2ecf20Sopenharmony_ci sym /= (state->internal->mclk >> 12); 8568c2ecf20Sopenharmony_ci } else if (srate > 6000000) { 8578c2ecf20Sopenharmony_ci sym = (srate << 6); 8588c2ecf20Sopenharmony_ci sym /= (state->internal->mclk >> 10); 8598c2ecf20Sopenharmony_ci } else { 8608c2ecf20Sopenharmony_ci sym = (srate << 9); 8618c2ecf20Sopenharmony_ci sym /= (state->internal->mclk >> 7); 8628c2ecf20Sopenharmony_ci } 8638c2ecf20Sopenharmony_ci 8648c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */ 8658c2ecf20Sopenharmony_ci goto err; 8668c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRINIT0, (sym & 0xff)) < 0) /* LSB */ 8678c2ecf20Sopenharmony_ci goto err; 8688c2ecf20Sopenharmony_ci 8698c2ecf20Sopenharmony_ci return 0; 8708c2ecf20Sopenharmony_cierr: 8718c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 8728c2ecf20Sopenharmony_ci return -1; 8738c2ecf20Sopenharmony_ci} 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_cistatic int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate) 8768c2ecf20Sopenharmony_ci{ 8778c2ecf20Sopenharmony_ci u32 sym; 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_ci srate = 105 * (srate / 100); 8808c2ecf20Sopenharmony_ci if (srate > 60000000) { 8818c2ecf20Sopenharmony_ci sym = (srate << 4); /* SR * 2^16 / master_clk */ 8828c2ecf20Sopenharmony_ci sym /= (state->internal->mclk >> 12); 8838c2ecf20Sopenharmony_ci } else if (srate > 6000000) { 8848c2ecf20Sopenharmony_ci sym = (srate << 6); 8858c2ecf20Sopenharmony_ci sym /= (state->internal->mclk >> 10); 8868c2ecf20Sopenharmony_ci } else { 8878c2ecf20Sopenharmony_ci sym = (srate << 9); 8888c2ecf20Sopenharmony_ci sym /= (state->internal->mclk >> 7); 8898c2ecf20Sopenharmony_ci } 8908c2ecf20Sopenharmony_ci 8918c2ecf20Sopenharmony_ci if (sym < 0x7fff) { 8928c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) /* MSB */ 8938c2ecf20Sopenharmony_ci goto err; 8948c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) /* LSB */ 8958c2ecf20Sopenharmony_ci goto err; 8968c2ecf20Sopenharmony_ci } else { 8978c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x7f) < 0) /* MSB */ 8988c2ecf20Sopenharmony_ci goto err; 8998c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xff) < 0) /* LSB */ 9008c2ecf20Sopenharmony_ci goto err; 9018c2ecf20Sopenharmony_ci } 9028c2ecf20Sopenharmony_ci 9038c2ecf20Sopenharmony_ci return 0; 9048c2ecf20Sopenharmony_cierr: 9058c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 9068c2ecf20Sopenharmony_ci return -1; 9078c2ecf20Sopenharmony_ci} 9088c2ecf20Sopenharmony_ci 9098c2ecf20Sopenharmony_cistatic int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate) 9108c2ecf20Sopenharmony_ci{ 9118c2ecf20Sopenharmony_ci u32 sym; 9128c2ecf20Sopenharmony_ci 9138c2ecf20Sopenharmony_ci srate = 95 * (srate / 100); 9148c2ecf20Sopenharmony_ci if (srate > 60000000) { 9158c2ecf20Sopenharmony_ci sym = (srate << 4); /* SR * 2^16 / master_clk */ 9168c2ecf20Sopenharmony_ci sym /= (state->internal->mclk >> 12); 9178c2ecf20Sopenharmony_ci } else if (srate > 6000000) { 9188c2ecf20Sopenharmony_ci sym = (srate << 6); 9198c2ecf20Sopenharmony_ci sym /= (state->internal->mclk >> 10); 9208c2ecf20Sopenharmony_ci } else { 9218c2ecf20Sopenharmony_ci sym = (srate << 9); 9228c2ecf20Sopenharmony_ci sym /= (state->internal->mclk >> 7); 9238c2ecf20Sopenharmony_ci } 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */ 9268c2ecf20Sopenharmony_ci goto err; 9278c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */ 9288c2ecf20Sopenharmony_ci goto err; 9298c2ecf20Sopenharmony_ci return 0; 9308c2ecf20Sopenharmony_cierr: 9318c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 9328c2ecf20Sopenharmony_ci return -1; 9338c2ecf20Sopenharmony_ci} 9348c2ecf20Sopenharmony_ci 9358c2ecf20Sopenharmony_cistatic u32 stv090x_car_width(u32 srate, enum stv090x_rolloff rolloff) 9368c2ecf20Sopenharmony_ci{ 9378c2ecf20Sopenharmony_ci u32 ro; 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_ci switch (rolloff) { 9408c2ecf20Sopenharmony_ci case STV090x_RO_20: 9418c2ecf20Sopenharmony_ci ro = 20; 9428c2ecf20Sopenharmony_ci break; 9438c2ecf20Sopenharmony_ci case STV090x_RO_25: 9448c2ecf20Sopenharmony_ci ro = 25; 9458c2ecf20Sopenharmony_ci break; 9468c2ecf20Sopenharmony_ci case STV090x_RO_35: 9478c2ecf20Sopenharmony_ci default: 9488c2ecf20Sopenharmony_ci ro = 35; 9498c2ecf20Sopenharmony_ci break; 9508c2ecf20Sopenharmony_ci } 9518c2ecf20Sopenharmony_ci 9528c2ecf20Sopenharmony_ci return srate + (srate * ro) / 100; 9538c2ecf20Sopenharmony_ci} 9548c2ecf20Sopenharmony_ci 9558c2ecf20Sopenharmony_cistatic int stv090x_set_vit_thacq(struct stv090x_state *state) 9568c2ecf20Sopenharmony_ci{ 9578c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH12, 0x96) < 0) 9588c2ecf20Sopenharmony_ci goto err; 9598c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH23, 0x64) < 0) 9608c2ecf20Sopenharmony_ci goto err; 9618c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH34, 0x36) < 0) 9628c2ecf20Sopenharmony_ci goto err; 9638c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH56, 0x23) < 0) 9648c2ecf20Sopenharmony_ci goto err; 9658c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH67, 0x1e) < 0) 9668c2ecf20Sopenharmony_ci goto err; 9678c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH78, 0x19) < 0) 9688c2ecf20Sopenharmony_ci goto err; 9698c2ecf20Sopenharmony_ci return 0; 9708c2ecf20Sopenharmony_cierr: 9718c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 9728c2ecf20Sopenharmony_ci return -1; 9738c2ecf20Sopenharmony_ci} 9748c2ecf20Sopenharmony_ci 9758c2ecf20Sopenharmony_cistatic int stv090x_set_vit_thtracq(struct stv090x_state *state) 9768c2ecf20Sopenharmony_ci{ 9778c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH12, 0xd0) < 0) 9788c2ecf20Sopenharmony_ci goto err; 9798c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH23, 0x7d) < 0) 9808c2ecf20Sopenharmony_ci goto err; 9818c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH34, 0x53) < 0) 9828c2ecf20Sopenharmony_ci goto err; 9838c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH56, 0x2f) < 0) 9848c2ecf20Sopenharmony_ci goto err; 9858c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH67, 0x24) < 0) 9868c2ecf20Sopenharmony_ci goto err; 9878c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VTH78, 0x1f) < 0) 9888c2ecf20Sopenharmony_ci goto err; 9898c2ecf20Sopenharmony_ci return 0; 9908c2ecf20Sopenharmony_cierr: 9918c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 9928c2ecf20Sopenharmony_ci return -1; 9938c2ecf20Sopenharmony_ci} 9948c2ecf20Sopenharmony_ci 9958c2ecf20Sopenharmony_cistatic int stv090x_set_viterbi(struct stv090x_state *state) 9968c2ecf20Sopenharmony_ci{ 9978c2ecf20Sopenharmony_ci switch (state->search_mode) { 9988c2ecf20Sopenharmony_ci case STV090x_SEARCH_AUTO: 9998c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, FECM, 0x10) < 0) /* DVB-S and DVB-S2 */ 10008c2ecf20Sopenharmony_ci goto err; 10018c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PRVIT, 0x3f) < 0) /* all puncture rate */ 10028c2ecf20Sopenharmony_ci goto err; 10038c2ecf20Sopenharmony_ci break; 10048c2ecf20Sopenharmony_ci case STV090x_SEARCH_DVBS1: 10058c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, FECM, 0x00) < 0) /* disable DSS */ 10068c2ecf20Sopenharmony_ci goto err; 10078c2ecf20Sopenharmony_ci switch (state->fec) { 10088c2ecf20Sopenharmony_ci case STV090x_PR12: 10098c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0) 10108c2ecf20Sopenharmony_ci goto err; 10118c2ecf20Sopenharmony_ci break; 10128c2ecf20Sopenharmony_ci 10138c2ecf20Sopenharmony_ci case STV090x_PR23: 10148c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0) 10158c2ecf20Sopenharmony_ci goto err; 10168c2ecf20Sopenharmony_ci break; 10178c2ecf20Sopenharmony_ci 10188c2ecf20Sopenharmony_ci case STV090x_PR34: 10198c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PRVIT, 0x04) < 0) 10208c2ecf20Sopenharmony_ci goto err; 10218c2ecf20Sopenharmony_ci break; 10228c2ecf20Sopenharmony_ci 10238c2ecf20Sopenharmony_ci case STV090x_PR56: 10248c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PRVIT, 0x08) < 0) 10258c2ecf20Sopenharmony_ci goto err; 10268c2ecf20Sopenharmony_ci break; 10278c2ecf20Sopenharmony_ci 10288c2ecf20Sopenharmony_ci case STV090x_PR78: 10298c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PRVIT, 0x20) < 0) 10308c2ecf20Sopenharmony_ci goto err; 10318c2ecf20Sopenharmony_ci break; 10328c2ecf20Sopenharmony_ci 10338c2ecf20Sopenharmony_ci default: 10348c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PRVIT, 0x2f) < 0) /* all */ 10358c2ecf20Sopenharmony_ci goto err; 10368c2ecf20Sopenharmony_ci break; 10378c2ecf20Sopenharmony_ci } 10388c2ecf20Sopenharmony_ci break; 10398c2ecf20Sopenharmony_ci case STV090x_SEARCH_DSS: 10408c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, FECM, 0x80) < 0) 10418c2ecf20Sopenharmony_ci goto err; 10428c2ecf20Sopenharmony_ci switch (state->fec) { 10438c2ecf20Sopenharmony_ci case STV090x_PR12: 10448c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0) 10458c2ecf20Sopenharmony_ci goto err; 10468c2ecf20Sopenharmony_ci break; 10478c2ecf20Sopenharmony_ci 10488c2ecf20Sopenharmony_ci case STV090x_PR23: 10498c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0) 10508c2ecf20Sopenharmony_ci goto err; 10518c2ecf20Sopenharmony_ci break; 10528c2ecf20Sopenharmony_ci 10538c2ecf20Sopenharmony_ci case STV090x_PR67: 10548c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PRVIT, 0x10) < 0) 10558c2ecf20Sopenharmony_ci goto err; 10568c2ecf20Sopenharmony_ci break; 10578c2ecf20Sopenharmony_ci 10588c2ecf20Sopenharmony_ci default: 10598c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PRVIT, 0x13) < 0) /* 1/2, 2/3, 6/7 */ 10608c2ecf20Sopenharmony_ci goto err; 10618c2ecf20Sopenharmony_ci break; 10628c2ecf20Sopenharmony_ci } 10638c2ecf20Sopenharmony_ci break; 10648c2ecf20Sopenharmony_ci default: 10658c2ecf20Sopenharmony_ci break; 10668c2ecf20Sopenharmony_ci } 10678c2ecf20Sopenharmony_ci return 0; 10688c2ecf20Sopenharmony_cierr: 10698c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 10708c2ecf20Sopenharmony_ci return -1; 10718c2ecf20Sopenharmony_ci} 10728c2ecf20Sopenharmony_ci 10738c2ecf20Sopenharmony_cistatic int stv090x_stop_modcod(struct stv090x_state *state) 10748c2ecf20Sopenharmony_ci{ 10758c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) 10768c2ecf20Sopenharmony_ci goto err; 10778c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0) 10788c2ecf20Sopenharmony_ci goto err; 10798c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0) 10808c2ecf20Sopenharmony_ci goto err; 10818c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0) 10828c2ecf20Sopenharmony_ci goto err; 10838c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0) 10848c2ecf20Sopenharmony_ci goto err; 10858c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0) 10868c2ecf20Sopenharmony_ci goto err; 10878c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0) 10888c2ecf20Sopenharmony_ci goto err; 10898c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xff) < 0) 10908c2ecf20Sopenharmony_ci goto err; 10918c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xff) < 0) 10928c2ecf20Sopenharmony_ci goto err; 10938c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xff) < 0) 10948c2ecf20Sopenharmony_ci goto err; 10958c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xff) < 0) 10968c2ecf20Sopenharmony_ci goto err; 10978c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xff) < 0) 10988c2ecf20Sopenharmony_ci goto err; 10998c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xff) < 0) 11008c2ecf20Sopenharmony_ci goto err; 11018c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xff) < 0) 11028c2ecf20Sopenharmony_ci goto err; 11038c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0) 11048c2ecf20Sopenharmony_ci goto err; 11058c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xff) < 0) 11068c2ecf20Sopenharmony_ci goto err; 11078c2ecf20Sopenharmony_ci return 0; 11088c2ecf20Sopenharmony_cierr: 11098c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 11108c2ecf20Sopenharmony_ci return -1; 11118c2ecf20Sopenharmony_ci} 11128c2ecf20Sopenharmony_ci 11138c2ecf20Sopenharmony_cistatic int stv090x_activate_modcod(struct stv090x_state *state) 11148c2ecf20Sopenharmony_ci{ 11158c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) 11168c2ecf20Sopenharmony_ci goto err; 11178c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xfc) < 0) 11188c2ecf20Sopenharmony_ci goto err; 11198c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xcc) < 0) 11208c2ecf20Sopenharmony_ci goto err; 11218c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xcc) < 0) 11228c2ecf20Sopenharmony_ci goto err; 11238c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xcc) < 0) 11248c2ecf20Sopenharmony_ci goto err; 11258c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xcc) < 0) 11268c2ecf20Sopenharmony_ci goto err; 11278c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xcc) < 0) 11288c2ecf20Sopenharmony_ci goto err; 11298c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0) 11308c2ecf20Sopenharmony_ci goto err; 11318c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0) 11328c2ecf20Sopenharmony_ci goto err; 11338c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0) 11348c2ecf20Sopenharmony_ci goto err; 11358c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0) 11368c2ecf20Sopenharmony_ci goto err; 11378c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0) 11388c2ecf20Sopenharmony_ci goto err; 11398c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0) 11408c2ecf20Sopenharmony_ci goto err; 11418c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0) 11428c2ecf20Sopenharmony_ci goto err; 11438c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xcc) < 0) 11448c2ecf20Sopenharmony_ci goto err; 11458c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0) 11468c2ecf20Sopenharmony_ci goto err; 11478c2ecf20Sopenharmony_ci 11488c2ecf20Sopenharmony_ci return 0; 11498c2ecf20Sopenharmony_cierr: 11508c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 11518c2ecf20Sopenharmony_ci return -1; 11528c2ecf20Sopenharmony_ci} 11538c2ecf20Sopenharmony_ci 11548c2ecf20Sopenharmony_cistatic int stv090x_activate_modcod_single(struct stv090x_state *state) 11558c2ecf20Sopenharmony_ci{ 11568c2ecf20Sopenharmony_ci 11578c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) 11588c2ecf20Sopenharmony_ci goto err; 11598c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xf0) < 0) 11608c2ecf20Sopenharmony_ci goto err; 11618c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0x00) < 0) 11628c2ecf20Sopenharmony_ci goto err; 11638c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0x00) < 0) 11648c2ecf20Sopenharmony_ci goto err; 11658c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0x00) < 0) 11668c2ecf20Sopenharmony_ci goto err; 11678c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0x00) < 0) 11688c2ecf20Sopenharmony_ci goto err; 11698c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0x00) < 0) 11708c2ecf20Sopenharmony_ci goto err; 11718c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0x00) < 0) 11728c2ecf20Sopenharmony_ci goto err; 11738c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0x00) < 0) 11748c2ecf20Sopenharmony_ci goto err; 11758c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0x00) < 0) 11768c2ecf20Sopenharmony_ci goto err; 11778c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0x00) < 0) 11788c2ecf20Sopenharmony_ci goto err; 11798c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0x00) < 0) 11808c2ecf20Sopenharmony_ci goto err; 11818c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0x00) < 0) 11828c2ecf20Sopenharmony_ci goto err; 11838c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0x00) < 0) 11848c2ecf20Sopenharmony_ci goto err; 11858c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0x00) < 0) 11868c2ecf20Sopenharmony_ci goto err; 11878c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0x0f) < 0) 11888c2ecf20Sopenharmony_ci goto err; 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_ci return 0; 11918c2ecf20Sopenharmony_ci 11928c2ecf20Sopenharmony_cierr: 11938c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 11948c2ecf20Sopenharmony_ci return -1; 11958c2ecf20Sopenharmony_ci} 11968c2ecf20Sopenharmony_ci 11978c2ecf20Sopenharmony_cistatic int stv090x_vitclk_ctl(struct stv090x_state *state, int enable) 11988c2ecf20Sopenharmony_ci{ 11998c2ecf20Sopenharmony_ci u32 reg; 12008c2ecf20Sopenharmony_ci 12018c2ecf20Sopenharmony_ci switch (state->demod) { 12028c2ecf20Sopenharmony_ci case STV090x_DEMODULATOR_0: 12038c2ecf20Sopenharmony_ci mutex_lock(&state->internal->demod_lock); 12048c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_STOPCLK2); 12058c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable); 12068c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 12078c2ecf20Sopenharmony_ci goto err; 12088c2ecf20Sopenharmony_ci mutex_unlock(&state->internal->demod_lock); 12098c2ecf20Sopenharmony_ci break; 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_ci case STV090x_DEMODULATOR_1: 12128c2ecf20Sopenharmony_ci mutex_lock(&state->internal->demod_lock); 12138c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_STOPCLK2); 12148c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable); 12158c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 12168c2ecf20Sopenharmony_ci goto err; 12178c2ecf20Sopenharmony_ci mutex_unlock(&state->internal->demod_lock); 12188c2ecf20Sopenharmony_ci break; 12198c2ecf20Sopenharmony_ci 12208c2ecf20Sopenharmony_ci default: 12218c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "Wrong demodulator!"); 12228c2ecf20Sopenharmony_ci break; 12238c2ecf20Sopenharmony_ci } 12248c2ecf20Sopenharmony_ci return 0; 12258c2ecf20Sopenharmony_cierr: 12268c2ecf20Sopenharmony_ci mutex_unlock(&state->internal->demod_lock); 12278c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 12288c2ecf20Sopenharmony_ci return -1; 12298c2ecf20Sopenharmony_ci} 12308c2ecf20Sopenharmony_ci 12318c2ecf20Sopenharmony_cistatic int stv090x_dvbs_track_crl(struct stv090x_state *state) 12328c2ecf20Sopenharmony_ci{ 12338c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x30) { 12348c2ecf20Sopenharmony_ci /* Set ACLC BCLC optimised value vs SR */ 12358c2ecf20Sopenharmony_ci if (state->srate >= 15000000) { 12368c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0) 12378c2ecf20Sopenharmony_ci goto err; 12388c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, BCLC, 0x1a) < 0) 12398c2ecf20Sopenharmony_ci goto err; 12408c2ecf20Sopenharmony_ci } else if ((state->srate >= 7000000) && (15000000 > state->srate)) { 12418c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC, 0x0c) < 0) 12428c2ecf20Sopenharmony_ci goto err; 12438c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, BCLC, 0x1b) < 0) 12448c2ecf20Sopenharmony_ci goto err; 12458c2ecf20Sopenharmony_ci } else if (state->srate < 7000000) { 12468c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC, 0x2c) < 0) 12478c2ecf20Sopenharmony_ci goto err; 12488c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, BCLC, 0x1c) < 0) 12498c2ecf20Sopenharmony_ci goto err; 12508c2ecf20Sopenharmony_ci } 12518c2ecf20Sopenharmony_ci 12528c2ecf20Sopenharmony_ci } else { 12538c2ecf20Sopenharmony_ci /* Cut 2.0 */ 12548c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) 12558c2ecf20Sopenharmony_ci goto err; 12568c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) 12578c2ecf20Sopenharmony_ci goto err; 12588c2ecf20Sopenharmony_ci } 12598c2ecf20Sopenharmony_ci return 0; 12608c2ecf20Sopenharmony_cierr: 12618c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 12628c2ecf20Sopenharmony_ci return -1; 12638c2ecf20Sopenharmony_ci} 12648c2ecf20Sopenharmony_ci 12658c2ecf20Sopenharmony_cistatic int stv090x_delivery_search(struct stv090x_state *state) 12668c2ecf20Sopenharmony_ci{ 12678c2ecf20Sopenharmony_ci u32 reg; 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_ci switch (state->search_mode) { 12708c2ecf20Sopenharmony_ci case STV090x_SEARCH_DVBS1: 12718c2ecf20Sopenharmony_ci case STV090x_SEARCH_DSS: 12728c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 12738c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); 12748c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); 12758c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 12768c2ecf20Sopenharmony_ci goto err; 12778c2ecf20Sopenharmony_ci 12788c2ecf20Sopenharmony_ci /* Activate Viterbi decoder in legacy search, 12798c2ecf20Sopenharmony_ci * do not use FRESVIT1, might impact VITERBI2 12808c2ecf20Sopenharmony_ci */ 12818c2ecf20Sopenharmony_ci if (stv090x_vitclk_ctl(state, 0) < 0) 12828c2ecf20Sopenharmony_ci goto err; 12838c2ecf20Sopenharmony_ci 12848c2ecf20Sopenharmony_ci if (stv090x_dvbs_track_crl(state) < 0) 12858c2ecf20Sopenharmony_ci goto err; 12868c2ecf20Sopenharmony_ci 12878c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x22) < 0) /* disable DVB-S2 */ 12888c2ecf20Sopenharmony_ci goto err; 12898c2ecf20Sopenharmony_ci 12908c2ecf20Sopenharmony_ci if (stv090x_set_vit_thacq(state) < 0) 12918c2ecf20Sopenharmony_ci goto err; 12928c2ecf20Sopenharmony_ci if (stv090x_set_viterbi(state) < 0) 12938c2ecf20Sopenharmony_ci goto err; 12948c2ecf20Sopenharmony_ci break; 12958c2ecf20Sopenharmony_ci 12968c2ecf20Sopenharmony_ci case STV090x_SEARCH_DVBS2: 12978c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 12988c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); 12998c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); 13008c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 13018c2ecf20Sopenharmony_ci goto err; 13028c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); 13038c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); 13048c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 13058c2ecf20Sopenharmony_ci goto err; 13068c2ecf20Sopenharmony_ci 13078c2ecf20Sopenharmony_ci if (stv090x_vitclk_ctl(state, 1) < 0) 13088c2ecf20Sopenharmony_ci goto err; 13098c2ecf20Sopenharmony_ci 13108c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) /* stop DVB-S CR loop */ 13118c2ecf20Sopenharmony_ci goto err; 13128c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) 13138c2ecf20Sopenharmony_ci goto err; 13148c2ecf20Sopenharmony_ci 13158c2ecf20Sopenharmony_ci if (state->internal->dev_ver <= 0x20) { 13168c2ecf20Sopenharmony_ci /* enable S2 carrier loop */ 13178c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) 13188c2ecf20Sopenharmony_ci goto err; 13198c2ecf20Sopenharmony_ci } else { 13208c2ecf20Sopenharmony_ci /* > Cut 3: Stop carrier 3 */ 13218c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0) 13228c2ecf20Sopenharmony_ci goto err; 13238c2ecf20Sopenharmony_ci } 13248c2ecf20Sopenharmony_ci 13258c2ecf20Sopenharmony_ci if (state->demod_mode != STV090x_SINGLE) { 13268c2ecf20Sopenharmony_ci /* Cut 2: enable link during search */ 13278c2ecf20Sopenharmony_ci if (stv090x_activate_modcod(state) < 0) 13288c2ecf20Sopenharmony_ci goto err; 13298c2ecf20Sopenharmony_ci } else { 13308c2ecf20Sopenharmony_ci /* Single demodulator 13318c2ecf20Sopenharmony_ci * Authorize SHORT and LONG frames, 13328c2ecf20Sopenharmony_ci * QPSK, 8PSK, 16APSK and 32APSK 13338c2ecf20Sopenharmony_ci */ 13348c2ecf20Sopenharmony_ci if (stv090x_activate_modcod_single(state) < 0) 13358c2ecf20Sopenharmony_ci goto err; 13368c2ecf20Sopenharmony_ci } 13378c2ecf20Sopenharmony_ci 13388c2ecf20Sopenharmony_ci if (stv090x_set_vit_thtracq(state) < 0) 13398c2ecf20Sopenharmony_ci goto err; 13408c2ecf20Sopenharmony_ci break; 13418c2ecf20Sopenharmony_ci 13428c2ecf20Sopenharmony_ci case STV090x_SEARCH_AUTO: 13438c2ecf20Sopenharmony_ci default: 13448c2ecf20Sopenharmony_ci /* enable DVB-S2 and DVB-S2 in Auto MODE */ 13458c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 13468c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); 13478c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); 13488c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 13498c2ecf20Sopenharmony_ci goto err; 13508c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); 13518c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); 13528c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 13538c2ecf20Sopenharmony_ci goto err; 13548c2ecf20Sopenharmony_ci 13558c2ecf20Sopenharmony_ci if (stv090x_vitclk_ctl(state, 0) < 0) 13568c2ecf20Sopenharmony_ci goto err; 13578c2ecf20Sopenharmony_ci 13588c2ecf20Sopenharmony_ci if (stv090x_dvbs_track_crl(state) < 0) 13598c2ecf20Sopenharmony_ci goto err; 13608c2ecf20Sopenharmony_ci 13618c2ecf20Sopenharmony_ci if (state->internal->dev_ver <= 0x20) { 13628c2ecf20Sopenharmony_ci /* enable S2 carrier loop */ 13638c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) 13648c2ecf20Sopenharmony_ci goto err; 13658c2ecf20Sopenharmony_ci } else { 13668c2ecf20Sopenharmony_ci /* > Cut 3: Stop carrier 3 */ 13678c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0) 13688c2ecf20Sopenharmony_ci goto err; 13698c2ecf20Sopenharmony_ci } 13708c2ecf20Sopenharmony_ci 13718c2ecf20Sopenharmony_ci if (state->demod_mode != STV090x_SINGLE) { 13728c2ecf20Sopenharmony_ci /* Cut 2: enable link during search */ 13738c2ecf20Sopenharmony_ci if (stv090x_activate_modcod(state) < 0) 13748c2ecf20Sopenharmony_ci goto err; 13758c2ecf20Sopenharmony_ci } else { 13768c2ecf20Sopenharmony_ci /* Single demodulator 13778c2ecf20Sopenharmony_ci * Authorize SHORT and LONG frames, 13788c2ecf20Sopenharmony_ci * QPSK, 8PSK, 16APSK and 32APSK 13798c2ecf20Sopenharmony_ci */ 13808c2ecf20Sopenharmony_ci if (stv090x_activate_modcod_single(state) < 0) 13818c2ecf20Sopenharmony_ci goto err; 13828c2ecf20Sopenharmony_ci } 13838c2ecf20Sopenharmony_ci 13848c2ecf20Sopenharmony_ci if (stv090x_set_vit_thacq(state) < 0) 13858c2ecf20Sopenharmony_ci goto err; 13868c2ecf20Sopenharmony_ci 13878c2ecf20Sopenharmony_ci if (stv090x_set_viterbi(state) < 0) 13888c2ecf20Sopenharmony_ci goto err; 13898c2ecf20Sopenharmony_ci break; 13908c2ecf20Sopenharmony_ci } 13918c2ecf20Sopenharmony_ci return 0; 13928c2ecf20Sopenharmony_cierr: 13938c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 13948c2ecf20Sopenharmony_ci return -1; 13958c2ecf20Sopenharmony_ci} 13968c2ecf20Sopenharmony_ci 13978c2ecf20Sopenharmony_cistatic int stv090x_start_search(struct stv090x_state *state) 13988c2ecf20Sopenharmony_ci{ 13998c2ecf20Sopenharmony_ci u32 reg, freq_abs; 14008c2ecf20Sopenharmony_ci s16 freq; 14018c2ecf20Sopenharmony_ci 14028c2ecf20Sopenharmony_ci /* Reset demodulator */ 14038c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDISTATE); 14048c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); 14058c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) 14068c2ecf20Sopenharmony_ci goto err; 14078c2ecf20Sopenharmony_ci 14088c2ecf20Sopenharmony_ci if (state->internal->dev_ver <= 0x20) { 14098c2ecf20Sopenharmony_ci if (state->srate <= 5000000) { 14108c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0) 14118c2ecf20Sopenharmony_ci goto err; 14128c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0) 14138c2ecf20Sopenharmony_ci goto err; 14148c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRUP0, 0xff) < 0) 14158c2ecf20Sopenharmony_ci goto err; 14168c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0) 14178c2ecf20Sopenharmony_ci goto err; 14188c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0) 14198c2ecf20Sopenharmony_ci goto err; 14208c2ecf20Sopenharmony_ci 14218c2ecf20Sopenharmony_ci /*enlarge the timing bandwidth for Low SR*/ 14228c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) 14238c2ecf20Sopenharmony_ci goto err; 14248c2ecf20Sopenharmony_ci } else { 14258c2ecf20Sopenharmony_ci /* If the symbol rate is >5 Msps 14268c2ecf20Sopenharmony_ci Set The carrier search up and low to auto mode */ 14278c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) 14288c2ecf20Sopenharmony_ci goto err; 14298c2ecf20Sopenharmony_ci /*reduce the timing bandwidth for high SR*/ 14308c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) 14318c2ecf20Sopenharmony_ci goto err; 14328c2ecf20Sopenharmony_ci } 14338c2ecf20Sopenharmony_ci } else { 14348c2ecf20Sopenharmony_ci /* >= Cut 3 */ 14358c2ecf20Sopenharmony_ci if (state->srate <= 5000000) { 14368c2ecf20Sopenharmony_ci /* enlarge the timing bandwidth for Low SR */ 14378c2ecf20Sopenharmony_ci STV090x_WRITE_DEMOD(state, RTCS2, 0x68); 14388c2ecf20Sopenharmony_ci } else { 14398c2ecf20Sopenharmony_ci /* reduce timing bandwidth for high SR */ 14408c2ecf20Sopenharmony_ci STV090x_WRITE_DEMOD(state, RTCS2, 0x44); 14418c2ecf20Sopenharmony_ci } 14428c2ecf20Sopenharmony_ci 14438c2ecf20Sopenharmony_ci /* Set CFR min and max to manual mode */ 14448c2ecf20Sopenharmony_ci STV090x_WRITE_DEMOD(state, CARCFG, 0x46); 14458c2ecf20Sopenharmony_ci 14468c2ecf20Sopenharmony_ci if (state->algo == STV090x_WARM_SEARCH) { 14478c2ecf20Sopenharmony_ci /* WARM Start 14488c2ecf20Sopenharmony_ci * CFR min = -1MHz, 14498c2ecf20Sopenharmony_ci * CFR max = +1MHz 14508c2ecf20Sopenharmony_ci */ 14518c2ecf20Sopenharmony_ci freq_abs = 1000 << 16; 14528c2ecf20Sopenharmony_ci freq_abs /= (state->internal->mclk / 1000); 14538c2ecf20Sopenharmony_ci freq = (s16) freq_abs; 14548c2ecf20Sopenharmony_ci } else { 14558c2ecf20Sopenharmony_ci /* COLD Start 14568c2ecf20Sopenharmony_ci * CFR min =- (SearchRange / 2 + 600KHz) 14578c2ecf20Sopenharmony_ci * CFR max = +(SearchRange / 2 + 600KHz) 14588c2ecf20Sopenharmony_ci * (600KHz for the tuner step size) 14598c2ecf20Sopenharmony_ci */ 14608c2ecf20Sopenharmony_ci freq_abs = (state->search_range / 2000) + 600; 14618c2ecf20Sopenharmony_ci freq_abs = freq_abs << 16; 14628c2ecf20Sopenharmony_ci freq_abs /= (state->internal->mclk / 1000); 14638c2ecf20Sopenharmony_ci freq = (s16) freq_abs; 14648c2ecf20Sopenharmony_ci } 14658c2ecf20Sopenharmony_ci 14668c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0) 14678c2ecf20Sopenharmony_ci goto err; 14688c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRUP0, LSB(freq)) < 0) 14698c2ecf20Sopenharmony_ci goto err; 14708c2ecf20Sopenharmony_ci 14718c2ecf20Sopenharmony_ci freq *= -1; 14728c2ecf20Sopenharmony_ci 14738c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRLOW1, MSB(freq)) < 0) 14748c2ecf20Sopenharmony_ci goto err; 14758c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRLOW0, LSB(freq)) < 0) 14768c2ecf20Sopenharmony_ci goto err; 14778c2ecf20Sopenharmony_ci 14788c2ecf20Sopenharmony_ci } 14798c2ecf20Sopenharmony_ci 14808c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0) < 0) 14818c2ecf20Sopenharmony_ci goto err; 14828c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0) 14838c2ecf20Sopenharmony_ci goto err; 14848c2ecf20Sopenharmony_ci 14858c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 14868c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) 14878c2ecf20Sopenharmony_ci goto err; 14888c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) 14898c2ecf20Sopenharmony_ci goto err; 14908c2ecf20Sopenharmony_ci 14918c2ecf20Sopenharmony_ci if ((state->search_mode == STV090x_SEARCH_DVBS1) || 14928c2ecf20Sopenharmony_ci (state->search_mode == STV090x_SEARCH_DSS) || 14938c2ecf20Sopenharmony_ci (state->search_mode == STV090x_SEARCH_AUTO)) { 14948c2ecf20Sopenharmony_ci 14958c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0) 14968c2ecf20Sopenharmony_ci goto err; 14978c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) 14988c2ecf20Sopenharmony_ci goto err; 14998c2ecf20Sopenharmony_ci } 15008c2ecf20Sopenharmony_ci } 15018c2ecf20Sopenharmony_ci 15028c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00) < 0) 15038c2ecf20Sopenharmony_ci goto err; 15048c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xe0) < 0) 15058c2ecf20Sopenharmony_ci goto err; 15068c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xc0) < 0) 15078c2ecf20Sopenharmony_ci goto err; 15088c2ecf20Sopenharmony_ci 15098c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 15108c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0); 15118c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0); 15128c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 15138c2ecf20Sopenharmony_ci goto err; 15148c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFG2); 15158c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, S1S2_SEQUENTIAL_FIELD, 0x0); 15168c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0) 15178c2ecf20Sopenharmony_ci goto err; 15188c2ecf20Sopenharmony_ci 15198c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) 15208c2ecf20Sopenharmony_ci goto err; 15218c2ecf20Sopenharmony_ci 15228c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 15238c2ecf20Sopenharmony_ci /*Frequency offset detector setting*/ 15248c2ecf20Sopenharmony_ci if (state->srate < 2000000) { 15258c2ecf20Sopenharmony_ci if (state->internal->dev_ver <= 0x20) { 15268c2ecf20Sopenharmony_ci /* Cut 2 */ 15278c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0) 15288c2ecf20Sopenharmony_ci goto err; 15298c2ecf20Sopenharmony_ci } else { 15308c2ecf20Sopenharmony_ci /* Cut 3 */ 15318c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0) 15328c2ecf20Sopenharmony_ci goto err; 15338c2ecf20Sopenharmony_ci } 15348c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0) 15358c2ecf20Sopenharmony_ci goto err; 15368c2ecf20Sopenharmony_ci } else if (state->srate < 10000000) { 15378c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0) 15388c2ecf20Sopenharmony_ci goto err; 15398c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0) 15408c2ecf20Sopenharmony_ci goto err; 15418c2ecf20Sopenharmony_ci } else { 15428c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0) 15438c2ecf20Sopenharmony_ci goto err; 15448c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0) 15458c2ecf20Sopenharmony_ci goto err; 15468c2ecf20Sopenharmony_ci } 15478c2ecf20Sopenharmony_ci } else { 15488c2ecf20Sopenharmony_ci if (state->srate < 10000000) { 15498c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0) 15508c2ecf20Sopenharmony_ci goto err; 15518c2ecf20Sopenharmony_ci } else { 15528c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0) 15538c2ecf20Sopenharmony_ci goto err; 15548c2ecf20Sopenharmony_ci } 15558c2ecf20Sopenharmony_ci } 15568c2ecf20Sopenharmony_ci 15578c2ecf20Sopenharmony_ci switch (state->algo) { 15588c2ecf20Sopenharmony_ci case STV090x_WARM_SEARCH: 15598c2ecf20Sopenharmony_ci /* The symbol rate and the exact 15608c2ecf20Sopenharmony_ci * carrier Frequency are known 15618c2ecf20Sopenharmony_ci */ 15628c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) 15638c2ecf20Sopenharmony_ci goto err; 15648c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) 15658c2ecf20Sopenharmony_ci goto err; 15668c2ecf20Sopenharmony_ci break; 15678c2ecf20Sopenharmony_ci 15688c2ecf20Sopenharmony_ci case STV090x_COLD_SEARCH: 15698c2ecf20Sopenharmony_ci /* The symbol rate is known */ 15708c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) 15718c2ecf20Sopenharmony_ci goto err; 15728c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) 15738c2ecf20Sopenharmony_ci goto err; 15748c2ecf20Sopenharmony_ci break; 15758c2ecf20Sopenharmony_ci 15768c2ecf20Sopenharmony_ci default: 15778c2ecf20Sopenharmony_ci break; 15788c2ecf20Sopenharmony_ci } 15798c2ecf20Sopenharmony_ci return 0; 15808c2ecf20Sopenharmony_cierr: 15818c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 15828c2ecf20Sopenharmony_ci return -1; 15838c2ecf20Sopenharmony_ci} 15848c2ecf20Sopenharmony_ci 15858c2ecf20Sopenharmony_cistatic int stv090x_get_agc2_min_level(struct stv090x_state *state) 15868c2ecf20Sopenharmony_ci{ 15878c2ecf20Sopenharmony_ci u32 agc2_min = 0xffff, agc2 = 0, freq_init, freq_step, reg; 15888c2ecf20Sopenharmony_ci s32 i, j, steps, dir; 15898c2ecf20Sopenharmony_ci 15908c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) 15918c2ecf20Sopenharmony_ci goto err; 15928c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 15938c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0); 15948c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0); 15958c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 15968c2ecf20Sopenharmony_ci goto err; 15978c2ecf20Sopenharmony_ci 15988c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) /* SR = 65 Msps Max */ 15998c2ecf20Sopenharmony_ci goto err; 16008c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0) 16018c2ecf20Sopenharmony_ci goto err; 16028c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) /* SR= 400 ksps Min */ 16038c2ecf20Sopenharmony_ci goto err; 16048c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0) 16058c2ecf20Sopenharmony_ci goto err; 16068c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) /* stop acq @ coarse carrier state */ 16078c2ecf20Sopenharmony_ci goto err; 16088c2ecf20Sopenharmony_ci if (stv090x_set_srate(state, 1000000) < 0) 16098c2ecf20Sopenharmony_ci goto err; 16108c2ecf20Sopenharmony_ci 16118c2ecf20Sopenharmony_ci steps = state->search_range / 1000000; 16128c2ecf20Sopenharmony_ci if (steps <= 0) 16138c2ecf20Sopenharmony_ci steps = 1; 16148c2ecf20Sopenharmony_ci 16158c2ecf20Sopenharmony_ci dir = 1; 16168c2ecf20Sopenharmony_ci freq_step = (1000000 * 256) / (state->internal->mclk / 256); 16178c2ecf20Sopenharmony_ci freq_init = 0; 16188c2ecf20Sopenharmony_ci 16198c2ecf20Sopenharmony_ci for (i = 0; i < steps; i++) { 16208c2ecf20Sopenharmony_ci if (dir > 0) 16218c2ecf20Sopenharmony_ci freq_init = freq_init + (freq_step * i); 16228c2ecf20Sopenharmony_ci else 16238c2ecf20Sopenharmony_ci freq_init = freq_init - (freq_step * i); 16248c2ecf20Sopenharmony_ci 16258c2ecf20Sopenharmony_ci dir *= -1; 16268c2ecf20Sopenharmony_ci 16278c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */ 16288c2ecf20Sopenharmony_ci goto err; 16298c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_init >> 8) & 0xff) < 0) 16308c2ecf20Sopenharmony_ci goto err; 16318c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_init & 0xff) < 0) 16328c2ecf20Sopenharmony_ci goto err; 16338c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */ 16348c2ecf20Sopenharmony_ci goto err; 16358c2ecf20Sopenharmony_ci msleep(10); 16368c2ecf20Sopenharmony_ci 16378c2ecf20Sopenharmony_ci agc2 = 0; 16388c2ecf20Sopenharmony_ci for (j = 0; j < 10; j++) { 16398c2ecf20Sopenharmony_ci agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) | 16408c2ecf20Sopenharmony_ci STV090x_READ_DEMOD(state, AGC2I0); 16418c2ecf20Sopenharmony_ci } 16428c2ecf20Sopenharmony_ci agc2 /= 10; 16438c2ecf20Sopenharmony_ci if (agc2 < agc2_min) 16448c2ecf20Sopenharmony_ci agc2_min = agc2; 16458c2ecf20Sopenharmony_ci } 16468c2ecf20Sopenharmony_ci 16478c2ecf20Sopenharmony_ci return agc2_min; 16488c2ecf20Sopenharmony_cierr: 16498c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 16508c2ecf20Sopenharmony_ci return -1; 16518c2ecf20Sopenharmony_ci} 16528c2ecf20Sopenharmony_ci 16538c2ecf20Sopenharmony_cistatic u32 stv090x_get_srate(struct stv090x_state *state, u32 clk) 16548c2ecf20Sopenharmony_ci{ 16558c2ecf20Sopenharmony_ci u8 r3, r2, r1, r0; 16568c2ecf20Sopenharmony_ci s32 srate, int_1, int_2, tmp_1, tmp_2; 16578c2ecf20Sopenharmony_ci 16588c2ecf20Sopenharmony_ci r3 = STV090x_READ_DEMOD(state, SFR3); 16598c2ecf20Sopenharmony_ci r2 = STV090x_READ_DEMOD(state, SFR2); 16608c2ecf20Sopenharmony_ci r1 = STV090x_READ_DEMOD(state, SFR1); 16618c2ecf20Sopenharmony_ci r0 = STV090x_READ_DEMOD(state, SFR0); 16628c2ecf20Sopenharmony_ci 16638c2ecf20Sopenharmony_ci srate = ((r3 << 24) | (r2 << 16) | (r1 << 8) | r0); 16648c2ecf20Sopenharmony_ci 16658c2ecf20Sopenharmony_ci int_1 = clk >> 16; 16668c2ecf20Sopenharmony_ci int_2 = srate >> 16; 16678c2ecf20Sopenharmony_ci 16688c2ecf20Sopenharmony_ci tmp_1 = clk % 0x10000; 16698c2ecf20Sopenharmony_ci tmp_2 = srate % 0x10000; 16708c2ecf20Sopenharmony_ci 16718c2ecf20Sopenharmony_ci srate = (int_1 * int_2) + 16728c2ecf20Sopenharmony_ci ((int_1 * tmp_2) >> 16) + 16738c2ecf20Sopenharmony_ci ((int_2 * tmp_1) >> 16); 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_ci return srate; 16768c2ecf20Sopenharmony_ci} 16778c2ecf20Sopenharmony_ci 16788c2ecf20Sopenharmony_cistatic u32 stv090x_srate_srch_coarse(struct stv090x_state *state) 16798c2ecf20Sopenharmony_ci{ 16808c2ecf20Sopenharmony_ci struct dvb_frontend *fe = &state->frontend; 16818c2ecf20Sopenharmony_ci 16828c2ecf20Sopenharmony_ci int tmg_lock = 0, i; 16838c2ecf20Sopenharmony_ci s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq; 16848c2ecf20Sopenharmony_ci u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg; 16858c2ecf20Sopenharmony_ci u32 agc2th; 16868c2ecf20Sopenharmony_ci 16878c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x30) 16888c2ecf20Sopenharmony_ci agc2th = 0x2e00; 16898c2ecf20Sopenharmony_ci else 16908c2ecf20Sopenharmony_ci agc2th = 0x1f00; 16918c2ecf20Sopenharmony_ci 16928c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDISTATE); 16938c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */ 16948c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) 16958c2ecf20Sopenharmony_ci goto err; 16968c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0) 16978c2ecf20Sopenharmony_ci goto err; 16988c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0) 16998c2ecf20Sopenharmony_ci goto err; 17008c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0) 17018c2ecf20Sopenharmony_ci goto err; 17028c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0) 17038c2ecf20Sopenharmony_ci goto err; 17048c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 17058c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1); 17068c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0); 17078c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 17088c2ecf20Sopenharmony_ci goto err; 17098c2ecf20Sopenharmony_ci 17108c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) 17118c2ecf20Sopenharmony_ci goto err; 17128c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0) 17138c2ecf20Sopenharmony_ci goto err; 17148c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) 17158c2ecf20Sopenharmony_ci goto err; 17168c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0) 17178c2ecf20Sopenharmony_ci goto err; 17188c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) 17198c2ecf20Sopenharmony_ci goto err; 17208c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0) 17218c2ecf20Sopenharmony_ci goto err; 17228c2ecf20Sopenharmony_ci 17238c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x30) { 17248c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0) 17258c2ecf20Sopenharmony_ci goto err; 17268c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0) 17278c2ecf20Sopenharmony_ci goto err; 17288c2ecf20Sopenharmony_ci 17298c2ecf20Sopenharmony_ci } else if (state->internal->dev_ver >= 0x20) { 17308c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0) 17318c2ecf20Sopenharmony_ci goto err; 17328c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) 17338c2ecf20Sopenharmony_ci goto err; 17348c2ecf20Sopenharmony_ci } 17358c2ecf20Sopenharmony_ci 17368c2ecf20Sopenharmony_ci if (state->srate <= 2000000) 17378c2ecf20Sopenharmony_ci car_step = 1000; 17388c2ecf20Sopenharmony_ci else if (state->srate <= 5000000) 17398c2ecf20Sopenharmony_ci car_step = 2000; 17408c2ecf20Sopenharmony_ci else if (state->srate <= 12000000) 17418c2ecf20Sopenharmony_ci car_step = 3000; 17428c2ecf20Sopenharmony_ci else 17438c2ecf20Sopenharmony_ci car_step = 5000; 17448c2ecf20Sopenharmony_ci 17458c2ecf20Sopenharmony_ci steps = -1 + ((state->search_range / 1000) / car_step); 17468c2ecf20Sopenharmony_ci steps /= 2; 17478c2ecf20Sopenharmony_ci steps = (2 * steps) + 1; 17488c2ecf20Sopenharmony_ci if (steps < 0) 17498c2ecf20Sopenharmony_ci steps = 1; 17508c2ecf20Sopenharmony_ci else if (steps > 10) { 17518c2ecf20Sopenharmony_ci steps = 11; 17528c2ecf20Sopenharmony_ci car_step = (state->search_range / 1000) / 10; 17538c2ecf20Sopenharmony_ci } 17548c2ecf20Sopenharmony_ci cur_step = 0; 17558c2ecf20Sopenharmony_ci dir = 1; 17568c2ecf20Sopenharmony_ci freq = state->frequency; 17578c2ecf20Sopenharmony_ci 17588c2ecf20Sopenharmony_ci while ((!tmg_lock) && (cur_step < steps)) { 17598c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */ 17608c2ecf20Sopenharmony_ci goto err; 17618c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) 17628c2ecf20Sopenharmony_ci goto err; 17638c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) 17648c2ecf20Sopenharmony_ci goto err; 17658c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRINIT1, 0x00) < 0) 17668c2ecf20Sopenharmony_ci goto err; 17678c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRINIT0, 0x00) < 0) 17688c2ecf20Sopenharmony_ci goto err; 17698c2ecf20Sopenharmony_ci /* trigger acquisition */ 17708c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x40) < 0) 17718c2ecf20Sopenharmony_ci goto err; 17728c2ecf20Sopenharmony_ci msleep(50); 17738c2ecf20Sopenharmony_ci for (i = 0; i < 10; i++) { 17748c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DSTATUS); 17758c2ecf20Sopenharmony_ci if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2) 17768c2ecf20Sopenharmony_ci tmg_cpt++; 17778c2ecf20Sopenharmony_ci agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) | 17788c2ecf20Sopenharmony_ci STV090x_READ_DEMOD(state, AGC2I0); 17798c2ecf20Sopenharmony_ci } 17808c2ecf20Sopenharmony_ci agc2 /= 10; 17818c2ecf20Sopenharmony_ci srate_coarse = stv090x_get_srate(state, state->internal->mclk); 17828c2ecf20Sopenharmony_ci cur_step++; 17838c2ecf20Sopenharmony_ci dir *= -1; 17848c2ecf20Sopenharmony_ci if ((tmg_cpt >= 5) && (agc2 < agc2th) && 17858c2ecf20Sopenharmony_ci (srate_coarse < 50000000) && (srate_coarse > 850000)) 17868c2ecf20Sopenharmony_ci tmg_lock = 1; 17878c2ecf20Sopenharmony_ci else if (cur_step < steps) { 17888c2ecf20Sopenharmony_ci if (dir > 0) 17898c2ecf20Sopenharmony_ci freq += cur_step * car_step; 17908c2ecf20Sopenharmony_ci else 17918c2ecf20Sopenharmony_ci freq -= cur_step * car_step; 17928c2ecf20Sopenharmony_ci 17938c2ecf20Sopenharmony_ci /* Setup tuner */ 17948c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 17958c2ecf20Sopenharmony_ci goto err; 17968c2ecf20Sopenharmony_ci 17978c2ecf20Sopenharmony_ci if (state->config->tuner_set_frequency) { 17988c2ecf20Sopenharmony_ci if (state->config->tuner_set_frequency(fe, freq) < 0) 17998c2ecf20Sopenharmony_ci goto err_gateoff; 18008c2ecf20Sopenharmony_ci } 18018c2ecf20Sopenharmony_ci 18028c2ecf20Sopenharmony_ci if (state->config->tuner_set_bandwidth) { 18038c2ecf20Sopenharmony_ci if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) 18048c2ecf20Sopenharmony_ci goto err_gateoff; 18058c2ecf20Sopenharmony_ci } 18068c2ecf20Sopenharmony_ci 18078c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 18088c2ecf20Sopenharmony_ci goto err; 18098c2ecf20Sopenharmony_ci 18108c2ecf20Sopenharmony_ci msleep(50); 18118c2ecf20Sopenharmony_ci 18128c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 18138c2ecf20Sopenharmony_ci goto err; 18148c2ecf20Sopenharmony_ci 18158c2ecf20Sopenharmony_ci if (state->config->tuner_get_status) { 18168c2ecf20Sopenharmony_ci if (state->config->tuner_get_status(fe, ®) < 0) 18178c2ecf20Sopenharmony_ci goto err_gateoff; 18188c2ecf20Sopenharmony_ci } 18198c2ecf20Sopenharmony_ci 18208c2ecf20Sopenharmony_ci if (reg) 18218c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Tuner phase locked"); 18228c2ecf20Sopenharmony_ci else 18238c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Tuner unlocked"); 18248c2ecf20Sopenharmony_ci 18258c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 18268c2ecf20Sopenharmony_ci goto err; 18278c2ecf20Sopenharmony_ci 18288c2ecf20Sopenharmony_ci } 18298c2ecf20Sopenharmony_ci } 18308c2ecf20Sopenharmony_ci if (!tmg_lock) 18318c2ecf20Sopenharmony_ci srate_coarse = 0; 18328c2ecf20Sopenharmony_ci else 18338c2ecf20Sopenharmony_ci srate_coarse = stv090x_get_srate(state, state->internal->mclk); 18348c2ecf20Sopenharmony_ci 18358c2ecf20Sopenharmony_ci return srate_coarse; 18368c2ecf20Sopenharmony_ci 18378c2ecf20Sopenharmony_cierr_gateoff: 18388c2ecf20Sopenharmony_ci stv090x_i2c_gate_ctrl(state, 0); 18398c2ecf20Sopenharmony_cierr: 18408c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 18418c2ecf20Sopenharmony_ci return -1; 18428c2ecf20Sopenharmony_ci} 18438c2ecf20Sopenharmony_ci 18448c2ecf20Sopenharmony_cistatic u32 stv090x_srate_srch_fine(struct stv090x_state *state) 18458c2ecf20Sopenharmony_ci{ 18468c2ecf20Sopenharmony_ci u32 srate_coarse, freq_coarse, sym, reg; 18478c2ecf20Sopenharmony_ci 18488c2ecf20Sopenharmony_ci srate_coarse = stv090x_get_srate(state, state->internal->mclk); 18498c2ecf20Sopenharmony_ci freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8; 18508c2ecf20Sopenharmony_ci freq_coarse |= STV090x_READ_DEMOD(state, CFR1); 18518c2ecf20Sopenharmony_ci sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ 18528c2ecf20Sopenharmony_ci 18538c2ecf20Sopenharmony_ci if (sym < state->srate) 18548c2ecf20Sopenharmony_ci srate_coarse = 0; 18558c2ecf20Sopenharmony_ci else { 18568c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */ 18578c2ecf20Sopenharmony_ci goto err; 18588c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) 18598c2ecf20Sopenharmony_ci goto err; 18608c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0) 18618c2ecf20Sopenharmony_ci goto err; 18628c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0) 18638c2ecf20Sopenharmony_ci goto err; 18648c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0) 18658c2ecf20Sopenharmony_ci goto err; 18668c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 18678c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); 18688c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 18698c2ecf20Sopenharmony_ci goto err; 18708c2ecf20Sopenharmony_ci 18718c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) 18728c2ecf20Sopenharmony_ci goto err; 18738c2ecf20Sopenharmony_ci 18748c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x30) { 18758c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0) 18768c2ecf20Sopenharmony_ci goto err; 18778c2ecf20Sopenharmony_ci } else if (state->internal->dev_ver >= 0x20) { 18788c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) 18798c2ecf20Sopenharmony_ci goto err; 18808c2ecf20Sopenharmony_ci } 18818c2ecf20Sopenharmony_ci 18828c2ecf20Sopenharmony_ci if (srate_coarse > 3000000) { 18838c2ecf20Sopenharmony_ci sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ 18848c2ecf20Sopenharmony_ci sym = (sym / 1000) * 65536; 18858c2ecf20Sopenharmony_ci sym /= (state->internal->mclk / 1000); 18868c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) 18878c2ecf20Sopenharmony_ci goto err; 18888c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) 18898c2ecf20Sopenharmony_ci goto err; 18908c2ecf20Sopenharmony_ci sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */ 18918c2ecf20Sopenharmony_ci sym = (sym / 1000) * 65536; 18928c2ecf20Sopenharmony_ci sym /= (state->internal->mclk / 1000); 18938c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) 18948c2ecf20Sopenharmony_ci goto err; 18958c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) 18968c2ecf20Sopenharmony_ci goto err; 18978c2ecf20Sopenharmony_ci sym = (srate_coarse / 1000) * 65536; 18988c2ecf20Sopenharmony_ci sym /= (state->internal->mclk / 1000); 18998c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) 19008c2ecf20Sopenharmony_ci goto err; 19018c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) 19028c2ecf20Sopenharmony_ci goto err; 19038c2ecf20Sopenharmony_ci } else { 19048c2ecf20Sopenharmony_ci sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ 19058c2ecf20Sopenharmony_ci sym = (sym / 100) * 65536; 19068c2ecf20Sopenharmony_ci sym /= (state->internal->mclk / 100); 19078c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) 19088c2ecf20Sopenharmony_ci goto err; 19098c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) 19108c2ecf20Sopenharmony_ci goto err; 19118c2ecf20Sopenharmony_ci sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */ 19128c2ecf20Sopenharmony_ci sym = (sym / 100) * 65536; 19138c2ecf20Sopenharmony_ci sym /= (state->internal->mclk / 100); 19148c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) 19158c2ecf20Sopenharmony_ci goto err; 19168c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) 19178c2ecf20Sopenharmony_ci goto err; 19188c2ecf20Sopenharmony_ci sym = (srate_coarse / 100) * 65536; 19198c2ecf20Sopenharmony_ci sym /= (state->internal->mclk / 100); 19208c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) 19218c2ecf20Sopenharmony_ci goto err; 19228c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) 19238c2ecf20Sopenharmony_ci goto err; 19248c2ecf20Sopenharmony_ci } 19258c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0) 19268c2ecf20Sopenharmony_ci goto err; 19278c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_coarse >> 8) & 0xff) < 0) 19288c2ecf20Sopenharmony_ci goto err; 19298c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_coarse & 0xff) < 0) 19308c2ecf20Sopenharmony_ci goto err; 19318c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) /* trigger acquisition */ 19328c2ecf20Sopenharmony_ci goto err; 19338c2ecf20Sopenharmony_ci } 19348c2ecf20Sopenharmony_ci 19358c2ecf20Sopenharmony_ci return srate_coarse; 19368c2ecf20Sopenharmony_ci 19378c2ecf20Sopenharmony_cierr: 19388c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 19398c2ecf20Sopenharmony_ci return -1; 19408c2ecf20Sopenharmony_ci} 19418c2ecf20Sopenharmony_ci 19428c2ecf20Sopenharmony_cistatic int stv090x_get_dmdlock(struct stv090x_state *state, s32 timeout) 19438c2ecf20Sopenharmony_ci{ 19448c2ecf20Sopenharmony_ci s32 timer = 0, lock = 0; 19458c2ecf20Sopenharmony_ci u32 reg; 19468c2ecf20Sopenharmony_ci u8 stat; 19478c2ecf20Sopenharmony_ci 19488c2ecf20Sopenharmony_ci while ((timer < timeout) && (!lock)) { 19498c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDSTATE); 19508c2ecf20Sopenharmony_ci stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); 19518c2ecf20Sopenharmony_ci 19528c2ecf20Sopenharmony_ci switch (stat) { 19538c2ecf20Sopenharmony_ci case 0: /* searching */ 19548c2ecf20Sopenharmony_ci case 1: /* first PLH detected */ 19558c2ecf20Sopenharmony_ci default: 19568c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Demodulator searching .."); 19578c2ecf20Sopenharmony_ci lock = 0; 19588c2ecf20Sopenharmony_ci break; 19598c2ecf20Sopenharmony_ci case 2: /* DVB-S2 mode */ 19608c2ecf20Sopenharmony_ci case 3: /* DVB-S1/legacy mode */ 19618c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DSTATUS); 19628c2ecf20Sopenharmony_ci lock = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD); 19638c2ecf20Sopenharmony_ci break; 19648c2ecf20Sopenharmony_ci } 19658c2ecf20Sopenharmony_ci 19668c2ecf20Sopenharmony_ci if (!lock) 19678c2ecf20Sopenharmony_ci msleep(10); 19688c2ecf20Sopenharmony_ci else 19698c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Demodulator acquired LOCK"); 19708c2ecf20Sopenharmony_ci 19718c2ecf20Sopenharmony_ci timer += 10; 19728c2ecf20Sopenharmony_ci } 19738c2ecf20Sopenharmony_ci return lock; 19748c2ecf20Sopenharmony_ci} 19758c2ecf20Sopenharmony_ci 19768c2ecf20Sopenharmony_cistatic int stv090x_blind_search(struct stv090x_state *state) 19778c2ecf20Sopenharmony_ci{ 19788c2ecf20Sopenharmony_ci u32 agc2, reg, srate_coarse; 19798c2ecf20Sopenharmony_ci s32 cpt_fail, agc2_ovflw, i; 19808c2ecf20Sopenharmony_ci u8 k_ref, k_max, k_min; 19818c2ecf20Sopenharmony_ci int coarse_fail = 0; 19828c2ecf20Sopenharmony_ci int lock; 19838c2ecf20Sopenharmony_ci 19848c2ecf20Sopenharmony_ci k_max = 110; 19858c2ecf20Sopenharmony_ci k_min = 10; 19868c2ecf20Sopenharmony_ci 19878c2ecf20Sopenharmony_ci agc2 = stv090x_get_agc2_min_level(state); 19888c2ecf20Sopenharmony_ci 19898c2ecf20Sopenharmony_ci if (agc2 > STV090x_SEARCH_AGC2_TH(state->internal->dev_ver)) { 19908c2ecf20Sopenharmony_ci lock = 0; 19918c2ecf20Sopenharmony_ci } else { 19928c2ecf20Sopenharmony_ci 19938c2ecf20Sopenharmony_ci if (state->internal->dev_ver <= 0x20) { 19948c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) 19958c2ecf20Sopenharmony_ci goto err; 19968c2ecf20Sopenharmony_ci } else { 19978c2ecf20Sopenharmony_ci /* > Cut 3 */ 19988c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARCFG, 0x06) < 0) 19998c2ecf20Sopenharmony_ci goto err; 20008c2ecf20Sopenharmony_ci } 20018c2ecf20Sopenharmony_ci 20028c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) 20038c2ecf20Sopenharmony_ci goto err; 20048c2ecf20Sopenharmony_ci 20058c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 20068c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) 20078c2ecf20Sopenharmony_ci goto err; 20088c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) 20098c2ecf20Sopenharmony_ci goto err; 20108c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0) 20118c2ecf20Sopenharmony_ci goto err; 20128c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) /* set viterbi hysteresis */ 20138c2ecf20Sopenharmony_ci goto err; 20148c2ecf20Sopenharmony_ci } 20158c2ecf20Sopenharmony_ci 20168c2ecf20Sopenharmony_ci k_ref = k_max; 20178c2ecf20Sopenharmony_ci do { 20188c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, KREFTMG, k_ref) < 0) 20198c2ecf20Sopenharmony_ci goto err; 20208c2ecf20Sopenharmony_ci if (stv090x_srate_srch_coarse(state) != 0) { 20218c2ecf20Sopenharmony_ci srate_coarse = stv090x_srate_srch_fine(state); 20228c2ecf20Sopenharmony_ci if (srate_coarse != 0) { 20238c2ecf20Sopenharmony_ci stv090x_get_lock_tmg(state); 20248c2ecf20Sopenharmony_ci lock = stv090x_get_dmdlock(state, 20258c2ecf20Sopenharmony_ci state->DemodTimeout); 20268c2ecf20Sopenharmony_ci } else { 20278c2ecf20Sopenharmony_ci lock = 0; 20288c2ecf20Sopenharmony_ci } 20298c2ecf20Sopenharmony_ci } else { 20308c2ecf20Sopenharmony_ci cpt_fail = 0; 20318c2ecf20Sopenharmony_ci agc2_ovflw = 0; 20328c2ecf20Sopenharmony_ci for (i = 0; i < 10; i++) { 20338c2ecf20Sopenharmony_ci agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) | 20348c2ecf20Sopenharmony_ci STV090x_READ_DEMOD(state, AGC2I0); 20358c2ecf20Sopenharmony_ci if (agc2 >= 0xff00) 20368c2ecf20Sopenharmony_ci agc2_ovflw++; 20378c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DSTATUS2); 20388c2ecf20Sopenharmony_ci if ((STV090x_GETFIELD_Px(reg, CFR_OVERFLOW_FIELD) == 0x01) && 20398c2ecf20Sopenharmony_ci (STV090x_GETFIELD_Px(reg, DEMOD_DELOCK_FIELD) == 0x01)) 20408c2ecf20Sopenharmony_ci 20418c2ecf20Sopenharmony_ci cpt_fail++; 20428c2ecf20Sopenharmony_ci } 20438c2ecf20Sopenharmony_ci if ((cpt_fail > 7) || (agc2_ovflw > 7)) 20448c2ecf20Sopenharmony_ci coarse_fail = 1; 20458c2ecf20Sopenharmony_ci 20468c2ecf20Sopenharmony_ci lock = 0; 20478c2ecf20Sopenharmony_ci } 20488c2ecf20Sopenharmony_ci k_ref -= 20; 20498c2ecf20Sopenharmony_ci } while ((k_ref >= k_min) && (!lock) && (!coarse_fail)); 20508c2ecf20Sopenharmony_ci } 20518c2ecf20Sopenharmony_ci 20528c2ecf20Sopenharmony_ci return lock; 20538c2ecf20Sopenharmony_ci 20548c2ecf20Sopenharmony_cierr: 20558c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 20568c2ecf20Sopenharmony_ci return -1; 20578c2ecf20Sopenharmony_ci} 20588c2ecf20Sopenharmony_ci 20598c2ecf20Sopenharmony_cistatic int stv090x_chk_tmg(struct stv090x_state *state) 20608c2ecf20Sopenharmony_ci{ 20618c2ecf20Sopenharmony_ci u32 reg; 20628c2ecf20Sopenharmony_ci s32 tmg_cpt = 0, i; 20638c2ecf20Sopenharmony_ci u8 freq, tmg_thh, tmg_thl; 20648c2ecf20Sopenharmony_ci int tmg_lock = 0; 20658c2ecf20Sopenharmony_ci 20668c2ecf20Sopenharmony_ci freq = STV090x_READ_DEMOD(state, CARFREQ); 20678c2ecf20Sopenharmony_ci tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE); 20688c2ecf20Sopenharmony_ci tmg_thl = STV090x_READ_DEMOD(state, TMGTHFALL); 20698c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0) 20708c2ecf20Sopenharmony_ci goto err; 20718c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0) 20728c2ecf20Sopenharmony_ci goto err; 20738c2ecf20Sopenharmony_ci 20748c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 20758c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); /* stop carrier offset search */ 20768c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 20778c2ecf20Sopenharmony_ci goto err; 20788c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, RTC, 0x80) < 0) 20798c2ecf20Sopenharmony_ci goto err; 20808c2ecf20Sopenharmony_ci 20818c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, RTCS2, 0x40) < 0) 20828c2ecf20Sopenharmony_ci goto err; 20838c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x00) < 0) 20848c2ecf20Sopenharmony_ci goto err; 20858c2ecf20Sopenharmony_ci 20868c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) /* set car ofset to 0 */ 20878c2ecf20Sopenharmony_ci goto err; 20888c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) 20898c2ecf20Sopenharmony_ci goto err; 20908c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x65) < 0) 20918c2ecf20Sopenharmony_ci goto err; 20928c2ecf20Sopenharmony_ci 20938c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* trigger acquisition */ 20948c2ecf20Sopenharmony_ci goto err; 20958c2ecf20Sopenharmony_ci msleep(10); 20968c2ecf20Sopenharmony_ci 20978c2ecf20Sopenharmony_ci for (i = 0; i < 10; i++) { 20988c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DSTATUS); 20998c2ecf20Sopenharmony_ci if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2) 21008c2ecf20Sopenharmony_ci tmg_cpt++; 21018c2ecf20Sopenharmony_ci msleep(1); 21028c2ecf20Sopenharmony_ci } 21038c2ecf20Sopenharmony_ci if (tmg_cpt >= 3) 21048c2ecf20Sopenharmony_ci tmg_lock = 1; 21058c2ecf20Sopenharmony_ci 21068c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) 21078c2ecf20Sopenharmony_ci goto err; 21088c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) /* DVB-S1 timing */ 21098c2ecf20Sopenharmony_ci goto err; 21108c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) /* DVB-S2 timing */ 21118c2ecf20Sopenharmony_ci goto err; 21128c2ecf20Sopenharmony_ci 21138c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, freq) < 0) 21148c2ecf20Sopenharmony_ci goto err; 21158c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGTHRISE, tmg_thh) < 0) 21168c2ecf20Sopenharmony_ci goto err; 21178c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGTHFALL, tmg_thl) < 0) 21188c2ecf20Sopenharmony_ci goto err; 21198c2ecf20Sopenharmony_ci 21208c2ecf20Sopenharmony_ci return tmg_lock; 21218c2ecf20Sopenharmony_ci 21228c2ecf20Sopenharmony_cierr: 21238c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 21248c2ecf20Sopenharmony_ci return -1; 21258c2ecf20Sopenharmony_ci} 21268c2ecf20Sopenharmony_ci 21278c2ecf20Sopenharmony_cistatic int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) 21288c2ecf20Sopenharmony_ci{ 21298c2ecf20Sopenharmony_ci struct dvb_frontend *fe = &state->frontend; 21308c2ecf20Sopenharmony_ci 21318c2ecf20Sopenharmony_ci u32 reg; 21328c2ecf20Sopenharmony_ci s32 car_step, steps, cur_step, dir, freq, timeout_lock; 21338c2ecf20Sopenharmony_ci int lock; 21348c2ecf20Sopenharmony_ci 21358c2ecf20Sopenharmony_ci if (state->srate >= 10000000) 21368c2ecf20Sopenharmony_ci timeout_lock = timeout_dmd / 3; 21378c2ecf20Sopenharmony_ci else 21388c2ecf20Sopenharmony_ci timeout_lock = timeout_dmd / 2; 21398c2ecf20Sopenharmony_ci 21408c2ecf20Sopenharmony_ci lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */ 21418c2ecf20Sopenharmony_ci if (lock) 21428c2ecf20Sopenharmony_ci return lock; 21438c2ecf20Sopenharmony_ci 21448c2ecf20Sopenharmony_ci if (state->srate >= 10000000) { 21458c2ecf20Sopenharmony_ci if (stv090x_chk_tmg(state)) { 21468c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) 21478c2ecf20Sopenharmony_ci goto err; 21488c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) 21498c2ecf20Sopenharmony_ci goto err; 21508c2ecf20Sopenharmony_ci return stv090x_get_dmdlock(state, timeout_dmd); 21518c2ecf20Sopenharmony_ci } 21528c2ecf20Sopenharmony_ci return 0; 21538c2ecf20Sopenharmony_ci } 21548c2ecf20Sopenharmony_ci 21558c2ecf20Sopenharmony_ci if (state->srate <= 4000000) 21568c2ecf20Sopenharmony_ci car_step = 1000; 21578c2ecf20Sopenharmony_ci else if (state->srate <= 7000000) 21588c2ecf20Sopenharmony_ci car_step = 2000; 21598c2ecf20Sopenharmony_ci else if (state->srate <= 10000000) 21608c2ecf20Sopenharmony_ci car_step = 3000; 21618c2ecf20Sopenharmony_ci else 21628c2ecf20Sopenharmony_ci car_step = 5000; 21638c2ecf20Sopenharmony_ci 21648c2ecf20Sopenharmony_ci steps = (state->search_range / 1000) / car_step; 21658c2ecf20Sopenharmony_ci steps /= 2; 21668c2ecf20Sopenharmony_ci steps = 2 * (steps + 1); 21678c2ecf20Sopenharmony_ci if (steps < 0) 21688c2ecf20Sopenharmony_ci steps = 2; 21698c2ecf20Sopenharmony_ci else if (steps > 12) 21708c2ecf20Sopenharmony_ci steps = 12; 21718c2ecf20Sopenharmony_ci 21728c2ecf20Sopenharmony_ci cur_step = 1; 21738c2ecf20Sopenharmony_ci dir = 1; 21748c2ecf20Sopenharmony_ci 21758c2ecf20Sopenharmony_ci freq = state->frequency; 21768c2ecf20Sopenharmony_ci state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate; 21778c2ecf20Sopenharmony_ci while ((cur_step <= steps) && (!lock)) { 21788c2ecf20Sopenharmony_ci if (dir > 0) 21798c2ecf20Sopenharmony_ci freq += cur_step * car_step; 21808c2ecf20Sopenharmony_ci else 21818c2ecf20Sopenharmony_ci freq -= cur_step * car_step; 21828c2ecf20Sopenharmony_ci 21838c2ecf20Sopenharmony_ci /* Setup tuner */ 21848c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 21858c2ecf20Sopenharmony_ci goto err; 21868c2ecf20Sopenharmony_ci 21878c2ecf20Sopenharmony_ci if (state->config->tuner_set_frequency) { 21888c2ecf20Sopenharmony_ci if (state->config->tuner_set_frequency(fe, freq) < 0) 21898c2ecf20Sopenharmony_ci goto err_gateoff; 21908c2ecf20Sopenharmony_ci } 21918c2ecf20Sopenharmony_ci 21928c2ecf20Sopenharmony_ci if (state->config->tuner_set_bandwidth) { 21938c2ecf20Sopenharmony_ci if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) 21948c2ecf20Sopenharmony_ci goto err_gateoff; 21958c2ecf20Sopenharmony_ci } 21968c2ecf20Sopenharmony_ci 21978c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 21988c2ecf20Sopenharmony_ci goto err; 21998c2ecf20Sopenharmony_ci 22008c2ecf20Sopenharmony_ci msleep(50); 22018c2ecf20Sopenharmony_ci 22028c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 22038c2ecf20Sopenharmony_ci goto err; 22048c2ecf20Sopenharmony_ci 22058c2ecf20Sopenharmony_ci if (state->config->tuner_get_status) { 22068c2ecf20Sopenharmony_ci if (state->config->tuner_get_status(fe, ®) < 0) 22078c2ecf20Sopenharmony_ci goto err_gateoff; 22088c2ecf20Sopenharmony_ci if (reg) 22098c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Tuner phase locked"); 22108c2ecf20Sopenharmony_ci else 22118c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Tuner unlocked"); 22128c2ecf20Sopenharmony_ci } 22138c2ecf20Sopenharmony_ci 22148c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 22158c2ecf20Sopenharmony_ci goto err; 22168c2ecf20Sopenharmony_ci 22178c2ecf20Sopenharmony_ci STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); 22188c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) 22198c2ecf20Sopenharmony_ci goto err; 22208c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) 22218c2ecf20Sopenharmony_ci goto err; 22228c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) 22238c2ecf20Sopenharmony_ci goto err; 22248c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) 22258c2ecf20Sopenharmony_ci goto err; 22268c2ecf20Sopenharmony_ci lock = stv090x_get_dmdlock(state, (timeout_dmd / 3)); 22278c2ecf20Sopenharmony_ci 22288c2ecf20Sopenharmony_ci dir *= -1; 22298c2ecf20Sopenharmony_ci cur_step++; 22308c2ecf20Sopenharmony_ci } 22318c2ecf20Sopenharmony_ci 22328c2ecf20Sopenharmony_ci return lock; 22338c2ecf20Sopenharmony_ci 22348c2ecf20Sopenharmony_cierr_gateoff: 22358c2ecf20Sopenharmony_ci stv090x_i2c_gate_ctrl(state, 0); 22368c2ecf20Sopenharmony_cierr: 22378c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 22388c2ecf20Sopenharmony_ci return -1; 22398c2ecf20Sopenharmony_ci} 22408c2ecf20Sopenharmony_ci 22418c2ecf20Sopenharmony_cistatic int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s32 *timeout_sw, s32 *steps) 22428c2ecf20Sopenharmony_ci{ 22438c2ecf20Sopenharmony_ci s32 timeout, inc, steps_max, srate, car_max; 22448c2ecf20Sopenharmony_ci 22458c2ecf20Sopenharmony_ci srate = state->srate; 22468c2ecf20Sopenharmony_ci car_max = state->search_range / 1000; 22478c2ecf20Sopenharmony_ci car_max += car_max / 10; 22488c2ecf20Sopenharmony_ci car_max = 65536 * (car_max / 2); 22498c2ecf20Sopenharmony_ci car_max /= (state->internal->mclk / 1000); 22508c2ecf20Sopenharmony_ci 22518c2ecf20Sopenharmony_ci if (car_max > 0x4000) 22528c2ecf20Sopenharmony_ci car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */ 22538c2ecf20Sopenharmony_ci 22548c2ecf20Sopenharmony_ci inc = srate; 22558c2ecf20Sopenharmony_ci inc /= state->internal->mclk / 1000; 22568c2ecf20Sopenharmony_ci inc *= 256; 22578c2ecf20Sopenharmony_ci inc *= 256; 22588c2ecf20Sopenharmony_ci inc /= 1000; 22598c2ecf20Sopenharmony_ci 22608c2ecf20Sopenharmony_ci switch (state->search_mode) { 22618c2ecf20Sopenharmony_ci case STV090x_SEARCH_DVBS1: 22628c2ecf20Sopenharmony_ci case STV090x_SEARCH_DSS: 22638c2ecf20Sopenharmony_ci inc *= 3; /* freq step = 3% of srate */ 22648c2ecf20Sopenharmony_ci timeout = 20; 22658c2ecf20Sopenharmony_ci break; 22668c2ecf20Sopenharmony_ci 22678c2ecf20Sopenharmony_ci case STV090x_SEARCH_DVBS2: 22688c2ecf20Sopenharmony_ci inc *= 4; 22698c2ecf20Sopenharmony_ci timeout = 25; 22708c2ecf20Sopenharmony_ci break; 22718c2ecf20Sopenharmony_ci 22728c2ecf20Sopenharmony_ci case STV090x_SEARCH_AUTO: 22738c2ecf20Sopenharmony_ci default: 22748c2ecf20Sopenharmony_ci inc *= 3; 22758c2ecf20Sopenharmony_ci timeout = 25; 22768c2ecf20Sopenharmony_ci break; 22778c2ecf20Sopenharmony_ci } 22788c2ecf20Sopenharmony_ci inc /= 100; 22798c2ecf20Sopenharmony_ci if ((inc > car_max) || (inc < 0)) 22808c2ecf20Sopenharmony_ci inc = car_max / 2; /* increment <= 1/8 Mclk */ 22818c2ecf20Sopenharmony_ci 22828c2ecf20Sopenharmony_ci timeout *= 27500; /* 27.5 Msps reference */ 22838c2ecf20Sopenharmony_ci if (srate > 0) 22848c2ecf20Sopenharmony_ci timeout /= (srate / 1000); 22858c2ecf20Sopenharmony_ci 22868c2ecf20Sopenharmony_ci if ((timeout > 100) || (timeout < 0)) 22878c2ecf20Sopenharmony_ci timeout = 100; 22888c2ecf20Sopenharmony_ci 22898c2ecf20Sopenharmony_ci steps_max = (car_max / inc) + 1; /* min steps = 3 */ 22908c2ecf20Sopenharmony_ci if ((steps_max > 100) || (steps_max < 0)) { 22918c2ecf20Sopenharmony_ci steps_max = 100; /* max steps <= 100 */ 22928c2ecf20Sopenharmony_ci inc = car_max / steps_max; 22938c2ecf20Sopenharmony_ci } 22948c2ecf20Sopenharmony_ci *freq_inc = inc; 22958c2ecf20Sopenharmony_ci *timeout_sw = timeout; 22968c2ecf20Sopenharmony_ci *steps = steps_max; 22978c2ecf20Sopenharmony_ci 22988c2ecf20Sopenharmony_ci return 0; 22998c2ecf20Sopenharmony_ci} 23008c2ecf20Sopenharmony_ci 23018c2ecf20Sopenharmony_cistatic int stv090x_chk_signal(struct stv090x_state *state) 23028c2ecf20Sopenharmony_ci{ 23038c2ecf20Sopenharmony_ci s32 offst_car, agc2, car_max; 23048c2ecf20Sopenharmony_ci int no_signal; 23058c2ecf20Sopenharmony_ci 23068c2ecf20Sopenharmony_ci offst_car = STV090x_READ_DEMOD(state, CFR2) << 8; 23078c2ecf20Sopenharmony_ci offst_car |= STV090x_READ_DEMOD(state, CFR1); 23088c2ecf20Sopenharmony_ci offst_car = comp2(offst_car, 16); 23098c2ecf20Sopenharmony_ci 23108c2ecf20Sopenharmony_ci agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8; 23118c2ecf20Sopenharmony_ci agc2 |= STV090x_READ_DEMOD(state, AGC2I0); 23128c2ecf20Sopenharmony_ci car_max = state->search_range / 1000; 23138c2ecf20Sopenharmony_ci 23148c2ecf20Sopenharmony_ci car_max += (car_max / 10); /* 10% margin */ 23158c2ecf20Sopenharmony_ci car_max = (65536 * car_max / 2); 23168c2ecf20Sopenharmony_ci car_max /= state->internal->mclk / 1000; 23178c2ecf20Sopenharmony_ci 23188c2ecf20Sopenharmony_ci if (car_max > 0x4000) 23198c2ecf20Sopenharmony_ci car_max = 0x4000; 23208c2ecf20Sopenharmony_ci 23218c2ecf20Sopenharmony_ci if ((agc2 > 0x2000) || (offst_car > 2 * car_max) || (offst_car < -2 * car_max)) { 23228c2ecf20Sopenharmony_ci no_signal = 1; 23238c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "No Signal"); 23248c2ecf20Sopenharmony_ci } else { 23258c2ecf20Sopenharmony_ci no_signal = 0; 23268c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Found Signal"); 23278c2ecf20Sopenharmony_ci } 23288c2ecf20Sopenharmony_ci 23298c2ecf20Sopenharmony_ci return no_signal; 23308c2ecf20Sopenharmony_ci} 23318c2ecf20Sopenharmony_ci 23328c2ecf20Sopenharmony_cistatic int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 timeout, int zigzag, s32 steps_max) 23338c2ecf20Sopenharmony_ci{ 23348c2ecf20Sopenharmony_ci int no_signal, lock = 0; 23358c2ecf20Sopenharmony_ci s32 cpt_step = 0, offst_freq, car_max; 23368c2ecf20Sopenharmony_ci u32 reg; 23378c2ecf20Sopenharmony_ci 23388c2ecf20Sopenharmony_ci car_max = state->search_range / 1000; 23398c2ecf20Sopenharmony_ci car_max += (car_max / 10); 23408c2ecf20Sopenharmony_ci car_max = (65536 * car_max / 2); 23418c2ecf20Sopenharmony_ci car_max /= (state->internal->mclk / 1000); 23428c2ecf20Sopenharmony_ci if (car_max > 0x4000) 23438c2ecf20Sopenharmony_ci car_max = 0x4000; 23448c2ecf20Sopenharmony_ci 23458c2ecf20Sopenharmony_ci if (zigzag) 23468c2ecf20Sopenharmony_ci offst_freq = 0; 23478c2ecf20Sopenharmony_ci else 23488c2ecf20Sopenharmony_ci offst_freq = -car_max + inc; 23498c2ecf20Sopenharmony_ci 23508c2ecf20Sopenharmony_ci do { 23518c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0) 23528c2ecf20Sopenharmony_ci goto err; 23538c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT1, ((offst_freq / 256) & 0xff)) < 0) 23548c2ecf20Sopenharmony_ci goto err; 23558c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT0, offst_freq & 0xff) < 0) 23568c2ecf20Sopenharmony_ci goto err; 23578c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) 23588c2ecf20Sopenharmony_ci goto err; 23598c2ecf20Sopenharmony_ci 23608c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, PDELCTRL1); 23618c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x1); /* stop DVB-S2 packet delin */ 23628c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) 23638c2ecf20Sopenharmony_ci goto err; 23648c2ecf20Sopenharmony_ci 23658c2ecf20Sopenharmony_ci if (zigzag) { 23668c2ecf20Sopenharmony_ci if (offst_freq >= 0) 23678c2ecf20Sopenharmony_ci offst_freq = -offst_freq - 2 * inc; 23688c2ecf20Sopenharmony_ci else 23698c2ecf20Sopenharmony_ci offst_freq = -offst_freq; 23708c2ecf20Sopenharmony_ci } else { 23718c2ecf20Sopenharmony_ci offst_freq += 2 * inc; 23728c2ecf20Sopenharmony_ci } 23738c2ecf20Sopenharmony_ci 23748c2ecf20Sopenharmony_ci cpt_step++; 23758c2ecf20Sopenharmony_ci 23768c2ecf20Sopenharmony_ci lock = stv090x_get_dmdlock(state, timeout); 23778c2ecf20Sopenharmony_ci no_signal = stv090x_chk_signal(state); 23788c2ecf20Sopenharmony_ci 23798c2ecf20Sopenharmony_ci } while ((!lock) && 23808c2ecf20Sopenharmony_ci (!no_signal) && 23818c2ecf20Sopenharmony_ci ((offst_freq - inc) < car_max) && 23828c2ecf20Sopenharmony_ci ((offst_freq + inc) > -car_max) && 23838c2ecf20Sopenharmony_ci (cpt_step < steps_max)); 23848c2ecf20Sopenharmony_ci 23858c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, PDELCTRL1); 23868c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0); 23878c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) 23888c2ecf20Sopenharmony_ci goto err; 23898c2ecf20Sopenharmony_ci 23908c2ecf20Sopenharmony_ci return lock; 23918c2ecf20Sopenharmony_cierr: 23928c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 23938c2ecf20Sopenharmony_ci return -1; 23948c2ecf20Sopenharmony_ci} 23958c2ecf20Sopenharmony_ci 23968c2ecf20Sopenharmony_cistatic int stv090x_sw_algo(struct stv090x_state *state) 23978c2ecf20Sopenharmony_ci{ 23988c2ecf20Sopenharmony_ci int no_signal, zigzag, lock = 0; 23998c2ecf20Sopenharmony_ci u32 reg; 24008c2ecf20Sopenharmony_ci 24018c2ecf20Sopenharmony_ci s32 dvbs2_fly_wheel; 24028c2ecf20Sopenharmony_ci s32 inc, timeout_step, trials, steps_max; 24038c2ecf20Sopenharmony_ci 24048c2ecf20Sopenharmony_ci /* get params */ 24058c2ecf20Sopenharmony_ci stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max); 24068c2ecf20Sopenharmony_ci 24078c2ecf20Sopenharmony_ci switch (state->search_mode) { 24088c2ecf20Sopenharmony_ci case STV090x_SEARCH_DVBS1: 24098c2ecf20Sopenharmony_ci case STV090x_SEARCH_DSS: 24108c2ecf20Sopenharmony_ci /* accelerate the frequency detector */ 24118c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 24128c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0) 24138c2ecf20Sopenharmony_ci goto err; 24148c2ecf20Sopenharmony_ci } 24158c2ecf20Sopenharmony_ci 24168c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x49) < 0) 24178c2ecf20Sopenharmony_ci goto err; 24188c2ecf20Sopenharmony_ci zigzag = 0; 24198c2ecf20Sopenharmony_ci break; 24208c2ecf20Sopenharmony_ci 24218c2ecf20Sopenharmony_ci case STV090x_SEARCH_DVBS2: 24228c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 24238c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) 24248c2ecf20Sopenharmony_ci goto err; 24258c2ecf20Sopenharmony_ci } 24268c2ecf20Sopenharmony_ci 24278c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0) 24288c2ecf20Sopenharmony_ci goto err; 24298c2ecf20Sopenharmony_ci zigzag = 1; 24308c2ecf20Sopenharmony_ci break; 24318c2ecf20Sopenharmony_ci 24328c2ecf20Sopenharmony_ci case STV090x_SEARCH_AUTO: 24338c2ecf20Sopenharmony_ci default: 24348c2ecf20Sopenharmony_ci /* accelerate the frequency detector */ 24358c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 24368c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0) 24378c2ecf20Sopenharmony_ci goto err; 24388c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) 24398c2ecf20Sopenharmony_ci goto err; 24408c2ecf20Sopenharmony_ci } 24418c2ecf20Sopenharmony_ci 24428c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0xc9) < 0) 24438c2ecf20Sopenharmony_ci goto err; 24448c2ecf20Sopenharmony_ci zigzag = 0; 24458c2ecf20Sopenharmony_ci break; 24468c2ecf20Sopenharmony_ci } 24478c2ecf20Sopenharmony_ci 24488c2ecf20Sopenharmony_ci trials = 0; 24498c2ecf20Sopenharmony_ci do { 24508c2ecf20Sopenharmony_ci lock = stv090x_search_car_loop(state, inc, timeout_step, zigzag, steps_max); 24518c2ecf20Sopenharmony_ci no_signal = stv090x_chk_signal(state); 24528c2ecf20Sopenharmony_ci trials++; 24538c2ecf20Sopenharmony_ci 24548c2ecf20Sopenharmony_ci /*run the SW search 2 times maximum*/ 24558c2ecf20Sopenharmony_ci if (lock || no_signal || (trials == 2)) { 24568c2ecf20Sopenharmony_ci /*Check if the demod is not losing lock in DVBS2*/ 24578c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 24588c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) 24598c2ecf20Sopenharmony_ci goto err; 24608c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) 24618c2ecf20Sopenharmony_ci goto err; 24628c2ecf20Sopenharmony_ci } 24638c2ecf20Sopenharmony_ci 24648c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDSTATE); 24658c2ecf20Sopenharmony_ci if ((lock) && (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == STV090x_DVBS2)) { 24668c2ecf20Sopenharmony_ci /*Check if the demod is not losing lock in DVBS2*/ 24678c2ecf20Sopenharmony_ci msleep(timeout_step); 24688c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDFLYW); 24698c2ecf20Sopenharmony_ci dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD); 24708c2ecf20Sopenharmony_ci if (dvbs2_fly_wheel < 0xd) { /*if correct frames is decrementing */ 24718c2ecf20Sopenharmony_ci msleep(timeout_step); 24728c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDFLYW); 24738c2ecf20Sopenharmony_ci dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD); 24748c2ecf20Sopenharmony_ci } 24758c2ecf20Sopenharmony_ci if (dvbs2_fly_wheel < 0xd) { 24768c2ecf20Sopenharmony_ci /*FALSE lock, The demod is losing lock */ 24778c2ecf20Sopenharmony_ci lock = 0; 24788c2ecf20Sopenharmony_ci if (trials < 2) { 24798c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 24808c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) 24818c2ecf20Sopenharmony_ci goto err; 24828c2ecf20Sopenharmony_ci } 24838c2ecf20Sopenharmony_ci 24848c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0) 24858c2ecf20Sopenharmony_ci goto err; 24868c2ecf20Sopenharmony_ci } 24878c2ecf20Sopenharmony_ci } 24888c2ecf20Sopenharmony_ci } 24898c2ecf20Sopenharmony_ci } 24908c2ecf20Sopenharmony_ci } while ((!lock) && (trials < 2) && (!no_signal)); 24918c2ecf20Sopenharmony_ci 24928c2ecf20Sopenharmony_ci return lock; 24938c2ecf20Sopenharmony_cierr: 24948c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 24958c2ecf20Sopenharmony_ci return -1; 24968c2ecf20Sopenharmony_ci} 24978c2ecf20Sopenharmony_ci 24988c2ecf20Sopenharmony_cistatic enum stv090x_delsys stv090x_get_std(struct stv090x_state *state) 24998c2ecf20Sopenharmony_ci{ 25008c2ecf20Sopenharmony_ci u32 reg; 25018c2ecf20Sopenharmony_ci enum stv090x_delsys delsys; 25028c2ecf20Sopenharmony_ci 25038c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDSTATE); 25048c2ecf20Sopenharmony_ci if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 2) 25058c2ecf20Sopenharmony_ci delsys = STV090x_DVBS2; 25068c2ecf20Sopenharmony_ci else if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 3) { 25078c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, FECM); 25088c2ecf20Sopenharmony_ci if (STV090x_GETFIELD_Px(reg, DSS_DVB_FIELD) == 1) 25098c2ecf20Sopenharmony_ci delsys = STV090x_DSS; 25108c2ecf20Sopenharmony_ci else 25118c2ecf20Sopenharmony_ci delsys = STV090x_DVBS1; 25128c2ecf20Sopenharmony_ci } else { 25138c2ecf20Sopenharmony_ci delsys = STV090x_ERROR; 25148c2ecf20Sopenharmony_ci } 25158c2ecf20Sopenharmony_ci 25168c2ecf20Sopenharmony_ci return delsys; 25178c2ecf20Sopenharmony_ci} 25188c2ecf20Sopenharmony_ci 25198c2ecf20Sopenharmony_ci/* in Hz */ 25208c2ecf20Sopenharmony_cistatic s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk) 25218c2ecf20Sopenharmony_ci{ 25228c2ecf20Sopenharmony_ci s32 derot, int_1, int_2, tmp_1, tmp_2; 25238c2ecf20Sopenharmony_ci 25248c2ecf20Sopenharmony_ci derot = STV090x_READ_DEMOD(state, CFR2) << 16; 25258c2ecf20Sopenharmony_ci derot |= STV090x_READ_DEMOD(state, CFR1) << 8; 25268c2ecf20Sopenharmony_ci derot |= STV090x_READ_DEMOD(state, CFR0); 25278c2ecf20Sopenharmony_ci 25288c2ecf20Sopenharmony_ci derot = comp2(derot, 24); 25298c2ecf20Sopenharmony_ci int_1 = mclk >> 12; 25308c2ecf20Sopenharmony_ci int_2 = derot >> 12; 25318c2ecf20Sopenharmony_ci 25328c2ecf20Sopenharmony_ci /* carrier_frequency = MasterClock * Reg / 2^24 */ 25338c2ecf20Sopenharmony_ci tmp_1 = mclk % 0x1000; 25348c2ecf20Sopenharmony_ci tmp_2 = derot % 0x1000; 25358c2ecf20Sopenharmony_ci 25368c2ecf20Sopenharmony_ci derot = (int_1 * int_2) + 25378c2ecf20Sopenharmony_ci ((int_1 * tmp_2) >> 12) + 25388c2ecf20Sopenharmony_ci ((int_2 * tmp_1) >> 12); 25398c2ecf20Sopenharmony_ci 25408c2ecf20Sopenharmony_ci return derot; 25418c2ecf20Sopenharmony_ci} 25428c2ecf20Sopenharmony_ci 25438c2ecf20Sopenharmony_cistatic int stv090x_get_viterbi(struct stv090x_state *state) 25448c2ecf20Sopenharmony_ci{ 25458c2ecf20Sopenharmony_ci u32 reg, rate; 25468c2ecf20Sopenharmony_ci 25478c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, VITCURPUN); 25488c2ecf20Sopenharmony_ci rate = STV090x_GETFIELD_Px(reg, VIT_CURPUN_FIELD); 25498c2ecf20Sopenharmony_ci 25508c2ecf20Sopenharmony_ci switch (rate) { 25518c2ecf20Sopenharmony_ci case 13: 25528c2ecf20Sopenharmony_ci state->fec = STV090x_PR12; 25538c2ecf20Sopenharmony_ci break; 25548c2ecf20Sopenharmony_ci 25558c2ecf20Sopenharmony_ci case 18: 25568c2ecf20Sopenharmony_ci state->fec = STV090x_PR23; 25578c2ecf20Sopenharmony_ci break; 25588c2ecf20Sopenharmony_ci 25598c2ecf20Sopenharmony_ci case 21: 25608c2ecf20Sopenharmony_ci state->fec = STV090x_PR34; 25618c2ecf20Sopenharmony_ci break; 25628c2ecf20Sopenharmony_ci 25638c2ecf20Sopenharmony_ci case 24: 25648c2ecf20Sopenharmony_ci state->fec = STV090x_PR56; 25658c2ecf20Sopenharmony_ci break; 25668c2ecf20Sopenharmony_ci 25678c2ecf20Sopenharmony_ci case 25: 25688c2ecf20Sopenharmony_ci state->fec = STV090x_PR67; 25698c2ecf20Sopenharmony_ci break; 25708c2ecf20Sopenharmony_ci 25718c2ecf20Sopenharmony_ci case 26: 25728c2ecf20Sopenharmony_ci state->fec = STV090x_PR78; 25738c2ecf20Sopenharmony_ci break; 25748c2ecf20Sopenharmony_ci 25758c2ecf20Sopenharmony_ci default: 25768c2ecf20Sopenharmony_ci state->fec = STV090x_PRERR; 25778c2ecf20Sopenharmony_ci break; 25788c2ecf20Sopenharmony_ci } 25798c2ecf20Sopenharmony_ci 25808c2ecf20Sopenharmony_ci return 0; 25818c2ecf20Sopenharmony_ci} 25828c2ecf20Sopenharmony_ci 25838c2ecf20Sopenharmony_cistatic enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *state) 25848c2ecf20Sopenharmony_ci{ 25858c2ecf20Sopenharmony_ci struct dvb_frontend *fe = &state->frontend; 25868c2ecf20Sopenharmony_ci 25878c2ecf20Sopenharmony_ci u8 tmg; 25888c2ecf20Sopenharmony_ci u32 reg; 25898c2ecf20Sopenharmony_ci s32 i = 0, offst_freq; 25908c2ecf20Sopenharmony_ci 25918c2ecf20Sopenharmony_ci msleep(5); 25928c2ecf20Sopenharmony_ci 25938c2ecf20Sopenharmony_ci if (state->algo == STV090x_BLIND_SEARCH) { 25948c2ecf20Sopenharmony_ci tmg = STV090x_READ_DEMOD(state, TMGREG2); 25958c2ecf20Sopenharmony_ci STV090x_WRITE_DEMOD(state, SFRSTEP, 0x5c); 25968c2ecf20Sopenharmony_ci while ((i <= 50) && (tmg != 0) && (tmg != 0xff)) { 25978c2ecf20Sopenharmony_ci tmg = STV090x_READ_DEMOD(state, TMGREG2); 25988c2ecf20Sopenharmony_ci msleep(5); 25998c2ecf20Sopenharmony_ci i += 5; 26008c2ecf20Sopenharmony_ci } 26018c2ecf20Sopenharmony_ci } 26028c2ecf20Sopenharmony_ci state->delsys = stv090x_get_std(state); 26038c2ecf20Sopenharmony_ci 26048c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 26058c2ecf20Sopenharmony_ci goto err; 26068c2ecf20Sopenharmony_ci 26078c2ecf20Sopenharmony_ci if (state->config->tuner_get_frequency) { 26088c2ecf20Sopenharmony_ci if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) 26098c2ecf20Sopenharmony_ci goto err_gateoff; 26108c2ecf20Sopenharmony_ci } 26118c2ecf20Sopenharmony_ci 26128c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 26138c2ecf20Sopenharmony_ci goto err; 26148c2ecf20Sopenharmony_ci 26158c2ecf20Sopenharmony_ci offst_freq = stv090x_get_car_freq(state, state->internal->mclk) / 1000; 26168c2ecf20Sopenharmony_ci state->frequency += offst_freq; 26178c2ecf20Sopenharmony_ci 26188c2ecf20Sopenharmony_ci if (stv090x_get_viterbi(state) < 0) 26198c2ecf20Sopenharmony_ci goto err; 26208c2ecf20Sopenharmony_ci 26218c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDMODCOD); 26228c2ecf20Sopenharmony_ci state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD); 26238c2ecf20Sopenharmony_ci state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01; 26248c2ecf20Sopenharmony_ci state->frame_len = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) >> 1; 26258c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, TMGOBS); 26268c2ecf20Sopenharmony_ci state->rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD); 26278c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, FECM); 26288c2ecf20Sopenharmony_ci state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD); 26298c2ecf20Sopenharmony_ci 26308c2ecf20Sopenharmony_ci if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) { 26318c2ecf20Sopenharmony_ci 26328c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 26338c2ecf20Sopenharmony_ci goto err; 26348c2ecf20Sopenharmony_ci 26358c2ecf20Sopenharmony_ci if (state->config->tuner_get_frequency) { 26368c2ecf20Sopenharmony_ci if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) 26378c2ecf20Sopenharmony_ci goto err_gateoff; 26388c2ecf20Sopenharmony_ci } 26398c2ecf20Sopenharmony_ci 26408c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 26418c2ecf20Sopenharmony_ci goto err; 26428c2ecf20Sopenharmony_ci 26438c2ecf20Sopenharmony_ci if (abs(offst_freq) <= ((state->search_range / 2000) + 500)) 26448c2ecf20Sopenharmony_ci return STV090x_RANGEOK; 26458c2ecf20Sopenharmony_ci else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000)) 26468c2ecf20Sopenharmony_ci return STV090x_RANGEOK; 26478c2ecf20Sopenharmony_ci } else { 26488c2ecf20Sopenharmony_ci if (abs(offst_freq) <= ((state->search_range / 2000) + 500)) 26498c2ecf20Sopenharmony_ci return STV090x_RANGEOK; 26508c2ecf20Sopenharmony_ci } 26518c2ecf20Sopenharmony_ci 26528c2ecf20Sopenharmony_ci return STV090x_OUTOFRANGE; 26538c2ecf20Sopenharmony_ci 26548c2ecf20Sopenharmony_cierr_gateoff: 26558c2ecf20Sopenharmony_ci stv090x_i2c_gate_ctrl(state, 0); 26568c2ecf20Sopenharmony_cierr: 26578c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 26588c2ecf20Sopenharmony_ci return -1; 26598c2ecf20Sopenharmony_ci} 26608c2ecf20Sopenharmony_ci 26618c2ecf20Sopenharmony_cistatic u32 stv090x_get_tmgoffst(struct stv090x_state *state, u32 srate) 26628c2ecf20Sopenharmony_ci{ 26638c2ecf20Sopenharmony_ci s32 offst_tmg; 26648c2ecf20Sopenharmony_ci 26658c2ecf20Sopenharmony_ci offst_tmg = STV090x_READ_DEMOD(state, TMGREG2) << 16; 26668c2ecf20Sopenharmony_ci offst_tmg |= STV090x_READ_DEMOD(state, TMGREG1) << 8; 26678c2ecf20Sopenharmony_ci offst_tmg |= STV090x_READ_DEMOD(state, TMGREG0); 26688c2ecf20Sopenharmony_ci 26698c2ecf20Sopenharmony_ci offst_tmg = comp2(offst_tmg, 24); /* 2's complement */ 26708c2ecf20Sopenharmony_ci if (!offst_tmg) 26718c2ecf20Sopenharmony_ci offst_tmg = 1; 26728c2ecf20Sopenharmony_ci 26738c2ecf20Sopenharmony_ci offst_tmg = ((s32) srate * 10) / ((s32) 0x1000000 / offst_tmg); 26748c2ecf20Sopenharmony_ci offst_tmg /= 320; 26758c2ecf20Sopenharmony_ci 26768c2ecf20Sopenharmony_ci return offst_tmg; 26778c2ecf20Sopenharmony_ci} 26788c2ecf20Sopenharmony_ci 26798c2ecf20Sopenharmony_cistatic u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_modcod modcod, s32 pilots) 26808c2ecf20Sopenharmony_ci{ 26818c2ecf20Sopenharmony_ci u8 aclc = 0x29; 26828c2ecf20Sopenharmony_ci s32 i; 26838c2ecf20Sopenharmony_ci struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low; 26848c2ecf20Sopenharmony_ci 26858c2ecf20Sopenharmony_ci if (state->internal->dev_ver == 0x20) { 26868c2ecf20Sopenharmony_ci car_loop = stv090x_s2_crl_cut20; 26878c2ecf20Sopenharmony_ci car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20; 26888c2ecf20Sopenharmony_ci car_loop_apsk_low = stv090x_s2_apsk_crl_cut20; 26898c2ecf20Sopenharmony_ci } else { 26908c2ecf20Sopenharmony_ci /* >= Cut 3 */ 26918c2ecf20Sopenharmony_ci car_loop = stv090x_s2_crl_cut30; 26928c2ecf20Sopenharmony_ci car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut30; 26938c2ecf20Sopenharmony_ci car_loop_apsk_low = stv090x_s2_apsk_crl_cut30; 26948c2ecf20Sopenharmony_ci } 26958c2ecf20Sopenharmony_ci 26968c2ecf20Sopenharmony_ci if (modcod < STV090x_QPSK_12) { 26978c2ecf20Sopenharmony_ci i = 0; 26988c2ecf20Sopenharmony_ci while ((i < 3) && (modcod != car_loop_qpsk_low[i].modcod)) 26998c2ecf20Sopenharmony_ci i++; 27008c2ecf20Sopenharmony_ci 27018c2ecf20Sopenharmony_ci if (i >= 3) 27028c2ecf20Sopenharmony_ci i = 2; 27038c2ecf20Sopenharmony_ci 27048c2ecf20Sopenharmony_ci } else { 27058c2ecf20Sopenharmony_ci i = 0; 27068c2ecf20Sopenharmony_ci while ((i < 14) && (modcod != car_loop[i].modcod)) 27078c2ecf20Sopenharmony_ci i++; 27088c2ecf20Sopenharmony_ci 27098c2ecf20Sopenharmony_ci if (i >= 14) { 27108c2ecf20Sopenharmony_ci i = 0; 27118c2ecf20Sopenharmony_ci while ((i < 11) && (modcod != car_loop_apsk_low[i].modcod)) 27128c2ecf20Sopenharmony_ci i++; 27138c2ecf20Sopenharmony_ci 27148c2ecf20Sopenharmony_ci if (i >= 11) 27158c2ecf20Sopenharmony_ci i = 10; 27168c2ecf20Sopenharmony_ci } 27178c2ecf20Sopenharmony_ci } 27188c2ecf20Sopenharmony_ci 27198c2ecf20Sopenharmony_ci if (modcod <= STV090x_QPSK_25) { 27208c2ecf20Sopenharmony_ci if (pilots) { 27218c2ecf20Sopenharmony_ci if (state->srate <= 3000000) 27228c2ecf20Sopenharmony_ci aclc = car_loop_qpsk_low[i].crl_pilots_on_2; 27238c2ecf20Sopenharmony_ci else if (state->srate <= 7000000) 27248c2ecf20Sopenharmony_ci aclc = car_loop_qpsk_low[i].crl_pilots_on_5; 27258c2ecf20Sopenharmony_ci else if (state->srate <= 15000000) 27268c2ecf20Sopenharmony_ci aclc = car_loop_qpsk_low[i].crl_pilots_on_10; 27278c2ecf20Sopenharmony_ci else if (state->srate <= 25000000) 27288c2ecf20Sopenharmony_ci aclc = car_loop_qpsk_low[i].crl_pilots_on_20; 27298c2ecf20Sopenharmony_ci else 27308c2ecf20Sopenharmony_ci aclc = car_loop_qpsk_low[i].crl_pilots_on_30; 27318c2ecf20Sopenharmony_ci } else { 27328c2ecf20Sopenharmony_ci if (state->srate <= 3000000) 27338c2ecf20Sopenharmony_ci aclc = car_loop_qpsk_low[i].crl_pilots_off_2; 27348c2ecf20Sopenharmony_ci else if (state->srate <= 7000000) 27358c2ecf20Sopenharmony_ci aclc = car_loop_qpsk_low[i].crl_pilots_off_5; 27368c2ecf20Sopenharmony_ci else if (state->srate <= 15000000) 27378c2ecf20Sopenharmony_ci aclc = car_loop_qpsk_low[i].crl_pilots_off_10; 27388c2ecf20Sopenharmony_ci else if (state->srate <= 25000000) 27398c2ecf20Sopenharmony_ci aclc = car_loop_qpsk_low[i].crl_pilots_off_20; 27408c2ecf20Sopenharmony_ci else 27418c2ecf20Sopenharmony_ci aclc = car_loop_qpsk_low[i].crl_pilots_off_30; 27428c2ecf20Sopenharmony_ci } 27438c2ecf20Sopenharmony_ci 27448c2ecf20Sopenharmony_ci } else if (modcod <= STV090x_8PSK_910) { 27458c2ecf20Sopenharmony_ci if (pilots) { 27468c2ecf20Sopenharmony_ci if (state->srate <= 3000000) 27478c2ecf20Sopenharmony_ci aclc = car_loop[i].crl_pilots_on_2; 27488c2ecf20Sopenharmony_ci else if (state->srate <= 7000000) 27498c2ecf20Sopenharmony_ci aclc = car_loop[i].crl_pilots_on_5; 27508c2ecf20Sopenharmony_ci else if (state->srate <= 15000000) 27518c2ecf20Sopenharmony_ci aclc = car_loop[i].crl_pilots_on_10; 27528c2ecf20Sopenharmony_ci else if (state->srate <= 25000000) 27538c2ecf20Sopenharmony_ci aclc = car_loop[i].crl_pilots_on_20; 27548c2ecf20Sopenharmony_ci else 27558c2ecf20Sopenharmony_ci aclc = car_loop[i].crl_pilots_on_30; 27568c2ecf20Sopenharmony_ci } else { 27578c2ecf20Sopenharmony_ci if (state->srate <= 3000000) 27588c2ecf20Sopenharmony_ci aclc = car_loop[i].crl_pilots_off_2; 27598c2ecf20Sopenharmony_ci else if (state->srate <= 7000000) 27608c2ecf20Sopenharmony_ci aclc = car_loop[i].crl_pilots_off_5; 27618c2ecf20Sopenharmony_ci else if (state->srate <= 15000000) 27628c2ecf20Sopenharmony_ci aclc = car_loop[i].crl_pilots_off_10; 27638c2ecf20Sopenharmony_ci else if (state->srate <= 25000000) 27648c2ecf20Sopenharmony_ci aclc = car_loop[i].crl_pilots_off_20; 27658c2ecf20Sopenharmony_ci else 27668c2ecf20Sopenharmony_ci aclc = car_loop[i].crl_pilots_off_30; 27678c2ecf20Sopenharmony_ci } 27688c2ecf20Sopenharmony_ci } else { /* 16APSK and 32APSK */ 27698c2ecf20Sopenharmony_ci /* 27708c2ecf20Sopenharmony_ci * This should never happen in practice, except if 27718c2ecf20Sopenharmony_ci * something is really wrong at the car_loop table. 27728c2ecf20Sopenharmony_ci */ 27738c2ecf20Sopenharmony_ci if (i >= 11) 27748c2ecf20Sopenharmony_ci i = 10; 27758c2ecf20Sopenharmony_ci if (state->srate <= 3000000) 27768c2ecf20Sopenharmony_ci aclc = car_loop_apsk_low[i].crl_pilots_on_2; 27778c2ecf20Sopenharmony_ci else if (state->srate <= 7000000) 27788c2ecf20Sopenharmony_ci aclc = car_loop_apsk_low[i].crl_pilots_on_5; 27798c2ecf20Sopenharmony_ci else if (state->srate <= 15000000) 27808c2ecf20Sopenharmony_ci aclc = car_loop_apsk_low[i].crl_pilots_on_10; 27818c2ecf20Sopenharmony_ci else if (state->srate <= 25000000) 27828c2ecf20Sopenharmony_ci aclc = car_loop_apsk_low[i].crl_pilots_on_20; 27838c2ecf20Sopenharmony_ci else 27848c2ecf20Sopenharmony_ci aclc = car_loop_apsk_low[i].crl_pilots_on_30; 27858c2ecf20Sopenharmony_ci } 27868c2ecf20Sopenharmony_ci 27878c2ecf20Sopenharmony_ci return aclc; 27888c2ecf20Sopenharmony_ci} 27898c2ecf20Sopenharmony_ci 27908c2ecf20Sopenharmony_cistatic u8 stv090x_optimize_carloop_short(struct stv090x_state *state) 27918c2ecf20Sopenharmony_ci{ 27928c2ecf20Sopenharmony_ci struct stv090x_short_frame_crloop *short_crl = NULL; 27938c2ecf20Sopenharmony_ci s32 index = 0; 27948c2ecf20Sopenharmony_ci u8 aclc = 0x0b; 27958c2ecf20Sopenharmony_ci 27968c2ecf20Sopenharmony_ci switch (state->modulation) { 27978c2ecf20Sopenharmony_ci case STV090x_QPSK: 27988c2ecf20Sopenharmony_ci default: 27998c2ecf20Sopenharmony_ci index = 0; 28008c2ecf20Sopenharmony_ci break; 28018c2ecf20Sopenharmony_ci case STV090x_8PSK: 28028c2ecf20Sopenharmony_ci index = 1; 28038c2ecf20Sopenharmony_ci break; 28048c2ecf20Sopenharmony_ci case STV090x_16APSK: 28058c2ecf20Sopenharmony_ci index = 2; 28068c2ecf20Sopenharmony_ci break; 28078c2ecf20Sopenharmony_ci case STV090x_32APSK: 28088c2ecf20Sopenharmony_ci index = 3; 28098c2ecf20Sopenharmony_ci break; 28108c2ecf20Sopenharmony_ci } 28118c2ecf20Sopenharmony_ci 28128c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x30) { 28138c2ecf20Sopenharmony_ci /* Cut 3.0 and up */ 28148c2ecf20Sopenharmony_ci short_crl = stv090x_s2_short_crl_cut30; 28158c2ecf20Sopenharmony_ci } else { 28168c2ecf20Sopenharmony_ci /* Cut 2.0 and up: we don't support cuts older than 2.0 */ 28178c2ecf20Sopenharmony_ci short_crl = stv090x_s2_short_crl_cut20; 28188c2ecf20Sopenharmony_ci } 28198c2ecf20Sopenharmony_ci 28208c2ecf20Sopenharmony_ci if (state->srate <= 3000000) 28218c2ecf20Sopenharmony_ci aclc = short_crl[index].crl_2; 28228c2ecf20Sopenharmony_ci else if (state->srate <= 7000000) 28238c2ecf20Sopenharmony_ci aclc = short_crl[index].crl_5; 28248c2ecf20Sopenharmony_ci else if (state->srate <= 15000000) 28258c2ecf20Sopenharmony_ci aclc = short_crl[index].crl_10; 28268c2ecf20Sopenharmony_ci else if (state->srate <= 25000000) 28278c2ecf20Sopenharmony_ci aclc = short_crl[index].crl_20; 28288c2ecf20Sopenharmony_ci else 28298c2ecf20Sopenharmony_ci aclc = short_crl[index].crl_30; 28308c2ecf20Sopenharmony_ci 28318c2ecf20Sopenharmony_ci return aclc; 28328c2ecf20Sopenharmony_ci} 28338c2ecf20Sopenharmony_ci 28348c2ecf20Sopenharmony_cistatic int stv090x_optimize_track(struct stv090x_state *state) 28358c2ecf20Sopenharmony_ci{ 28368c2ecf20Sopenharmony_ci struct dvb_frontend *fe = &state->frontend; 28378c2ecf20Sopenharmony_ci 28388c2ecf20Sopenharmony_ci enum stv090x_modcod modcod; 28398c2ecf20Sopenharmony_ci 28408c2ecf20Sopenharmony_ci s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; 28418c2ecf20Sopenharmony_ci u32 reg; 28428c2ecf20Sopenharmony_ci 28438c2ecf20Sopenharmony_ci srate = stv090x_get_srate(state, state->internal->mclk); 28448c2ecf20Sopenharmony_ci srate += stv090x_get_tmgoffst(state, srate); 28458c2ecf20Sopenharmony_ci 28468c2ecf20Sopenharmony_ci switch (state->delsys) { 28478c2ecf20Sopenharmony_ci case STV090x_DVBS1: 28488c2ecf20Sopenharmony_ci case STV090x_DSS: 28498c2ecf20Sopenharmony_ci if (state->search_mode == STV090x_SEARCH_AUTO) { 28508c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 28518c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); 28528c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); 28538c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 28548c2ecf20Sopenharmony_ci goto err; 28558c2ecf20Sopenharmony_ci } 28568c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DEMOD); 28578c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff); 28588c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x01); 28598c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) 28608c2ecf20Sopenharmony_ci goto err; 28618c2ecf20Sopenharmony_ci 28628c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x30) { 28638c2ecf20Sopenharmony_ci if (stv090x_get_viterbi(state) < 0) 28648c2ecf20Sopenharmony_ci goto err; 28658c2ecf20Sopenharmony_ci 28668c2ecf20Sopenharmony_ci if (state->fec == STV090x_PR12) { 28678c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x98) < 0) 28688c2ecf20Sopenharmony_ci goto err; 28698c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0) 28708c2ecf20Sopenharmony_ci goto err; 28718c2ecf20Sopenharmony_ci } else { 28728c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x18) < 0) 28738c2ecf20Sopenharmony_ci goto err; 28748c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0) 28758c2ecf20Sopenharmony_ci goto err; 28768c2ecf20Sopenharmony_ci } 28778c2ecf20Sopenharmony_ci } 28788c2ecf20Sopenharmony_ci 28798c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0) 28808c2ecf20Sopenharmony_ci goto err; 28818c2ecf20Sopenharmony_ci break; 28828c2ecf20Sopenharmony_ci 28838c2ecf20Sopenharmony_ci case STV090x_DVBS2: 28848c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 28858c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); 28868c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); 28878c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 28888c2ecf20Sopenharmony_ci goto err; 28898c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x30) { 28908c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0) 28918c2ecf20Sopenharmony_ci goto err; 28928c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0) 28938c2ecf20Sopenharmony_ci goto err; 28948c2ecf20Sopenharmony_ci } 28958c2ecf20Sopenharmony_ci if (state->frame_len == STV090x_LONG_FRAME) { 28968c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDMODCOD); 28978c2ecf20Sopenharmony_ci modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD); 28988c2ecf20Sopenharmony_ci pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01; 28998c2ecf20Sopenharmony_ci aclc = stv090x_optimize_carloop(state, modcod, pilots); 29008c2ecf20Sopenharmony_ci if (modcod <= STV090x_QPSK_910) { 29018c2ecf20Sopenharmony_ci STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc); 29028c2ecf20Sopenharmony_ci } else if (modcod <= STV090x_8PSK_910) { 29038c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) 29048c2ecf20Sopenharmony_ci goto err; 29058c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0) 29068c2ecf20Sopenharmony_ci goto err; 29078c2ecf20Sopenharmony_ci } 29088c2ecf20Sopenharmony_ci if ((state->demod_mode == STV090x_SINGLE) && (modcod > STV090x_8PSK_910)) { 29098c2ecf20Sopenharmony_ci if (modcod <= STV090x_16APSK_910) { 29108c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) 29118c2ecf20Sopenharmony_ci goto err; 29128c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0) 29138c2ecf20Sopenharmony_ci goto err; 29148c2ecf20Sopenharmony_ci } else { 29158c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) 29168c2ecf20Sopenharmony_ci goto err; 29178c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0) 29188c2ecf20Sopenharmony_ci goto err; 29198c2ecf20Sopenharmony_ci } 29208c2ecf20Sopenharmony_ci } 29218c2ecf20Sopenharmony_ci } else { 29228c2ecf20Sopenharmony_ci /*Carrier loop setting for short frame*/ 29238c2ecf20Sopenharmony_ci aclc = stv090x_optimize_carloop_short(state); 29248c2ecf20Sopenharmony_ci if (state->modulation == STV090x_QPSK) { 29258c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc) < 0) 29268c2ecf20Sopenharmony_ci goto err; 29278c2ecf20Sopenharmony_ci } else if (state->modulation == STV090x_8PSK) { 29288c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) 29298c2ecf20Sopenharmony_ci goto err; 29308c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0) 29318c2ecf20Sopenharmony_ci goto err; 29328c2ecf20Sopenharmony_ci } else if (state->modulation == STV090x_16APSK) { 29338c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) 29348c2ecf20Sopenharmony_ci goto err; 29358c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0) 29368c2ecf20Sopenharmony_ci goto err; 29378c2ecf20Sopenharmony_ci } else if (state->modulation == STV090x_32APSK) { 29388c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0) 29398c2ecf20Sopenharmony_ci goto err; 29408c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0) 29418c2ecf20Sopenharmony_ci goto err; 29428c2ecf20Sopenharmony_ci } 29438c2ecf20Sopenharmony_ci } 29448c2ecf20Sopenharmony_ci 29458c2ecf20Sopenharmony_ci STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */ 29468c2ecf20Sopenharmony_ci break; 29478c2ecf20Sopenharmony_ci 29488c2ecf20Sopenharmony_ci case STV090x_ERROR: 29498c2ecf20Sopenharmony_ci default: 29508c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 29518c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); 29528c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); 29538c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 29548c2ecf20Sopenharmony_ci goto err; 29558c2ecf20Sopenharmony_ci break; 29568c2ecf20Sopenharmony_ci } 29578c2ecf20Sopenharmony_ci 29588c2ecf20Sopenharmony_ci f_1 = STV090x_READ_DEMOD(state, CFR2); 29598c2ecf20Sopenharmony_ci f_0 = STV090x_READ_DEMOD(state, CFR1); 29608c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, TMGOBS); 29618c2ecf20Sopenharmony_ci 29628c2ecf20Sopenharmony_ci if (state->algo == STV090x_BLIND_SEARCH) { 29638c2ecf20Sopenharmony_ci STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00); 29648c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDCFGMD); 29658c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0x00); 29668c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); 29678c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 29688c2ecf20Sopenharmony_ci goto err; 29698c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) 29708c2ecf20Sopenharmony_ci goto err; 29718c2ecf20Sopenharmony_ci 29728c2ecf20Sopenharmony_ci if (stv090x_set_srate(state, srate) < 0) 29738c2ecf20Sopenharmony_ci goto err; 29748c2ecf20Sopenharmony_ci blind_tune = 1; 29758c2ecf20Sopenharmony_ci 29768c2ecf20Sopenharmony_ci if (stv090x_dvbs_track_crl(state) < 0) 29778c2ecf20Sopenharmony_ci goto err; 29788c2ecf20Sopenharmony_ci } 29798c2ecf20Sopenharmony_ci 29808c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 29818c2ecf20Sopenharmony_ci if ((state->search_mode == STV090x_SEARCH_DVBS1) || 29828c2ecf20Sopenharmony_ci (state->search_mode == STV090x_SEARCH_DSS) || 29838c2ecf20Sopenharmony_ci (state->search_mode == STV090x_SEARCH_AUTO)) { 29848c2ecf20Sopenharmony_ci 29858c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x0a) < 0) 29868c2ecf20Sopenharmony_ci goto err; 29878c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x00) < 0) 29888c2ecf20Sopenharmony_ci goto err; 29898c2ecf20Sopenharmony_ci } 29908c2ecf20Sopenharmony_ci } 29918c2ecf20Sopenharmony_ci 29928c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) 29938c2ecf20Sopenharmony_ci goto err; 29948c2ecf20Sopenharmony_ci 29958c2ecf20Sopenharmony_ci /* AUTO tracking MODE */ 29968c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x80) < 0) 29978c2ecf20Sopenharmony_ci goto err; 29988c2ecf20Sopenharmony_ci /* AUTO tracking MODE */ 29998c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0) 30008c2ecf20Sopenharmony_ci goto err; 30018c2ecf20Sopenharmony_ci 30028c2ecf20Sopenharmony_ci if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1) || 30038c2ecf20Sopenharmony_ci (state->srate < 10000000)) { 30048c2ecf20Sopenharmony_ci /* update initial carrier freq with the found freq offset */ 30058c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) 30068c2ecf20Sopenharmony_ci goto err; 30078c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0) 30088c2ecf20Sopenharmony_ci goto err; 30098c2ecf20Sopenharmony_ci state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000; 30108c2ecf20Sopenharmony_ci 30118c2ecf20Sopenharmony_ci if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1)) { 30128c2ecf20Sopenharmony_ci 30138c2ecf20Sopenharmony_ci if (state->algo != STV090x_WARM_SEARCH) { 30148c2ecf20Sopenharmony_ci 30158c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 30168c2ecf20Sopenharmony_ci goto err; 30178c2ecf20Sopenharmony_ci 30188c2ecf20Sopenharmony_ci if (state->config->tuner_set_bandwidth) { 30198c2ecf20Sopenharmony_ci if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) 30208c2ecf20Sopenharmony_ci goto err_gateoff; 30218c2ecf20Sopenharmony_ci } 30228c2ecf20Sopenharmony_ci 30238c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 30248c2ecf20Sopenharmony_ci goto err; 30258c2ecf20Sopenharmony_ci 30268c2ecf20Sopenharmony_ci } 30278c2ecf20Sopenharmony_ci } 30288c2ecf20Sopenharmony_ci if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) 30298c2ecf20Sopenharmony_ci msleep(50); /* blind search: wait 50ms for SR stabilization */ 30308c2ecf20Sopenharmony_ci else 30318c2ecf20Sopenharmony_ci msleep(5); 30328c2ecf20Sopenharmony_ci 30338c2ecf20Sopenharmony_ci stv090x_get_lock_tmg(state); 30348c2ecf20Sopenharmony_ci 30358c2ecf20Sopenharmony_ci if (!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) { 30368c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) 30378c2ecf20Sopenharmony_ci goto err; 30388c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) 30398c2ecf20Sopenharmony_ci goto err; 30408c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0) 30418c2ecf20Sopenharmony_ci goto err; 30428c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) 30438c2ecf20Sopenharmony_ci goto err; 30448c2ecf20Sopenharmony_ci 30458c2ecf20Sopenharmony_ci i = 0; 30468c2ecf20Sopenharmony_ci 30478c2ecf20Sopenharmony_ci while ((!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) && (i <= 2)) { 30488c2ecf20Sopenharmony_ci 30498c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) 30508c2ecf20Sopenharmony_ci goto err; 30518c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) 30528c2ecf20Sopenharmony_ci goto err; 30538c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0) 30548c2ecf20Sopenharmony_ci goto err; 30558c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) 30568c2ecf20Sopenharmony_ci goto err; 30578c2ecf20Sopenharmony_ci i++; 30588c2ecf20Sopenharmony_ci } 30598c2ecf20Sopenharmony_ci } 30608c2ecf20Sopenharmony_ci 30618c2ecf20Sopenharmony_ci } 30628c2ecf20Sopenharmony_ci 30638c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 30648c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) 30658c2ecf20Sopenharmony_ci goto err; 30668c2ecf20Sopenharmony_ci } 30678c2ecf20Sopenharmony_ci 30688c2ecf20Sopenharmony_ci if ((state->delsys == STV090x_DVBS1) || (state->delsys == STV090x_DSS)) 30698c2ecf20Sopenharmony_ci stv090x_set_vit_thtracq(state); 30708c2ecf20Sopenharmony_ci 30718c2ecf20Sopenharmony_ci return 0; 30728c2ecf20Sopenharmony_ci 30738c2ecf20Sopenharmony_cierr_gateoff: 30748c2ecf20Sopenharmony_ci stv090x_i2c_gate_ctrl(state, 0); 30758c2ecf20Sopenharmony_cierr: 30768c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 30778c2ecf20Sopenharmony_ci return -1; 30788c2ecf20Sopenharmony_ci} 30798c2ecf20Sopenharmony_ci 30808c2ecf20Sopenharmony_cistatic int stv090x_get_feclock(struct stv090x_state *state, s32 timeout) 30818c2ecf20Sopenharmony_ci{ 30828c2ecf20Sopenharmony_ci s32 timer = 0, lock = 0, stat; 30838c2ecf20Sopenharmony_ci u32 reg; 30848c2ecf20Sopenharmony_ci 30858c2ecf20Sopenharmony_ci while ((timer < timeout) && (!lock)) { 30868c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDSTATE); 30878c2ecf20Sopenharmony_ci stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); 30888c2ecf20Sopenharmony_ci 30898c2ecf20Sopenharmony_ci switch (stat) { 30908c2ecf20Sopenharmony_ci case 0: /* searching */ 30918c2ecf20Sopenharmony_ci case 1: /* first PLH detected */ 30928c2ecf20Sopenharmony_ci default: 30938c2ecf20Sopenharmony_ci lock = 0; 30948c2ecf20Sopenharmony_ci break; 30958c2ecf20Sopenharmony_ci 30968c2ecf20Sopenharmony_ci case 2: /* DVB-S2 mode */ 30978c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, PDELSTATUS1); 30988c2ecf20Sopenharmony_ci lock = STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD); 30998c2ecf20Sopenharmony_ci break; 31008c2ecf20Sopenharmony_ci 31018c2ecf20Sopenharmony_ci case 3: /* DVB-S1/legacy mode */ 31028c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, VSTATUSVIT); 31038c2ecf20Sopenharmony_ci lock = STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD); 31048c2ecf20Sopenharmony_ci break; 31058c2ecf20Sopenharmony_ci } 31068c2ecf20Sopenharmony_ci if (!lock) { 31078c2ecf20Sopenharmony_ci msleep(10); 31088c2ecf20Sopenharmony_ci timer += 10; 31098c2ecf20Sopenharmony_ci } 31108c2ecf20Sopenharmony_ci } 31118c2ecf20Sopenharmony_ci return lock; 31128c2ecf20Sopenharmony_ci} 31138c2ecf20Sopenharmony_ci 31148c2ecf20Sopenharmony_cistatic int stv090x_get_lock(struct stv090x_state *state, s32 timeout_dmd, s32 timeout_fec) 31158c2ecf20Sopenharmony_ci{ 31168c2ecf20Sopenharmony_ci u32 reg; 31178c2ecf20Sopenharmony_ci s32 timer = 0; 31188c2ecf20Sopenharmony_ci int lock; 31198c2ecf20Sopenharmony_ci 31208c2ecf20Sopenharmony_ci lock = stv090x_get_dmdlock(state, timeout_dmd); 31218c2ecf20Sopenharmony_ci if (lock) 31228c2ecf20Sopenharmony_ci lock = stv090x_get_feclock(state, timeout_fec); 31238c2ecf20Sopenharmony_ci 31248c2ecf20Sopenharmony_ci if (lock) { 31258c2ecf20Sopenharmony_ci lock = 0; 31268c2ecf20Sopenharmony_ci 31278c2ecf20Sopenharmony_ci while ((timer < timeout_fec) && (!lock)) { 31288c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, TSSTATUS); 31298c2ecf20Sopenharmony_ci lock = STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD); 31308c2ecf20Sopenharmony_ci msleep(1); 31318c2ecf20Sopenharmony_ci timer++; 31328c2ecf20Sopenharmony_ci } 31338c2ecf20Sopenharmony_ci } 31348c2ecf20Sopenharmony_ci 31358c2ecf20Sopenharmony_ci return lock; 31368c2ecf20Sopenharmony_ci} 31378c2ecf20Sopenharmony_ci 31388c2ecf20Sopenharmony_cistatic int stv090x_set_s2rolloff(struct stv090x_state *state) 31398c2ecf20Sopenharmony_ci{ 31408c2ecf20Sopenharmony_ci u32 reg; 31418c2ecf20Sopenharmony_ci 31428c2ecf20Sopenharmony_ci if (state->internal->dev_ver <= 0x20) { 31438c2ecf20Sopenharmony_ci /* rolloff to auto mode if DVBS2 */ 31448c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DEMOD); 31458c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00); 31468c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) 31478c2ecf20Sopenharmony_ci goto err; 31488c2ecf20Sopenharmony_ci } else { 31498c2ecf20Sopenharmony_ci /* DVB-S2 rolloff to auto mode if DVBS2 */ 31508c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DEMOD); 31518c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 0x00); 31528c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) 31538c2ecf20Sopenharmony_ci goto err; 31548c2ecf20Sopenharmony_ci } 31558c2ecf20Sopenharmony_ci return 0; 31568c2ecf20Sopenharmony_cierr: 31578c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 31588c2ecf20Sopenharmony_ci return -1; 31598c2ecf20Sopenharmony_ci} 31608c2ecf20Sopenharmony_ci 31618c2ecf20Sopenharmony_ci 31628c2ecf20Sopenharmony_cistatic enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) 31638c2ecf20Sopenharmony_ci{ 31648c2ecf20Sopenharmony_ci struct dvb_frontend *fe = &state->frontend; 31658c2ecf20Sopenharmony_ci enum stv090x_signal_state signal_state = STV090x_NOCARRIER; 31668c2ecf20Sopenharmony_ci u32 reg; 31678c2ecf20Sopenharmony_ci s32 agc1_power, power_iq = 0, i; 31688c2ecf20Sopenharmony_ci int lock = 0, low_sr = 0; 31698c2ecf20Sopenharmony_ci 31708c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, TSCFGH); 31718c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */ 31728c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) 31738c2ecf20Sopenharmony_ci goto err; 31748c2ecf20Sopenharmony_ci 31758c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */ 31768c2ecf20Sopenharmony_ci goto err; 31778c2ecf20Sopenharmony_ci 31788c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 31798c2ecf20Sopenharmony_ci if (state->srate > 5000000) { 31808c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) 31818c2ecf20Sopenharmony_ci goto err; 31828c2ecf20Sopenharmony_ci } else { 31838c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x82) < 0) 31848c2ecf20Sopenharmony_ci goto err; 31858c2ecf20Sopenharmony_ci } 31868c2ecf20Sopenharmony_ci } 31878c2ecf20Sopenharmony_ci 31888c2ecf20Sopenharmony_ci stv090x_get_lock_tmg(state); 31898c2ecf20Sopenharmony_ci 31908c2ecf20Sopenharmony_ci if (state->algo == STV090x_BLIND_SEARCH) { 31918c2ecf20Sopenharmony_ci state->tuner_bw = 2 * 36000000; /* wide bw for unknown srate */ 31928c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0) /* wider srate scan */ 31938c2ecf20Sopenharmony_ci goto err; 31948c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0) 31958c2ecf20Sopenharmony_ci goto err; 31968c2ecf20Sopenharmony_ci if (stv090x_set_srate(state, 1000000) < 0) /* initial srate = 1Msps */ 31978c2ecf20Sopenharmony_ci goto err; 31988c2ecf20Sopenharmony_ci } else { 31998c2ecf20Sopenharmony_ci /* known srate */ 32008c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0) 32018c2ecf20Sopenharmony_ci goto err; 32028c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0) 32038c2ecf20Sopenharmony_ci goto err; 32048c2ecf20Sopenharmony_ci 32058c2ecf20Sopenharmony_ci if (state->srate < 2000000) { 32068c2ecf20Sopenharmony_ci /* SR < 2MSPS */ 32078c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x63) < 0) 32088c2ecf20Sopenharmony_ci goto err; 32098c2ecf20Sopenharmony_ci } else { 32108c2ecf20Sopenharmony_ci /* SR >= 2Msps */ 32118c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0) 32128c2ecf20Sopenharmony_ci goto err; 32138c2ecf20Sopenharmony_ci } 32148c2ecf20Sopenharmony_ci 32158c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) 32168c2ecf20Sopenharmony_ci goto err; 32178c2ecf20Sopenharmony_ci 32188c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 32198c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0) 32208c2ecf20Sopenharmony_ci goto err; 32218c2ecf20Sopenharmony_ci if (state->algo == STV090x_COLD_SEARCH) 32228c2ecf20Sopenharmony_ci state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10; 32238c2ecf20Sopenharmony_ci else if (state->algo == STV090x_WARM_SEARCH) 32248c2ecf20Sopenharmony_ci state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + 10000000; 32258c2ecf20Sopenharmony_ci } 32268c2ecf20Sopenharmony_ci 32278c2ecf20Sopenharmony_ci /* if cold start or warm (Symbolrate is known) 32288c2ecf20Sopenharmony_ci * use a Narrow symbol rate scan range 32298c2ecf20Sopenharmony_ci */ 32308c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) /* narrow srate scan */ 32318c2ecf20Sopenharmony_ci goto err; 32328c2ecf20Sopenharmony_ci 32338c2ecf20Sopenharmony_ci if (stv090x_set_srate(state, state->srate) < 0) 32348c2ecf20Sopenharmony_ci goto err; 32358c2ecf20Sopenharmony_ci 32368c2ecf20Sopenharmony_ci if (stv090x_set_max_srate(state, state->internal->mclk, 32378c2ecf20Sopenharmony_ci state->srate) < 0) 32388c2ecf20Sopenharmony_ci goto err; 32398c2ecf20Sopenharmony_ci if (stv090x_set_min_srate(state, state->internal->mclk, 32408c2ecf20Sopenharmony_ci state->srate) < 0) 32418c2ecf20Sopenharmony_ci goto err; 32428c2ecf20Sopenharmony_ci 32438c2ecf20Sopenharmony_ci if (state->srate >= 10000000) 32448c2ecf20Sopenharmony_ci low_sr = 0; 32458c2ecf20Sopenharmony_ci else 32468c2ecf20Sopenharmony_ci low_sr = 1; 32478c2ecf20Sopenharmony_ci } 32488c2ecf20Sopenharmony_ci 32498c2ecf20Sopenharmony_ci /* Setup tuner */ 32508c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 32518c2ecf20Sopenharmony_ci goto err; 32528c2ecf20Sopenharmony_ci 32538c2ecf20Sopenharmony_ci if (state->config->tuner_set_bbgain) { 32548c2ecf20Sopenharmony_ci reg = state->config->tuner_bbgain; 32558c2ecf20Sopenharmony_ci if (reg == 0) 32568c2ecf20Sopenharmony_ci reg = 10; /* default: 10dB */ 32578c2ecf20Sopenharmony_ci if (state->config->tuner_set_bbgain(fe, reg) < 0) 32588c2ecf20Sopenharmony_ci goto err_gateoff; 32598c2ecf20Sopenharmony_ci } 32608c2ecf20Sopenharmony_ci 32618c2ecf20Sopenharmony_ci if (state->config->tuner_set_frequency) { 32628c2ecf20Sopenharmony_ci if (state->config->tuner_set_frequency(fe, state->frequency) < 0) 32638c2ecf20Sopenharmony_ci goto err_gateoff; 32648c2ecf20Sopenharmony_ci } 32658c2ecf20Sopenharmony_ci 32668c2ecf20Sopenharmony_ci if (state->config->tuner_set_bandwidth) { 32678c2ecf20Sopenharmony_ci if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) 32688c2ecf20Sopenharmony_ci goto err_gateoff; 32698c2ecf20Sopenharmony_ci } 32708c2ecf20Sopenharmony_ci 32718c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 32728c2ecf20Sopenharmony_ci goto err; 32738c2ecf20Sopenharmony_ci 32748c2ecf20Sopenharmony_ci msleep(50); 32758c2ecf20Sopenharmony_ci 32768c2ecf20Sopenharmony_ci if (state->config->tuner_get_status) { 32778c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 32788c2ecf20Sopenharmony_ci goto err; 32798c2ecf20Sopenharmony_ci if (state->config->tuner_get_status(fe, ®) < 0) 32808c2ecf20Sopenharmony_ci goto err_gateoff; 32818c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 32828c2ecf20Sopenharmony_ci goto err; 32838c2ecf20Sopenharmony_ci 32848c2ecf20Sopenharmony_ci if (reg) 32858c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Tuner phase locked"); 32868c2ecf20Sopenharmony_ci else { 32878c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Tuner unlocked"); 32888c2ecf20Sopenharmony_ci return STV090x_NOCARRIER; 32898c2ecf20Sopenharmony_ci } 32908c2ecf20Sopenharmony_ci } 32918c2ecf20Sopenharmony_ci 32928c2ecf20Sopenharmony_ci msleep(10); 32938c2ecf20Sopenharmony_ci agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1), 32948c2ecf20Sopenharmony_ci STV090x_READ_DEMOD(state, AGCIQIN0)); 32958c2ecf20Sopenharmony_ci 32968c2ecf20Sopenharmony_ci if (agc1_power == 0) { 32978c2ecf20Sopenharmony_ci /* If AGC1 integrator value is 0 32988c2ecf20Sopenharmony_ci * then read POWERI, POWERQ 32998c2ecf20Sopenharmony_ci */ 33008c2ecf20Sopenharmony_ci for (i = 0; i < 5; i++) { 33018c2ecf20Sopenharmony_ci power_iq += (STV090x_READ_DEMOD(state, POWERI) + 33028c2ecf20Sopenharmony_ci STV090x_READ_DEMOD(state, POWERQ)) >> 1; 33038c2ecf20Sopenharmony_ci } 33048c2ecf20Sopenharmony_ci power_iq /= 5; 33058c2ecf20Sopenharmony_ci } 33068c2ecf20Sopenharmony_ci 33078c2ecf20Sopenharmony_ci if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) { 33088c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq); 33098c2ecf20Sopenharmony_ci lock = 0; 33108c2ecf20Sopenharmony_ci signal_state = STV090x_NOAGC1; 33118c2ecf20Sopenharmony_ci } else { 33128c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DEMOD); 33138c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); 33148c2ecf20Sopenharmony_ci 33158c2ecf20Sopenharmony_ci if (state->internal->dev_ver <= 0x20) { 33168c2ecf20Sopenharmony_ci /* rolloff to auto mode if DVBS2 */ 33178c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1); 33188c2ecf20Sopenharmony_ci } else { 33198c2ecf20Sopenharmony_ci /* DVB-S2 rolloff to auto mode if DVBS2 */ 33208c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 1); 33218c2ecf20Sopenharmony_ci } 33228c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) 33238c2ecf20Sopenharmony_ci goto err; 33248c2ecf20Sopenharmony_ci 33258c2ecf20Sopenharmony_ci if (stv090x_delivery_search(state) < 0) 33268c2ecf20Sopenharmony_ci goto err; 33278c2ecf20Sopenharmony_ci 33288c2ecf20Sopenharmony_ci if (state->algo != STV090x_BLIND_SEARCH) { 33298c2ecf20Sopenharmony_ci if (stv090x_start_search(state) < 0) 33308c2ecf20Sopenharmony_ci goto err; 33318c2ecf20Sopenharmony_ci } 33328c2ecf20Sopenharmony_ci } 33338c2ecf20Sopenharmony_ci 33348c2ecf20Sopenharmony_ci if (signal_state == STV090x_NOAGC1) 33358c2ecf20Sopenharmony_ci return signal_state; 33368c2ecf20Sopenharmony_ci 33378c2ecf20Sopenharmony_ci if (state->algo == STV090x_BLIND_SEARCH) 33388c2ecf20Sopenharmony_ci lock = stv090x_blind_search(state); 33398c2ecf20Sopenharmony_ci 33408c2ecf20Sopenharmony_ci else if (state->algo == STV090x_COLD_SEARCH) 33418c2ecf20Sopenharmony_ci lock = stv090x_get_coldlock(state, state->DemodTimeout); 33428c2ecf20Sopenharmony_ci 33438c2ecf20Sopenharmony_ci else if (state->algo == STV090x_WARM_SEARCH) 33448c2ecf20Sopenharmony_ci lock = stv090x_get_dmdlock(state, state->DemodTimeout); 33458c2ecf20Sopenharmony_ci 33468c2ecf20Sopenharmony_ci if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) { 33478c2ecf20Sopenharmony_ci if (!low_sr) { 33488c2ecf20Sopenharmony_ci if (stv090x_chk_tmg(state)) 33498c2ecf20Sopenharmony_ci lock = stv090x_sw_algo(state); 33508c2ecf20Sopenharmony_ci } 33518c2ecf20Sopenharmony_ci } 33528c2ecf20Sopenharmony_ci 33538c2ecf20Sopenharmony_ci if (lock) 33548c2ecf20Sopenharmony_ci signal_state = stv090x_get_sig_params(state); 33558c2ecf20Sopenharmony_ci 33568c2ecf20Sopenharmony_ci if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */ 33578c2ecf20Sopenharmony_ci stv090x_optimize_track(state); 33588c2ecf20Sopenharmony_ci 33598c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 33608c2ecf20Sopenharmony_ci /* >= Cut 2.0 :release TS reset after 33618c2ecf20Sopenharmony_ci * demod lock and optimized Tracking 33628c2ecf20Sopenharmony_ci */ 33638c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, TSCFGH); 33648c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ 33658c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) 33668c2ecf20Sopenharmony_ci goto err; 33678c2ecf20Sopenharmony_ci 33688c2ecf20Sopenharmony_ci msleep(3); 33698c2ecf20Sopenharmony_ci 33708c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */ 33718c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) 33728c2ecf20Sopenharmony_ci goto err; 33738c2ecf20Sopenharmony_ci 33748c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */ 33758c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0) 33768c2ecf20Sopenharmony_ci goto err; 33778c2ecf20Sopenharmony_ci } 33788c2ecf20Sopenharmony_ci 33798c2ecf20Sopenharmony_ci lock = stv090x_get_lock(state, state->FecTimeout, 33808c2ecf20Sopenharmony_ci state->FecTimeout); 33818c2ecf20Sopenharmony_ci if (lock) { 33828c2ecf20Sopenharmony_ci if (state->delsys == STV090x_DVBS2) { 33838c2ecf20Sopenharmony_ci stv090x_set_s2rolloff(state); 33848c2ecf20Sopenharmony_ci 33858c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, PDELCTRL2); 33868c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 1); 33878c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0) 33888c2ecf20Sopenharmony_ci goto err; 33898c2ecf20Sopenharmony_ci /* Reset DVBS2 packet delinator error counter */ 33908c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, PDELCTRL2); 33918c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 0); 33928c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0) 33938c2ecf20Sopenharmony_ci goto err; 33948c2ecf20Sopenharmony_ci 33958c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67) < 0) /* PER */ 33968c2ecf20Sopenharmony_ci goto err; 33978c2ecf20Sopenharmony_ci } else { 33988c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0) 33998c2ecf20Sopenharmony_ci goto err; 34008c2ecf20Sopenharmony_ci } 34018c2ecf20Sopenharmony_ci /* Reset the Total packet counter */ 34028c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0x00) < 0) 34038c2ecf20Sopenharmony_ci goto err; 34048c2ecf20Sopenharmony_ci /* Reset the packet Error counter2 */ 34058c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0) 34068c2ecf20Sopenharmony_ci goto err; 34078c2ecf20Sopenharmony_ci } else { 34088c2ecf20Sopenharmony_ci signal_state = STV090x_NODATA; 34098c2ecf20Sopenharmony_ci stv090x_chk_signal(state); 34108c2ecf20Sopenharmony_ci } 34118c2ecf20Sopenharmony_ci } 34128c2ecf20Sopenharmony_ci return signal_state; 34138c2ecf20Sopenharmony_ci 34148c2ecf20Sopenharmony_cierr_gateoff: 34158c2ecf20Sopenharmony_ci stv090x_i2c_gate_ctrl(state, 0); 34168c2ecf20Sopenharmony_cierr: 34178c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 34188c2ecf20Sopenharmony_ci return -1; 34198c2ecf20Sopenharmony_ci} 34208c2ecf20Sopenharmony_ci 34218c2ecf20Sopenharmony_cistatic int stv090x_set_pls(struct stv090x_state *state, u32 pls_code) 34228c2ecf20Sopenharmony_ci{ 34238c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Set Gold PLS code %d", pls_code); 34248c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PLROOT0, pls_code & 0xff) < 0) 34258c2ecf20Sopenharmony_ci goto err; 34268c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PLROOT1, (pls_code >> 8) & 0xff) < 0) 34278c2ecf20Sopenharmony_ci goto err; 34288c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PLROOT2, 0x04 | (pls_code >> 16)) < 0) 34298c2ecf20Sopenharmony_ci goto err; 34308c2ecf20Sopenharmony_ci return 0; 34318c2ecf20Sopenharmony_cierr: 34328c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 34338c2ecf20Sopenharmony_ci return -1; 34348c2ecf20Sopenharmony_ci} 34358c2ecf20Sopenharmony_ci 34368c2ecf20Sopenharmony_cistatic int stv090x_set_mis(struct stv090x_state *state, int mis) 34378c2ecf20Sopenharmony_ci{ 34388c2ecf20Sopenharmony_ci u32 reg; 34398c2ecf20Sopenharmony_ci 34408c2ecf20Sopenharmony_ci if (mis < 0 || mis > 255) { 34418c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Disable MIS filtering"); 34428c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, PDELCTRL1); 34438c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x00); 34448c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) 34458c2ecf20Sopenharmony_ci goto err; 34468c2ecf20Sopenharmony_ci } else { 34478c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Enable MIS filtering - %d", mis); 34488c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, PDELCTRL1); 34498c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x01); 34508c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) 34518c2ecf20Sopenharmony_ci goto err; 34528c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ISIENTRY, mis) < 0) 34538c2ecf20Sopenharmony_ci goto err; 34548c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ISIBITENA, 0xff) < 0) 34558c2ecf20Sopenharmony_ci goto err; 34568c2ecf20Sopenharmony_ci } 34578c2ecf20Sopenharmony_ci return 0; 34588c2ecf20Sopenharmony_cierr: 34598c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 34608c2ecf20Sopenharmony_ci return -1; 34618c2ecf20Sopenharmony_ci} 34628c2ecf20Sopenharmony_ci 34638c2ecf20Sopenharmony_cistatic enum dvbfe_search stv090x_search(struct dvb_frontend *fe) 34648c2ecf20Sopenharmony_ci{ 34658c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 34668c2ecf20Sopenharmony_ci struct dtv_frontend_properties *props = &fe->dtv_property_cache; 34678c2ecf20Sopenharmony_ci 34688c2ecf20Sopenharmony_ci if (props->frequency == 0) 34698c2ecf20Sopenharmony_ci return DVBFE_ALGO_SEARCH_INVALID; 34708c2ecf20Sopenharmony_ci 34718c2ecf20Sopenharmony_ci switch (props->delivery_system) { 34728c2ecf20Sopenharmony_ci case SYS_DSS: 34738c2ecf20Sopenharmony_ci state->delsys = STV090x_DSS; 34748c2ecf20Sopenharmony_ci break; 34758c2ecf20Sopenharmony_ci case SYS_DVBS: 34768c2ecf20Sopenharmony_ci state->delsys = STV090x_DVBS1; 34778c2ecf20Sopenharmony_ci break; 34788c2ecf20Sopenharmony_ci case SYS_DVBS2: 34798c2ecf20Sopenharmony_ci state->delsys = STV090x_DVBS2; 34808c2ecf20Sopenharmony_ci break; 34818c2ecf20Sopenharmony_ci default: 34828c2ecf20Sopenharmony_ci return DVBFE_ALGO_SEARCH_INVALID; 34838c2ecf20Sopenharmony_ci } 34848c2ecf20Sopenharmony_ci 34858c2ecf20Sopenharmony_ci state->frequency = props->frequency; 34868c2ecf20Sopenharmony_ci state->srate = props->symbol_rate; 34878c2ecf20Sopenharmony_ci state->search_mode = STV090x_SEARCH_AUTO; 34888c2ecf20Sopenharmony_ci state->algo = STV090x_COLD_SEARCH; 34898c2ecf20Sopenharmony_ci state->fec = STV090x_PRERR; 34908c2ecf20Sopenharmony_ci if (state->srate > 10000000) { 34918c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Search range: 10 MHz"); 34928c2ecf20Sopenharmony_ci state->search_range = 10000000; 34938c2ecf20Sopenharmony_ci } else { 34948c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Search range: 5 MHz"); 34958c2ecf20Sopenharmony_ci state->search_range = 5000000; 34968c2ecf20Sopenharmony_ci } 34978c2ecf20Sopenharmony_ci 34988c2ecf20Sopenharmony_ci stv090x_set_pls(state, props->scrambling_sequence_index); 34998c2ecf20Sopenharmony_ci stv090x_set_mis(state, props->stream_id); 35008c2ecf20Sopenharmony_ci 35018c2ecf20Sopenharmony_ci if (stv090x_algo(state) == STV090x_RANGEOK) { 35028c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Search success!"); 35038c2ecf20Sopenharmony_ci return DVBFE_ALGO_SEARCH_SUCCESS; 35048c2ecf20Sopenharmony_ci } else { 35058c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Search failed!"); 35068c2ecf20Sopenharmony_ci return DVBFE_ALGO_SEARCH_FAILED; 35078c2ecf20Sopenharmony_ci } 35088c2ecf20Sopenharmony_ci 35098c2ecf20Sopenharmony_ci return DVBFE_ALGO_SEARCH_ERROR; 35108c2ecf20Sopenharmony_ci} 35118c2ecf20Sopenharmony_ci 35128c2ecf20Sopenharmony_cistatic int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) 35138c2ecf20Sopenharmony_ci{ 35148c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 35158c2ecf20Sopenharmony_ci u32 reg, dstatus; 35168c2ecf20Sopenharmony_ci u8 search_state; 35178c2ecf20Sopenharmony_ci 35188c2ecf20Sopenharmony_ci *status = 0; 35198c2ecf20Sopenharmony_ci 35208c2ecf20Sopenharmony_ci dstatus = STV090x_READ_DEMOD(state, DSTATUS); 35218c2ecf20Sopenharmony_ci if (STV090x_GETFIELD_Px(dstatus, CAR_LOCK_FIELD)) 35228c2ecf20Sopenharmony_ci *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; 35238c2ecf20Sopenharmony_ci 35248c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DMDSTATE); 35258c2ecf20Sopenharmony_ci search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); 35268c2ecf20Sopenharmony_ci 35278c2ecf20Sopenharmony_ci switch (search_state) { 35288c2ecf20Sopenharmony_ci case 0: /* searching */ 35298c2ecf20Sopenharmony_ci case 1: /* first PLH detected */ 35308c2ecf20Sopenharmony_ci default: 35318c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)"); 35328c2ecf20Sopenharmony_ci break; 35338c2ecf20Sopenharmony_ci 35348c2ecf20Sopenharmony_ci case 2: /* DVB-S2 mode */ 35358c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2"); 35368c2ecf20Sopenharmony_ci if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) { 35378c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, PDELSTATUS1); 35388c2ecf20Sopenharmony_ci if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) { 35398c2ecf20Sopenharmony_ci *status |= FE_HAS_VITERBI; 35408c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, TSSTATUS); 35418c2ecf20Sopenharmony_ci if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) 35428c2ecf20Sopenharmony_ci *status |= FE_HAS_SYNC | FE_HAS_LOCK; 35438c2ecf20Sopenharmony_ci } 35448c2ecf20Sopenharmony_ci } 35458c2ecf20Sopenharmony_ci break; 35468c2ecf20Sopenharmony_ci 35478c2ecf20Sopenharmony_ci case 3: /* DVB-S1/legacy mode */ 35488c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Delivery system: DVB-S"); 35498c2ecf20Sopenharmony_ci if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) { 35508c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, VSTATUSVIT); 35518c2ecf20Sopenharmony_ci if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) { 35528c2ecf20Sopenharmony_ci *status |= FE_HAS_VITERBI; 35538c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, TSSTATUS); 35548c2ecf20Sopenharmony_ci if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) 35558c2ecf20Sopenharmony_ci *status |= FE_HAS_SYNC | FE_HAS_LOCK; 35568c2ecf20Sopenharmony_ci } 35578c2ecf20Sopenharmony_ci } 35588c2ecf20Sopenharmony_ci break; 35598c2ecf20Sopenharmony_ci } 35608c2ecf20Sopenharmony_ci 35618c2ecf20Sopenharmony_ci return 0; 35628c2ecf20Sopenharmony_ci} 35638c2ecf20Sopenharmony_ci 35648c2ecf20Sopenharmony_cistatic int stv090x_read_per(struct dvb_frontend *fe, u32 *per) 35658c2ecf20Sopenharmony_ci{ 35668c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 35678c2ecf20Sopenharmony_ci 35688c2ecf20Sopenharmony_ci s32 count_4, count_3, count_2, count_1, count_0, count; 35698c2ecf20Sopenharmony_ci u32 reg, h, m, l; 35708c2ecf20Sopenharmony_ci enum fe_status status; 35718c2ecf20Sopenharmony_ci 35728c2ecf20Sopenharmony_ci stv090x_read_status(fe, &status); 35738c2ecf20Sopenharmony_ci if (!(status & FE_HAS_LOCK)) { 35748c2ecf20Sopenharmony_ci *per = 1 << 23; /* Max PER */ 35758c2ecf20Sopenharmony_ci } else { 35768c2ecf20Sopenharmony_ci /* Counter 2 */ 35778c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, ERRCNT22); 35788c2ecf20Sopenharmony_ci h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD); 35798c2ecf20Sopenharmony_ci 35808c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, ERRCNT21); 35818c2ecf20Sopenharmony_ci m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD); 35828c2ecf20Sopenharmony_ci 35838c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, ERRCNT20); 35848c2ecf20Sopenharmony_ci l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD); 35858c2ecf20Sopenharmony_ci 35868c2ecf20Sopenharmony_ci *per = ((h << 16) | (m << 8) | l); 35878c2ecf20Sopenharmony_ci 35888c2ecf20Sopenharmony_ci count_4 = STV090x_READ_DEMOD(state, FBERCPT4); 35898c2ecf20Sopenharmony_ci count_3 = STV090x_READ_DEMOD(state, FBERCPT3); 35908c2ecf20Sopenharmony_ci count_2 = STV090x_READ_DEMOD(state, FBERCPT2); 35918c2ecf20Sopenharmony_ci count_1 = STV090x_READ_DEMOD(state, FBERCPT1); 35928c2ecf20Sopenharmony_ci count_0 = STV090x_READ_DEMOD(state, FBERCPT0); 35938c2ecf20Sopenharmony_ci 35948c2ecf20Sopenharmony_ci if ((!count_4) && (!count_3)) { 35958c2ecf20Sopenharmony_ci count = (count_2 & 0xff) << 16; 35968c2ecf20Sopenharmony_ci count |= (count_1 & 0xff) << 8; 35978c2ecf20Sopenharmony_ci count |= count_0 & 0xff; 35988c2ecf20Sopenharmony_ci } else { 35998c2ecf20Sopenharmony_ci count = 1 << 24; 36008c2ecf20Sopenharmony_ci } 36018c2ecf20Sopenharmony_ci if (count == 0) 36028c2ecf20Sopenharmony_ci *per = 1; 36038c2ecf20Sopenharmony_ci } 36048c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0) < 0) 36058c2ecf20Sopenharmony_ci goto err; 36068c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0) 36078c2ecf20Sopenharmony_ci goto err; 36088c2ecf20Sopenharmony_ci 36098c2ecf20Sopenharmony_ci return 0; 36108c2ecf20Sopenharmony_cierr: 36118c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 36128c2ecf20Sopenharmony_ci return -1; 36138c2ecf20Sopenharmony_ci} 36148c2ecf20Sopenharmony_ci 36158c2ecf20Sopenharmony_cistatic int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val) 36168c2ecf20Sopenharmony_ci{ 36178c2ecf20Sopenharmony_ci int res = 0; 36188c2ecf20Sopenharmony_ci int min = 0, med; 36198c2ecf20Sopenharmony_ci 36208c2ecf20Sopenharmony_ci if ((val >= tab[min].read && val < tab[max].read) || 36218c2ecf20Sopenharmony_ci (val >= tab[max].read && val < tab[min].read)) { 36228c2ecf20Sopenharmony_ci while ((max - min) > 1) { 36238c2ecf20Sopenharmony_ci med = (max + min) / 2; 36248c2ecf20Sopenharmony_ci if ((val >= tab[min].read && val < tab[med].read) || 36258c2ecf20Sopenharmony_ci (val >= tab[med].read && val < tab[min].read)) 36268c2ecf20Sopenharmony_ci max = med; 36278c2ecf20Sopenharmony_ci else 36288c2ecf20Sopenharmony_ci min = med; 36298c2ecf20Sopenharmony_ci } 36308c2ecf20Sopenharmony_ci res = ((val - tab[min].read) * 36318c2ecf20Sopenharmony_ci (tab[max].real - tab[min].real) / 36328c2ecf20Sopenharmony_ci (tab[max].read - tab[min].read)) + 36338c2ecf20Sopenharmony_ci tab[min].real; 36348c2ecf20Sopenharmony_ci } else { 36358c2ecf20Sopenharmony_ci if (tab[min].read < tab[max].read) { 36368c2ecf20Sopenharmony_ci if (val < tab[min].read) 36378c2ecf20Sopenharmony_ci res = tab[min].real; 36388c2ecf20Sopenharmony_ci else if (val >= tab[max].read) 36398c2ecf20Sopenharmony_ci res = tab[max].real; 36408c2ecf20Sopenharmony_ci } else { 36418c2ecf20Sopenharmony_ci if (val >= tab[min].read) 36428c2ecf20Sopenharmony_ci res = tab[min].real; 36438c2ecf20Sopenharmony_ci else if (val < tab[max].read) 36448c2ecf20Sopenharmony_ci res = tab[max].real; 36458c2ecf20Sopenharmony_ci } 36468c2ecf20Sopenharmony_ci } 36478c2ecf20Sopenharmony_ci 36488c2ecf20Sopenharmony_ci return res; 36498c2ecf20Sopenharmony_ci} 36508c2ecf20Sopenharmony_ci 36518c2ecf20Sopenharmony_cistatic int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 36528c2ecf20Sopenharmony_ci{ 36538c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 36548c2ecf20Sopenharmony_ci u32 reg; 36558c2ecf20Sopenharmony_ci s32 agc_0, agc_1, agc; 36568c2ecf20Sopenharmony_ci s32 str; 36578c2ecf20Sopenharmony_ci 36588c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, AGCIQIN1); 36598c2ecf20Sopenharmony_ci agc_1 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); 36608c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, AGCIQIN0); 36618c2ecf20Sopenharmony_ci agc_0 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD); 36628c2ecf20Sopenharmony_ci agc = MAKEWORD16(agc_1, agc_0); 36638c2ecf20Sopenharmony_ci 36648c2ecf20Sopenharmony_ci str = stv090x_table_lookup(stv090x_rf_tab, 36658c2ecf20Sopenharmony_ci ARRAY_SIZE(stv090x_rf_tab) - 1, agc); 36668c2ecf20Sopenharmony_ci if (agc > stv090x_rf_tab[0].read) 36678c2ecf20Sopenharmony_ci str = 0; 36688c2ecf20Sopenharmony_ci else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read) 36698c2ecf20Sopenharmony_ci str = -100; 36708c2ecf20Sopenharmony_ci *strength = (str + 100) * 0xFFFF / 100; 36718c2ecf20Sopenharmony_ci 36728c2ecf20Sopenharmony_ci return 0; 36738c2ecf20Sopenharmony_ci} 36748c2ecf20Sopenharmony_ci 36758c2ecf20Sopenharmony_cistatic int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) 36768c2ecf20Sopenharmony_ci{ 36778c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 36788c2ecf20Sopenharmony_ci u32 reg_0, reg_1, reg, i; 36798c2ecf20Sopenharmony_ci s32 val_0, val_1, val = 0; 36808c2ecf20Sopenharmony_ci u8 lock_f; 36818c2ecf20Sopenharmony_ci s32 div; 36828c2ecf20Sopenharmony_ci u32 last; 36838c2ecf20Sopenharmony_ci 36848c2ecf20Sopenharmony_ci switch (state->delsys) { 36858c2ecf20Sopenharmony_ci case STV090x_DVBS2: 36868c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DSTATUS); 36878c2ecf20Sopenharmony_ci lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD); 36888c2ecf20Sopenharmony_ci if (lock_f) { 36898c2ecf20Sopenharmony_ci msleep(5); 36908c2ecf20Sopenharmony_ci for (i = 0; i < 16; i++) { 36918c2ecf20Sopenharmony_ci reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1); 36928c2ecf20Sopenharmony_ci val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD); 36938c2ecf20Sopenharmony_ci reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0); 36948c2ecf20Sopenharmony_ci val_0 = STV090x_GETFIELD_Px(reg_0, NOSPLHT_NORMED_FIELD); 36958c2ecf20Sopenharmony_ci val += MAKEWORD16(val_1, val_0); 36968c2ecf20Sopenharmony_ci msleep(1); 36978c2ecf20Sopenharmony_ci } 36988c2ecf20Sopenharmony_ci val /= 16; 36998c2ecf20Sopenharmony_ci last = ARRAY_SIZE(stv090x_s2cn_tab) - 1; 37008c2ecf20Sopenharmony_ci div = stv090x_s2cn_tab[last].real - 37018c2ecf20Sopenharmony_ci stv090x_s2cn_tab[3].real; 37028c2ecf20Sopenharmony_ci val = stv090x_table_lookup(stv090x_s2cn_tab, last, val); 37038c2ecf20Sopenharmony_ci if (val < 0) 37048c2ecf20Sopenharmony_ci val = 0; 37058c2ecf20Sopenharmony_ci *cnr = val * 0xFFFF / div; 37068c2ecf20Sopenharmony_ci } 37078c2ecf20Sopenharmony_ci break; 37088c2ecf20Sopenharmony_ci 37098c2ecf20Sopenharmony_ci case STV090x_DVBS1: 37108c2ecf20Sopenharmony_ci case STV090x_DSS: 37118c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DSTATUS); 37128c2ecf20Sopenharmony_ci lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD); 37138c2ecf20Sopenharmony_ci if (lock_f) { 37148c2ecf20Sopenharmony_ci msleep(5); 37158c2ecf20Sopenharmony_ci for (i = 0; i < 16; i++) { 37168c2ecf20Sopenharmony_ci reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1); 37178c2ecf20Sopenharmony_ci val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD); 37188c2ecf20Sopenharmony_ci reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0); 37198c2ecf20Sopenharmony_ci val_0 = STV090x_GETFIELD_Px(reg_0, NOSDATAT_UNNORMED_FIELD); 37208c2ecf20Sopenharmony_ci val += MAKEWORD16(val_1, val_0); 37218c2ecf20Sopenharmony_ci msleep(1); 37228c2ecf20Sopenharmony_ci } 37238c2ecf20Sopenharmony_ci val /= 16; 37248c2ecf20Sopenharmony_ci last = ARRAY_SIZE(stv090x_s1cn_tab) - 1; 37258c2ecf20Sopenharmony_ci div = stv090x_s1cn_tab[last].real - 37268c2ecf20Sopenharmony_ci stv090x_s1cn_tab[0].real; 37278c2ecf20Sopenharmony_ci val = stv090x_table_lookup(stv090x_s1cn_tab, last, val); 37288c2ecf20Sopenharmony_ci *cnr = val * 0xFFFF / div; 37298c2ecf20Sopenharmony_ci } 37308c2ecf20Sopenharmony_ci break; 37318c2ecf20Sopenharmony_ci default: 37328c2ecf20Sopenharmony_ci break; 37338c2ecf20Sopenharmony_ci } 37348c2ecf20Sopenharmony_ci 37358c2ecf20Sopenharmony_ci return 0; 37368c2ecf20Sopenharmony_ci} 37378c2ecf20Sopenharmony_ci 37388c2ecf20Sopenharmony_cistatic int stv090x_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) 37398c2ecf20Sopenharmony_ci{ 37408c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 37418c2ecf20Sopenharmony_ci u32 reg; 37428c2ecf20Sopenharmony_ci 37438c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DISTXCTL); 37448c2ecf20Sopenharmony_ci switch (tone) { 37458c2ecf20Sopenharmony_ci case SEC_TONE_ON: 37468c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0); 37478c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); 37488c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) 37498c2ecf20Sopenharmony_ci goto err; 37508c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0); 37518c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) 37528c2ecf20Sopenharmony_ci goto err; 37538c2ecf20Sopenharmony_ci break; 37548c2ecf20Sopenharmony_ci 37558c2ecf20Sopenharmony_ci case SEC_TONE_OFF: 37568c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0); 37578c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); 37588c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) 37598c2ecf20Sopenharmony_ci goto err; 37608c2ecf20Sopenharmony_ci break; 37618c2ecf20Sopenharmony_ci default: 37628c2ecf20Sopenharmony_ci return -EINVAL; 37638c2ecf20Sopenharmony_ci } 37648c2ecf20Sopenharmony_ci 37658c2ecf20Sopenharmony_ci return 0; 37668c2ecf20Sopenharmony_cierr: 37678c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 37688c2ecf20Sopenharmony_ci return -1; 37698c2ecf20Sopenharmony_ci} 37708c2ecf20Sopenharmony_ci 37718c2ecf20Sopenharmony_ci 37728c2ecf20Sopenharmony_cistatic enum dvbfe_algo stv090x_frontend_algo(struct dvb_frontend *fe) 37738c2ecf20Sopenharmony_ci{ 37748c2ecf20Sopenharmony_ci return DVBFE_ALGO_CUSTOM; 37758c2ecf20Sopenharmony_ci} 37768c2ecf20Sopenharmony_ci 37778c2ecf20Sopenharmony_cistatic int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) 37788c2ecf20Sopenharmony_ci{ 37798c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 37808c2ecf20Sopenharmony_ci u32 reg, idle = 0, fifo_full = 1; 37818c2ecf20Sopenharmony_ci int i; 37828c2ecf20Sopenharmony_ci 37838c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DISTXCTL); 37848c2ecf20Sopenharmony_ci 37858c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 37868c2ecf20Sopenharmony_ci (state->config->diseqc_envelope_mode) ? 4 : 2); 37878c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); 37888c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) 37898c2ecf20Sopenharmony_ci goto err; 37908c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0); 37918c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) 37928c2ecf20Sopenharmony_ci goto err; 37938c2ecf20Sopenharmony_ci 37948c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1); 37958c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) 37968c2ecf20Sopenharmony_ci goto err; 37978c2ecf20Sopenharmony_ci 37988c2ecf20Sopenharmony_ci for (i = 0; i < cmd->msg_len; i++) { 37998c2ecf20Sopenharmony_ci 38008c2ecf20Sopenharmony_ci while (fifo_full) { 38018c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DISTXSTATUS); 38028c2ecf20Sopenharmony_ci fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD); 38038c2ecf20Sopenharmony_ci } 38048c2ecf20Sopenharmony_ci 38058c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXDATA, cmd->msg[i]) < 0) 38068c2ecf20Sopenharmony_ci goto err; 38078c2ecf20Sopenharmony_ci } 38088c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DISTXCTL); 38098c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0); 38108c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) 38118c2ecf20Sopenharmony_ci goto err; 38128c2ecf20Sopenharmony_ci 38138c2ecf20Sopenharmony_ci i = 0; 38148c2ecf20Sopenharmony_ci 38158c2ecf20Sopenharmony_ci while ((!idle) && (i < 10)) { 38168c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DISTXSTATUS); 38178c2ecf20Sopenharmony_ci idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD); 38188c2ecf20Sopenharmony_ci msleep(10); 38198c2ecf20Sopenharmony_ci i++; 38208c2ecf20Sopenharmony_ci } 38218c2ecf20Sopenharmony_ci 38228c2ecf20Sopenharmony_ci return 0; 38238c2ecf20Sopenharmony_cierr: 38248c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 38258c2ecf20Sopenharmony_ci return -1; 38268c2ecf20Sopenharmony_ci} 38278c2ecf20Sopenharmony_ci 38288c2ecf20Sopenharmony_cistatic int stv090x_send_diseqc_burst(struct dvb_frontend *fe, 38298c2ecf20Sopenharmony_ci enum fe_sec_mini_cmd burst) 38308c2ecf20Sopenharmony_ci{ 38318c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 38328c2ecf20Sopenharmony_ci u32 reg, idle = 0, fifo_full = 1; 38338c2ecf20Sopenharmony_ci u8 mode, value; 38348c2ecf20Sopenharmony_ci int i; 38358c2ecf20Sopenharmony_ci 38368c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DISTXCTL); 38378c2ecf20Sopenharmony_ci 38388c2ecf20Sopenharmony_ci if (burst == SEC_MINI_A) { 38398c2ecf20Sopenharmony_ci mode = (state->config->diseqc_envelope_mode) ? 5 : 3; 38408c2ecf20Sopenharmony_ci value = 0x00; 38418c2ecf20Sopenharmony_ci } else { 38428c2ecf20Sopenharmony_ci mode = (state->config->diseqc_envelope_mode) ? 4 : 2; 38438c2ecf20Sopenharmony_ci value = 0xFF; 38448c2ecf20Sopenharmony_ci } 38458c2ecf20Sopenharmony_ci 38468c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, mode); 38478c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1); 38488c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) 38498c2ecf20Sopenharmony_ci goto err; 38508c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0); 38518c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) 38528c2ecf20Sopenharmony_ci goto err; 38538c2ecf20Sopenharmony_ci 38548c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1); 38558c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) 38568c2ecf20Sopenharmony_ci goto err; 38578c2ecf20Sopenharmony_ci 38588c2ecf20Sopenharmony_ci while (fifo_full) { 38598c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DISTXSTATUS); 38608c2ecf20Sopenharmony_ci fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD); 38618c2ecf20Sopenharmony_ci } 38628c2ecf20Sopenharmony_ci 38638c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXDATA, value) < 0) 38648c2ecf20Sopenharmony_ci goto err; 38658c2ecf20Sopenharmony_ci 38668c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DISTXCTL); 38678c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0); 38688c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0) 38698c2ecf20Sopenharmony_ci goto err; 38708c2ecf20Sopenharmony_ci 38718c2ecf20Sopenharmony_ci i = 0; 38728c2ecf20Sopenharmony_ci 38738c2ecf20Sopenharmony_ci while ((!idle) && (i < 10)) { 38748c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DISTXSTATUS); 38758c2ecf20Sopenharmony_ci idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD); 38768c2ecf20Sopenharmony_ci msleep(10); 38778c2ecf20Sopenharmony_ci i++; 38788c2ecf20Sopenharmony_ci } 38798c2ecf20Sopenharmony_ci 38808c2ecf20Sopenharmony_ci return 0; 38818c2ecf20Sopenharmony_cierr: 38828c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 38838c2ecf20Sopenharmony_ci return -1; 38848c2ecf20Sopenharmony_ci} 38858c2ecf20Sopenharmony_ci 38868c2ecf20Sopenharmony_cistatic int stv090x_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply) 38878c2ecf20Sopenharmony_ci{ 38888c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 38898c2ecf20Sopenharmony_ci u32 reg = 0, i = 0, rx_end = 0; 38908c2ecf20Sopenharmony_ci 38918c2ecf20Sopenharmony_ci while ((rx_end != 1) && (i < 10)) { 38928c2ecf20Sopenharmony_ci msleep(10); 38938c2ecf20Sopenharmony_ci i++; 38948c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DISRX_ST0); 38958c2ecf20Sopenharmony_ci rx_end = STV090x_GETFIELD_Px(reg, RX_END_FIELD); 38968c2ecf20Sopenharmony_ci } 38978c2ecf20Sopenharmony_ci 38988c2ecf20Sopenharmony_ci if (rx_end) { 38998c2ecf20Sopenharmony_ci reply->msg_len = STV090x_GETFIELD_Px(reg, FIFO_BYTENBR_FIELD); 39008c2ecf20Sopenharmony_ci for (i = 0; i < reply->msg_len; i++) 39018c2ecf20Sopenharmony_ci reply->msg[i] = STV090x_READ_DEMOD(state, DISRXDATA); 39028c2ecf20Sopenharmony_ci } 39038c2ecf20Sopenharmony_ci 39048c2ecf20Sopenharmony_ci return 0; 39058c2ecf20Sopenharmony_ci} 39068c2ecf20Sopenharmony_ci 39078c2ecf20Sopenharmony_cistatic int stv090x_sleep(struct dvb_frontend *fe) 39088c2ecf20Sopenharmony_ci{ 39098c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 39108c2ecf20Sopenharmony_ci u32 reg; 39118c2ecf20Sopenharmony_ci u8 full_standby = 0; 39128c2ecf20Sopenharmony_ci 39138c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 39148c2ecf20Sopenharmony_ci goto err; 39158c2ecf20Sopenharmony_ci 39168c2ecf20Sopenharmony_ci if (state->config->tuner_sleep) { 39178c2ecf20Sopenharmony_ci if (state->config->tuner_sleep(fe) < 0) 39188c2ecf20Sopenharmony_ci goto err_gateoff; 39198c2ecf20Sopenharmony_ci } 39208c2ecf20Sopenharmony_ci 39218c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 39228c2ecf20Sopenharmony_ci goto err; 39238c2ecf20Sopenharmony_ci 39248c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Set %s(%d) to sleep", 39258c2ecf20Sopenharmony_ci state->device == STV0900 ? "STV0900" : "STV0903", 39268c2ecf20Sopenharmony_ci state->demod); 39278c2ecf20Sopenharmony_ci 39288c2ecf20Sopenharmony_ci mutex_lock(&state->internal->demod_lock); 39298c2ecf20Sopenharmony_ci 39308c2ecf20Sopenharmony_ci switch (state->demod) { 39318c2ecf20Sopenharmony_ci case STV090x_DEMODULATOR_0: 39328c2ecf20Sopenharmony_ci /* power off ADC 1 */ 39338c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR1); 39348c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); 39358c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 39368c2ecf20Sopenharmony_ci goto err_unlock; 39378c2ecf20Sopenharmony_ci /* power off DiSEqC 1 */ 39388c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR2); 39398c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0); 39408c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0) 39418c2ecf20Sopenharmony_ci goto err_unlock; 39428c2ecf20Sopenharmony_ci 39438c2ecf20Sopenharmony_ci /* check whether path 2 is already sleeping, that is when 39448c2ecf20Sopenharmony_ci ADC2 is off */ 39458c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR3); 39468c2ecf20Sopenharmony_ci if (STV090x_GETFIELD(reg, ADC2_PON_FIELD) == 0) 39478c2ecf20Sopenharmony_ci full_standby = 1; 39488c2ecf20Sopenharmony_ci 39498c2ecf20Sopenharmony_ci /* stop clocks */ 39508c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_STOPCLK1); 39518c2ecf20Sopenharmony_ci /* packet delineator 1 clock */ 39528c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 1); 39538c2ecf20Sopenharmony_ci /* ADC 1 clock */ 39548c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 1); 39558c2ecf20Sopenharmony_ci /* FEC clock is shared between the two paths, only stop it 39568c2ecf20Sopenharmony_ci when full standby is possible */ 39578c2ecf20Sopenharmony_ci if (full_standby) 39588c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); 39598c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) 39608c2ecf20Sopenharmony_ci goto err_unlock; 39618c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_STOPCLK2); 39628c2ecf20Sopenharmony_ci /* sampling 1 clock */ 39638c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1); 39648c2ecf20Sopenharmony_ci /* viterbi 1 clock */ 39658c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 1); 39668c2ecf20Sopenharmony_ci /* TS clock is shared between the two paths, only stop it 39678c2ecf20Sopenharmony_ci when full standby is possible */ 39688c2ecf20Sopenharmony_ci if (full_standby) 39698c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); 39708c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 39718c2ecf20Sopenharmony_ci goto err_unlock; 39728c2ecf20Sopenharmony_ci break; 39738c2ecf20Sopenharmony_ci 39748c2ecf20Sopenharmony_ci case STV090x_DEMODULATOR_1: 39758c2ecf20Sopenharmony_ci /* power off ADC 2 */ 39768c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR3); 39778c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0); 39788c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0) 39798c2ecf20Sopenharmony_ci goto err_unlock; 39808c2ecf20Sopenharmony_ci /* power off DiSEqC 2 */ 39818c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR4); 39828c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0); 39838c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0) 39848c2ecf20Sopenharmony_ci goto err_unlock; 39858c2ecf20Sopenharmony_ci 39868c2ecf20Sopenharmony_ci /* check whether path 1 is already sleeping, that is when 39878c2ecf20Sopenharmony_ci ADC1 is off */ 39888c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR1); 39898c2ecf20Sopenharmony_ci if (STV090x_GETFIELD(reg, ADC1_PON_FIELD) == 0) 39908c2ecf20Sopenharmony_ci full_standby = 1; 39918c2ecf20Sopenharmony_ci 39928c2ecf20Sopenharmony_ci /* stop clocks */ 39938c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_STOPCLK1); 39948c2ecf20Sopenharmony_ci /* packet delineator 2 clock */ 39958c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 1); 39968c2ecf20Sopenharmony_ci /* ADC 2 clock */ 39978c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 1); 39988c2ecf20Sopenharmony_ci /* FEC clock is shared between the two paths, only stop it 39998c2ecf20Sopenharmony_ci when full standby is possible */ 40008c2ecf20Sopenharmony_ci if (full_standby) 40018c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); 40028c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) 40038c2ecf20Sopenharmony_ci goto err_unlock; 40048c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_STOPCLK2); 40058c2ecf20Sopenharmony_ci /* sampling 2 clock */ 40068c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1); 40078c2ecf20Sopenharmony_ci /* viterbi 2 clock */ 40088c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 1); 40098c2ecf20Sopenharmony_ci /* TS clock is shared between the two paths, only stop it 40108c2ecf20Sopenharmony_ci when full standby is possible */ 40118c2ecf20Sopenharmony_ci if (full_standby) 40128c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); 40138c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 40148c2ecf20Sopenharmony_ci goto err_unlock; 40158c2ecf20Sopenharmony_ci break; 40168c2ecf20Sopenharmony_ci 40178c2ecf20Sopenharmony_ci default: 40188c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "Wrong demodulator!"); 40198c2ecf20Sopenharmony_ci break; 40208c2ecf20Sopenharmony_ci } 40218c2ecf20Sopenharmony_ci 40228c2ecf20Sopenharmony_ci if (full_standby) { 40238c2ecf20Sopenharmony_ci /* general power off */ 40248c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 40258c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01); 40268c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) 40278c2ecf20Sopenharmony_ci goto err_unlock; 40288c2ecf20Sopenharmony_ci } 40298c2ecf20Sopenharmony_ci 40308c2ecf20Sopenharmony_ci mutex_unlock(&state->internal->demod_lock); 40318c2ecf20Sopenharmony_ci return 0; 40328c2ecf20Sopenharmony_ci 40338c2ecf20Sopenharmony_cierr_gateoff: 40348c2ecf20Sopenharmony_ci stv090x_i2c_gate_ctrl(state, 0); 40358c2ecf20Sopenharmony_ci goto err; 40368c2ecf20Sopenharmony_cierr_unlock: 40378c2ecf20Sopenharmony_ci mutex_unlock(&state->internal->demod_lock); 40388c2ecf20Sopenharmony_cierr: 40398c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 40408c2ecf20Sopenharmony_ci return -1; 40418c2ecf20Sopenharmony_ci} 40428c2ecf20Sopenharmony_ci 40438c2ecf20Sopenharmony_cistatic int stv090x_wakeup(struct dvb_frontend *fe) 40448c2ecf20Sopenharmony_ci{ 40458c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 40468c2ecf20Sopenharmony_ci u32 reg; 40478c2ecf20Sopenharmony_ci 40488c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Wake %s(%d) from standby", 40498c2ecf20Sopenharmony_ci state->device == STV0900 ? "STV0900" : "STV0903", 40508c2ecf20Sopenharmony_ci state->demod); 40518c2ecf20Sopenharmony_ci 40528c2ecf20Sopenharmony_ci mutex_lock(&state->internal->demod_lock); 40538c2ecf20Sopenharmony_ci 40548c2ecf20Sopenharmony_ci /* general power on */ 40558c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 40568c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00); 40578c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) 40588c2ecf20Sopenharmony_ci goto err; 40598c2ecf20Sopenharmony_ci 40608c2ecf20Sopenharmony_ci switch (state->demod) { 40618c2ecf20Sopenharmony_ci case STV090x_DEMODULATOR_0: 40628c2ecf20Sopenharmony_ci /* power on ADC 1 */ 40638c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR1); 40648c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1); 40658c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 40668c2ecf20Sopenharmony_ci goto err; 40678c2ecf20Sopenharmony_ci /* power on DiSEqC 1 */ 40688c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR2); 40698c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 1); 40708c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0) 40718c2ecf20Sopenharmony_ci goto err; 40728c2ecf20Sopenharmony_ci 40738c2ecf20Sopenharmony_ci /* activate clocks */ 40748c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_STOPCLK1); 40758c2ecf20Sopenharmony_ci /* packet delineator 1 clock */ 40768c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 0); 40778c2ecf20Sopenharmony_ci /* ADC 1 clock */ 40788c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 0); 40798c2ecf20Sopenharmony_ci /* FEC clock */ 40808c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0); 40818c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) 40828c2ecf20Sopenharmony_ci goto err; 40838c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_STOPCLK2); 40848c2ecf20Sopenharmony_ci /* sampling 1 clock */ 40858c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 0); 40868c2ecf20Sopenharmony_ci /* viterbi 1 clock */ 40878c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 0); 40888c2ecf20Sopenharmony_ci /* TS clock */ 40898c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0); 40908c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 40918c2ecf20Sopenharmony_ci goto err; 40928c2ecf20Sopenharmony_ci break; 40938c2ecf20Sopenharmony_ci 40948c2ecf20Sopenharmony_ci case STV090x_DEMODULATOR_1: 40958c2ecf20Sopenharmony_ci /* power on ADC 2 */ 40968c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR3); 40978c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, ADC2_PON_FIELD, 1); 40988c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0) 40998c2ecf20Sopenharmony_ci goto err; 41008c2ecf20Sopenharmony_ci /* power on DiSEqC 2 */ 41018c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR4); 41028c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 1); 41038c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0) 41048c2ecf20Sopenharmony_ci goto err; 41058c2ecf20Sopenharmony_ci 41068c2ecf20Sopenharmony_ci /* activate clocks */ 41078c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_STOPCLK1); 41088c2ecf20Sopenharmony_ci /* packet delineator 2 clock */ 41098c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 0); 41108c2ecf20Sopenharmony_ci /* ADC 2 clock */ 41118c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 0); 41128c2ecf20Sopenharmony_ci /* FEC clock */ 41138c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0); 41148c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) 41158c2ecf20Sopenharmony_ci goto err; 41168c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_STOPCLK2); 41178c2ecf20Sopenharmony_ci /* sampling 2 clock */ 41188c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 0); 41198c2ecf20Sopenharmony_ci /* viterbi 2 clock */ 41208c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 0); 41218c2ecf20Sopenharmony_ci /* TS clock */ 41228c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0); 41238c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) 41248c2ecf20Sopenharmony_ci goto err; 41258c2ecf20Sopenharmony_ci break; 41268c2ecf20Sopenharmony_ci 41278c2ecf20Sopenharmony_ci default: 41288c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "Wrong demodulator!"); 41298c2ecf20Sopenharmony_ci break; 41308c2ecf20Sopenharmony_ci } 41318c2ecf20Sopenharmony_ci 41328c2ecf20Sopenharmony_ci mutex_unlock(&state->internal->demod_lock); 41338c2ecf20Sopenharmony_ci return 0; 41348c2ecf20Sopenharmony_cierr: 41358c2ecf20Sopenharmony_ci mutex_unlock(&state->internal->demod_lock); 41368c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 41378c2ecf20Sopenharmony_ci return -1; 41388c2ecf20Sopenharmony_ci} 41398c2ecf20Sopenharmony_ci 41408c2ecf20Sopenharmony_cistatic void stv090x_release(struct dvb_frontend *fe) 41418c2ecf20Sopenharmony_ci{ 41428c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 41438c2ecf20Sopenharmony_ci 41448c2ecf20Sopenharmony_ci state->internal->num_used--; 41458c2ecf20Sopenharmony_ci if (state->internal->num_used <= 0) { 41468c2ecf20Sopenharmony_ci 41478c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "Actually removing"); 41488c2ecf20Sopenharmony_ci 41498c2ecf20Sopenharmony_ci remove_dev(state->internal); 41508c2ecf20Sopenharmony_ci kfree(state->internal); 41518c2ecf20Sopenharmony_ci } 41528c2ecf20Sopenharmony_ci 41538c2ecf20Sopenharmony_ci kfree(state); 41548c2ecf20Sopenharmony_ci} 41558c2ecf20Sopenharmony_ci 41568c2ecf20Sopenharmony_cistatic int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc_mode) 41578c2ecf20Sopenharmony_ci{ 41588c2ecf20Sopenharmony_ci u32 reg = 0; 41598c2ecf20Sopenharmony_ci 41608c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_GENCFG); 41618c2ecf20Sopenharmony_ci 41628c2ecf20Sopenharmony_ci switch (ldpc_mode) { 41638c2ecf20Sopenharmony_ci case STV090x_DUAL: 41648c2ecf20Sopenharmony_ci default: 41658c2ecf20Sopenharmony_ci if ((state->demod_mode != STV090x_DUAL) || (STV090x_GETFIELD(reg, DDEMOD_FIELD) != 1)) { 41668c2ecf20Sopenharmony_ci /* set LDPC to dual mode */ 41678c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_GENCFG, 0x1d) < 0) 41688c2ecf20Sopenharmony_ci goto err; 41698c2ecf20Sopenharmony_ci 41708c2ecf20Sopenharmony_ci state->demod_mode = STV090x_DUAL; 41718c2ecf20Sopenharmony_ci 41728c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTRES0); 41738c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1); 41748c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) 41758c2ecf20Sopenharmony_ci goto err; 41768c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0); 41778c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) 41788c2ecf20Sopenharmony_ci goto err; 41798c2ecf20Sopenharmony_ci 41808c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0) 41818c2ecf20Sopenharmony_ci goto err; 41828c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0) 41838c2ecf20Sopenharmony_ci goto err; 41848c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0) 41858c2ecf20Sopenharmony_ci goto err; 41868c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0) 41878c2ecf20Sopenharmony_ci goto err; 41888c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0) 41898c2ecf20Sopenharmony_ci goto err; 41908c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0) 41918c2ecf20Sopenharmony_ci goto err; 41928c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0) 41938c2ecf20Sopenharmony_ci goto err; 41948c2ecf20Sopenharmony_ci 41958c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0) 41968c2ecf20Sopenharmony_ci goto err; 41978c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0) 41988c2ecf20Sopenharmony_ci goto err; 41998c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0) 42008c2ecf20Sopenharmony_ci goto err; 42018c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0) 42028c2ecf20Sopenharmony_ci goto err; 42038c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0) 42048c2ecf20Sopenharmony_ci goto err; 42058c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0) 42068c2ecf20Sopenharmony_ci goto err; 42078c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0) 42088c2ecf20Sopenharmony_ci goto err; 42098c2ecf20Sopenharmony_ci 42108c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0) 42118c2ecf20Sopenharmony_ci goto err; 42128c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0) 42138c2ecf20Sopenharmony_ci goto err; 42148c2ecf20Sopenharmony_ci } 42158c2ecf20Sopenharmony_ci break; 42168c2ecf20Sopenharmony_ci 42178c2ecf20Sopenharmony_ci case STV090x_SINGLE: 42188c2ecf20Sopenharmony_ci if (stv090x_stop_modcod(state) < 0) 42198c2ecf20Sopenharmony_ci goto err; 42208c2ecf20Sopenharmony_ci if (stv090x_activate_modcod_single(state) < 0) 42218c2ecf20Sopenharmony_ci goto err; 42228c2ecf20Sopenharmony_ci 42238c2ecf20Sopenharmony_ci if (state->demod == STV090x_DEMODULATOR_1) { 42248c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_GENCFG, 0x06) < 0) /* path 2 */ 42258c2ecf20Sopenharmony_ci goto err; 42268c2ecf20Sopenharmony_ci } else { 42278c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_GENCFG, 0x04) < 0) /* path 1 */ 42288c2ecf20Sopenharmony_ci goto err; 42298c2ecf20Sopenharmony_ci } 42308c2ecf20Sopenharmony_ci 42318c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTRES0); 42328c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1); 42338c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) 42348c2ecf20Sopenharmony_ci goto err; 42358c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0); 42368c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0) 42378c2ecf20Sopenharmony_ci goto err; 42388c2ecf20Sopenharmony_ci 42398c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, PDELCTRL1); 42408c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x01); 42418c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) 42428c2ecf20Sopenharmony_ci goto err; 42438c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x00); 42448c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) 42458c2ecf20Sopenharmony_ci goto err; 42468c2ecf20Sopenharmony_ci break; 42478c2ecf20Sopenharmony_ci } 42488c2ecf20Sopenharmony_ci 42498c2ecf20Sopenharmony_ci return 0; 42508c2ecf20Sopenharmony_cierr: 42518c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 42528c2ecf20Sopenharmony_ci return -1; 42538c2ecf20Sopenharmony_ci} 42548c2ecf20Sopenharmony_ci 42558c2ecf20Sopenharmony_ci/* return (Hz), clk in Hz*/ 42568c2ecf20Sopenharmony_cistatic u32 stv090x_get_mclk(struct stv090x_state *state) 42578c2ecf20Sopenharmony_ci{ 42588c2ecf20Sopenharmony_ci const struct stv090x_config *config = state->config; 42598c2ecf20Sopenharmony_ci u32 div, reg; 42608c2ecf20Sopenharmony_ci u8 ratio; 42618c2ecf20Sopenharmony_ci 42628c2ecf20Sopenharmony_ci div = stv090x_read_reg(state, STV090x_NCOARSE); 42638c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 42648c2ecf20Sopenharmony_ci ratio = STV090x_GETFIELD(reg, SELX1RATIO_FIELD) ? 4 : 6; 42658c2ecf20Sopenharmony_ci 42668c2ecf20Sopenharmony_ci return (div + 1) * config->xtal / ratio; /* kHz */ 42678c2ecf20Sopenharmony_ci} 42688c2ecf20Sopenharmony_ci 42698c2ecf20Sopenharmony_cistatic int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk) 42708c2ecf20Sopenharmony_ci{ 42718c2ecf20Sopenharmony_ci const struct stv090x_config *config = state->config; 42728c2ecf20Sopenharmony_ci u32 reg, div, clk_sel; 42738c2ecf20Sopenharmony_ci 42748c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 42758c2ecf20Sopenharmony_ci clk_sel = ((STV090x_GETFIELD(reg, SELX1RATIO_FIELD) == 1) ? 4 : 6); 42768c2ecf20Sopenharmony_ci 42778c2ecf20Sopenharmony_ci div = ((clk_sel * mclk) / config->xtal) - 1; 42788c2ecf20Sopenharmony_ci 42798c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_NCOARSE); 42808c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, M_DIV_FIELD, div); 42818c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0) 42828c2ecf20Sopenharmony_ci goto err; 42838c2ecf20Sopenharmony_ci 42848c2ecf20Sopenharmony_ci state->internal->mclk = stv090x_get_mclk(state); 42858c2ecf20Sopenharmony_ci 42868c2ecf20Sopenharmony_ci /*Set the DiseqC frequency to 22KHz */ 42878c2ecf20Sopenharmony_ci div = state->internal->mclk / 704000; 42888c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0) 42898c2ecf20Sopenharmony_ci goto err; 42908c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0) 42918c2ecf20Sopenharmony_ci goto err; 42928c2ecf20Sopenharmony_ci 42938c2ecf20Sopenharmony_ci return 0; 42948c2ecf20Sopenharmony_cierr: 42958c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 42968c2ecf20Sopenharmony_ci return -1; 42978c2ecf20Sopenharmony_ci} 42988c2ecf20Sopenharmony_ci 42998c2ecf20Sopenharmony_cistatic int stv0900_set_tspath(struct stv090x_state *state) 43008c2ecf20Sopenharmony_ci{ 43018c2ecf20Sopenharmony_ci u32 reg; 43028c2ecf20Sopenharmony_ci 43038c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 43048c2ecf20Sopenharmony_ci switch (state->config->ts1_mode) { 43058c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 43068c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 43078c2ecf20Sopenharmony_ci switch (state->config->ts2_mode) { 43088c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 43098c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 43108c2ecf20Sopenharmony_ci default: 43118c2ecf20Sopenharmony_ci stv090x_write_reg(state, STV090x_TSGENERAL, 0x00); 43128c2ecf20Sopenharmony_ci break; 43138c2ecf20Sopenharmony_ci 43148c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 43158c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 43168c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x06) < 0) /* Mux'd stream mode */ 43178c2ecf20Sopenharmony_ci goto err; 43188c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); 43198c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); 43208c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) 43218c2ecf20Sopenharmony_ci goto err; 43228c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P2_TSCFGM); 43238c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); 43248c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0) 43258c2ecf20Sopenharmony_ci goto err; 43268c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0) 43278c2ecf20Sopenharmony_ci goto err; 43288c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0) 43298c2ecf20Sopenharmony_ci goto err; 43308c2ecf20Sopenharmony_ci break; 43318c2ecf20Sopenharmony_ci } 43328c2ecf20Sopenharmony_ci break; 43338c2ecf20Sopenharmony_ci 43348c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 43358c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 43368c2ecf20Sopenharmony_ci default: 43378c2ecf20Sopenharmony_ci switch (state->config->ts2_mode) { 43388c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 43398c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 43408c2ecf20Sopenharmony_ci default: 43418c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) 43428c2ecf20Sopenharmony_ci goto err; 43438c2ecf20Sopenharmony_ci break; 43448c2ecf20Sopenharmony_ci 43458c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 43468c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 43478c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0a) < 0) 43488c2ecf20Sopenharmony_ci goto err; 43498c2ecf20Sopenharmony_ci break; 43508c2ecf20Sopenharmony_ci } 43518c2ecf20Sopenharmony_ci break; 43528c2ecf20Sopenharmony_ci } 43538c2ecf20Sopenharmony_ci } else { 43548c2ecf20Sopenharmony_ci switch (state->config->ts1_mode) { 43558c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 43568c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 43578c2ecf20Sopenharmony_ci switch (state->config->ts2_mode) { 43588c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 43598c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 43608c2ecf20Sopenharmony_ci default: 43618c2ecf20Sopenharmony_ci stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10); 43628c2ecf20Sopenharmony_ci break; 43638c2ecf20Sopenharmony_ci 43648c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 43658c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 43668c2ecf20Sopenharmony_ci stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x16); 43678c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); 43688c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); 43698c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) 43708c2ecf20Sopenharmony_ci goto err; 43718c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); 43728c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 0); 43738c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) 43748c2ecf20Sopenharmony_ci goto err; 43758c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0) 43768c2ecf20Sopenharmony_ci goto err; 43778c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0) 43788c2ecf20Sopenharmony_ci goto err; 43798c2ecf20Sopenharmony_ci break; 43808c2ecf20Sopenharmony_ci } 43818c2ecf20Sopenharmony_ci break; 43828c2ecf20Sopenharmony_ci 43838c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 43848c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 43858c2ecf20Sopenharmony_ci default: 43868c2ecf20Sopenharmony_ci switch (state->config->ts2_mode) { 43878c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 43888c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 43898c2ecf20Sopenharmony_ci default: 43908c2ecf20Sopenharmony_ci stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14); 43918c2ecf20Sopenharmony_ci break; 43928c2ecf20Sopenharmony_ci 43938c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 43948c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 43958c2ecf20Sopenharmony_ci stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x12); 43968c2ecf20Sopenharmony_ci break; 43978c2ecf20Sopenharmony_ci } 43988c2ecf20Sopenharmony_ci break; 43998c2ecf20Sopenharmony_ci } 44008c2ecf20Sopenharmony_ci } 44018c2ecf20Sopenharmony_ci 44028c2ecf20Sopenharmony_ci switch (state->config->ts1_mode) { 44038c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 44048c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 44058c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei); 44068c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 44078c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 44088c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 44098c2ecf20Sopenharmony_ci goto err; 44108c2ecf20Sopenharmony_ci break; 44118c2ecf20Sopenharmony_ci 44128c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 44138c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 44148c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei); 44158c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 44168c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 44178c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 44188c2ecf20Sopenharmony_ci goto err; 44198c2ecf20Sopenharmony_ci break; 44208c2ecf20Sopenharmony_ci 44218c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 44228c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 44238c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei); 44248c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 44258c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 44268c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 44278c2ecf20Sopenharmony_ci goto err; 44288c2ecf20Sopenharmony_ci break; 44298c2ecf20Sopenharmony_ci 44308c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 44318c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 44328c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei); 44338c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 44348c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 44358c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 44368c2ecf20Sopenharmony_ci goto err; 44378c2ecf20Sopenharmony_ci break; 44388c2ecf20Sopenharmony_ci 44398c2ecf20Sopenharmony_ci default: 44408c2ecf20Sopenharmony_ci break; 44418c2ecf20Sopenharmony_ci } 44428c2ecf20Sopenharmony_ci 44438c2ecf20Sopenharmony_ci switch (state->config->ts2_mode) { 44448c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 44458c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 44468c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei); 44478c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 44488c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 44498c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 44508c2ecf20Sopenharmony_ci goto err; 44518c2ecf20Sopenharmony_ci break; 44528c2ecf20Sopenharmony_ci 44538c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 44548c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 44558c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei); 44568c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 44578c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 44588c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 44598c2ecf20Sopenharmony_ci goto err; 44608c2ecf20Sopenharmony_ci break; 44618c2ecf20Sopenharmony_ci 44628c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 44638c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 44648c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei); 44658c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 44668c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 44678c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 44688c2ecf20Sopenharmony_ci goto err; 44698c2ecf20Sopenharmony_ci break; 44708c2ecf20Sopenharmony_ci 44718c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 44728c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 44738c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei); 44748c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 44758c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 44768c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 44778c2ecf20Sopenharmony_ci goto err; 44788c2ecf20Sopenharmony_ci break; 44798c2ecf20Sopenharmony_ci 44808c2ecf20Sopenharmony_ci default: 44818c2ecf20Sopenharmony_ci break; 44828c2ecf20Sopenharmony_ci } 44838c2ecf20Sopenharmony_ci 44848c2ecf20Sopenharmony_ci if (state->config->ts1_clk > 0) { 44858c2ecf20Sopenharmony_ci u32 speed; 44868c2ecf20Sopenharmony_ci 44878c2ecf20Sopenharmony_ci switch (state->config->ts1_mode) { 44888c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 44898c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 44908c2ecf20Sopenharmony_ci default: 44918c2ecf20Sopenharmony_ci speed = state->internal->mclk / 44928c2ecf20Sopenharmony_ci (state->config->ts1_clk / 4); 44938c2ecf20Sopenharmony_ci if (speed < 0x08) 44948c2ecf20Sopenharmony_ci speed = 0x08; 44958c2ecf20Sopenharmony_ci if (speed > 0xFF) 44968c2ecf20Sopenharmony_ci speed = 0xFF; 44978c2ecf20Sopenharmony_ci break; 44988c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 44998c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 45008c2ecf20Sopenharmony_ci speed = state->internal->mclk / 45018c2ecf20Sopenharmony_ci (state->config->ts1_clk / 32); 45028c2ecf20Sopenharmony_ci if (speed < 0x20) 45038c2ecf20Sopenharmony_ci speed = 0x20; 45048c2ecf20Sopenharmony_ci if (speed > 0xFF) 45058c2ecf20Sopenharmony_ci speed = 0xFF; 45068c2ecf20Sopenharmony_ci break; 45078c2ecf20Sopenharmony_ci } 45088c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); 45098c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); 45108c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) 45118c2ecf20Sopenharmony_ci goto err; 45128c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0) 45138c2ecf20Sopenharmony_ci goto err; 45148c2ecf20Sopenharmony_ci } 45158c2ecf20Sopenharmony_ci 45168c2ecf20Sopenharmony_ci if (state->config->ts2_clk > 0) { 45178c2ecf20Sopenharmony_ci u32 speed; 45188c2ecf20Sopenharmony_ci 45198c2ecf20Sopenharmony_ci switch (state->config->ts2_mode) { 45208c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 45218c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 45228c2ecf20Sopenharmony_ci default: 45238c2ecf20Sopenharmony_ci speed = state->internal->mclk / 45248c2ecf20Sopenharmony_ci (state->config->ts2_clk / 4); 45258c2ecf20Sopenharmony_ci if (speed < 0x08) 45268c2ecf20Sopenharmony_ci speed = 0x08; 45278c2ecf20Sopenharmony_ci if (speed > 0xFF) 45288c2ecf20Sopenharmony_ci speed = 0xFF; 45298c2ecf20Sopenharmony_ci break; 45308c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 45318c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 45328c2ecf20Sopenharmony_ci speed = state->internal->mclk / 45338c2ecf20Sopenharmony_ci (state->config->ts2_clk / 32); 45348c2ecf20Sopenharmony_ci if (speed < 0x20) 45358c2ecf20Sopenharmony_ci speed = 0x20; 45368c2ecf20Sopenharmony_ci if (speed > 0xFF) 45378c2ecf20Sopenharmony_ci speed = 0xFF; 45388c2ecf20Sopenharmony_ci break; 45398c2ecf20Sopenharmony_ci } 45408c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P2_TSCFGM); 45418c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); 45428c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0) 45438c2ecf20Sopenharmony_ci goto err; 45448c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TSSPEED, speed) < 0) 45458c2ecf20Sopenharmony_ci goto err; 45468c2ecf20Sopenharmony_ci } 45478c2ecf20Sopenharmony_ci 45488c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 45498c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); 45508c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 45518c2ecf20Sopenharmony_ci goto err; 45528c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00); 45538c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 45548c2ecf20Sopenharmony_ci goto err; 45558c2ecf20Sopenharmony_ci 45568c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 45578c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); 45588c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 45598c2ecf20Sopenharmony_ci goto err; 45608c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00); 45618c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 45628c2ecf20Sopenharmony_ci goto err; 45638c2ecf20Sopenharmony_ci 45648c2ecf20Sopenharmony_ci return 0; 45658c2ecf20Sopenharmony_cierr: 45668c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 45678c2ecf20Sopenharmony_ci return -1; 45688c2ecf20Sopenharmony_ci} 45698c2ecf20Sopenharmony_ci 45708c2ecf20Sopenharmony_cistatic int stv0903_set_tspath(struct stv090x_state *state) 45718c2ecf20Sopenharmony_ci{ 45728c2ecf20Sopenharmony_ci u32 reg; 45738c2ecf20Sopenharmony_ci 45748c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 45758c2ecf20Sopenharmony_ci switch (state->config->ts1_mode) { 45768c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 45778c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 45788c2ecf20Sopenharmony_ci stv090x_write_reg(state, STV090x_TSGENERAL, 0x00); 45798c2ecf20Sopenharmony_ci break; 45808c2ecf20Sopenharmony_ci 45818c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 45828c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 45838c2ecf20Sopenharmony_ci default: 45848c2ecf20Sopenharmony_ci stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c); 45858c2ecf20Sopenharmony_ci break; 45868c2ecf20Sopenharmony_ci } 45878c2ecf20Sopenharmony_ci } else { 45888c2ecf20Sopenharmony_ci switch (state->config->ts1_mode) { 45898c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 45908c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 45918c2ecf20Sopenharmony_ci stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10); 45928c2ecf20Sopenharmony_ci break; 45938c2ecf20Sopenharmony_ci 45948c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 45958c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 45968c2ecf20Sopenharmony_ci default: 45978c2ecf20Sopenharmony_ci stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14); 45988c2ecf20Sopenharmony_ci break; 45998c2ecf20Sopenharmony_ci } 46008c2ecf20Sopenharmony_ci } 46018c2ecf20Sopenharmony_ci 46028c2ecf20Sopenharmony_ci switch (state->config->ts1_mode) { 46038c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 46048c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 46058c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 46068c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 46078c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 46088c2ecf20Sopenharmony_ci goto err; 46098c2ecf20Sopenharmony_ci break; 46108c2ecf20Sopenharmony_ci 46118c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 46128c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 46138c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 46148c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 46158c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 46168c2ecf20Sopenharmony_ci goto err; 46178c2ecf20Sopenharmony_ci break; 46188c2ecf20Sopenharmony_ci 46198c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 46208c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 46218c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 46228c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 46238c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 46248c2ecf20Sopenharmony_ci goto err; 46258c2ecf20Sopenharmony_ci break; 46268c2ecf20Sopenharmony_ci 46278c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 46288c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 46298c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 46308c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 46318c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 46328c2ecf20Sopenharmony_ci goto err; 46338c2ecf20Sopenharmony_ci break; 46348c2ecf20Sopenharmony_ci 46358c2ecf20Sopenharmony_ci default: 46368c2ecf20Sopenharmony_ci break; 46378c2ecf20Sopenharmony_ci } 46388c2ecf20Sopenharmony_ci 46398c2ecf20Sopenharmony_ci if (state->config->ts1_clk > 0) { 46408c2ecf20Sopenharmony_ci u32 speed; 46418c2ecf20Sopenharmony_ci 46428c2ecf20Sopenharmony_ci switch (state->config->ts1_mode) { 46438c2ecf20Sopenharmony_ci case STV090x_TSMODE_PARALLEL_PUNCTURED: 46448c2ecf20Sopenharmony_ci case STV090x_TSMODE_DVBCI: 46458c2ecf20Sopenharmony_ci default: 46468c2ecf20Sopenharmony_ci speed = state->internal->mclk / 46478c2ecf20Sopenharmony_ci (state->config->ts1_clk / 4); 46488c2ecf20Sopenharmony_ci if (speed < 0x08) 46498c2ecf20Sopenharmony_ci speed = 0x08; 46508c2ecf20Sopenharmony_ci if (speed > 0xFF) 46518c2ecf20Sopenharmony_ci speed = 0xFF; 46528c2ecf20Sopenharmony_ci break; 46538c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_PUNCTURED: 46548c2ecf20Sopenharmony_ci case STV090x_TSMODE_SERIAL_CONTINUOUS: 46558c2ecf20Sopenharmony_ci speed = state->internal->mclk / 46568c2ecf20Sopenharmony_ci (state->config->ts1_clk / 32); 46578c2ecf20Sopenharmony_ci if (speed < 0x20) 46588c2ecf20Sopenharmony_ci speed = 0x20; 46598c2ecf20Sopenharmony_ci if (speed > 0xFF) 46608c2ecf20Sopenharmony_ci speed = 0xFF; 46618c2ecf20Sopenharmony_ci break; 46628c2ecf20Sopenharmony_ci } 46638c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); 46648c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); 46658c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) 46668c2ecf20Sopenharmony_ci goto err; 46678c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0) 46688c2ecf20Sopenharmony_ci goto err; 46698c2ecf20Sopenharmony_ci } 46708c2ecf20Sopenharmony_ci 46718c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 46728c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); 46738c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 46748c2ecf20Sopenharmony_ci goto err; 46758c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00); 46768c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 46778c2ecf20Sopenharmony_ci goto err; 46788c2ecf20Sopenharmony_ci 46798c2ecf20Sopenharmony_ci return 0; 46808c2ecf20Sopenharmony_cierr: 46818c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 46828c2ecf20Sopenharmony_ci return -1; 46838c2ecf20Sopenharmony_ci} 46848c2ecf20Sopenharmony_ci 46858c2ecf20Sopenharmony_cistatic int stv090x_init(struct dvb_frontend *fe) 46868c2ecf20Sopenharmony_ci{ 46878c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 46888c2ecf20Sopenharmony_ci const struct stv090x_config *config = state->config; 46898c2ecf20Sopenharmony_ci u32 reg; 46908c2ecf20Sopenharmony_ci 46918c2ecf20Sopenharmony_ci if (state->internal->mclk == 0) { 46928c2ecf20Sopenharmony_ci /* call tuner init to configure the tuner's clock output 46938c2ecf20Sopenharmony_ci divider directly before setting up the master clock of 46948c2ecf20Sopenharmony_ci the stv090x. */ 46958c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 46968c2ecf20Sopenharmony_ci goto err; 46978c2ecf20Sopenharmony_ci 46988c2ecf20Sopenharmony_ci if (config->tuner_init) { 46998c2ecf20Sopenharmony_ci if (config->tuner_init(fe) < 0) 47008c2ecf20Sopenharmony_ci goto err_gateoff; 47018c2ecf20Sopenharmony_ci } 47028c2ecf20Sopenharmony_ci 47038c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 47048c2ecf20Sopenharmony_ci goto err; 47058c2ecf20Sopenharmony_ci 47068c2ecf20Sopenharmony_ci stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */ 47078c2ecf20Sopenharmony_ci msleep(5); 47088c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_SYNTCTRL, 47098c2ecf20Sopenharmony_ci 0x20 | config->clk_mode) < 0) 47108c2ecf20Sopenharmony_ci goto err; 47118c2ecf20Sopenharmony_ci stv090x_get_mclk(state); 47128c2ecf20Sopenharmony_ci } 47138c2ecf20Sopenharmony_ci 47148c2ecf20Sopenharmony_ci if (stv090x_wakeup(fe) < 0) { 47158c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "Error waking device"); 47168c2ecf20Sopenharmony_ci goto err; 47178c2ecf20Sopenharmony_ci } 47188c2ecf20Sopenharmony_ci 47198c2ecf20Sopenharmony_ci if (stv090x_ldpc_mode(state, state->demod_mode) < 0) 47208c2ecf20Sopenharmony_ci goto err; 47218c2ecf20Sopenharmony_ci 47228c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, TNRCFG2); 47238c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, TUN_IQSWAP_FIELD, state->inversion); 47248c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, TNRCFG2, reg) < 0) 47258c2ecf20Sopenharmony_ci goto err; 47268c2ecf20Sopenharmony_ci reg = STV090x_READ_DEMOD(state, DEMOD); 47278c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff); 47288c2ecf20Sopenharmony_ci if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) 47298c2ecf20Sopenharmony_ci goto err; 47308c2ecf20Sopenharmony_ci 47318c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 1) < 0) 47328c2ecf20Sopenharmony_ci goto err; 47338c2ecf20Sopenharmony_ci 47348c2ecf20Sopenharmony_ci if (config->tuner_set_mode) { 47358c2ecf20Sopenharmony_ci if (config->tuner_set_mode(fe, TUNER_WAKE) < 0) 47368c2ecf20Sopenharmony_ci goto err_gateoff; 47378c2ecf20Sopenharmony_ci } 47388c2ecf20Sopenharmony_ci 47398c2ecf20Sopenharmony_ci if (config->tuner_init) { 47408c2ecf20Sopenharmony_ci if (config->tuner_init(fe) < 0) 47418c2ecf20Sopenharmony_ci goto err_gateoff; 47428c2ecf20Sopenharmony_ci } 47438c2ecf20Sopenharmony_ci 47448c2ecf20Sopenharmony_ci if (stv090x_i2c_gate_ctrl(state, 0) < 0) 47458c2ecf20Sopenharmony_ci goto err; 47468c2ecf20Sopenharmony_ci 47478c2ecf20Sopenharmony_ci if (state->device == STV0900) { 47488c2ecf20Sopenharmony_ci if (stv0900_set_tspath(state) < 0) 47498c2ecf20Sopenharmony_ci goto err; 47508c2ecf20Sopenharmony_ci } else { 47518c2ecf20Sopenharmony_ci if (stv0903_set_tspath(state) < 0) 47528c2ecf20Sopenharmony_ci goto err; 47538c2ecf20Sopenharmony_ci } 47548c2ecf20Sopenharmony_ci 47558c2ecf20Sopenharmony_ci return 0; 47568c2ecf20Sopenharmony_ci 47578c2ecf20Sopenharmony_cierr_gateoff: 47588c2ecf20Sopenharmony_ci stv090x_i2c_gate_ctrl(state, 0); 47598c2ecf20Sopenharmony_cierr: 47608c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 47618c2ecf20Sopenharmony_ci return -1; 47628c2ecf20Sopenharmony_ci} 47638c2ecf20Sopenharmony_ci 47648c2ecf20Sopenharmony_cistatic int stv090x_setup(struct dvb_frontend *fe) 47658c2ecf20Sopenharmony_ci{ 47668c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 47678c2ecf20Sopenharmony_ci const struct stv090x_config *config = state->config; 47688c2ecf20Sopenharmony_ci const struct stv090x_reg *stv090x_initval = NULL; 47698c2ecf20Sopenharmony_ci const struct stv090x_reg *stv090x_cut20_val = NULL; 47708c2ecf20Sopenharmony_ci unsigned long t1_size = 0, t2_size = 0; 47718c2ecf20Sopenharmony_ci u32 reg = 0; 47728c2ecf20Sopenharmony_ci 47738c2ecf20Sopenharmony_ci int i; 47748c2ecf20Sopenharmony_ci 47758c2ecf20Sopenharmony_ci if (state->device == STV0900) { 47768c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Initializing STV0900"); 47778c2ecf20Sopenharmony_ci stv090x_initval = stv0900_initval; 47788c2ecf20Sopenharmony_ci t1_size = ARRAY_SIZE(stv0900_initval); 47798c2ecf20Sopenharmony_ci stv090x_cut20_val = stv0900_cut20_val; 47808c2ecf20Sopenharmony_ci t2_size = ARRAY_SIZE(stv0900_cut20_val); 47818c2ecf20Sopenharmony_ci } else if (state->device == STV0903) { 47828c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Initializing STV0903"); 47838c2ecf20Sopenharmony_ci stv090x_initval = stv0903_initval; 47848c2ecf20Sopenharmony_ci t1_size = ARRAY_SIZE(stv0903_initval); 47858c2ecf20Sopenharmony_ci stv090x_cut20_val = stv0903_cut20_val; 47868c2ecf20Sopenharmony_ci t2_size = ARRAY_SIZE(stv0903_cut20_val); 47878c2ecf20Sopenharmony_ci } 47888c2ecf20Sopenharmony_ci 47898c2ecf20Sopenharmony_ci /* STV090x init */ 47908c2ecf20Sopenharmony_ci 47918c2ecf20Sopenharmony_ci /* Stop Demod */ 47928c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0) 47938c2ecf20Sopenharmony_ci goto err; 47948c2ecf20Sopenharmony_ci if (state->device == STV0900) 47958c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0) 47968c2ecf20Sopenharmony_ci goto err; 47978c2ecf20Sopenharmony_ci 47988c2ecf20Sopenharmony_ci msleep(5); 47998c2ecf20Sopenharmony_ci 48008c2ecf20Sopenharmony_ci /* Set No Tuner Mode */ 48018c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0) 48028c2ecf20Sopenharmony_ci goto err; 48038c2ecf20Sopenharmony_ci if (state->device == STV0900) 48048c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0) 48058c2ecf20Sopenharmony_ci goto err; 48068c2ecf20Sopenharmony_ci 48078c2ecf20Sopenharmony_ci /* I2C repeater OFF */ 48088c2ecf20Sopenharmony_ci STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level); 48098c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0) 48108c2ecf20Sopenharmony_ci goto err; 48118c2ecf20Sopenharmony_ci if (state->device == STV0900) 48128c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0) 48138c2ecf20Sopenharmony_ci goto err; 48148c2ecf20Sopenharmony_ci 48158c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */ 48168c2ecf20Sopenharmony_ci goto err; 48178c2ecf20Sopenharmony_ci msleep(5); 48188c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_I2CCFG, 0x08) < 0) /* 1/41 oversampling */ 48198c2ecf20Sopenharmony_ci goto err; 48208c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) /* enable PLL */ 48218c2ecf20Sopenharmony_ci goto err; 48228c2ecf20Sopenharmony_ci msleep(5); 48238c2ecf20Sopenharmony_ci 48248c2ecf20Sopenharmony_ci /* write initval */ 48258c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Setting up initial values"); 48268c2ecf20Sopenharmony_ci for (i = 0; i < t1_size; i++) { 48278c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, stv090x_initval[i].addr, stv090x_initval[i].data) < 0) 48288c2ecf20Sopenharmony_ci goto err; 48298c2ecf20Sopenharmony_ci } 48308c2ecf20Sopenharmony_ci 48318c2ecf20Sopenharmony_ci state->internal->dev_ver = stv090x_read_reg(state, STV090x_MID); 48328c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x20) { 48338c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) 48348c2ecf20Sopenharmony_ci goto err; 48358c2ecf20Sopenharmony_ci 48368c2ecf20Sopenharmony_ci /* write cut20_val*/ 48378c2ecf20Sopenharmony_ci dprintk(FE_DEBUG, 1, "Setting up Cut 2.0 initial values"); 48388c2ecf20Sopenharmony_ci for (i = 0; i < t2_size; i++) { 48398c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, stv090x_cut20_val[i].addr, stv090x_cut20_val[i].data) < 0) 48408c2ecf20Sopenharmony_ci goto err; 48418c2ecf20Sopenharmony_ci } 48428c2ecf20Sopenharmony_ci 48438c2ecf20Sopenharmony_ci } else if (state->internal->dev_ver < 0x20) { 48448c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!", 48458c2ecf20Sopenharmony_ci state->internal->dev_ver); 48468c2ecf20Sopenharmony_ci 48478c2ecf20Sopenharmony_ci goto err; 48488c2ecf20Sopenharmony_ci } else if (state->internal->dev_ver > 0x30) { 48498c2ecf20Sopenharmony_ci /* we shouldn't bail out from here */ 48508c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!", 48518c2ecf20Sopenharmony_ci state->internal->dev_ver); 48528c2ecf20Sopenharmony_ci } 48538c2ecf20Sopenharmony_ci 48548c2ecf20Sopenharmony_ci /* ADC1 range */ 48558c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR1); 48568c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, ADC1_INMODE_FIELD, 48578c2ecf20Sopenharmony_ci (config->adc1_range == STV090x_ADC_1Vpp) ? 0 : 1); 48588c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 48598c2ecf20Sopenharmony_ci goto err; 48608c2ecf20Sopenharmony_ci 48618c2ecf20Sopenharmony_ci /* ADC2 range */ 48628c2ecf20Sopenharmony_ci reg = stv090x_read_reg(state, STV090x_TSTTNR3); 48638c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, ADC2_INMODE_FIELD, 48648c2ecf20Sopenharmony_ci (config->adc2_range == STV090x_ADC_1Vpp) ? 0 : 1); 48658c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0) 48668c2ecf20Sopenharmony_ci goto err; 48678c2ecf20Sopenharmony_ci 48688c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0) 48698c2ecf20Sopenharmony_ci goto err; 48708c2ecf20Sopenharmony_ci if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0) 48718c2ecf20Sopenharmony_ci goto err; 48728c2ecf20Sopenharmony_ci 48738c2ecf20Sopenharmony_ci return 0; 48748c2ecf20Sopenharmony_cierr: 48758c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "I/O error"); 48768c2ecf20Sopenharmony_ci return -1; 48778c2ecf20Sopenharmony_ci} 48788c2ecf20Sopenharmony_ci 48798c2ecf20Sopenharmony_cistatic int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, 48808c2ecf20Sopenharmony_ci u8 value, u8 xor_value) 48818c2ecf20Sopenharmony_ci{ 48828c2ecf20Sopenharmony_ci struct stv090x_state *state = fe->demodulator_priv; 48838c2ecf20Sopenharmony_ci u8 reg = 0; 48848c2ecf20Sopenharmony_ci 48858c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, GPIOx_OPD_FIELD, dir); 48868c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, GPIOx_CONFIG_FIELD, value); 48878c2ecf20Sopenharmony_ci STV090x_SETFIELD(reg, GPIOx_XOR_FIELD, xor_value); 48888c2ecf20Sopenharmony_ci 48898c2ecf20Sopenharmony_ci return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg); 48908c2ecf20Sopenharmony_ci} 48918c2ecf20Sopenharmony_ci 48928c2ecf20Sopenharmony_cistatic int stv090x_setup_compound(struct stv090x_state *state) 48938c2ecf20Sopenharmony_ci{ 48948c2ecf20Sopenharmony_ci struct stv090x_dev *temp_int; 48958c2ecf20Sopenharmony_ci 48968c2ecf20Sopenharmony_ci temp_int = find_dev(state->i2c, 48978c2ecf20Sopenharmony_ci state->config->address); 48988c2ecf20Sopenharmony_ci 48998c2ecf20Sopenharmony_ci if (temp_int && state->demod_mode == STV090x_DUAL) { 49008c2ecf20Sopenharmony_ci state->internal = temp_int->internal; 49018c2ecf20Sopenharmony_ci state->internal->num_used++; 49028c2ecf20Sopenharmony_ci dprintk(FE_INFO, 1, "Found Internal Structure!"); 49038c2ecf20Sopenharmony_ci } else { 49048c2ecf20Sopenharmony_ci state->internal = kmalloc(sizeof(*state->internal), GFP_KERNEL); 49058c2ecf20Sopenharmony_ci if (!state->internal) 49068c2ecf20Sopenharmony_ci goto error; 49078c2ecf20Sopenharmony_ci temp_int = append_internal(state->internal); 49088c2ecf20Sopenharmony_ci if (!temp_int) { 49098c2ecf20Sopenharmony_ci kfree(state->internal); 49108c2ecf20Sopenharmony_ci goto error; 49118c2ecf20Sopenharmony_ci } 49128c2ecf20Sopenharmony_ci state->internal->num_used = 1; 49138c2ecf20Sopenharmony_ci state->internal->mclk = 0; 49148c2ecf20Sopenharmony_ci state->internal->dev_ver = 0; 49158c2ecf20Sopenharmony_ci state->internal->i2c_adap = state->i2c; 49168c2ecf20Sopenharmony_ci state->internal->i2c_addr = state->config->address; 49178c2ecf20Sopenharmony_ci dprintk(FE_INFO, 1, "Create New Internal Structure!"); 49188c2ecf20Sopenharmony_ci 49198c2ecf20Sopenharmony_ci mutex_init(&state->internal->demod_lock); 49208c2ecf20Sopenharmony_ci mutex_init(&state->internal->tuner_lock); 49218c2ecf20Sopenharmony_ci 49228c2ecf20Sopenharmony_ci if (stv090x_setup(&state->frontend) < 0) { 49238c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "Error setting up device"); 49248c2ecf20Sopenharmony_ci goto err_remove; 49258c2ecf20Sopenharmony_ci } 49268c2ecf20Sopenharmony_ci } 49278c2ecf20Sopenharmony_ci 49288c2ecf20Sopenharmony_ci if (state->internal->dev_ver >= 0x30) 49298c2ecf20Sopenharmony_ci state->frontend.ops.info.caps |= FE_CAN_MULTISTREAM; 49308c2ecf20Sopenharmony_ci 49318c2ecf20Sopenharmony_ci /* workaround for stuck DiSEqC output */ 49328c2ecf20Sopenharmony_ci if (state->config->diseqc_envelope_mode) 49338c2ecf20Sopenharmony_ci stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A); 49348c2ecf20Sopenharmony_ci 49358c2ecf20Sopenharmony_ci state->config->set_gpio = stv090x_set_gpio; 49368c2ecf20Sopenharmony_ci 49378c2ecf20Sopenharmony_ci dprintk(FE_ERROR, 1, "Probing %s demodulator(%d) Cut=0x%02x", 49388c2ecf20Sopenharmony_ci state->device == STV0900 ? "STV0900" : "STV0903", 49398c2ecf20Sopenharmony_ci state->config->demod, 49408c2ecf20Sopenharmony_ci state->internal->dev_ver); 49418c2ecf20Sopenharmony_ci 49428c2ecf20Sopenharmony_ci return 0; 49438c2ecf20Sopenharmony_ci 49448c2ecf20Sopenharmony_cierror: 49458c2ecf20Sopenharmony_ci return -ENOMEM; 49468c2ecf20Sopenharmony_cierr_remove: 49478c2ecf20Sopenharmony_ci remove_dev(state->internal); 49488c2ecf20Sopenharmony_ci kfree(state->internal); 49498c2ecf20Sopenharmony_ci return -ENODEV; 49508c2ecf20Sopenharmony_ci} 49518c2ecf20Sopenharmony_ci 49528c2ecf20Sopenharmony_cistatic const struct dvb_frontend_ops stv090x_ops = { 49538c2ecf20Sopenharmony_ci .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, 49548c2ecf20Sopenharmony_ci .info = { 49558c2ecf20Sopenharmony_ci .name = "STV090x Multistandard", 49568c2ecf20Sopenharmony_ci .frequency_min_hz = 950 * MHz, 49578c2ecf20Sopenharmony_ci .frequency_max_hz = 2150 * MHz, 49588c2ecf20Sopenharmony_ci .symbol_rate_min = 1000000, 49598c2ecf20Sopenharmony_ci .symbol_rate_max = 45000000, 49608c2ecf20Sopenharmony_ci .caps = FE_CAN_INVERSION_AUTO | 49618c2ecf20Sopenharmony_ci FE_CAN_FEC_AUTO | 49628c2ecf20Sopenharmony_ci FE_CAN_QPSK | 49638c2ecf20Sopenharmony_ci FE_CAN_2G_MODULATION 49648c2ecf20Sopenharmony_ci }, 49658c2ecf20Sopenharmony_ci 49668c2ecf20Sopenharmony_ci .release = stv090x_release, 49678c2ecf20Sopenharmony_ci .init = stv090x_init, 49688c2ecf20Sopenharmony_ci 49698c2ecf20Sopenharmony_ci .sleep = stv090x_sleep, 49708c2ecf20Sopenharmony_ci .get_frontend_algo = stv090x_frontend_algo, 49718c2ecf20Sopenharmony_ci 49728c2ecf20Sopenharmony_ci .diseqc_send_master_cmd = stv090x_send_diseqc_msg, 49738c2ecf20Sopenharmony_ci .diseqc_send_burst = stv090x_send_diseqc_burst, 49748c2ecf20Sopenharmony_ci .diseqc_recv_slave_reply = stv090x_recv_slave_reply, 49758c2ecf20Sopenharmony_ci .set_tone = stv090x_set_tone, 49768c2ecf20Sopenharmony_ci 49778c2ecf20Sopenharmony_ci .search = stv090x_search, 49788c2ecf20Sopenharmony_ci .read_status = stv090x_read_status, 49798c2ecf20Sopenharmony_ci .read_ber = stv090x_read_per, 49808c2ecf20Sopenharmony_ci .read_signal_strength = stv090x_read_signal_strength, 49818c2ecf20Sopenharmony_ci .read_snr = stv090x_read_cnr, 49828c2ecf20Sopenharmony_ci}; 49838c2ecf20Sopenharmony_ci 49848c2ecf20Sopenharmony_cistatic struct dvb_frontend *stv090x_get_dvb_frontend(struct i2c_client *client) 49858c2ecf20Sopenharmony_ci{ 49868c2ecf20Sopenharmony_ci struct stv090x_state *state = i2c_get_clientdata(client); 49878c2ecf20Sopenharmony_ci 49888c2ecf20Sopenharmony_ci dev_dbg(&client->dev, "\n"); 49898c2ecf20Sopenharmony_ci 49908c2ecf20Sopenharmony_ci return &state->frontend; 49918c2ecf20Sopenharmony_ci} 49928c2ecf20Sopenharmony_ci 49938c2ecf20Sopenharmony_cistatic int stv090x_probe(struct i2c_client *client, 49948c2ecf20Sopenharmony_ci const struct i2c_device_id *id) 49958c2ecf20Sopenharmony_ci{ 49968c2ecf20Sopenharmony_ci int ret = 0; 49978c2ecf20Sopenharmony_ci struct stv090x_config *config = client->dev.platform_data; 49988c2ecf20Sopenharmony_ci 49998c2ecf20Sopenharmony_ci struct stv090x_state *state = NULL; 50008c2ecf20Sopenharmony_ci 50018c2ecf20Sopenharmony_ci state = kzalloc(sizeof(*state), GFP_KERNEL); 50028c2ecf20Sopenharmony_ci if (!state) { 50038c2ecf20Sopenharmony_ci ret = -ENOMEM; 50048c2ecf20Sopenharmony_ci goto error; 50058c2ecf20Sopenharmony_ci } 50068c2ecf20Sopenharmony_ci 50078c2ecf20Sopenharmony_ci state->verbose = &verbose; 50088c2ecf20Sopenharmony_ci state->config = config; 50098c2ecf20Sopenharmony_ci state->i2c = client->adapter; 50108c2ecf20Sopenharmony_ci state->frontend.ops = stv090x_ops; 50118c2ecf20Sopenharmony_ci state->frontend.demodulator_priv = state; 50128c2ecf20Sopenharmony_ci state->demod = config->demod; 50138c2ecf20Sopenharmony_ci /* Single or Dual mode */ 50148c2ecf20Sopenharmony_ci state->demod_mode = config->demod_mode; 50158c2ecf20Sopenharmony_ci state->device = config->device; 50168c2ecf20Sopenharmony_ci /* default */ 50178c2ecf20Sopenharmony_ci state->rolloff = STV090x_RO_35; 50188c2ecf20Sopenharmony_ci 50198c2ecf20Sopenharmony_ci ret = stv090x_setup_compound(state); 50208c2ecf20Sopenharmony_ci if (ret) 50218c2ecf20Sopenharmony_ci goto error; 50228c2ecf20Sopenharmony_ci 50238c2ecf20Sopenharmony_ci i2c_set_clientdata(client, state); 50248c2ecf20Sopenharmony_ci 50258c2ecf20Sopenharmony_ci /* setup callbacks */ 50268c2ecf20Sopenharmony_ci config->get_dvb_frontend = stv090x_get_dvb_frontend; 50278c2ecf20Sopenharmony_ci 50288c2ecf20Sopenharmony_ci return 0; 50298c2ecf20Sopenharmony_ci 50308c2ecf20Sopenharmony_cierror: 50318c2ecf20Sopenharmony_ci kfree(state); 50328c2ecf20Sopenharmony_ci return ret; 50338c2ecf20Sopenharmony_ci} 50348c2ecf20Sopenharmony_ci 50358c2ecf20Sopenharmony_cistatic int stv090x_remove(struct i2c_client *client) 50368c2ecf20Sopenharmony_ci{ 50378c2ecf20Sopenharmony_ci struct stv090x_state *state = i2c_get_clientdata(client); 50388c2ecf20Sopenharmony_ci 50398c2ecf20Sopenharmony_ci stv090x_release(&state->frontend); 50408c2ecf20Sopenharmony_ci return 0; 50418c2ecf20Sopenharmony_ci} 50428c2ecf20Sopenharmony_ci 50438c2ecf20Sopenharmony_cistruct dvb_frontend *stv090x_attach(struct stv090x_config *config, 50448c2ecf20Sopenharmony_ci struct i2c_adapter *i2c, 50458c2ecf20Sopenharmony_ci enum stv090x_demodulator demod) 50468c2ecf20Sopenharmony_ci{ 50478c2ecf20Sopenharmony_ci int ret = 0; 50488c2ecf20Sopenharmony_ci struct stv090x_state *state = NULL; 50498c2ecf20Sopenharmony_ci 50508c2ecf20Sopenharmony_ci state = kzalloc(sizeof(*state), GFP_KERNEL); 50518c2ecf20Sopenharmony_ci if (!state) 50528c2ecf20Sopenharmony_ci goto error; 50538c2ecf20Sopenharmony_ci 50548c2ecf20Sopenharmony_ci state->verbose = &verbose; 50558c2ecf20Sopenharmony_ci state->config = config; 50568c2ecf20Sopenharmony_ci state->i2c = i2c; 50578c2ecf20Sopenharmony_ci state->frontend.ops = stv090x_ops; 50588c2ecf20Sopenharmony_ci state->frontend.demodulator_priv = state; 50598c2ecf20Sopenharmony_ci state->demod = demod; 50608c2ecf20Sopenharmony_ci /* Single or Dual mode */ 50618c2ecf20Sopenharmony_ci state->demod_mode = config->demod_mode; 50628c2ecf20Sopenharmony_ci state->device = config->device; 50638c2ecf20Sopenharmony_ci /* default */ 50648c2ecf20Sopenharmony_ci state->rolloff = STV090x_RO_35; 50658c2ecf20Sopenharmony_ci 50668c2ecf20Sopenharmony_ci ret = stv090x_setup_compound(state); 50678c2ecf20Sopenharmony_ci if (ret) 50688c2ecf20Sopenharmony_ci goto error; 50698c2ecf20Sopenharmony_ci 50708c2ecf20Sopenharmony_ci return &state->frontend; 50718c2ecf20Sopenharmony_ci 50728c2ecf20Sopenharmony_cierror: 50738c2ecf20Sopenharmony_ci kfree(state); 50748c2ecf20Sopenharmony_ci return NULL; 50758c2ecf20Sopenharmony_ci} 50768c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(stv090x_attach); 50778c2ecf20Sopenharmony_ci 50788c2ecf20Sopenharmony_cistatic const struct i2c_device_id stv090x_id_table[] = { 50798c2ecf20Sopenharmony_ci {"stv090x", 0}, 50808c2ecf20Sopenharmony_ci {} 50818c2ecf20Sopenharmony_ci}; 50828c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, stv090x_id_table); 50838c2ecf20Sopenharmony_ci 50848c2ecf20Sopenharmony_cistatic struct i2c_driver stv090x_driver = { 50858c2ecf20Sopenharmony_ci .driver = { 50868c2ecf20Sopenharmony_ci .name = "stv090x", 50878c2ecf20Sopenharmony_ci .suppress_bind_attrs = true, 50888c2ecf20Sopenharmony_ci }, 50898c2ecf20Sopenharmony_ci .probe = stv090x_probe, 50908c2ecf20Sopenharmony_ci .remove = stv090x_remove, 50918c2ecf20Sopenharmony_ci .id_table = stv090x_id_table, 50928c2ecf20Sopenharmony_ci}; 50938c2ecf20Sopenharmony_ci 50948c2ecf20Sopenharmony_cimodule_i2c_driver(stv090x_driver); 50958c2ecf20Sopenharmony_ci 50968c2ecf20Sopenharmony_ciMODULE_PARM_DESC(verbose, "Set Verbosity level"); 50978c2ecf20Sopenharmony_ciMODULE_AUTHOR("Manu Abraham"); 50988c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend"); 50998c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 5100