5103 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 STV0900/0903 Multistandard Broadcast Frontend driver4 Copyright (C) Manu Abraham <abraham.manu@gmail.com>5 6 Copyright (C) ST Microelectronics7 8*/9 10#include <linux/init.h>11#include <linux/kernel.h>12#include <linux/module.h>13#include <linux/string.h>14#include <linux/slab.h>15#include <linux/mutex.h>16 17#include <linux/dvb/frontend.h>18#include <media/dvb_frontend.h>19 20#include "stv6110x.h" /* for demodulator internal modes */21 22#include "stv090x_reg.h"23#include "stv090x.h"24#include "stv090x_priv.h"25 26/* Max transfer size done by I2C transfer functions */27#define MAX_XFER_SIZE 6428 29static unsigned int verbose;30module_param(verbose, int, 0644);31 32/* internal params node */33struct stv090x_dev {34 /* pointer for internal params, one for each pair of demods */35 struct stv090x_internal *internal;36 struct stv090x_dev *next_dev;37};38 39/* first internal params */40static struct stv090x_dev *stv090x_first_dev;41 42/* find chip by i2c adapter and i2c address */43static struct stv090x_dev *find_dev(struct i2c_adapter *i2c_adap,44 u8 i2c_addr)45{46 struct stv090x_dev *temp_dev = stv090x_first_dev;47 48 /*49 Search of the last stv0900 chip or50 find it by i2c adapter and i2c address */51 while ((temp_dev != NULL) &&52 ((temp_dev->internal->i2c_adap != i2c_adap) ||53 (temp_dev->internal->i2c_addr != i2c_addr))) {54 55 temp_dev = temp_dev->next_dev;56 }57 58 return temp_dev;59}60 61/* deallocating chip */62static void remove_dev(struct stv090x_internal *internal)63{64 struct stv090x_dev *prev_dev = stv090x_first_dev;65 struct stv090x_dev *del_dev = find_dev(internal->i2c_adap,66 internal->i2c_addr);67 68 if (del_dev != NULL) {69 if (del_dev == stv090x_first_dev) {70 stv090x_first_dev = del_dev->next_dev;71 } else {72 while (prev_dev->next_dev != del_dev)73 prev_dev = prev_dev->next_dev;74 75 prev_dev->next_dev = del_dev->next_dev;76 }77 78 kfree(del_dev);79 }80}81 82/* allocating new chip */83static struct stv090x_dev *append_internal(struct stv090x_internal *internal)84{85 struct stv090x_dev *new_dev;86 struct stv090x_dev *temp_dev;87 88 new_dev = kmalloc(sizeof(struct stv090x_dev), GFP_KERNEL);89 if (new_dev != NULL) {90 new_dev->internal = internal;91 new_dev->next_dev = NULL;92 93 /* append to list */94 if (stv090x_first_dev == NULL) {95 stv090x_first_dev = new_dev;96 } else {97 temp_dev = stv090x_first_dev;98 while (temp_dev->next_dev != NULL)99 temp_dev = temp_dev->next_dev;100 101 temp_dev->next_dev = new_dev;102 }103 }104 105 return new_dev;106}107 108 109/* DVBS1 and DSS C/N Lookup table */110static const struct stv090x_tab stv090x_s1cn_tab[] = {111 { 0, 8917 }, /* 0.0dB */112 { 5, 8801 }, /* 0.5dB */113 { 10, 8667 }, /* 1.0dB */114 { 15, 8522 }, /* 1.5dB */115 { 20, 8355 }, /* 2.0dB */116 { 25, 8175 }, /* 2.5dB */117 { 30, 7979 }, /* 3.0dB */118 { 35, 7763 }, /* 3.5dB */119 { 40, 7530 }, /* 4.0dB */120 { 45, 7282 }, /* 4.5dB */121 { 50, 7026 }, /* 5.0dB */122 { 55, 6781 }, /* 5.5dB */123 { 60, 6514 }, /* 6.0dB */124 { 65, 6241 }, /* 6.5dB */125 { 70, 5965 }, /* 7.0dB */126 { 75, 5690 }, /* 7.5dB */127 { 80, 5424 }, /* 8.0dB */128 { 85, 5161 }, /* 8.5dB */129 { 90, 4902 }, /* 9.0dB */130 { 95, 4654 }, /* 9.5dB */131 { 100, 4417 }, /* 10.0dB */132 { 105, 4186 }, /* 10.5dB */133 { 110, 3968 }, /* 11.0dB */134 { 115, 3757 }, /* 11.5dB */135 { 120, 3558 }, /* 12.0dB */136 { 125, 3366 }, /* 12.5dB */137 { 130, 3185 }, /* 13.0dB */138 { 135, 3012 }, /* 13.5dB */139 { 140, 2850 }, /* 14.0dB */140 { 145, 2698 }, /* 14.5dB */141 { 150, 2550 }, /* 15.0dB */142 { 160, 2283 }, /* 16.0dB */143 { 170, 2042 }, /* 17.0dB */144 { 180, 1827 }, /* 18.0dB */145 { 190, 1636 }, /* 19.0dB */146 { 200, 1466 }, /* 20.0dB */147 { 210, 1315 }, /* 21.0dB */148 { 220, 1181 }, /* 22.0dB */149 { 230, 1064 }, /* 23.0dB */150 { 240, 960 }, /* 24.0dB */151 { 250, 869 }, /* 25.0dB */152 { 260, 792 }, /* 26.0dB */153 { 270, 724 }, /* 27.0dB */154 { 280, 665 }, /* 28.0dB */155 { 290, 616 }, /* 29.0dB */156 { 300, 573 }, /* 30.0dB */157 { 310, 537 }, /* 31.0dB */158 { 320, 507 }, /* 32.0dB */159 { 330, 483 }, /* 33.0dB */160 { 400, 398 }, /* 40.0dB */161 { 450, 381 }, /* 45.0dB */162 { 500, 377 } /* 50.0dB */163};164 165/* DVBS2 C/N Lookup table */166static const struct stv090x_tab stv090x_s2cn_tab[] = {167 { -30, 13348 }, /* -3.0dB */168 { -20, 12640 }, /* -2d.0B */169 { -10, 11883 }, /* -1.0dB */170 { 0, 11101 }, /* -0.0dB */171 { 5, 10718 }, /* 0.5dB */172 { 10, 10339 }, /* 1.0dB */173 { 15, 9947 }, /* 1.5dB */174 { 20, 9552 }, /* 2.0dB */175 { 25, 9183 }, /* 2.5dB */176 { 30, 8799 }, /* 3.0dB */177 { 35, 8422 }, /* 3.5dB */178 { 40, 8062 }, /* 4.0dB */179 { 45, 7707 }, /* 4.5dB */180 { 50, 7353 }, /* 5.0dB */181 { 55, 7025 }, /* 5.5dB */182 { 60, 6684 }, /* 6.0dB */183 { 65, 6331 }, /* 6.5dB */184 { 70, 6036 }, /* 7.0dB */185 { 75, 5727 }, /* 7.5dB */186 { 80, 5437 }, /* 8.0dB */187 { 85, 5164 }, /* 8.5dB */188 { 90, 4902 }, /* 9.0dB */189 { 95, 4653 }, /* 9.5dB */190 { 100, 4408 }, /* 10.0dB */191 { 105, 4187 }, /* 10.5dB */192 { 110, 3961 }, /* 11.0dB */193 { 115, 3751 }, /* 11.5dB */194 { 120, 3558 }, /* 12.0dB */195 { 125, 3368 }, /* 12.5dB */196 { 130, 3191 }, /* 13.0dB */197 { 135, 3017 }, /* 13.5dB */198 { 140, 2862 }, /* 14.0dB */199 { 145, 2710 }, /* 14.5dB */200 { 150, 2565 }, /* 15.0dB */201 { 160, 2300 }, /* 16.0dB */202 { 170, 2058 }, /* 17.0dB */203 { 180, 1849 }, /* 18.0dB */204 { 190, 1663 }, /* 19.0dB */205 { 200, 1495 }, /* 20.0dB */206 { 210, 1349 }, /* 21.0dB */207 { 220, 1222 }, /* 22.0dB */208 { 230, 1110 }, /* 23.0dB */209 { 240, 1011 }, /* 24.0dB */210 { 250, 925 }, /* 25.0dB */211 { 260, 853 }, /* 26.0dB */212 { 270, 789 }, /* 27.0dB */213 { 280, 734 }, /* 28.0dB */214 { 290, 690 }, /* 29.0dB */215 { 300, 650 }, /* 30.0dB */216 { 310, 619 }, /* 31.0dB */217 { 320, 593 }, /* 32.0dB */218 { 330, 571 }, /* 33.0dB */219 { 400, 498 }, /* 40.0dB */220 { 450, 484 }, /* 45.0dB */221 { 500, 481 } /* 50.0dB */222};223 224/* RF level C/N lookup table */225static const struct stv090x_tab stv090x_rf_tab[] = {226 { -5, 0xcaa1 }, /* -5dBm */227 { -10, 0xc229 }, /* -10dBm */228 { -15, 0xbb08 }, /* -15dBm */229 { -20, 0xb4bc }, /* -20dBm */230 { -25, 0xad5a }, /* -25dBm */231 { -30, 0xa298 }, /* -30dBm */232 { -35, 0x98a8 }, /* -35dBm */233 { -40, 0x8389 }, /* -40dBm */234 { -45, 0x59be }, /* -45dBm */235 { -50, 0x3a14 }, /* -50dBm */236 { -55, 0x2d11 }, /* -55dBm */237 { -60, 0x210d }, /* -60dBm */238 { -65, 0xa14f }, /* -65dBm */239 { -70, 0x07aa } /* -70dBm */240};241 242 243static struct stv090x_reg stv0900_initval[] = {244 245 { STV090x_OUTCFG, 0x00 },246 { STV090x_MODECFG, 0xff },247 { STV090x_AGCRF1CFG, 0x11 },248 { STV090x_AGCRF2CFG, 0x13 },249 { STV090x_TSGENERAL1X, 0x14 },250 { STV090x_TSTTNR2, 0x21 },251 { STV090x_TSTTNR4, 0x21 },252 { STV090x_P2_DISTXCTL, 0x22 },253 { STV090x_P2_F22TX, 0xc0 },254 { STV090x_P2_F22RX, 0xc0 },255 { STV090x_P2_DISRXCTL, 0x00 },256 { STV090x_P2_DMDCFGMD, 0xF9 },257 { STV090x_P2_DEMOD, 0x08 },258 { STV090x_P2_DMDCFG3, 0xc4 },259 { STV090x_P2_CARFREQ, 0xed },260 { STV090x_P2_LDT, 0xd0 },261 { STV090x_P2_LDT2, 0xb8 },262 { STV090x_P2_TMGCFG, 0xd2 },263 { STV090x_P2_TMGTHRISE, 0x20 },264 { STV090x_P1_TMGCFG, 0xd2 },265 266 { STV090x_P2_TMGTHFALL, 0x00 },267 { STV090x_P2_FECSPY, 0x88 },268 { STV090x_P2_FSPYDATA, 0x3a },269 { STV090x_P2_FBERCPT4, 0x00 },270 { STV090x_P2_FSPYBER, 0x10 },271 { STV090x_P2_ERRCTRL1, 0x35 },272 { STV090x_P2_ERRCTRL2, 0xc1 },273 { STV090x_P2_CFRICFG, 0xf8 },274 { STV090x_P2_NOSCFG, 0x1c },275 { STV090x_P2_DMDTOM, 0x20 },276 { STV090x_P2_CORRELMANT, 0x70 },277 { STV090x_P2_CORRELABS, 0x88 },278 { STV090x_P2_AGC2O, 0x5b },279 { STV090x_P2_AGC2REF, 0x38 },280 { STV090x_P2_CARCFG, 0xe4 },281 { STV090x_P2_ACLC, 0x1A },282 { STV090x_P2_BCLC, 0x09 },283 { STV090x_P2_CARHDR, 0x08 },284 { STV090x_P2_KREFTMG, 0xc1 },285 { STV090x_P2_SFRUPRATIO, 0xf0 },286 { STV090x_P2_SFRLOWRATIO, 0x70 },287 { STV090x_P2_SFRSTEP, 0x58 },288 { STV090x_P2_TMGCFG2, 0x01 },289 { STV090x_P2_CAR2CFG, 0x26 },290 { STV090x_P2_BCLC2S2Q, 0x86 },291 { STV090x_P2_BCLC2S28, 0x86 },292 { STV090x_P2_SMAPCOEF7, 0x77 },293 { STV090x_P2_SMAPCOEF6, 0x85 },294 { STV090x_P2_SMAPCOEF5, 0x77 },295 { STV090x_P2_TSCFGL, 0x20 },296 { STV090x_P2_DMDCFG2, 0x3b },297 { STV090x_P2_MODCODLST0, 0xff },298 { STV090x_P2_MODCODLST1, 0xff },299 { STV090x_P2_MODCODLST2, 0xff },300 { STV090x_P2_MODCODLST3, 0xff },301 { STV090x_P2_MODCODLST4, 0xff },302 { STV090x_P2_MODCODLST5, 0xff },303 { STV090x_P2_MODCODLST6, 0xff },304 { STV090x_P2_MODCODLST7, 0xcc },305 { STV090x_P2_MODCODLST8, 0xcc },306 { STV090x_P2_MODCODLST9, 0xcc },307 { STV090x_P2_MODCODLSTA, 0xcc },308 { STV090x_P2_MODCODLSTB, 0xcc },309 { STV090x_P2_MODCODLSTC, 0xcc },310 { STV090x_P2_MODCODLSTD, 0xcc },311 { STV090x_P2_MODCODLSTE, 0xcc },312 { STV090x_P2_MODCODLSTF, 0xcf },313 { STV090x_P1_DISTXCTL, 0x22 },314 { STV090x_P1_F22TX, 0xc0 },315 { STV090x_P1_F22RX, 0xc0 },316 { STV090x_P1_DISRXCTL, 0x00 },317 { STV090x_P1_DMDCFGMD, 0xf9 },318 { STV090x_P1_DEMOD, 0x08 },319 { STV090x_P1_DMDCFG3, 0xc4 },320 { STV090x_P1_DMDTOM, 0x20 },321 { STV090x_P1_CARFREQ, 0xed },322 { STV090x_P1_LDT, 0xd0 },323 { STV090x_P1_LDT2, 0xb8 },324 { STV090x_P1_TMGCFG, 0xd2 },325 { STV090x_P1_TMGTHRISE, 0x20 },326 { STV090x_P1_TMGTHFALL, 0x00 },327 { STV090x_P1_SFRUPRATIO, 0xf0 },328 { STV090x_P1_SFRLOWRATIO, 0x70 },329 { STV090x_P1_TSCFGL, 0x20 },330 { STV090x_P1_FECSPY, 0x88 },331 { STV090x_P1_FSPYDATA, 0x3a },332 { STV090x_P1_FBERCPT4, 0x00 },333 { STV090x_P1_FSPYBER, 0x10 },334 { STV090x_P1_ERRCTRL1, 0x35 },335 { STV090x_P1_ERRCTRL2, 0xc1 },336 { STV090x_P1_CFRICFG, 0xf8 },337 { STV090x_P1_NOSCFG, 0x1c },338 { STV090x_P1_CORRELMANT, 0x70 },339 { STV090x_P1_CORRELABS, 0x88 },340 { STV090x_P1_AGC2O, 0x5b },341 { STV090x_P1_AGC2REF, 0x38 },342 { STV090x_P1_CARCFG, 0xe4 },343 { STV090x_P1_ACLC, 0x1A },344 { STV090x_P1_BCLC, 0x09 },345 { STV090x_P1_CARHDR, 0x08 },346 { STV090x_P1_KREFTMG, 0xc1 },347 { STV090x_P1_SFRSTEP, 0x58 },348 { STV090x_P1_TMGCFG2, 0x01 },349 { STV090x_P1_CAR2CFG, 0x26 },350 { STV090x_P1_BCLC2S2Q, 0x86 },351 { STV090x_P1_BCLC2S28, 0x86 },352 { STV090x_P1_SMAPCOEF7, 0x77 },353 { STV090x_P1_SMAPCOEF6, 0x85 },354 { STV090x_P1_SMAPCOEF5, 0x77 },355 { STV090x_P1_DMDCFG2, 0x3b },356 { STV090x_P1_MODCODLST0, 0xff },357 { STV090x_P1_MODCODLST1, 0xff },358 { STV090x_P1_MODCODLST2, 0xff },359 { STV090x_P1_MODCODLST3, 0xff },360 { STV090x_P1_MODCODLST4, 0xff },361 { STV090x_P1_MODCODLST5, 0xff },362 { STV090x_P1_MODCODLST6, 0xff },363 { STV090x_P1_MODCODLST7, 0xcc },364 { STV090x_P1_MODCODLST8, 0xcc },365 { STV090x_P1_MODCODLST9, 0xcc },366 { STV090x_P1_MODCODLSTA, 0xcc },367 { STV090x_P1_MODCODLSTB, 0xcc },368 { STV090x_P1_MODCODLSTC, 0xcc },369 { STV090x_P1_MODCODLSTD, 0xcc },370 { STV090x_P1_MODCODLSTE, 0xcc },371 { STV090x_P1_MODCODLSTF, 0xcf },372 { STV090x_GENCFG, 0x1d },373 { STV090x_NBITER_NF4, 0x37 },374 { STV090x_NBITER_NF5, 0x29 },375 { STV090x_NBITER_NF6, 0x37 },376 { STV090x_NBITER_NF7, 0x33 },377 { STV090x_NBITER_NF8, 0x31 },378 { STV090x_NBITER_NF9, 0x2f },379 { STV090x_NBITER_NF10, 0x39 },380 { STV090x_NBITER_NF11, 0x3a },381 { STV090x_NBITER_NF12, 0x29 },382 { STV090x_NBITER_NF13, 0x37 },383 { STV090x_NBITER_NF14, 0x33 },384 { STV090x_NBITER_NF15, 0x2f },385 { STV090x_NBITER_NF16, 0x39 },386 { STV090x_NBITER_NF17, 0x3a },387 { STV090x_NBITERNOERR, 0x04 },388 { STV090x_GAINLLR_NF4, 0x0C },389 { STV090x_GAINLLR_NF5, 0x0F },390 { STV090x_GAINLLR_NF6, 0x11 },391 { STV090x_GAINLLR_NF7, 0x14 },392 { STV090x_GAINLLR_NF8, 0x17 },393 { STV090x_GAINLLR_NF9, 0x19 },394 { STV090x_GAINLLR_NF10, 0x20 },395 { STV090x_GAINLLR_NF11, 0x21 },396 { STV090x_GAINLLR_NF12, 0x0D },397 { STV090x_GAINLLR_NF13, 0x0F },398 { STV090x_GAINLLR_NF14, 0x13 },399 { STV090x_GAINLLR_NF15, 0x1A },400 { STV090x_GAINLLR_NF16, 0x1F },401 { STV090x_GAINLLR_NF17, 0x21 },402 { STV090x_RCCFGH, 0x20 },403 { STV090x_P1_FECM, 0x01 }, /* disable DSS modes */404 { STV090x_P2_FECM, 0x01 }, /* disable DSS modes */405 { STV090x_P1_PRVIT, 0x2F }, /* disable PR 6/7 */406 { STV090x_P2_PRVIT, 0x2F }, /* disable PR 6/7 */407};408 409static struct stv090x_reg stv0903_initval[] = {410 { STV090x_OUTCFG, 0x00 },411 { STV090x_AGCRF1CFG, 0x11 },412 { STV090x_STOPCLK1, 0x48 },413 { STV090x_STOPCLK2, 0x14 },414 { STV090x_TSTTNR1, 0x27 },415 { STV090x_TSTTNR2, 0x21 },416 { STV090x_P1_DISTXCTL, 0x22 },417 { STV090x_P1_F22TX, 0xc0 },418 { STV090x_P1_F22RX, 0xc0 },419 { STV090x_P1_DISRXCTL, 0x00 },420 { STV090x_P1_DMDCFGMD, 0xF9 },421 { STV090x_P1_DEMOD, 0x08 },422 { STV090x_P1_DMDCFG3, 0xc4 },423 { STV090x_P1_CARFREQ, 0xed },424 { STV090x_P1_TNRCFG2, 0x82 },425 { STV090x_P1_LDT, 0xd0 },426 { STV090x_P1_LDT2, 0xb8 },427 { STV090x_P1_TMGCFG, 0xd2 },428 { STV090x_P1_TMGTHRISE, 0x20 },429 { STV090x_P1_TMGTHFALL, 0x00 },430 { STV090x_P1_SFRUPRATIO, 0xf0 },431 { STV090x_P1_SFRLOWRATIO, 0x70 },432 { STV090x_P1_TSCFGL, 0x20 },433 { STV090x_P1_FECSPY, 0x88 },434 { STV090x_P1_FSPYDATA, 0x3a },435 { STV090x_P1_FBERCPT4, 0x00 },436 { STV090x_P1_FSPYBER, 0x10 },437 { STV090x_P1_ERRCTRL1, 0x35 },438 { STV090x_P1_ERRCTRL2, 0xc1 },439 { STV090x_P1_CFRICFG, 0xf8 },440 { STV090x_P1_NOSCFG, 0x1c },441 { STV090x_P1_DMDTOM, 0x20 },442 { STV090x_P1_CORRELMANT, 0x70 },443 { STV090x_P1_CORRELABS, 0x88 },444 { STV090x_P1_AGC2O, 0x5b },445 { STV090x_P1_AGC2REF, 0x38 },446 { STV090x_P1_CARCFG, 0xe4 },447 { STV090x_P1_ACLC, 0x1A },448 { STV090x_P1_BCLC, 0x09 },449 { STV090x_P1_CARHDR, 0x08 },450 { STV090x_P1_KREFTMG, 0xc1 },451 { STV090x_P1_SFRSTEP, 0x58 },452 { STV090x_P1_TMGCFG2, 0x01 },453 { STV090x_P1_CAR2CFG, 0x26 },454 { STV090x_P1_BCLC2S2Q, 0x86 },455 { STV090x_P1_BCLC2S28, 0x86 },456 { STV090x_P1_SMAPCOEF7, 0x77 },457 { STV090x_P1_SMAPCOEF6, 0x85 },458 { STV090x_P1_SMAPCOEF5, 0x77 },459 { STV090x_P1_DMDCFG2, 0x3b },460 { STV090x_P1_MODCODLST0, 0xff },461 { STV090x_P1_MODCODLST1, 0xff },462 { STV090x_P1_MODCODLST2, 0xff },463 { STV090x_P1_MODCODLST3, 0xff },464 { STV090x_P1_MODCODLST4, 0xff },465 { STV090x_P1_MODCODLST5, 0xff },466 { STV090x_P1_MODCODLST6, 0xff },467 { STV090x_P1_MODCODLST7, 0xcc },468 { STV090x_P1_MODCODLST8, 0xcc },469 { STV090x_P1_MODCODLST9, 0xcc },470 { STV090x_P1_MODCODLSTA, 0xcc },471 { STV090x_P1_MODCODLSTB, 0xcc },472 { STV090x_P1_MODCODLSTC, 0xcc },473 { STV090x_P1_MODCODLSTD, 0xcc },474 { STV090x_P1_MODCODLSTE, 0xcc },475 { STV090x_P1_MODCODLSTF, 0xcf },476 { STV090x_GENCFG, 0x1c },477 { STV090x_NBITER_NF4, 0x37 },478 { STV090x_NBITER_NF5, 0x29 },479 { STV090x_NBITER_NF6, 0x37 },480 { STV090x_NBITER_NF7, 0x33 },481 { STV090x_NBITER_NF8, 0x31 },482 { STV090x_NBITER_NF9, 0x2f },483 { STV090x_NBITER_NF10, 0x39 },484 { STV090x_NBITER_NF11, 0x3a },485 { STV090x_NBITER_NF12, 0x29 },486 { STV090x_NBITER_NF13, 0x37 },487 { STV090x_NBITER_NF14, 0x33 },488 { STV090x_NBITER_NF15, 0x2f },489 { STV090x_NBITER_NF16, 0x39 },490 { STV090x_NBITER_NF17, 0x3a },491 { STV090x_NBITERNOERR, 0x04 },492 { STV090x_GAINLLR_NF4, 0x0C },493 { STV090x_GAINLLR_NF5, 0x0F },494 { STV090x_GAINLLR_NF6, 0x11 },495 { STV090x_GAINLLR_NF7, 0x14 },496 { STV090x_GAINLLR_NF8, 0x17 },497 { STV090x_GAINLLR_NF9, 0x19 },498 { STV090x_GAINLLR_NF10, 0x20 },499 { STV090x_GAINLLR_NF11, 0x21 },500 { STV090x_GAINLLR_NF12, 0x0D },501 { STV090x_GAINLLR_NF13, 0x0F },502 { STV090x_GAINLLR_NF14, 0x13 },503 { STV090x_GAINLLR_NF15, 0x1A },504 { STV090x_GAINLLR_NF16, 0x1F },505 { STV090x_GAINLLR_NF17, 0x21 },506 { STV090x_RCCFGH, 0x20 },507 { STV090x_P1_FECM, 0x01 }, /*disable the DSS mode */508 { STV090x_P1_PRVIT, 0x2f } /*disable puncture rate 6/7*/509};510 511static struct stv090x_reg stv0900_cut20_val[] = {512 513 { STV090x_P2_DMDCFG3, 0xe8 },514 { STV090x_P2_DMDCFG4, 0x10 },515 { STV090x_P2_CARFREQ, 0x38 },516 { STV090x_P2_CARHDR, 0x20 },517 { STV090x_P2_KREFTMG, 0x5a },518 { STV090x_P2_SMAPCOEF7, 0x06 },519 { STV090x_P2_SMAPCOEF6, 0x00 },520 { STV090x_P2_SMAPCOEF5, 0x04 },521 { STV090x_P2_NOSCFG, 0x0c },522 { STV090x_P1_DMDCFG3, 0xe8 },523 { STV090x_P1_DMDCFG4, 0x10 },524 { STV090x_P1_CARFREQ, 0x38 },525 { STV090x_P1_CARHDR, 0x20 },526 { STV090x_P1_KREFTMG, 0x5a },527 { STV090x_P1_SMAPCOEF7, 0x06 },528 { STV090x_P1_SMAPCOEF6, 0x00 },529 { STV090x_P1_SMAPCOEF5, 0x04 },530 { STV090x_P1_NOSCFG, 0x0c },531 { STV090x_GAINLLR_NF4, 0x21 },532 { STV090x_GAINLLR_NF5, 0x21 },533 { STV090x_GAINLLR_NF6, 0x20 },534 { STV090x_GAINLLR_NF7, 0x1F },535 { STV090x_GAINLLR_NF8, 0x1E },536 { STV090x_GAINLLR_NF9, 0x1E },537 { STV090x_GAINLLR_NF10, 0x1D },538 { STV090x_GAINLLR_NF11, 0x1B },539 { STV090x_GAINLLR_NF12, 0x20 },540 { STV090x_GAINLLR_NF13, 0x20 },541 { STV090x_GAINLLR_NF14, 0x20 },542 { STV090x_GAINLLR_NF15, 0x20 },543 { STV090x_GAINLLR_NF16, 0x20 },544 { STV090x_GAINLLR_NF17, 0x21 },545};546 547static struct stv090x_reg stv0903_cut20_val[] = {548 { STV090x_P1_DMDCFG3, 0xe8 },549 { STV090x_P1_DMDCFG4, 0x10 },550 { STV090x_P1_CARFREQ, 0x38 },551 { STV090x_P1_CARHDR, 0x20 },552 { STV090x_P1_KREFTMG, 0x5a },553 { STV090x_P1_SMAPCOEF7, 0x06 },554 { STV090x_P1_SMAPCOEF6, 0x00 },555 { STV090x_P1_SMAPCOEF5, 0x04 },556 { STV090x_P1_NOSCFG, 0x0c },557 { STV090x_GAINLLR_NF4, 0x21 },558 { STV090x_GAINLLR_NF5, 0x21 },559 { STV090x_GAINLLR_NF6, 0x20 },560 { STV090x_GAINLLR_NF7, 0x1F },561 { STV090x_GAINLLR_NF8, 0x1E },562 { STV090x_GAINLLR_NF9, 0x1E },563 { STV090x_GAINLLR_NF10, 0x1D },564 { STV090x_GAINLLR_NF11, 0x1B },565 { STV090x_GAINLLR_NF12, 0x20 },566 { STV090x_GAINLLR_NF13, 0x20 },567 { STV090x_GAINLLR_NF14, 0x20 },568 { STV090x_GAINLLR_NF15, 0x20 },569 { STV090x_GAINLLR_NF16, 0x20 },570 { STV090x_GAINLLR_NF17, 0x21 }571};572 573/* Cut 2.0 Long Frame Tracking CR loop */574static struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = {575 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */576 { STV090x_QPSK_12, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x1e },577 { STV090x_QPSK_35, 0x2f, 0x3f, 0x2e, 0x2f, 0x3d, 0x0f, 0x0e, 0x2e, 0x3d, 0x0e },578 { STV090x_QPSK_23, 0x2f, 0x3f, 0x2e, 0x2f, 0x0e, 0x0f, 0x0e, 0x1e, 0x3d, 0x3d },579 { STV090x_QPSK_34, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },580 { STV090x_QPSK_45, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },581 { STV090x_QPSK_56, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },582 { STV090x_QPSK_89, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },583 { STV090x_QPSK_910, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },584 { STV090x_8PSK_35, 0x3c, 0x3e, 0x1c, 0x2e, 0x0c, 0x1e, 0x2b, 0x2d, 0x1b, 0x1d },585 { STV090x_8PSK_23, 0x1d, 0x3e, 0x3c, 0x2e, 0x2c, 0x1e, 0x0c, 0x2d, 0x2b, 0x1d },586 { STV090x_8PSK_34, 0x0e, 0x3e, 0x3d, 0x2e, 0x0d, 0x1e, 0x2c, 0x2d, 0x0c, 0x1d },587 { STV090x_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d },588 { STV090x_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d },589 { STV090x_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d }590};591 592/* Cut 3.0 Long Frame Tracking CR loop */593static struct stv090x_long_frame_crloop stv090x_s2_crl_cut30[] = {594 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */595 { STV090x_QPSK_12, 0x3c, 0x2c, 0x0c, 0x2c, 0x1b, 0x2c, 0x1b, 0x1c, 0x0b, 0x3b },596 { STV090x_QPSK_35, 0x0d, 0x0d, 0x0c, 0x0d, 0x1b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },597 { STV090x_QPSK_23, 0x1d, 0x0d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },598 { STV090x_QPSK_34, 0x1d, 0x1d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },599 { STV090x_QPSK_45, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },600 { STV090x_QPSK_56, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },601 { STV090x_QPSK_89, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },602 { STV090x_QPSK_910, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },603 { STV090x_8PSK_35, 0x39, 0x29, 0x39, 0x19, 0x19, 0x19, 0x19, 0x19, 0x09, 0x19 },604 { STV090x_8PSK_23, 0x2a, 0x39, 0x1a, 0x0a, 0x39, 0x0a, 0x29, 0x39, 0x29, 0x0a },605 { STV090x_8PSK_34, 0x2b, 0x3a, 0x1b, 0x1b, 0x3a, 0x1b, 0x1a, 0x0b, 0x1a, 0x3a },606 { STV090x_8PSK_56, 0x0c, 0x1b, 0x3b, 0x3b, 0x1b, 0x3b, 0x3a, 0x3b, 0x3a, 0x1b },607 { STV090x_8PSK_89, 0x0d, 0x3c, 0x2c, 0x2c, 0x2b, 0x0c, 0x0b, 0x3b, 0x0b, 0x1b },608 { STV090x_8PSK_910, 0x0d, 0x0d, 0x2c, 0x3c, 0x3b, 0x1c, 0x0b, 0x3b, 0x0b, 0x1b }609};610 611/* Cut 2.0 Long Frame Tracking CR Loop */612static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = {613 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */614 { STV090x_16APSK_23, 0x0c, 0x0c, 0x0c, 0x0c, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x0c },615 { STV090x_16APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0c, 0x2d, 0x0c, 0x1d, 0x0c },616 { STV090x_16APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },617 { STV090x_16APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },618 { STV090x_16APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },619 { STV090x_16APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },620 { STV090x_32APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },621 { STV090x_32APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },622 { STV090x_32APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },623 { STV090x_32APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },624 { STV090x_32APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }625};626 627/* Cut 3.0 Long Frame Tracking CR Loop */628static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut30[] = {629 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */630 { STV090x_16APSK_23, 0x0a, 0x0a, 0x0a, 0x0a, 0x1a, 0x0a, 0x3a, 0x0a, 0x2a, 0x0a },631 { STV090x_16APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x3b, 0x0a, 0x1b, 0x0a },632 { STV090x_16APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },633 { STV090x_16APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },634 { STV090x_16APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },635 { STV090x_16APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },636 { STV090x_32APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },637 { STV090x_32APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },638 { STV090x_32APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },639 { STV090x_32APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },640 { STV090x_32APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }641};642 643static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = {644 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */645 { STV090x_QPSK_14, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x2d, 0x1f, 0x3d, 0x3e },646 { STV090x_QPSK_13, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x3d, 0x0f, 0x3d, 0x2e },647 { STV090x_QPSK_25, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x2e }648};649 650static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut30[] = {651 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */652 { STV090x_QPSK_14, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x2a, 0x1c, 0x3a, 0x3b },653 { STV090x_QPSK_13, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x3a, 0x0c, 0x3a, 0x2b },654 { STV090x_QPSK_25, 0x1c, 0x3c, 0x1b, 0x3c, 0x3a, 0x1c, 0x3a, 0x3b, 0x3a, 0x2b }655};656 657/* Cut 2.0 Short Frame Tracking CR Loop */658static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = {659 /* MODCOD 2M 5M 10M 20M 30M */660 { STV090x_QPSK, 0x2f, 0x2e, 0x0e, 0x0e, 0x3d },661 { STV090x_8PSK, 0x3e, 0x0e, 0x2d, 0x0d, 0x3c },662 { STV090x_16APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d },663 { STV090x_32APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d }664};665 666/* Cut 3.0 Short Frame Tracking CR Loop */667static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = {668 /* MODCOD 2M 5M 10M 20M 30M */669 { STV090x_QPSK, 0x2C, 0x2B, 0x0B, 0x0B, 0x3A },670 { STV090x_8PSK, 0x3B, 0x0B, 0x2A, 0x0A, 0x39 },671 { STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },672 { STV090x_32APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A }673};674 675static inline s32 comp2(s32 __x, s32 __width)676{677 if (__width == 32)678 return __x;679 else680 return (__x >= (1 << (__width - 1))) ? (__x - (1 << __width)) : __x;681}682 683static int stv090x_read_reg(struct stv090x_state *state, unsigned int reg)684{685 const struct stv090x_config *config = state->config;686 int ret;687 688 u8 b0[] = { reg >> 8, reg & 0xff };689 u8 buf;690 691 struct i2c_msg msg[] = {692 { .addr = config->address, .flags = 0, .buf = b0, .len = 2 },693 { .addr = config->address, .flags = I2C_M_RD, .buf = &buf, .len = 1 }694 };695 696 ret = i2c_transfer(state->i2c, msg, 2);697 if (ret != 2) {698 if (ret != -ERESTARTSYS)699 dprintk(FE_ERROR, 1,700 "Read error, Reg=[0x%02x], Status=%d",701 reg, ret);702 703 return ret < 0 ? ret : -EREMOTEIO;704 }705 if (unlikely(*state->verbose >= FE_DEBUGREG))706 dprintk(FE_ERROR, 1, "Reg=[0x%02x], data=%02x",707 reg, buf);708 709 return (unsigned int) buf;710}711 712static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 *data, u32 count)713{714 const struct stv090x_config *config = state->config;715 int ret;716 u8 buf[MAX_XFER_SIZE];717 struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count };718 719 if (2 + count > sizeof(buf)) {720 printk(KERN_WARNING721 "%s: i2c wr reg=%04x: len=%d is too big!\n",722 KBUILD_MODNAME, reg, count);723 return -EINVAL;724 }725 726 buf[0] = reg >> 8;727 buf[1] = reg & 0xff;728 memcpy(&buf[2], data, count);729 730 dprintk(FE_DEBUGREG, 1, "%s [0x%04x]: %*ph",731 __func__, reg, count, data);732 733 ret = i2c_transfer(state->i2c, &i2c_msg, 1);734 if (ret != 1) {735 if (ret != -ERESTARTSYS)736 dprintk(FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",737 reg, data[0], count, ret);738 return ret < 0 ? ret : -EREMOTEIO;739 }740 741 return 0;742}743 744static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)745{746 u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */747 748 return stv090x_write_regs(state, reg, &tmp, 1);749}750 751static inline void stv090x_tuner_i2c_lock(struct stv090x_state *state)752{753 if (state->config->tuner_i2c_lock)754 state->config->tuner_i2c_lock(&state->frontend, 1);755 else756 mutex_lock(&state->internal->tuner_lock);757}758 759static inline void stv090x_tuner_i2c_unlock(struct stv090x_state *state)760{761 if (state->config->tuner_i2c_lock)762 state->config->tuner_i2c_lock(&state->frontend, 0);763 else764 mutex_unlock(&state->internal->tuner_lock);765}766 767static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)768{769 u32 reg;770 771 /*772 * NOTE! A lock is used as a FSM to control the state in which773 * access is serialized between two tuners on the same demod.774 * This has nothing to do with a lock to protect a critical section775 * which may in some other cases be confused with protecting I/O776 * access to the demodulator gate.777 * In case of any error, the lock is unlocked and exit within the778 * relevant operations themselves.779 */780 if (enable)781 stv090x_tuner_i2c_lock(state);782 783 reg = STV090x_READ_DEMOD(state, I2CRPT);784 if (enable) {785 dprintk(FE_DEBUG, 1, "Enable Gate");786 STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 1);787 if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0)788 goto err;789 790 } else {791 dprintk(FE_DEBUG, 1, "Disable Gate");792 STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 0);793 if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0)794 goto err;795 }796 797 if (!enable)798 stv090x_tuner_i2c_unlock(state);799 800 return 0;801err:802 dprintk(FE_ERROR, 1, "I/O error");803 stv090x_tuner_i2c_unlock(state);804 return -1;805}806 807static void stv090x_get_lock_tmg(struct stv090x_state *state)808{809 switch (state->algo) {810 case STV090x_BLIND_SEARCH:811 dprintk(FE_DEBUG, 1, "Blind Search");812 if (state->srate <= 1500000) { /*10Msps< SR <=15Msps*/813 state->DemodTimeout = 1500;814 state->FecTimeout = 400;815 } else if (state->srate <= 5000000) { /*10Msps< SR <=15Msps*/816 state->DemodTimeout = 1000;817 state->FecTimeout = 300;818 } else { /*SR >20Msps*/819 state->DemodTimeout = 700;820 state->FecTimeout = 100;821 }822 break;823 824 case STV090x_COLD_SEARCH:825 case STV090x_WARM_SEARCH:826 default:827 dprintk(FE_DEBUG, 1, "Normal Search");828 if (state->srate <= 1000000) { /*SR <=1Msps*/829 state->DemodTimeout = 4500;830 state->FecTimeout = 1700;831 } else if (state->srate <= 2000000) { /*1Msps < SR <= 2Msps */832 state->DemodTimeout = 2500;833 state->FecTimeout = 1100;834 } else if (state->srate <= 5000000) { /*2Msps < SR <= 5Msps */835 state->DemodTimeout = 1000;836 state->FecTimeout = 550;837 } else if (state->srate <= 10000000) { /*5Msps < SR <= 10Msps */838 state->DemodTimeout = 700;839 state->FecTimeout = 250;840 } else if (state->srate <= 20000000) { /*10Msps < SR <= 20Msps */841 state->DemodTimeout = 400;842 state->FecTimeout = 130;843 } else { /*SR >20Msps*/844 state->DemodTimeout = 300;845 state->FecTimeout = 100;846 }847 break;848 }849 850 if (state->algo == STV090x_WARM_SEARCH)851 state->DemodTimeout /= 2;852}853 854static int stv090x_set_srate(struct stv090x_state *state, u32 srate)855{856 u32 sym;857 858 if (srate > 60000000) {859 sym = (srate << 4); /* SR * 2^16 / master_clk */860 sym /= (state->internal->mclk >> 12);861 } else if (srate > 6000000) {862 sym = (srate << 6);863 sym /= (state->internal->mclk >> 10);864 } else {865 sym = (srate << 9);866 sym /= (state->internal->mclk >> 7);867 }868 869 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */870 goto err;871 if (STV090x_WRITE_DEMOD(state, SFRINIT0, (sym & 0xff)) < 0) /* LSB */872 goto err;873 874 return 0;875err:876 dprintk(FE_ERROR, 1, "I/O error");877 return -1;878}879 880static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate)881{882 u32 sym;883 884 srate = 105 * (srate / 100);885 if (srate > 60000000) {886 sym = (srate << 4); /* SR * 2^16 / master_clk */887 sym /= (state->internal->mclk >> 12);888 } else if (srate > 6000000) {889 sym = (srate << 6);890 sym /= (state->internal->mclk >> 10);891 } else {892 sym = (srate << 9);893 sym /= (state->internal->mclk >> 7);894 }895 896 if (sym < 0x7fff) {897 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) /* MSB */898 goto err;899 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) /* LSB */900 goto err;901 } else {902 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x7f) < 0) /* MSB */903 goto err;904 if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xff) < 0) /* LSB */905 goto err;906 }907 908 return 0;909err:910 dprintk(FE_ERROR, 1, "I/O error");911 return -1;912}913 914static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate)915{916 u32 sym;917 918 srate = 95 * (srate / 100);919 if (srate > 60000000) {920 sym = (srate << 4); /* SR * 2^16 / master_clk */921 sym /= (state->internal->mclk >> 12);922 } else if (srate > 6000000) {923 sym = (srate << 6);924 sym /= (state->internal->mclk >> 10);925 } else {926 sym = (srate << 9);927 sym /= (state->internal->mclk >> 7);928 }929 930 if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */931 goto err;932 if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */933 goto err;934 return 0;935err:936 dprintk(FE_ERROR, 1, "I/O error");937 return -1;938}939 940static u32 stv090x_car_width(u32 srate, enum stv090x_rolloff rolloff)941{942 u32 ro;943 944 switch (rolloff) {945 case STV090x_RO_20:946 ro = 20;947 break;948 case STV090x_RO_25:949 ro = 25;950 break;951 case STV090x_RO_35:952 default:953 ro = 35;954 break;955 }956 957 return srate + (srate * ro) / 100;958}959 960static int stv090x_set_vit_thacq(struct stv090x_state *state)961{962 if (STV090x_WRITE_DEMOD(state, VTH12, 0x96) < 0)963 goto err;964 if (STV090x_WRITE_DEMOD(state, VTH23, 0x64) < 0)965 goto err;966 if (STV090x_WRITE_DEMOD(state, VTH34, 0x36) < 0)967 goto err;968 if (STV090x_WRITE_DEMOD(state, VTH56, 0x23) < 0)969 goto err;970 if (STV090x_WRITE_DEMOD(state, VTH67, 0x1e) < 0)971 goto err;972 if (STV090x_WRITE_DEMOD(state, VTH78, 0x19) < 0)973 goto err;974 return 0;975err:976 dprintk(FE_ERROR, 1, "I/O error");977 return -1;978}979 980static int stv090x_set_vit_thtracq(struct stv090x_state *state)981{982 if (STV090x_WRITE_DEMOD(state, VTH12, 0xd0) < 0)983 goto err;984 if (STV090x_WRITE_DEMOD(state, VTH23, 0x7d) < 0)985 goto err;986 if (STV090x_WRITE_DEMOD(state, VTH34, 0x53) < 0)987 goto err;988 if (STV090x_WRITE_DEMOD(state, VTH56, 0x2f) < 0)989 goto err;990 if (STV090x_WRITE_DEMOD(state, VTH67, 0x24) < 0)991 goto err;992 if (STV090x_WRITE_DEMOD(state, VTH78, 0x1f) < 0)993 goto err;994 return 0;995err:996 dprintk(FE_ERROR, 1, "I/O error");997 return -1;998}999 1000static int stv090x_set_viterbi(struct stv090x_state *state)1001{1002 switch (state->search_mode) {1003 case STV090x_SEARCH_AUTO:1004 if (STV090x_WRITE_DEMOD(state, FECM, 0x10) < 0) /* DVB-S and DVB-S2 */1005 goto err;1006 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x3f) < 0) /* all puncture rate */1007 goto err;1008 break;1009 case STV090x_SEARCH_DVBS1:1010 if (STV090x_WRITE_DEMOD(state, FECM, 0x00) < 0) /* disable DSS */1011 goto err;1012 switch (state->fec) {1013 case STV090x_PR12:1014 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)1015 goto err;1016 break;1017 1018 case STV090x_PR23:1019 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)1020 goto err;1021 break;1022 1023 case STV090x_PR34:1024 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x04) < 0)1025 goto err;1026 break;1027 1028 case STV090x_PR56:1029 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x08) < 0)1030 goto err;1031 break;1032 1033 case STV090x_PR78:1034 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x20) < 0)1035 goto err;1036 break;1037 1038 default:1039 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x2f) < 0) /* all */1040 goto err;1041 break;1042 }1043 break;1044 case STV090x_SEARCH_DSS:1045 if (STV090x_WRITE_DEMOD(state, FECM, 0x80) < 0)1046 goto err;1047 switch (state->fec) {1048 case STV090x_PR12:1049 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)1050 goto err;1051 break;1052 1053 case STV090x_PR23:1054 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)1055 goto err;1056 break;1057 1058 case STV090x_PR67:1059 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x10) < 0)1060 goto err;1061 break;1062 1063 default:1064 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x13) < 0) /* 1/2, 2/3, 6/7 */1065 goto err;1066 break;1067 }1068 break;1069 default:1070 break;1071 }1072 return 0;1073err:1074 dprintk(FE_ERROR, 1, "I/O error");1075 return -1;1076}1077 1078static int stv090x_stop_modcod(struct stv090x_state *state)1079{1080 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)1081 goto err;1082 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)1083 goto err;1084 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)1085 goto err;1086 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)1087 goto err;1088 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)1089 goto err;1090 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)1091 goto err;1092 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)1093 goto err;1094 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xff) < 0)1095 goto err;1096 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xff) < 0)1097 goto err;1098 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xff) < 0)1099 goto err;1100 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xff) < 0)1101 goto err;1102 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xff) < 0)1103 goto err;1104 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xff) < 0)1105 goto err;1106 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xff) < 0)1107 goto err;1108 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)1109 goto err;1110 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xff) < 0)1111 goto err;1112 return 0;1113err:1114 dprintk(FE_ERROR, 1, "I/O error");1115 return -1;1116}1117 1118static int stv090x_activate_modcod(struct stv090x_state *state)1119{1120 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)1121 goto err;1122 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xfc) < 0)1123 goto err;1124 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xcc) < 0)1125 goto err;1126 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xcc) < 0)1127 goto err;1128 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xcc) < 0)1129 goto err;1130 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xcc) < 0)1131 goto err;1132 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xcc) < 0)1133 goto err;1134 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)1135 goto err;1136 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)1137 goto err;1138 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)1139 goto err;1140 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)1141 goto err;1142 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)1143 goto err;1144 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)1145 goto err;1146 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)1147 goto err;1148 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xcc) < 0)1149 goto err;1150 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)1151 goto err;1152 1153 return 0;1154err:1155 dprintk(FE_ERROR, 1, "I/O error");1156 return -1;1157}1158 1159static int stv090x_activate_modcod_single(struct stv090x_state *state)1160{1161 1162 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)1163 goto err;1164 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xf0) < 0)1165 goto err;1166 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0x00) < 0)1167 goto err;1168 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0x00) < 0)1169 goto err;1170 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0x00) < 0)1171 goto err;1172 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0x00) < 0)1173 goto err;1174 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0x00) < 0)1175 goto err;1176 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0x00) < 0)1177 goto err;1178 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0x00) < 0)1179 goto err;1180 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0x00) < 0)1181 goto err;1182 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0x00) < 0)1183 goto err;1184 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0x00) < 0)1185 goto err;1186 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0x00) < 0)1187 goto err;1188 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0x00) < 0)1189 goto err;1190 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0x00) < 0)1191 goto err;1192 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0x0f) < 0)1193 goto err;1194 1195 return 0;1196 1197err:1198 dprintk(FE_ERROR, 1, "I/O error");1199 return -1;1200}1201 1202static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable)1203{1204 u32 reg;1205 1206 switch (state->demod) {1207 case STV090x_DEMODULATOR_0:1208 mutex_lock(&state->internal->demod_lock);1209 reg = stv090x_read_reg(state, STV090x_STOPCLK2);1210 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable);1211 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)1212 goto err;1213 mutex_unlock(&state->internal->demod_lock);1214 break;1215 1216 case STV090x_DEMODULATOR_1:1217 mutex_lock(&state->internal->demod_lock);1218 reg = stv090x_read_reg(state, STV090x_STOPCLK2);1219 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable);1220 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)1221 goto err;1222 mutex_unlock(&state->internal->demod_lock);1223 break;1224 1225 default:1226 dprintk(FE_ERROR, 1, "Wrong demodulator!");1227 break;1228 }1229 return 0;1230err:1231 mutex_unlock(&state->internal->demod_lock);1232 dprintk(FE_ERROR, 1, "I/O error");1233 return -1;1234}1235 1236static int stv090x_dvbs_track_crl(struct stv090x_state *state)1237{1238 if (state->internal->dev_ver >= 0x30) {1239 /* Set ACLC BCLC optimised value vs SR */1240 if (state->srate >= 15000000) {1241 if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0)1242 goto err;1243 if (STV090x_WRITE_DEMOD(state, BCLC, 0x1a) < 0)1244 goto err;1245 } else if ((state->srate >= 7000000) && (15000000 > state->srate)) {1246 if (STV090x_WRITE_DEMOD(state, ACLC, 0x0c) < 0)1247 goto err;1248 if (STV090x_WRITE_DEMOD(state, BCLC, 0x1b) < 0)1249 goto err;1250 } else if (state->srate < 7000000) {1251 if (STV090x_WRITE_DEMOD(state, ACLC, 0x2c) < 0)1252 goto err;1253 if (STV090x_WRITE_DEMOD(state, BCLC, 0x1c) < 0)1254 goto err;1255 }1256 1257 } else {1258 /* Cut 2.0 */1259 if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0)1260 goto err;1261 if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)1262 goto err;1263 }1264 return 0;1265err:1266 dprintk(FE_ERROR, 1, "I/O error");1267 return -1;1268}1269 1270static int stv090x_delivery_search(struct stv090x_state *state)1271{1272 u32 reg;1273 1274 switch (state->search_mode) {1275 case STV090x_SEARCH_DVBS1:1276 case STV090x_SEARCH_DSS:1277 reg = STV090x_READ_DEMOD(state, DMDCFGMD);1278 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);1279 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);1280 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)1281 goto err;1282 1283 /* Activate Viterbi decoder in legacy search,1284 * do not use FRESVIT1, might impact VITERBI21285 */1286 if (stv090x_vitclk_ctl(state, 0) < 0)1287 goto err;1288 1289 if (stv090x_dvbs_track_crl(state) < 0)1290 goto err;1291 1292 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x22) < 0) /* disable DVB-S2 */1293 goto err;1294 1295 if (stv090x_set_vit_thacq(state) < 0)1296 goto err;1297 if (stv090x_set_viterbi(state) < 0)1298 goto err;1299 break;1300 1301 case STV090x_SEARCH_DVBS2:1302 reg = STV090x_READ_DEMOD(state, DMDCFGMD);1303 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);1304 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);1305 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)1306 goto err;1307 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);1308 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);1309 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)1310 goto err;1311 1312 if (stv090x_vitclk_ctl(state, 1) < 0)1313 goto err;1314 1315 if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) /* stop DVB-S CR loop */1316 goto err;1317 if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)1318 goto err;1319 1320 if (state->internal->dev_ver <= 0x20) {1321 /* enable S2 carrier loop */1322 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)1323 goto err;1324 } else {1325 /* > Cut 3: Stop carrier 3 */1326 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)1327 goto err;1328 }1329 1330 if (state->demod_mode != STV090x_SINGLE) {1331 /* Cut 2: enable link during search */1332 if (stv090x_activate_modcod(state) < 0)1333 goto err;1334 } else {1335 /* Single demodulator1336 * Authorize SHORT and LONG frames,1337 * QPSK, 8PSK, 16APSK and 32APSK1338 */1339 if (stv090x_activate_modcod_single(state) < 0)1340 goto err;1341 }1342 1343 if (stv090x_set_vit_thtracq(state) < 0)1344 goto err;1345 break;1346 1347 case STV090x_SEARCH_AUTO:1348 default:1349 /* enable DVB-S2 and DVB-S2 in Auto MODE */1350 reg = STV090x_READ_DEMOD(state, DMDCFGMD);1351 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);1352 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);1353 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)1354 goto err;1355 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);1356 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);1357 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)1358 goto err;1359 1360 if (stv090x_vitclk_ctl(state, 0) < 0)1361 goto err;1362 1363 if (stv090x_dvbs_track_crl(state) < 0)1364 goto err;1365 1366 if (state->internal->dev_ver <= 0x20) {1367 /* enable S2 carrier loop */1368 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)1369 goto err;1370 } else {1371 /* > Cut 3: Stop carrier 3 */1372 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)1373 goto err;1374 }1375 1376 if (state->demod_mode != STV090x_SINGLE) {1377 /* Cut 2: enable link during search */1378 if (stv090x_activate_modcod(state) < 0)1379 goto err;1380 } else {1381 /* Single demodulator1382 * Authorize SHORT and LONG frames,1383 * QPSK, 8PSK, 16APSK and 32APSK1384 */1385 if (stv090x_activate_modcod_single(state) < 0)1386 goto err;1387 }1388 1389 if (stv090x_set_vit_thacq(state) < 0)1390 goto err;1391 1392 if (stv090x_set_viterbi(state) < 0)1393 goto err;1394 break;1395 }1396 return 0;1397err:1398 dprintk(FE_ERROR, 1, "I/O error");1399 return -1;1400}1401 1402static int stv090x_start_search(struct stv090x_state *state)1403{1404 u32 reg, freq_abs;1405 s16 freq;1406 1407 /* Reset demodulator */1408 reg = STV090x_READ_DEMOD(state, DMDISTATE);1409 STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f);1410 if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)1411 goto err;1412 1413 if (state->internal->dev_ver <= 0x20) {1414 if (state->srate <= 5000000) {1415 if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0)1416 goto err;1417 if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0)1418 goto err;1419 if (STV090x_WRITE_DEMOD(state, CFRUP0, 0xff) < 0)1420 goto err;1421 if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0)1422 goto err;1423 if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0)1424 goto err;1425 1426 /*enlarge the timing bandwidth for Low SR*/1427 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0)1428 goto err;1429 } else {1430 /* If the symbol rate is >5 Msps1431 Set The carrier search up and low to auto mode */1432 if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)1433 goto err;1434 /*reduce the timing bandwidth for high SR*/1435 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)1436 goto err;1437 }1438 } else {1439 /* >= Cut 3 */1440 if (state->srate <= 5000000) {1441 /* enlarge the timing bandwidth for Low SR */1442 STV090x_WRITE_DEMOD(state, RTCS2, 0x68);1443 } else {1444 /* reduce timing bandwidth for high SR */1445 STV090x_WRITE_DEMOD(state, RTCS2, 0x44);1446 }1447 1448 /* Set CFR min and max to manual mode */1449 STV090x_WRITE_DEMOD(state, CARCFG, 0x46);1450 1451 if (state->algo == STV090x_WARM_SEARCH) {1452 /* WARM Start1453 * CFR min = -1MHz,1454 * CFR max = +1MHz1455 */1456 freq_abs = 1000 << 16;1457 freq_abs /= (state->internal->mclk / 1000);1458 freq = (s16) freq_abs;1459 } else {1460 /* COLD Start1461 * CFR min =- (SearchRange / 2 + 600KHz)1462 * CFR max = +(SearchRange / 2 + 600KHz)1463 * (600KHz for the tuner step size)1464 */1465 freq_abs = (state->search_range / 2000) + 600;1466 freq_abs = freq_abs << 16;1467 freq_abs /= (state->internal->mclk / 1000);1468 freq = (s16) freq_abs;1469 }1470 1471 if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0)1472 goto err;1473 if (STV090x_WRITE_DEMOD(state, CFRUP0, LSB(freq)) < 0)1474 goto err;1475 1476 freq *= -1;1477 1478 if (STV090x_WRITE_DEMOD(state, CFRLOW1, MSB(freq)) < 0)1479 goto err;1480 if (STV090x_WRITE_DEMOD(state, CFRLOW0, LSB(freq)) < 0)1481 goto err;1482 1483 }1484 1485 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0) < 0)1486 goto err;1487 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0)1488 goto err;1489 1490 if (state->internal->dev_ver >= 0x20) {1491 if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)1492 goto err;1493 if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)1494 goto err;1495 1496 if ((state->search_mode == STV090x_SEARCH_DVBS1) ||1497 (state->search_mode == STV090x_SEARCH_DSS) ||1498 (state->search_mode == STV090x_SEARCH_AUTO)) {1499 1500 if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)1501 goto err;1502 if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0)1503 goto err;1504 }1505 }1506 1507 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00) < 0)1508 goto err;1509 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xe0) < 0)1510 goto err;1511 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xc0) < 0)1512 goto err;1513 1514 reg = STV090x_READ_DEMOD(state, DMDCFGMD);1515 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);1516 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);1517 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)1518 goto err;1519 reg = STV090x_READ_DEMOD(state, DMDCFG2);1520 STV090x_SETFIELD_Px(reg, S1S2_SEQUENTIAL_FIELD, 0x0);1521 if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0)1522 goto err;1523 1524 if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0)1525 goto err;1526 1527 if (state->internal->dev_ver >= 0x20) {1528 /*Frequency offset detector setting*/1529 if (state->srate < 2000000) {1530 if (state->internal->dev_ver <= 0x20) {1531 /* Cut 2 */1532 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)1533 goto err;1534 } else {1535 /* Cut 3 */1536 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0)1537 goto err;1538 }1539 if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0)1540 goto err;1541 } else if (state->srate < 10000000) {1542 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0)1543 goto err;1544 if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)1545 goto err;1546 } else {1547 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0)1548 goto err;1549 if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)1550 goto err;1551 }1552 } else {1553 if (state->srate < 10000000) {1554 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0)1555 goto err;1556 } else {1557 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0)1558 goto err;1559 }1560 }1561 1562 switch (state->algo) {1563 case STV090x_WARM_SEARCH:1564 /* The symbol rate and the exact1565 * carrier Frequency are known1566 */1567 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)1568 goto err;1569 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)1570 goto err;1571 break;1572 1573 case STV090x_COLD_SEARCH:1574 /* The symbol rate is known */1575 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)1576 goto err;1577 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)1578 goto err;1579 break;1580 1581 default:1582 break;1583 }1584 return 0;1585err:1586 dprintk(FE_ERROR, 1, "I/O error");1587 return -1;1588}1589 1590static int stv090x_get_agc2_min_level(struct stv090x_state *state)1591{1592 u32 agc2_min = 0xffff, agc2 = 0, freq_init, freq_step, reg;1593 s32 i, j, steps, dir;1594 1595 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)1596 goto err;1597 reg = STV090x_READ_DEMOD(state, DMDCFGMD);1598 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);1599 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);1600 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)1601 goto err;1602 1603 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) /* SR = 65 Msps Max */1604 goto err;1605 if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)1606 goto err;1607 if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) /* SR= 400 ksps Min */1608 goto err;1609 if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)1610 goto err;1611 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) /* stop acq @ coarse carrier state */1612 goto err;1613 if (stv090x_set_srate(state, 1000000) < 0)1614 goto err;1615 1616 steps = state->search_range / 1000000;1617 if (steps <= 0)1618 steps = 1;1619 1620 dir = 1;1621 freq_step = (1000000 * 256) / (state->internal->mclk / 256);1622 freq_init = 0;1623 1624 for (i = 0; i < steps; i++) {1625 if (dir > 0)1626 freq_init = freq_init + (freq_step * i);1627 else1628 freq_init = freq_init - (freq_step * i);1629 1630 dir *= -1;1631 1632 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */1633 goto err;1634 if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_init >> 8) & 0xff) < 0)1635 goto err;1636 if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_init & 0xff) < 0)1637 goto err;1638 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */1639 goto err;1640 msleep(10);1641 1642 agc2 = 0;1643 for (j = 0; j < 10; j++) {1644 agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |1645 STV090x_READ_DEMOD(state, AGC2I0);1646 }1647 agc2 /= 10;1648 if (agc2 < agc2_min)1649 agc2_min = agc2;1650 }1651 1652 return agc2_min;1653err:1654 dprintk(FE_ERROR, 1, "I/O error");1655 return -1;1656}1657 1658static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk)1659{1660 u8 r3, r2, r1, r0;1661 s32 srate, int_1, int_2, tmp_1, tmp_2;1662 1663 r3 = STV090x_READ_DEMOD(state, SFR3);1664 r2 = STV090x_READ_DEMOD(state, SFR2);1665 r1 = STV090x_READ_DEMOD(state, SFR1);1666 r0 = STV090x_READ_DEMOD(state, SFR0);1667 1668 srate = ((r3 << 24) | (r2 << 16) | (r1 << 8) | r0);1669 1670 int_1 = clk >> 16;1671 int_2 = srate >> 16;1672 1673 tmp_1 = clk % 0x10000;1674 tmp_2 = srate % 0x10000;1675 1676 srate = (int_1 * int_2) +1677 ((int_1 * tmp_2) >> 16) +1678 ((int_2 * tmp_1) >> 16);1679 1680 return srate;1681}1682 1683static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)1684{1685 struct dvb_frontend *fe = &state->frontend;1686 1687 int tmg_lock = 0, i;1688 s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq;1689 u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;1690 u32 agc2th;1691 1692 if (state->internal->dev_ver >= 0x30)1693 agc2th = 0x2e00;1694 else1695 agc2th = 0x1f00;1696 1697 reg = STV090x_READ_DEMOD(state, DMDISTATE);1698 STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */1699 if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)1700 goto err;1701 if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0)1702 goto err;1703 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0)1704 goto err;1705 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0)1706 goto err;1707 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0)1708 goto err;1709 reg = STV090x_READ_DEMOD(state, DMDCFGMD);1710 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);1711 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);1712 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)1713 goto err;1714 1715 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0)1716 goto err;1717 if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)1718 goto err;1719 if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0)1720 goto err;1721 if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)1722 goto err;1723 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0)1724 goto err;1725 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0)1726 goto err;1727 1728 if (state->internal->dev_ver >= 0x30) {1729 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)1730 goto err;1731 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0)1732 goto err;1733 1734 } else if (state->internal->dev_ver >= 0x20) {1735 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0)1736 goto err;1737 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)1738 goto err;1739 }1740 1741 if (state->srate <= 2000000)1742 car_step = 1000;1743 else if (state->srate <= 5000000)1744 car_step = 2000;1745 else if (state->srate <= 12000000)1746 car_step = 3000;1747 else1748 car_step = 5000;1749 1750 steps = -1 + ((state->search_range / 1000) / car_step);1751 steps /= 2;1752 steps = (2 * steps) + 1;1753 if (steps < 0)1754 steps = 1;1755 else if (steps > 10) {1756 steps = 11;1757 car_step = (state->search_range / 1000) / 10;1758 }1759 cur_step = 0;1760 dir = 1;1761 freq = state->frequency;1762 1763 while ((!tmg_lock) && (cur_step < steps)) {1764 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */1765 goto err;1766 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)1767 goto err;1768 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)1769 goto err;1770 if (STV090x_WRITE_DEMOD(state, SFRINIT1, 0x00) < 0)1771 goto err;1772 if (STV090x_WRITE_DEMOD(state, SFRINIT0, 0x00) < 0)1773 goto err;1774 /* trigger acquisition */1775 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x40) < 0)1776 goto err;1777 msleep(50);1778 for (i = 0; i < 10; i++) {1779 reg = STV090x_READ_DEMOD(state, DSTATUS);1780 if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)1781 tmg_cpt++;1782 agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |1783 STV090x_READ_DEMOD(state, AGC2I0);1784 }1785 agc2 /= 10;1786 srate_coarse = stv090x_get_srate(state, state->internal->mclk);1787 cur_step++;1788 dir *= -1;1789 if ((tmg_cpt >= 5) && (agc2 < agc2th) &&1790 (srate_coarse < 50000000) && (srate_coarse > 850000))1791 tmg_lock = 1;1792 else if (cur_step < steps) {1793 if (dir > 0)1794 freq += cur_step * car_step;1795 else1796 freq -= cur_step * car_step;1797 1798 /* Setup tuner */1799 if (stv090x_i2c_gate_ctrl(state, 1) < 0)1800 goto err;1801 1802 if (state->config->tuner_set_frequency) {1803 if (state->config->tuner_set_frequency(fe, freq) < 0)1804 goto err_gateoff;1805 }1806 1807 if (state->config->tuner_set_bandwidth) {1808 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)1809 goto err_gateoff;1810 }1811 1812 if (stv090x_i2c_gate_ctrl(state, 0) < 0)1813 goto err;1814 1815 msleep(50);1816 1817 if (stv090x_i2c_gate_ctrl(state, 1) < 0)1818 goto err;1819 1820 if (state->config->tuner_get_status) {1821 if (state->config->tuner_get_status(fe, ®) < 0)1822 goto err_gateoff;1823 }1824 1825 if (reg)1826 dprintk(FE_DEBUG, 1, "Tuner phase locked");1827 else1828 dprintk(FE_DEBUG, 1, "Tuner unlocked");1829 1830 if (stv090x_i2c_gate_ctrl(state, 0) < 0)1831 goto err;1832 1833 }1834 }1835 if (!tmg_lock)1836 srate_coarse = 0;1837 else1838 srate_coarse = stv090x_get_srate(state, state->internal->mclk);1839 1840 return srate_coarse;1841 1842err_gateoff:1843 stv090x_i2c_gate_ctrl(state, 0);1844err:1845 dprintk(FE_ERROR, 1, "I/O error");1846 return -1;1847}1848 1849static u32 stv090x_srate_srch_fine(struct stv090x_state *state)1850{1851 u32 srate_coarse, freq_coarse, sym, reg;1852 1853 srate_coarse = stv090x_get_srate(state, state->internal->mclk);1854 freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8;1855 freq_coarse |= STV090x_READ_DEMOD(state, CFR1);1856 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */1857 1858 if (sym < state->srate)1859 srate_coarse = 0;1860 else {1861 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */1862 goto err;1863 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)1864 goto err;1865 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)1866 goto err;1867 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)1868 goto err;1869 if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)1870 goto err;1871 reg = STV090x_READ_DEMOD(state, DMDCFGMD);1872 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);1873 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)1874 goto err;1875 1876 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)1877 goto err;1878 1879 if (state->internal->dev_ver >= 0x30) {1880 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)1881 goto err;1882 } else if (state->internal->dev_ver >= 0x20) {1883 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)1884 goto err;1885 }1886 1887 if (srate_coarse > 3000000) {1888 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */1889 sym = (sym / 1000) * 65536;1890 sym /= (state->internal->mclk / 1000);1891 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)1892 goto err;1893 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)1894 goto err;1895 sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */1896 sym = (sym / 1000) * 65536;1897 sym /= (state->internal->mclk / 1000);1898 if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)1899 goto err;1900 if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)1901 goto err;1902 sym = (srate_coarse / 1000) * 65536;1903 sym /= (state->internal->mclk / 1000);1904 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)1905 goto err;1906 if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)1907 goto err;1908 } else {1909 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */1910 sym = (sym / 100) * 65536;1911 sym /= (state->internal->mclk / 100);1912 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)1913 goto err;1914 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)1915 goto err;1916 sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */1917 sym = (sym / 100) * 65536;1918 sym /= (state->internal->mclk / 100);1919 if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)1920 goto err;1921 if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)1922 goto err;1923 sym = (srate_coarse / 100) * 65536;1924 sym /= (state->internal->mclk / 100);1925 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)1926 goto err;1927 if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)1928 goto err;1929 }1930 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)1931 goto err;1932 if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_coarse >> 8) & 0xff) < 0)1933 goto err;1934 if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_coarse & 0xff) < 0)1935 goto err;1936 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) /* trigger acquisition */1937 goto err;1938 }1939 1940 return srate_coarse;1941 1942err:1943 dprintk(FE_ERROR, 1, "I/O error");1944 return -1;1945}1946 1947static int stv090x_get_dmdlock(struct stv090x_state *state, s32 timeout)1948{1949 s32 timer = 0, lock = 0;1950 u32 reg;1951 u8 stat;1952 1953 while ((timer < timeout) && (!lock)) {1954 reg = STV090x_READ_DEMOD(state, DMDSTATE);1955 stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);1956 1957 switch (stat) {1958 case 0: /* searching */1959 case 1: /* first PLH detected */1960 default:1961 dprintk(FE_DEBUG, 1, "Demodulator searching ..");1962 lock = 0;1963 break;1964 case 2: /* DVB-S2 mode */1965 case 3: /* DVB-S1/legacy mode */1966 reg = STV090x_READ_DEMOD(state, DSTATUS);1967 lock = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);1968 break;1969 }1970 1971 if (!lock)1972 msleep(10);1973 else1974 dprintk(FE_DEBUG, 1, "Demodulator acquired LOCK");1975 1976 timer += 10;1977 }1978 return lock;1979}1980 1981static int stv090x_blind_search(struct stv090x_state *state)1982{1983 u32 agc2, reg, srate_coarse;1984 s32 cpt_fail, agc2_ovflw, i;1985 u8 k_ref, k_max, k_min;1986 int coarse_fail = 0;1987 int lock;1988 1989 k_max = 110;1990 k_min = 10;1991 1992 agc2 = stv090x_get_agc2_min_level(state);1993 1994 if (agc2 > STV090x_SEARCH_AGC2_TH(state->internal->dev_ver)) {1995 lock = 0;1996 } else {1997 1998 if (state->internal->dev_ver <= 0x20) {1999 if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)2000 goto err;2001 } else {2002 /* > Cut 3 */2003 if (STV090x_WRITE_DEMOD(state, CARCFG, 0x06) < 0)2004 goto err;2005 }2006 2007 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)2008 goto err;2009 2010 if (state->internal->dev_ver >= 0x20) {2011 if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)2012 goto err;2013 if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)2014 goto err;2015 if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)2016 goto err;2017 if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) /* set viterbi hysteresis */2018 goto err;2019 }2020 2021 k_ref = k_max;2022 do {2023 if (STV090x_WRITE_DEMOD(state, KREFTMG, k_ref) < 0)2024 goto err;2025 if (stv090x_srate_srch_coarse(state) != 0) {2026 srate_coarse = stv090x_srate_srch_fine(state);2027 if (srate_coarse != 0) {2028 stv090x_get_lock_tmg(state);2029 lock = stv090x_get_dmdlock(state,2030 state->DemodTimeout);2031 } else {2032 lock = 0;2033 }2034 } else {2035 cpt_fail = 0;2036 agc2_ovflw = 0;2037 for (i = 0; i < 10; i++) {2038 agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |2039 STV090x_READ_DEMOD(state, AGC2I0);2040 if (agc2 >= 0xff00)2041 agc2_ovflw++;2042 reg = STV090x_READ_DEMOD(state, DSTATUS2);2043 if ((STV090x_GETFIELD_Px(reg, CFR_OVERFLOW_FIELD) == 0x01) &&2044 (STV090x_GETFIELD_Px(reg, DEMOD_DELOCK_FIELD) == 0x01))2045 2046 cpt_fail++;2047 }2048 if ((cpt_fail > 7) || (agc2_ovflw > 7))2049 coarse_fail = 1;2050 2051 lock = 0;2052 }2053 k_ref -= 20;2054 } while ((k_ref >= k_min) && (!lock) && (!coarse_fail));2055 }2056 2057 return lock;2058 2059err:2060 dprintk(FE_ERROR, 1, "I/O error");2061 return -1;2062}2063 2064static int stv090x_chk_tmg(struct stv090x_state *state)2065{2066 u32 reg;2067 s32 tmg_cpt = 0, i;2068 u8 freq, tmg_thh, tmg_thl;2069 int tmg_lock = 0;2070 2071 freq = STV090x_READ_DEMOD(state, CARFREQ);2072 tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE);2073 tmg_thl = STV090x_READ_DEMOD(state, TMGTHFALL);2074 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)2075 goto err;2076 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)2077 goto err;2078 2079 reg = STV090x_READ_DEMOD(state, DMDCFGMD);2080 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); /* stop carrier offset search */2081 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)2082 goto err;2083 if (STV090x_WRITE_DEMOD(state, RTC, 0x80) < 0)2084 goto err;2085 2086 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x40) < 0)2087 goto err;2088 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x00) < 0)2089 goto err;2090 2091 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) /* set car ofset to 0 */2092 goto err;2093 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)2094 goto err;2095 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x65) < 0)2096 goto err;2097 2098 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* trigger acquisition */2099 goto err;2100 msleep(10);2101 2102 for (i = 0; i < 10; i++) {2103 reg = STV090x_READ_DEMOD(state, DSTATUS);2104 if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)2105 tmg_cpt++;2106 msleep(1);2107 }2108 if (tmg_cpt >= 3)2109 tmg_lock = 1;2110 2111 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)2112 goto err;2113 if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) /* DVB-S1 timing */2114 goto err;2115 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) /* DVB-S2 timing */2116 goto err;2117 2118 if (STV090x_WRITE_DEMOD(state, CARFREQ, freq) < 0)2119 goto err;2120 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, tmg_thh) < 0)2121 goto err;2122 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, tmg_thl) < 0)2123 goto err;2124 2125 return tmg_lock;2126 2127err:2128 dprintk(FE_ERROR, 1, "I/O error");2129 return -1;2130}2131 2132static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)2133{2134 struct dvb_frontend *fe = &state->frontend;2135 2136 u32 reg;2137 s32 car_step, steps, cur_step, dir, freq, timeout_lock;2138 int lock;2139 2140 if (state->srate >= 10000000)2141 timeout_lock = timeout_dmd / 3;2142 else2143 timeout_lock = timeout_dmd / 2;2144 2145 lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */2146 if (lock)2147 return lock;2148 2149 if (state->srate >= 10000000) {2150 if (stv090x_chk_tmg(state)) {2151 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)2152 goto err;2153 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)2154 goto err;2155 return stv090x_get_dmdlock(state, timeout_dmd);2156 }2157 return 0;2158 }2159 2160 if (state->srate <= 4000000)2161 car_step = 1000;2162 else if (state->srate <= 7000000)2163 car_step = 2000;2164 else if (state->srate <= 10000000)2165 car_step = 3000;2166 else2167 car_step = 5000;2168 2169 steps = (state->search_range / 1000) / car_step;2170 steps /= 2;2171 steps = 2 * (steps + 1);2172 if (steps < 0)2173 steps = 2;2174 else if (steps > 12)2175 steps = 12;2176 2177 cur_step = 1;2178 dir = 1;2179 2180 freq = state->frequency;2181 state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;2182 while ((cur_step <= steps) && (!lock)) {2183 if (dir > 0)2184 freq += cur_step * car_step;2185 else2186 freq -= cur_step * car_step;2187 2188 /* Setup tuner */2189 if (stv090x_i2c_gate_ctrl(state, 1) < 0)2190 goto err;2191 2192 if (state->config->tuner_set_frequency) {2193 if (state->config->tuner_set_frequency(fe, freq) < 0)2194 goto err_gateoff;2195 }2196 2197 if (state->config->tuner_set_bandwidth) {2198 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)2199 goto err_gateoff;2200 }2201 2202 if (stv090x_i2c_gate_ctrl(state, 0) < 0)2203 goto err;2204 2205 msleep(50);2206 2207 if (stv090x_i2c_gate_ctrl(state, 1) < 0)2208 goto err;2209 2210 if (state->config->tuner_get_status) {2211 if (state->config->tuner_get_status(fe, ®) < 0)2212 goto err_gateoff;2213 if (reg)2214 dprintk(FE_DEBUG, 1, "Tuner phase locked");2215 else2216 dprintk(FE_DEBUG, 1, "Tuner unlocked");2217 }2218 2219 if (stv090x_i2c_gate_ctrl(state, 0) < 0)2220 goto err;2221 2222 STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);2223 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)2224 goto err;2225 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)2226 goto err;2227 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)2228 goto err;2229 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)2230 goto err;2231 lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));2232 2233 dir *= -1;2234 cur_step++;2235 }2236 2237 return lock;2238 2239err_gateoff:2240 stv090x_i2c_gate_ctrl(state, 0);2241err:2242 dprintk(FE_ERROR, 1, "I/O error");2243 return -1;2244}2245 2246static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s32 *timeout_sw, s32 *steps)2247{2248 s32 timeout, inc, steps_max, srate, car_max;2249 2250 srate = state->srate;2251 car_max = state->search_range / 1000;2252 car_max += car_max / 10;2253 car_max = 65536 * (car_max / 2);2254 car_max /= (state->internal->mclk / 1000);2255 2256 if (car_max > 0x4000)2257 car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */2258 2259 inc = srate;2260 inc /= state->internal->mclk / 1000;2261 inc *= 256;2262 inc *= 256;2263 inc /= 1000;2264 2265 switch (state->search_mode) {2266 case STV090x_SEARCH_DVBS1:2267 case STV090x_SEARCH_DSS:2268 inc *= 3; /* freq step = 3% of srate */2269 timeout = 20;2270 break;2271 2272 case STV090x_SEARCH_DVBS2:2273 inc *= 4;2274 timeout = 25;2275 break;2276 2277 case STV090x_SEARCH_AUTO:2278 default:2279 inc *= 3;2280 timeout = 25;2281 break;2282 }2283 inc /= 100;2284 if ((inc > car_max) || (inc < 0))2285 inc = car_max / 2; /* increment <= 1/8 Mclk */2286 2287 timeout *= 27500; /* 27.5 Msps reference */2288 if (srate > 0)2289 timeout /= (srate / 1000);2290 2291 if ((timeout > 100) || (timeout < 0))2292 timeout = 100;2293 2294 steps_max = (car_max / inc) + 1; /* min steps = 3 */2295 if ((steps_max > 100) || (steps_max < 0)) {2296 steps_max = 100; /* max steps <= 100 */2297 inc = car_max / steps_max;2298 }2299 *freq_inc = inc;2300 *timeout_sw = timeout;2301 *steps = steps_max;2302 2303 return 0;2304}2305 2306static int stv090x_chk_signal(struct stv090x_state *state)2307{2308 s32 offst_car, agc2, car_max;2309 int no_signal;2310 2311 offst_car = STV090x_READ_DEMOD(state, CFR2) << 8;2312 offst_car |= STV090x_READ_DEMOD(state, CFR1);2313 offst_car = comp2(offst_car, 16);2314 2315 agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8;2316 agc2 |= STV090x_READ_DEMOD(state, AGC2I0);2317 car_max = state->search_range / 1000;2318 2319 car_max += (car_max / 10); /* 10% margin */2320 car_max = (65536 * car_max / 2);2321 car_max /= state->internal->mclk / 1000;2322 2323 if (car_max > 0x4000)2324 car_max = 0x4000;2325 2326 if ((agc2 > 0x2000) || (offst_car > 2 * car_max) || (offst_car < -2 * car_max)) {2327 no_signal = 1;2328 dprintk(FE_DEBUG, 1, "No Signal");2329 } else {2330 no_signal = 0;2331 dprintk(FE_DEBUG, 1, "Found Signal");2332 }2333 2334 return no_signal;2335}2336 2337static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 timeout, int zigzag, s32 steps_max)2338{2339 int no_signal, lock = 0;2340 s32 cpt_step = 0, offst_freq, car_max;2341 u32 reg;2342 2343 car_max = state->search_range / 1000;2344 car_max += (car_max / 10);2345 car_max = (65536 * car_max / 2);2346 car_max /= (state->internal->mclk / 1000);2347 if (car_max > 0x4000)2348 car_max = 0x4000;2349 2350 if (zigzag)2351 offst_freq = 0;2352 else2353 offst_freq = -car_max + inc;2354 2355 do {2356 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0)2357 goto err;2358 if (STV090x_WRITE_DEMOD(state, CFRINIT1, ((offst_freq / 256) & 0xff)) < 0)2359 goto err;2360 if (STV090x_WRITE_DEMOD(state, CFRINIT0, offst_freq & 0xff) < 0)2361 goto err;2362 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)2363 goto err;2364 2365 reg = STV090x_READ_DEMOD(state, PDELCTRL1);2366 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x1); /* stop DVB-S2 packet delin */2367 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)2368 goto err;2369 2370 if (zigzag) {2371 if (offst_freq >= 0)2372 offst_freq = -offst_freq - 2 * inc;2373 else2374 offst_freq = -offst_freq;2375 } else {2376 offst_freq += 2 * inc;2377 }2378 2379 cpt_step++;2380 2381 lock = stv090x_get_dmdlock(state, timeout);2382 no_signal = stv090x_chk_signal(state);2383 2384 } while ((!lock) &&2385 (!no_signal) &&2386 ((offst_freq - inc) < car_max) &&2387 ((offst_freq + inc) > -car_max) &&2388 (cpt_step < steps_max));2389 2390 reg = STV090x_READ_DEMOD(state, PDELCTRL1);2391 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0);2392 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)2393 goto err;2394 2395 return lock;2396err:2397 dprintk(FE_ERROR, 1, "I/O error");2398 return -1;2399}2400 2401static int stv090x_sw_algo(struct stv090x_state *state)2402{2403 int no_signal, zigzag, lock = 0;2404 u32 reg;2405 2406 s32 dvbs2_fly_wheel;2407 s32 inc, timeout_step, trials, steps_max;2408 2409 /* get params */2410 stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max);2411 2412 switch (state->search_mode) {2413 case STV090x_SEARCH_DVBS1:2414 case STV090x_SEARCH_DSS:2415 /* accelerate the frequency detector */2416 if (state->internal->dev_ver >= 0x20) {2417 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0)2418 goto err;2419 }2420 2421 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x49) < 0)2422 goto err;2423 zigzag = 0;2424 break;2425 2426 case STV090x_SEARCH_DVBS2:2427 if (state->internal->dev_ver >= 0x20) {2428 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)2429 goto err;2430 }2431 2432 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)2433 goto err;2434 zigzag = 1;2435 break;2436 2437 case STV090x_SEARCH_AUTO:2438 default:2439 /* accelerate the frequency detector */2440 if (state->internal->dev_ver >= 0x20) {2441 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0)2442 goto err;2443 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)2444 goto err;2445 }2446 2447 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0xc9) < 0)2448 goto err;2449 zigzag = 0;2450 break;2451 }2452 2453 trials = 0;2454 do {2455 lock = stv090x_search_car_loop(state, inc, timeout_step, zigzag, steps_max);2456 no_signal = stv090x_chk_signal(state);2457 trials++;2458 2459 /*run the SW search 2 times maximum*/2460 if (lock || no_signal || (trials == 2)) {2461 /*Check if the demod is not losing lock in DVBS2*/2462 if (state->internal->dev_ver >= 0x20) {2463 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)2464 goto err;2465 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)2466 goto err;2467 }2468 2469 reg = STV090x_READ_DEMOD(state, DMDSTATE);2470 if ((lock) && (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == STV090x_DVBS2)) {2471 /*Check if the demod is not losing lock in DVBS2*/2472 msleep(timeout_step);2473 reg = STV090x_READ_DEMOD(state, DMDFLYW);2474 dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);2475 if (dvbs2_fly_wheel < 0xd) { /*if correct frames is decrementing */2476 msleep(timeout_step);2477 reg = STV090x_READ_DEMOD(state, DMDFLYW);2478 dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);2479 }2480 if (dvbs2_fly_wheel < 0xd) {2481 /*FALSE lock, The demod is losing lock */2482 lock = 0;2483 if (trials < 2) {2484 if (state->internal->dev_ver >= 0x20) {2485 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)2486 goto err;2487 }2488 2489 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)2490 goto err;2491 }2492 }2493 }2494 }2495 } while ((!lock) && (trials < 2) && (!no_signal));2496 2497 return lock;2498err:2499 dprintk(FE_ERROR, 1, "I/O error");2500 return -1;2501}2502 2503static enum stv090x_delsys stv090x_get_std(struct stv090x_state *state)2504{2505 u32 reg;2506 enum stv090x_delsys delsys;2507 2508 reg = STV090x_READ_DEMOD(state, DMDSTATE);2509 if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 2)2510 delsys = STV090x_DVBS2;2511 else if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 3) {2512 reg = STV090x_READ_DEMOD(state, FECM);2513 if (STV090x_GETFIELD_Px(reg, DSS_DVB_FIELD) == 1)2514 delsys = STV090x_DSS;2515 else2516 delsys = STV090x_DVBS1;2517 } else {2518 delsys = STV090x_ERROR;2519 }2520 2521 return delsys;2522}2523 2524/* in Hz */2525static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk)2526{2527 s32 derot, int_1, int_2, tmp_1, tmp_2;2528 2529 derot = STV090x_READ_DEMOD(state, CFR2) << 16;2530 derot |= STV090x_READ_DEMOD(state, CFR1) << 8;2531 derot |= STV090x_READ_DEMOD(state, CFR0);2532 2533 derot = comp2(derot, 24);2534 int_1 = mclk >> 12;2535 int_2 = derot >> 12;2536 2537 /* carrier_frequency = MasterClock * Reg / 2^24 */2538 tmp_1 = mclk % 0x1000;2539 tmp_2 = derot % 0x1000;2540 2541 derot = (int_1 * int_2) +2542 ((int_1 * tmp_2) >> 12) +2543 ((int_2 * tmp_1) >> 12);2544 2545 return derot;2546}2547 2548static int stv090x_get_viterbi(struct stv090x_state *state)2549{2550 u32 reg, rate;2551 2552 reg = STV090x_READ_DEMOD(state, VITCURPUN);2553 rate = STV090x_GETFIELD_Px(reg, VIT_CURPUN_FIELD);2554 2555 switch (rate) {2556 case 13:2557 state->fec = STV090x_PR12;2558 break;2559 2560 case 18:2561 state->fec = STV090x_PR23;2562 break;2563 2564 case 21:2565 state->fec = STV090x_PR34;2566 break;2567 2568 case 24:2569 state->fec = STV090x_PR56;2570 break;2571 2572 case 25:2573 state->fec = STV090x_PR67;2574 break;2575 2576 case 26:2577 state->fec = STV090x_PR78;2578 break;2579 2580 default:2581 state->fec = STV090x_PRERR;2582 break;2583 }2584 2585 return 0;2586}2587 2588static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *state)2589{2590 struct dvb_frontend *fe = &state->frontend;2591 2592 u8 tmg;2593 u32 reg;2594 s32 i = 0, offst_freq;2595 2596 msleep(5);2597 2598 if (state->algo == STV090x_BLIND_SEARCH) {2599 tmg = STV090x_READ_DEMOD(state, TMGREG2);2600 STV090x_WRITE_DEMOD(state, SFRSTEP, 0x5c);2601 while ((i <= 50) && (tmg != 0) && (tmg != 0xff)) {2602 tmg = STV090x_READ_DEMOD(state, TMGREG2);2603 msleep(5);2604 i += 5;2605 }2606 }2607 state->delsys = stv090x_get_std(state);2608 2609 if (stv090x_i2c_gate_ctrl(state, 1) < 0)2610 goto err;2611 2612 if (state->config->tuner_get_frequency) {2613 if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)2614 goto err_gateoff;2615 }2616 2617 if (stv090x_i2c_gate_ctrl(state, 0) < 0)2618 goto err;2619 2620 offst_freq = stv090x_get_car_freq(state, state->internal->mclk) / 1000;2621 state->frequency += offst_freq;2622 2623 if (stv090x_get_viterbi(state) < 0)2624 goto err;2625 2626 reg = STV090x_READ_DEMOD(state, DMDMODCOD);2627 state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);2628 state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;2629 state->frame_len = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) >> 1;2630 reg = STV090x_READ_DEMOD(state, TMGOBS);2631 state->rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD);2632 reg = STV090x_READ_DEMOD(state, FECM);2633 state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD);2634 2635 if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) {2636 2637 if (stv090x_i2c_gate_ctrl(state, 1) < 0)2638 goto err;2639 2640 if (state->config->tuner_get_frequency) {2641 if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)2642 goto err_gateoff;2643 }2644 2645 if (stv090x_i2c_gate_ctrl(state, 0) < 0)2646 goto err;2647 2648 if (abs(offst_freq) <= ((state->search_range / 2000) + 500))2649 return STV090x_RANGEOK;2650 else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000))2651 return STV090x_RANGEOK;2652 } else {2653 if (abs(offst_freq) <= ((state->search_range / 2000) + 500))2654 return STV090x_RANGEOK;2655 }2656 2657 return STV090x_OUTOFRANGE;2658 2659err_gateoff:2660 stv090x_i2c_gate_ctrl(state, 0);2661err:2662 dprintk(FE_ERROR, 1, "I/O error");2663 return -1;2664}2665 2666static u32 stv090x_get_tmgoffst(struct stv090x_state *state, u32 srate)2667{2668 s32 offst_tmg;2669 2670 offst_tmg = STV090x_READ_DEMOD(state, TMGREG2) << 16;2671 offst_tmg |= STV090x_READ_DEMOD(state, TMGREG1) << 8;2672 offst_tmg |= STV090x_READ_DEMOD(state, TMGREG0);2673 2674 offst_tmg = comp2(offst_tmg, 24); /* 2's complement */2675 if (!offst_tmg)2676 offst_tmg = 1;2677 2678 offst_tmg = ((s32) srate * 10) / ((s32) 0x1000000 / offst_tmg);2679 offst_tmg /= 320;2680 2681 return offst_tmg;2682}2683 2684static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_modcod modcod, s32 pilots)2685{2686 u8 aclc = 0x29;2687 s32 i;2688 struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low;2689 2690 if (state->internal->dev_ver == 0x20) {2691 car_loop = stv090x_s2_crl_cut20;2692 car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20;2693 car_loop_apsk_low = stv090x_s2_apsk_crl_cut20;2694 } else {2695 /* >= Cut 3 */2696 car_loop = stv090x_s2_crl_cut30;2697 car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut30;2698 car_loop_apsk_low = stv090x_s2_apsk_crl_cut30;2699 }2700 2701 if (modcod < STV090x_QPSK_12) {2702 i = 0;2703 while ((i < 3) && (modcod != car_loop_qpsk_low[i].modcod))2704 i++;2705 2706 if (i >= 3)2707 i = 2;2708 2709 } else {2710 i = 0;2711 while ((i < 14) && (modcod != car_loop[i].modcod))2712 i++;2713 2714 if (i >= 14) {2715 i = 0;2716 while ((i < 11) && (modcod != car_loop_apsk_low[i].modcod))2717 i++;2718 2719 if (i >= 11)2720 i = 10;2721 }2722 }2723 2724 if (modcod <= STV090x_QPSK_25) {2725 if (pilots) {2726 if (state->srate <= 3000000)2727 aclc = car_loop_qpsk_low[i].crl_pilots_on_2;2728 else if (state->srate <= 7000000)2729 aclc = car_loop_qpsk_low[i].crl_pilots_on_5;2730 else if (state->srate <= 15000000)2731 aclc = car_loop_qpsk_low[i].crl_pilots_on_10;2732 else if (state->srate <= 25000000)2733 aclc = car_loop_qpsk_low[i].crl_pilots_on_20;2734 else2735 aclc = car_loop_qpsk_low[i].crl_pilots_on_30;2736 } else {2737 if (state->srate <= 3000000)2738 aclc = car_loop_qpsk_low[i].crl_pilots_off_2;2739 else if (state->srate <= 7000000)2740 aclc = car_loop_qpsk_low[i].crl_pilots_off_5;2741 else if (state->srate <= 15000000)2742 aclc = car_loop_qpsk_low[i].crl_pilots_off_10;2743 else if (state->srate <= 25000000)2744 aclc = car_loop_qpsk_low[i].crl_pilots_off_20;2745 else2746 aclc = car_loop_qpsk_low[i].crl_pilots_off_30;2747 }2748 2749 } else if (modcod <= STV090x_8PSK_910) {2750 if (pilots) {2751 if (state->srate <= 3000000)2752 aclc = car_loop[i].crl_pilots_on_2;2753 else if (state->srate <= 7000000)2754 aclc = car_loop[i].crl_pilots_on_5;2755 else if (state->srate <= 15000000)2756 aclc = car_loop[i].crl_pilots_on_10;2757 else if (state->srate <= 25000000)2758 aclc = car_loop[i].crl_pilots_on_20;2759 else2760 aclc = car_loop[i].crl_pilots_on_30;2761 } else {2762 if (state->srate <= 3000000)2763 aclc = car_loop[i].crl_pilots_off_2;2764 else if (state->srate <= 7000000)2765 aclc = car_loop[i].crl_pilots_off_5;2766 else if (state->srate <= 15000000)2767 aclc = car_loop[i].crl_pilots_off_10;2768 else if (state->srate <= 25000000)2769 aclc = car_loop[i].crl_pilots_off_20;2770 else2771 aclc = car_loop[i].crl_pilots_off_30;2772 }2773 } else { /* 16APSK and 32APSK */2774 /*2775 * This should never happen in practice, except if2776 * something is really wrong at the car_loop table.2777 */2778 if (i >= 11)2779 i = 10;2780 if (state->srate <= 3000000)2781 aclc = car_loop_apsk_low[i].crl_pilots_on_2;2782 else if (state->srate <= 7000000)2783 aclc = car_loop_apsk_low[i].crl_pilots_on_5;2784 else if (state->srate <= 15000000)2785 aclc = car_loop_apsk_low[i].crl_pilots_on_10;2786 else if (state->srate <= 25000000)2787 aclc = car_loop_apsk_low[i].crl_pilots_on_20;2788 else2789 aclc = car_loop_apsk_low[i].crl_pilots_on_30;2790 }2791 2792 return aclc;2793}2794 2795static u8 stv090x_optimize_carloop_short(struct stv090x_state *state)2796{2797 struct stv090x_short_frame_crloop *short_crl = NULL;2798 s32 index = 0;2799 u8 aclc = 0x0b;2800 2801 switch (state->modulation) {2802 case STV090x_QPSK:2803 default:2804 index = 0;2805 break;2806 case STV090x_8PSK:2807 index = 1;2808 break;2809 case STV090x_16APSK:2810 index = 2;2811 break;2812 case STV090x_32APSK:2813 index = 3;2814 break;2815 }2816 2817 if (state->internal->dev_ver >= 0x30) {2818 /* Cut 3.0 and up */2819 short_crl = stv090x_s2_short_crl_cut30;2820 } else {2821 /* Cut 2.0 and up: we don't support cuts older than 2.0 */2822 short_crl = stv090x_s2_short_crl_cut20;2823 }2824 2825 if (state->srate <= 3000000)2826 aclc = short_crl[index].crl_2;2827 else if (state->srate <= 7000000)2828 aclc = short_crl[index].crl_5;2829 else if (state->srate <= 15000000)2830 aclc = short_crl[index].crl_10;2831 else if (state->srate <= 25000000)2832 aclc = short_crl[index].crl_20;2833 else2834 aclc = short_crl[index].crl_30;2835 2836 return aclc;2837}2838 2839static int stv090x_optimize_track(struct stv090x_state *state)2840{2841 struct dvb_frontend *fe = &state->frontend;2842 2843 enum stv090x_modcod modcod;2844 2845 s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0;2846 u32 reg;2847 2848 srate = stv090x_get_srate(state, state->internal->mclk);2849 srate += stv090x_get_tmgoffst(state, srate);2850 2851 switch (state->delsys) {2852 case STV090x_DVBS1:2853 case STV090x_DSS:2854 if (state->search_mode == STV090x_SEARCH_AUTO) {2855 reg = STV090x_READ_DEMOD(state, DMDCFGMD);2856 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);2857 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);2858 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)2859 goto err;2860 }2861 reg = STV090x_READ_DEMOD(state, DEMOD);2862 STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);2863 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x01);2864 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)2865 goto err;2866 2867 if (state->internal->dev_ver >= 0x30) {2868 if (stv090x_get_viterbi(state) < 0)2869 goto err;2870 2871 if (state->fec == STV090x_PR12) {2872 if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x98) < 0)2873 goto err;2874 if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)2875 goto err;2876 } else {2877 if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x18) < 0)2878 goto err;2879 if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)2880 goto err;2881 }2882 }2883 2884 if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)2885 goto err;2886 break;2887 2888 case STV090x_DVBS2:2889 reg = STV090x_READ_DEMOD(state, DMDCFGMD);2890 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);2891 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);2892 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)2893 goto err;2894 if (state->internal->dev_ver >= 0x30) {2895 if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0)2896 goto err;2897 if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0)2898 goto err;2899 }2900 if (state->frame_len == STV090x_LONG_FRAME) {2901 reg = STV090x_READ_DEMOD(state, DMDMODCOD);2902 modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);2903 pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;2904 aclc = stv090x_optimize_carloop(state, modcod, pilots);2905 if (modcod <= STV090x_QPSK_910) {2906 STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc);2907 } else if (modcod <= STV090x_8PSK_910) {2908 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)2909 goto err;2910 if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)2911 goto err;2912 }2913 if ((state->demod_mode == STV090x_SINGLE) && (modcod > STV090x_8PSK_910)) {2914 if (modcod <= STV090x_16APSK_910) {2915 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)2916 goto err;2917 if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)2918 goto err;2919 } else {2920 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)2921 goto err;2922 if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)2923 goto err;2924 }2925 }2926 } else {2927 /*Carrier loop setting for short frame*/2928 aclc = stv090x_optimize_carloop_short(state);2929 if (state->modulation == STV090x_QPSK) {2930 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc) < 0)2931 goto err;2932 } else if (state->modulation == STV090x_8PSK) {2933 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)2934 goto err;2935 if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)2936 goto err;2937 } else if (state->modulation == STV090x_16APSK) {2938 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)2939 goto err;2940 if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)2941 goto err;2942 } else if (state->modulation == STV090x_32APSK) {2943 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)2944 goto err;2945 if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)2946 goto err;2947 }2948 }2949 2950 STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */2951 break;2952 2953 case STV090x_ERROR:2954 default:2955 reg = STV090x_READ_DEMOD(state, DMDCFGMD);2956 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);2957 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);2958 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)2959 goto err;2960 break;2961 }2962 2963 f_1 = STV090x_READ_DEMOD(state, CFR2);2964 f_0 = STV090x_READ_DEMOD(state, CFR1);2965 reg = STV090x_READ_DEMOD(state, TMGOBS);2966 2967 if (state->algo == STV090x_BLIND_SEARCH) {2968 STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00);2969 reg = STV090x_READ_DEMOD(state, DMDCFGMD);2970 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0x00);2971 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);2972 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)2973 goto err;2974 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)2975 goto err;2976 2977 if (stv090x_set_srate(state, srate) < 0)2978 goto err;2979 blind_tune = 1;2980 2981 if (stv090x_dvbs_track_crl(state) < 0)2982 goto err;2983 }2984 2985 if (state->internal->dev_ver >= 0x20) {2986 if ((state->search_mode == STV090x_SEARCH_DVBS1) ||2987 (state->search_mode == STV090x_SEARCH_DSS) ||2988 (state->search_mode == STV090x_SEARCH_AUTO)) {2989 2990 if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x0a) < 0)2991 goto err;2992 if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x00) < 0)2993 goto err;2994 }2995 }2996 2997 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)2998 goto err;2999 3000 /* AUTO tracking MODE */3001 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x80) < 0)3002 goto err;3003 /* AUTO tracking MODE */3004 if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0)3005 goto err;3006 3007 if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1) ||3008 (state->srate < 10000000)) {3009 /* update initial carrier freq with the found freq offset */3010 if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)3011 goto err;3012 if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)3013 goto err;3014 state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000;3015 3016 if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1)) {3017 3018 if (state->algo != STV090x_WARM_SEARCH) {3019 3020 if (stv090x_i2c_gate_ctrl(state, 1) < 0)3021 goto err;3022 3023 if (state->config->tuner_set_bandwidth) {3024 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)3025 goto err_gateoff;3026 }3027 3028 if (stv090x_i2c_gate_ctrl(state, 0) < 0)3029 goto err;3030 3031 }3032 }3033 if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000))3034 msleep(50); /* blind search: wait 50ms for SR stabilization */3035 else3036 msleep(5);3037 3038 stv090x_get_lock_tmg(state);3039 3040 if (!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) {3041 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)3042 goto err;3043 if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)3044 goto err;3045 if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)3046 goto err;3047 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)3048 goto err;3049 3050 i = 0;3051 3052 while ((!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) && (i <= 2)) {3053 3054 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)3055 goto err;3056 if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)3057 goto err;3058 if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)3059 goto err;3060 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)3061 goto err;3062 i++;3063 }3064 }3065 3066 }3067 3068 if (state->internal->dev_ver >= 0x20) {3069 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)3070 goto err;3071 }3072 3073 if ((state->delsys == STV090x_DVBS1) || (state->delsys == STV090x_DSS))3074 stv090x_set_vit_thtracq(state);3075 3076 return 0;3077 3078err_gateoff:3079 stv090x_i2c_gate_ctrl(state, 0);3080err:3081 dprintk(FE_ERROR, 1, "I/O error");3082 return -1;3083}3084 3085static int stv090x_get_feclock(struct stv090x_state *state, s32 timeout)3086{3087 s32 timer = 0, lock = 0, stat;3088 u32 reg;3089 3090 while ((timer < timeout) && (!lock)) {3091 reg = STV090x_READ_DEMOD(state, DMDSTATE);3092 stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);3093 3094 switch (stat) {3095 case 0: /* searching */3096 case 1: /* first PLH detected */3097 default:3098 lock = 0;3099 break;3100 3101 case 2: /* DVB-S2 mode */3102 reg = STV090x_READ_DEMOD(state, PDELSTATUS1);3103 lock = STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD);3104 break;3105 3106 case 3: /* DVB-S1/legacy mode */3107 reg = STV090x_READ_DEMOD(state, VSTATUSVIT);3108 lock = STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD);3109 break;3110 }3111 if (!lock) {3112 msleep(10);3113 timer += 10;3114 }3115 }3116 return lock;3117}3118 3119static int stv090x_get_lock(struct stv090x_state *state, s32 timeout_dmd, s32 timeout_fec)3120{3121 u32 reg;3122 s32 timer = 0;3123 int lock;3124 3125 lock = stv090x_get_dmdlock(state, timeout_dmd);3126 if (lock)3127 lock = stv090x_get_feclock(state, timeout_fec);3128 3129 if (lock) {3130 lock = 0;3131 3132 while ((timer < timeout_fec) && (!lock)) {3133 reg = STV090x_READ_DEMOD(state, TSSTATUS);3134 lock = STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD);3135 msleep(1);3136 timer++;3137 }3138 }3139 3140 return lock;3141}3142 3143static int stv090x_set_s2rolloff(struct stv090x_state *state)3144{3145 u32 reg;3146 3147 if (state->internal->dev_ver <= 0x20) {3148 /* rolloff to auto mode if DVBS2 */3149 reg = STV090x_READ_DEMOD(state, DEMOD);3150 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00);3151 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)3152 goto err;3153 } else {3154 /* DVB-S2 rolloff to auto mode if DVBS2 */3155 reg = STV090x_READ_DEMOD(state, DEMOD);3156 STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 0x00);3157 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)3158 goto err;3159 }3160 return 0;3161err:3162 dprintk(FE_ERROR, 1, "I/O error");3163 return -1;3164}3165 3166 3167static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)3168{3169 struct dvb_frontend *fe = &state->frontend;3170 enum stv090x_signal_state signal_state = STV090x_NOCARRIER;3171 u32 reg;3172 s32 agc1_power, power_iq = 0, i;3173 int lock = 0, low_sr = 0;3174 3175 reg = STV090x_READ_DEMOD(state, TSCFGH);3176 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */3177 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)3178 goto err;3179 3180 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */3181 goto err;3182 3183 if (state->internal->dev_ver >= 0x20) {3184 if (state->srate > 5000000) {3185 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)3186 goto err;3187 } else {3188 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x82) < 0)3189 goto err;3190 }3191 }3192 3193 stv090x_get_lock_tmg(state);3194 3195 if (state->algo == STV090x_BLIND_SEARCH) {3196 state->tuner_bw = 2 * 36000000; /* wide bw for unknown srate */3197 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0) /* wider srate scan */3198 goto err;3199 if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)3200 goto err;3201 if (stv090x_set_srate(state, 1000000) < 0) /* initial srate = 1Msps */3202 goto err;3203 } else {3204 /* known srate */3205 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)3206 goto err;3207 if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)3208 goto err;3209 3210 if (state->srate < 2000000) {3211 /* SR < 2MSPS */3212 if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x63) < 0)3213 goto err;3214 } else {3215 /* SR >= 2Msps */3216 if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)3217 goto err;3218 }3219 3220 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)3221 goto err;3222 3223 if (state->internal->dev_ver >= 0x20) {3224 if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0)3225 goto err;3226 if (state->algo == STV090x_COLD_SEARCH)3227 state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10;3228 else if (state->algo == STV090x_WARM_SEARCH)3229 state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + 10000000;3230 }3231 3232 /* if cold start or warm (Symbolrate is known)3233 * use a Narrow symbol rate scan range3234 */3235 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) /* narrow srate scan */3236 goto err;3237 3238 if (stv090x_set_srate(state, state->srate) < 0)3239 goto err;3240 3241 if (stv090x_set_max_srate(state, state->internal->mclk,3242 state->srate) < 0)3243 goto err;3244 if (stv090x_set_min_srate(state, state->internal->mclk,3245 state->srate) < 0)3246 goto err;3247 3248 if (state->srate >= 10000000)3249 low_sr = 0;3250 else3251 low_sr = 1;3252 }3253 3254 /* Setup tuner */3255 if (stv090x_i2c_gate_ctrl(state, 1) < 0)3256 goto err;3257 3258 if (state->config->tuner_set_bbgain) {3259 reg = state->config->tuner_bbgain;3260 if (reg == 0)3261 reg = 10; /* default: 10dB */3262 if (state->config->tuner_set_bbgain(fe, reg) < 0)3263 goto err_gateoff;3264 }3265 3266 if (state->config->tuner_set_frequency) {3267 if (state->config->tuner_set_frequency(fe, state->frequency) < 0)3268 goto err_gateoff;3269 }3270 3271 if (state->config->tuner_set_bandwidth) {3272 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)3273 goto err_gateoff;3274 }3275 3276 if (stv090x_i2c_gate_ctrl(state, 0) < 0)3277 goto err;3278 3279 msleep(50);3280 3281 if (state->config->tuner_get_status) {3282 if (stv090x_i2c_gate_ctrl(state, 1) < 0)3283 goto err;3284 if (state->config->tuner_get_status(fe, ®) < 0)3285 goto err_gateoff;3286 if (stv090x_i2c_gate_ctrl(state, 0) < 0)3287 goto err;3288 3289 if (reg)3290 dprintk(FE_DEBUG, 1, "Tuner phase locked");3291 else {3292 dprintk(FE_DEBUG, 1, "Tuner unlocked");3293 return STV090x_NOCARRIER;3294 }3295 }3296 3297 msleep(10);3298 agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1),3299 STV090x_READ_DEMOD(state, AGCIQIN0));3300 3301 if (agc1_power == 0) {3302 /* If AGC1 integrator value is 03303 * then read POWERI, POWERQ3304 */3305 for (i = 0; i < 5; i++) {3306 power_iq += (STV090x_READ_DEMOD(state, POWERI) +3307 STV090x_READ_DEMOD(state, POWERQ)) >> 1;3308 }3309 power_iq /= 5;3310 }3311 3312 if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) {3313 dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq);3314 lock = 0;3315 signal_state = STV090x_NOAGC1;3316 } else {3317 reg = STV090x_READ_DEMOD(state, DEMOD);3318 STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion);3319 3320 if (state->internal->dev_ver <= 0x20) {3321 /* rolloff to auto mode if DVBS2 */3322 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1);3323 } else {3324 /* DVB-S2 rolloff to auto mode if DVBS2 */3325 STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 1);3326 }3327 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)3328 goto err;3329 3330 if (stv090x_delivery_search(state) < 0)3331 goto err;3332 3333 if (state->algo != STV090x_BLIND_SEARCH) {3334 if (stv090x_start_search(state) < 0)3335 goto err;3336 }3337 }3338 3339 if (signal_state == STV090x_NOAGC1)3340 return signal_state;3341 3342 if (state->algo == STV090x_BLIND_SEARCH)3343 lock = stv090x_blind_search(state);3344 3345 else if (state->algo == STV090x_COLD_SEARCH)3346 lock = stv090x_get_coldlock(state, state->DemodTimeout);3347 3348 else if (state->algo == STV090x_WARM_SEARCH)3349 lock = stv090x_get_dmdlock(state, state->DemodTimeout);3350 3351 if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) {3352 if (!low_sr) {3353 if (stv090x_chk_tmg(state))3354 lock = stv090x_sw_algo(state);3355 }3356 }3357 3358 if (lock)3359 signal_state = stv090x_get_sig_params(state);3360 3361 if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */3362 stv090x_optimize_track(state);3363 3364 if (state->internal->dev_ver >= 0x20) {3365 /* >= Cut 2.0 :release TS reset after3366 * demod lock and optimized Tracking3367 */3368 reg = STV090x_READ_DEMOD(state, TSCFGH);3369 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */3370 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)3371 goto err;3372 3373 msleep(3);3374 3375 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */3376 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)3377 goto err;3378 3379 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */3380 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)3381 goto err;3382 }3383 3384 lock = stv090x_get_lock(state, state->FecTimeout,3385 state->FecTimeout);3386 if (lock) {3387 if (state->delsys == STV090x_DVBS2) {3388 stv090x_set_s2rolloff(state);3389 3390 reg = STV090x_READ_DEMOD(state, PDELCTRL2);3391 STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 1);3392 if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)3393 goto err;3394 /* Reset DVBS2 packet delinator error counter */3395 reg = STV090x_READ_DEMOD(state, PDELCTRL2);3396 STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 0);3397 if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)3398 goto err;3399 3400 if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67) < 0) /* PER */3401 goto err;3402 } else {3403 if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)3404 goto err;3405 }3406 /* Reset the Total packet counter */3407 if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0x00) < 0)3408 goto err;3409 /* Reset the packet Error counter2 */3410 if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)3411 goto err;3412 } else {3413 signal_state = STV090x_NODATA;3414 stv090x_chk_signal(state);3415 }3416 }3417 return signal_state;3418 3419err_gateoff:3420 stv090x_i2c_gate_ctrl(state, 0);3421err:3422 dprintk(FE_ERROR, 1, "I/O error");3423 return -1;3424}3425 3426static int stv090x_set_pls(struct stv090x_state *state, u32 pls_code)3427{3428 dprintk(FE_DEBUG, 1, "Set Gold PLS code %d", pls_code);3429 if (STV090x_WRITE_DEMOD(state, PLROOT0, pls_code & 0xff) < 0)3430 goto err;3431 if (STV090x_WRITE_DEMOD(state, PLROOT1, (pls_code >> 8) & 0xff) < 0)3432 goto err;3433 if (STV090x_WRITE_DEMOD(state, PLROOT2, 0x04 | (pls_code >> 16)) < 0)3434 goto err;3435 return 0;3436err:3437 dprintk(FE_ERROR, 1, "I/O error");3438 return -1;3439}3440 3441static int stv090x_set_mis(struct stv090x_state *state, int mis)3442{3443 u32 reg;3444 3445 if (mis < 0 || mis > 255) {3446 dprintk(FE_DEBUG, 1, "Disable MIS filtering");3447 reg = STV090x_READ_DEMOD(state, PDELCTRL1);3448 STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x00);3449 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)3450 goto err;3451 } else {3452 dprintk(FE_DEBUG, 1, "Enable MIS filtering - %d", mis);3453 reg = STV090x_READ_DEMOD(state, PDELCTRL1);3454 STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x01);3455 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)3456 goto err;3457 if (STV090x_WRITE_DEMOD(state, ISIENTRY, mis) < 0)3458 goto err;3459 if (STV090x_WRITE_DEMOD(state, ISIBITENA, 0xff) < 0)3460 goto err;3461 }3462 return 0;3463err:3464 dprintk(FE_ERROR, 1, "I/O error");3465 return -1;3466}3467 3468static enum dvbfe_search stv090x_search(struct dvb_frontend *fe)3469{3470 struct stv090x_state *state = fe->demodulator_priv;3471 struct dtv_frontend_properties *props = &fe->dtv_property_cache;3472 3473 if (props->frequency == 0)3474 return DVBFE_ALGO_SEARCH_INVALID;3475 3476 switch (props->delivery_system) {3477 case SYS_DSS:3478 state->delsys = STV090x_DSS;3479 break;3480 case SYS_DVBS:3481 state->delsys = STV090x_DVBS1;3482 break;3483 case SYS_DVBS2:3484 state->delsys = STV090x_DVBS2;3485 break;3486 default:3487 return DVBFE_ALGO_SEARCH_INVALID;3488 }3489 3490 state->frequency = props->frequency;3491 state->srate = props->symbol_rate;3492 state->search_mode = STV090x_SEARCH_AUTO;3493 state->algo = STV090x_COLD_SEARCH;3494 state->fec = STV090x_PRERR;3495 if (state->srate > 10000000) {3496 dprintk(FE_DEBUG, 1, "Search range: 10 MHz");3497 state->search_range = 10000000;3498 } else {3499 dprintk(FE_DEBUG, 1, "Search range: 5 MHz");3500 state->search_range = 5000000;3501 }3502 3503 stv090x_set_pls(state, props->scrambling_sequence_index);3504 stv090x_set_mis(state, props->stream_id);3505 3506 if (stv090x_algo(state) == STV090x_RANGEOK) {3507 dprintk(FE_DEBUG, 1, "Search success!");3508 return DVBFE_ALGO_SEARCH_SUCCESS;3509 } else {3510 dprintk(FE_DEBUG, 1, "Search failed!");3511 return DVBFE_ALGO_SEARCH_FAILED;3512 }3513 3514 return DVBFE_ALGO_SEARCH_ERROR;3515}3516 3517static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)3518{3519 struct stv090x_state *state = fe->demodulator_priv;3520 u32 reg, dstatus;3521 u8 search_state;3522 3523 *status = 0;3524 3525 dstatus = STV090x_READ_DEMOD(state, DSTATUS);3526 if (STV090x_GETFIELD_Px(dstatus, CAR_LOCK_FIELD))3527 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;3528 3529 reg = STV090x_READ_DEMOD(state, DMDSTATE);3530 search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);3531 3532 switch (search_state) {3533 case 0: /* searching */3534 case 1: /* first PLH detected */3535 default:3536 dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)");3537 break;3538 3539 case 2: /* DVB-S2 mode */3540 dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2");3541 if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) {3542 reg = STV090x_READ_DEMOD(state, PDELSTATUS1);3543 if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) {3544 *status |= FE_HAS_VITERBI;3545 reg = STV090x_READ_DEMOD(state, TSSTATUS);3546 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD))3547 *status |= FE_HAS_SYNC | FE_HAS_LOCK;3548 }3549 }3550 break;3551 3552 case 3: /* DVB-S1/legacy mode */3553 dprintk(FE_DEBUG, 1, "Delivery system: DVB-S");3554 if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) {3555 reg = STV090x_READ_DEMOD(state, VSTATUSVIT);3556 if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) {3557 *status |= FE_HAS_VITERBI;3558 reg = STV090x_READ_DEMOD(state, TSSTATUS);3559 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD))3560 *status |= FE_HAS_SYNC | FE_HAS_LOCK;3561 }3562 }3563 break;3564 }3565 3566 return 0;3567}3568 3569static int stv090x_read_per(struct dvb_frontend *fe, u32 *per)3570{3571 struct stv090x_state *state = fe->demodulator_priv;3572 3573 s32 count_4, count_3, count_2, count_1, count_0, count;3574 u32 reg, h, m, l;3575 enum fe_status status;3576 3577 stv090x_read_status(fe, &status);3578 if (!(status & FE_HAS_LOCK)) {3579 *per = 1 << 23; /* Max PER */3580 } else {3581 /* Counter 2 */3582 reg = STV090x_READ_DEMOD(state, ERRCNT22);3583 h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD);3584 3585 reg = STV090x_READ_DEMOD(state, ERRCNT21);3586 m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD);3587 3588 reg = STV090x_READ_DEMOD(state, ERRCNT20);3589 l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD);3590 3591 *per = ((h << 16) | (m << 8) | l);3592 3593 count_4 = STV090x_READ_DEMOD(state, FBERCPT4);3594 count_3 = STV090x_READ_DEMOD(state, FBERCPT3);3595 count_2 = STV090x_READ_DEMOD(state, FBERCPT2);3596 count_1 = STV090x_READ_DEMOD(state, FBERCPT1);3597 count_0 = STV090x_READ_DEMOD(state, FBERCPT0);3598 3599 if ((!count_4) && (!count_3)) {3600 count = (count_2 & 0xff) << 16;3601 count |= (count_1 & 0xff) << 8;3602 count |= count_0 & 0xff;3603 } else {3604 count = 1 << 24;3605 }3606 if (count == 0)3607 *per = 1;3608 }3609 if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0) < 0)3610 goto err;3611 if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)3612 goto err;3613 3614 return 0;3615err:3616 dprintk(FE_ERROR, 1, "I/O error");3617 return -1;3618}3619 3620static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val)3621{3622 int res = 0;3623 int min = 0, med;3624 3625 if ((val >= tab[min].read && val < tab[max].read) ||3626 (val >= tab[max].read && val < tab[min].read)) {3627 while ((max - min) > 1) {3628 med = (max + min) / 2;3629 if ((val >= tab[min].read && val < tab[med].read) ||3630 (val >= tab[med].read && val < tab[min].read))3631 max = med;3632 else3633 min = med;3634 }3635 res = ((val - tab[min].read) *3636 (tab[max].real - tab[min].real) /3637 (tab[max].read - tab[min].read)) +3638 tab[min].real;3639 } else {3640 if (tab[min].read < tab[max].read) {3641 if (val < tab[min].read)3642 res = tab[min].real;3643 else if (val >= tab[max].read)3644 res = tab[max].real;3645 } else {3646 if (val >= tab[min].read)3647 res = tab[min].real;3648 else if (val < tab[max].read)3649 res = tab[max].real;3650 }3651 }3652 3653 return res;3654}3655 3656static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)3657{3658 struct stv090x_state *state = fe->demodulator_priv;3659 u32 reg;3660 s32 agc_0, agc_1, agc;3661 s32 str;3662 3663 reg = STV090x_READ_DEMOD(state, AGCIQIN1);3664 agc_1 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);3665 reg = STV090x_READ_DEMOD(state, AGCIQIN0);3666 agc_0 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);3667 agc = MAKEWORD16(agc_1, agc_0);3668 3669 str = stv090x_table_lookup(stv090x_rf_tab,3670 ARRAY_SIZE(stv090x_rf_tab) - 1, agc);3671 if (agc > stv090x_rf_tab[0].read)3672 str = 0;3673 else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)3674 str = -100;3675 *strength = (str + 100) * 0xFFFF / 100;3676 3677 return 0;3678}3679 3680static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)3681{3682 struct stv090x_state *state = fe->demodulator_priv;3683 u32 reg_0, reg_1, reg, i;3684 s32 val_0, val_1, val = 0;3685 u8 lock_f;3686 s32 div;3687 u32 last;3688 3689 switch (state->delsys) {3690 case STV090x_DVBS2:3691 reg = STV090x_READ_DEMOD(state, DSTATUS);3692 lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);3693 if (lock_f) {3694 msleep(5);3695 for (i = 0; i < 16; i++) {3696 reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1);3697 val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);3698 reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0);3699 val_0 = STV090x_GETFIELD_Px(reg_0, NOSPLHT_NORMED_FIELD);3700 val += MAKEWORD16(val_1, val_0);3701 msleep(1);3702 }3703 val /= 16;3704 last = ARRAY_SIZE(stv090x_s2cn_tab) - 1;3705 div = stv090x_s2cn_tab[last].real -3706 stv090x_s2cn_tab[3].real;3707 val = stv090x_table_lookup(stv090x_s2cn_tab, last, val);3708 if (val < 0)3709 val = 0;3710 *cnr = val * 0xFFFF / div;3711 }3712 break;3713 3714 case STV090x_DVBS1:3715 case STV090x_DSS:3716 reg = STV090x_READ_DEMOD(state, DSTATUS);3717 lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);3718 if (lock_f) {3719 msleep(5);3720 for (i = 0; i < 16; i++) {3721 reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1);3722 val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);3723 reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0);3724 val_0 = STV090x_GETFIELD_Px(reg_0, NOSDATAT_UNNORMED_FIELD);3725 val += MAKEWORD16(val_1, val_0);3726 msleep(1);3727 }3728 val /= 16;3729 last = ARRAY_SIZE(stv090x_s1cn_tab) - 1;3730 div = stv090x_s1cn_tab[last].real -3731 stv090x_s1cn_tab[0].real;3732 val = stv090x_table_lookup(stv090x_s1cn_tab, last, val);3733 *cnr = val * 0xFFFF / div;3734 }3735 break;3736 default:3737 break;3738 }3739 3740 return 0;3741}3742 3743static int stv090x_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)3744{3745 struct stv090x_state *state = fe->demodulator_priv;3746 u32 reg;3747 3748 reg = STV090x_READ_DEMOD(state, DISTXCTL);3749 switch (tone) {3750 case SEC_TONE_ON:3751 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);3752 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);3753 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)3754 goto err;3755 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);3756 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)3757 goto err;3758 break;3759 3760 case SEC_TONE_OFF:3761 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);3762 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);3763 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)3764 goto err;3765 break;3766 default:3767 return -EINVAL;3768 }3769 3770 return 0;3771err:3772 dprintk(FE_ERROR, 1, "I/O error");3773 return -1;3774}3775 3776 3777static enum dvbfe_algo stv090x_frontend_algo(struct dvb_frontend *fe)3778{3779 return DVBFE_ALGO_CUSTOM;3780}3781 3782static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)3783{3784 struct stv090x_state *state = fe->demodulator_priv;3785 u32 reg, idle = 0, fifo_full = 1;3786 int i;3787 3788 reg = STV090x_READ_DEMOD(state, DISTXCTL);3789 3790 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD,3791 (state->config->diseqc_envelope_mode) ? 4 : 2);3792 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);3793 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)3794 goto err;3795 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);3796 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)3797 goto err;3798 3799 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);3800 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)3801 goto err;3802 3803 for (i = 0; i < cmd->msg_len; i++) {3804 3805 while (fifo_full) {3806 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);3807 fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);3808 }3809 3810 if (STV090x_WRITE_DEMOD(state, DISTXDATA, cmd->msg[i]) < 0)3811 goto err;3812 }3813 reg = STV090x_READ_DEMOD(state, DISTXCTL);3814 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);3815 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)3816 goto err;3817 3818 i = 0;3819 3820 while ((!idle) && (i < 10)) {3821 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);3822 idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);3823 msleep(10);3824 i++;3825 }3826 3827 return 0;3828err:3829 dprintk(FE_ERROR, 1, "I/O error");3830 return -1;3831}3832 3833static int stv090x_send_diseqc_burst(struct dvb_frontend *fe,3834 enum fe_sec_mini_cmd burst)3835{3836 struct stv090x_state *state = fe->demodulator_priv;3837 u32 reg, idle = 0, fifo_full = 1;3838 u8 mode, value;3839 int i;3840 3841 reg = STV090x_READ_DEMOD(state, DISTXCTL);3842 3843 if (burst == SEC_MINI_A) {3844 mode = (state->config->diseqc_envelope_mode) ? 5 : 3;3845 value = 0x00;3846 } else {3847 mode = (state->config->diseqc_envelope_mode) ? 4 : 2;3848 value = 0xFF;3849 }3850 3851 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, mode);3852 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);3853 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)3854 goto err;3855 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);3856 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)3857 goto err;3858 3859 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);3860 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)3861 goto err;3862 3863 while (fifo_full) {3864 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);3865 fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);3866 }3867 3868 if (STV090x_WRITE_DEMOD(state, DISTXDATA, value) < 0)3869 goto err;3870 3871 reg = STV090x_READ_DEMOD(state, DISTXCTL);3872 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);3873 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)3874 goto err;3875 3876 i = 0;3877 3878 while ((!idle) && (i < 10)) {3879 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);3880 idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);3881 msleep(10);3882 i++;3883 }3884 3885 return 0;3886err:3887 dprintk(FE_ERROR, 1, "I/O error");3888 return -1;3889}3890 3891static int stv090x_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)3892{3893 struct stv090x_state *state = fe->demodulator_priv;3894 u32 reg = 0, i = 0, rx_end = 0;3895 3896 while ((rx_end != 1) && (i < 10)) {3897 msleep(10);3898 i++;3899 reg = STV090x_READ_DEMOD(state, DISRX_ST0);3900 rx_end = STV090x_GETFIELD_Px(reg, RX_END_FIELD);3901 }3902 3903 if (rx_end) {3904 reply->msg_len = STV090x_GETFIELD_Px(reg, FIFO_BYTENBR_FIELD);3905 for (i = 0; i < reply->msg_len; i++)3906 reply->msg[i] = STV090x_READ_DEMOD(state, DISRXDATA);3907 }3908 3909 return 0;3910}3911 3912static int stv090x_sleep(struct dvb_frontend *fe)3913{3914 struct stv090x_state *state = fe->demodulator_priv;3915 u32 reg;3916 u8 full_standby = 0;3917 3918 if (stv090x_i2c_gate_ctrl(state, 1) < 0)3919 goto err;3920 3921 if (state->config->tuner_sleep) {3922 if (state->config->tuner_sleep(fe) < 0)3923 goto err_gateoff;3924 }3925 3926 if (stv090x_i2c_gate_ctrl(state, 0) < 0)3927 goto err;3928 3929 dprintk(FE_DEBUG, 1, "Set %s(%d) to sleep",3930 state->device == STV0900 ? "STV0900" : "STV0903",3931 state->demod);3932 3933 mutex_lock(&state->internal->demod_lock);3934 3935 switch (state->demod) {3936 case STV090x_DEMODULATOR_0:3937 /* power off ADC 1 */3938 reg = stv090x_read_reg(state, STV090x_TSTTNR1);3939 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);3940 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)3941 goto err_unlock;3942 /* power off DiSEqC 1 */3943 reg = stv090x_read_reg(state, STV090x_TSTTNR2);3944 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);3945 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)3946 goto err_unlock;3947 3948 /* check whether path 2 is already sleeping, that is when3949 ADC2 is off */3950 reg = stv090x_read_reg(state, STV090x_TSTTNR3);3951 if (STV090x_GETFIELD(reg, ADC2_PON_FIELD) == 0)3952 full_standby = 1;3953 3954 /* stop clocks */3955 reg = stv090x_read_reg(state, STV090x_STOPCLK1);3956 /* packet delineator 1 clock */3957 STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 1);3958 /* ADC 1 clock */3959 STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 1);3960 /* FEC clock is shared between the two paths, only stop it3961 when full standby is possible */3962 if (full_standby)3963 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);3964 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)3965 goto err_unlock;3966 reg = stv090x_read_reg(state, STV090x_STOPCLK2);3967 /* sampling 1 clock */3968 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);3969 /* viterbi 1 clock */3970 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 1);3971 /* TS clock is shared between the two paths, only stop it3972 when full standby is possible */3973 if (full_standby)3974 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);3975 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)3976 goto err_unlock;3977 break;3978 3979 case STV090x_DEMODULATOR_1:3980 /* power off ADC 2 */3981 reg = stv090x_read_reg(state, STV090x_TSTTNR3);3982 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);3983 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)3984 goto err_unlock;3985 /* power off DiSEqC 2 */3986 reg = stv090x_read_reg(state, STV090x_TSTTNR4);3987 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);3988 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)3989 goto err_unlock;3990 3991 /* check whether path 1 is already sleeping, that is when3992 ADC1 is off */3993 reg = stv090x_read_reg(state, STV090x_TSTTNR1);3994 if (STV090x_GETFIELD(reg, ADC1_PON_FIELD) == 0)3995 full_standby = 1;3996 3997 /* stop clocks */3998 reg = stv090x_read_reg(state, STV090x_STOPCLK1);3999 /* packet delineator 2 clock */4000 STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 1);4001 /* ADC 2 clock */4002 STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 1);4003 /* FEC clock is shared between the two paths, only stop it4004 when full standby is possible */4005 if (full_standby)4006 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);4007 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)4008 goto err_unlock;4009 reg = stv090x_read_reg(state, STV090x_STOPCLK2);4010 /* sampling 2 clock */4011 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);4012 /* viterbi 2 clock */4013 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 1);4014 /* TS clock is shared between the two paths, only stop it4015 when full standby is possible */4016 if (full_standby)4017 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);4018 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)4019 goto err_unlock;4020 break;4021 4022 default:4023 dprintk(FE_ERROR, 1, "Wrong demodulator!");4024 break;4025 }4026 4027 if (full_standby) {4028 /* general power off */4029 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);4030 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);4031 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)4032 goto err_unlock;4033 }4034 4035 mutex_unlock(&state->internal->demod_lock);4036 return 0;4037 4038err_gateoff:4039 stv090x_i2c_gate_ctrl(state, 0);4040 goto err;4041err_unlock:4042 mutex_unlock(&state->internal->demod_lock);4043err:4044 dprintk(FE_ERROR, 1, "I/O error");4045 return -1;4046}4047 4048static int stv090x_wakeup(struct dvb_frontend *fe)4049{4050 struct stv090x_state *state = fe->demodulator_priv;4051 u32 reg;4052 4053 dprintk(FE_DEBUG, 1, "Wake %s(%d) from standby",4054 state->device == STV0900 ? "STV0900" : "STV0903",4055 state->demod);4056 4057 mutex_lock(&state->internal->demod_lock);4058 4059 /* general power on */4060 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);4061 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00);4062 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)4063 goto err;4064 4065 switch (state->demod) {4066 case STV090x_DEMODULATOR_0:4067 /* power on ADC 1 */4068 reg = stv090x_read_reg(state, STV090x_TSTTNR1);4069 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1);4070 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)4071 goto err;4072 /* power on DiSEqC 1 */4073 reg = stv090x_read_reg(state, STV090x_TSTTNR2);4074 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 1);4075 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)4076 goto err;4077 4078 /* activate clocks */4079 reg = stv090x_read_reg(state, STV090x_STOPCLK1);4080 /* packet delineator 1 clock */4081 STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 0);4082 /* ADC 1 clock */4083 STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 0);4084 /* FEC clock */4085 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);4086 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)4087 goto err;4088 reg = stv090x_read_reg(state, STV090x_STOPCLK2);4089 /* sampling 1 clock */4090 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 0);4091 /* viterbi 1 clock */4092 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 0);4093 /* TS clock */4094 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);4095 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)4096 goto err;4097 break;4098 4099 case STV090x_DEMODULATOR_1:4100 /* power on ADC 2 */4101 reg = stv090x_read_reg(state, STV090x_TSTTNR3);4102 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 1);4103 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)4104 goto err;4105 /* power on DiSEqC 2 */4106 reg = stv090x_read_reg(state, STV090x_TSTTNR4);4107 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 1);4108 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)4109 goto err;4110 4111 /* activate clocks */4112 reg = stv090x_read_reg(state, STV090x_STOPCLK1);4113 /* packet delineator 2 clock */4114 STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 0);4115 /* ADC 2 clock */4116 STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 0);4117 /* FEC clock */4118 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);4119 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)4120 goto err;4121 reg = stv090x_read_reg(state, STV090x_STOPCLK2);4122 /* sampling 2 clock */4123 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 0);4124 /* viterbi 2 clock */4125 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 0);4126 /* TS clock */4127 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);4128 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)4129 goto err;4130 break;4131 4132 default:4133 dprintk(FE_ERROR, 1, "Wrong demodulator!");4134 break;4135 }4136 4137 mutex_unlock(&state->internal->demod_lock);4138 return 0;4139err:4140 mutex_unlock(&state->internal->demod_lock);4141 dprintk(FE_ERROR, 1, "I/O error");4142 return -1;4143}4144 4145static void stv090x_release(struct dvb_frontend *fe)4146{4147 struct stv090x_state *state = fe->demodulator_priv;4148 4149 state->internal->num_used--;4150 if (state->internal->num_used <= 0) {4151 4152 dprintk(FE_ERROR, 1, "Actually removing");4153 4154 remove_dev(state->internal);4155 kfree(state->internal);4156 }4157 4158 kfree(state);4159}4160 4161static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc_mode)4162{4163 u32 reg = 0;4164 4165 reg = stv090x_read_reg(state, STV090x_GENCFG);4166 4167 switch (ldpc_mode) {4168 case STV090x_DUAL:4169 default:4170 if ((state->demod_mode != STV090x_DUAL) || (STV090x_GETFIELD(reg, DDEMOD_FIELD) != 1)) {4171 /* set LDPC to dual mode */4172 if (stv090x_write_reg(state, STV090x_GENCFG, 0x1d) < 0)4173 goto err;4174 4175 state->demod_mode = STV090x_DUAL;4176 4177 reg = stv090x_read_reg(state, STV090x_TSTRES0);4178 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);4179 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)4180 goto err;4181 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);4182 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)4183 goto err;4184 4185 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)4186 goto err;4187 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)4188 goto err;4189 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)4190 goto err;4191 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)4192 goto err;4193 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)4194 goto err;4195 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)4196 goto err;4197 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)4198 goto err;4199 4200 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)4201 goto err;4202 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)4203 goto err;4204 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)4205 goto err;4206 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)4207 goto err;4208 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)4209 goto err;4210 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)4211 goto err;4212 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)4213 goto err;4214 4215 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)4216 goto err;4217 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)4218 goto err;4219 }4220 break;4221 4222 case STV090x_SINGLE:4223 if (stv090x_stop_modcod(state) < 0)4224 goto err;4225 if (stv090x_activate_modcod_single(state) < 0)4226 goto err;4227 4228 if (state->demod == STV090x_DEMODULATOR_1) {4229 if (stv090x_write_reg(state, STV090x_GENCFG, 0x06) < 0) /* path 2 */4230 goto err;4231 } else {4232 if (stv090x_write_reg(state, STV090x_GENCFG, 0x04) < 0) /* path 1 */4233 goto err;4234 }4235 4236 reg = stv090x_read_reg(state, STV090x_TSTRES0);4237 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);4238 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)4239 goto err;4240 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);4241 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)4242 goto err;4243 4244 reg = STV090x_READ_DEMOD(state, PDELCTRL1);4245 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x01);4246 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)4247 goto err;4248 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x00);4249 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)4250 goto err;4251 break;4252 }4253 4254 return 0;4255err:4256 dprintk(FE_ERROR, 1, "I/O error");4257 return -1;4258}4259 4260/* return (Hz), clk in Hz*/4261static u32 stv090x_get_mclk(struct stv090x_state *state)4262{4263 const struct stv090x_config *config = state->config;4264 u32 div, reg;4265 u8 ratio;4266 4267 div = stv090x_read_reg(state, STV090x_NCOARSE);4268 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);4269 ratio = STV090x_GETFIELD(reg, SELX1RATIO_FIELD) ? 4 : 6;4270 4271 return (div + 1) * config->xtal / ratio; /* kHz */4272}4273 4274static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk)4275{4276 const struct stv090x_config *config = state->config;4277 u32 reg, div, clk_sel;4278 4279 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);4280 clk_sel = ((STV090x_GETFIELD(reg, SELX1RATIO_FIELD) == 1) ? 4 : 6);4281 4282 div = ((clk_sel * mclk) / config->xtal) - 1;4283 4284 reg = stv090x_read_reg(state, STV090x_NCOARSE);4285 STV090x_SETFIELD(reg, M_DIV_FIELD, div);4286 if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0)4287 goto err;4288 4289 state->internal->mclk = stv090x_get_mclk(state);4290 4291 /*Set the DiseqC frequency to 22KHz */4292 div = state->internal->mclk / 704000;4293 if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0)4294 goto err;4295 if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0)4296 goto err;4297 4298 return 0;4299err:4300 dprintk(FE_ERROR, 1, "I/O error");4301 return -1;4302}4303 4304static int stv0900_set_tspath(struct stv090x_state *state)4305{4306 u32 reg;4307 4308 if (state->internal->dev_ver >= 0x20) {4309 switch (state->config->ts1_mode) {4310 case STV090x_TSMODE_PARALLEL_PUNCTURED:4311 case STV090x_TSMODE_DVBCI:4312 switch (state->config->ts2_mode) {4313 case STV090x_TSMODE_SERIAL_PUNCTURED:4314 case STV090x_TSMODE_SERIAL_CONTINUOUS:4315 default:4316 stv090x_write_reg(state, STV090x_TSGENERAL, 0x00);4317 break;4318 4319 case STV090x_TSMODE_PARALLEL_PUNCTURED:4320 case STV090x_TSMODE_DVBCI:4321 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x06) < 0) /* Mux'd stream mode */4322 goto err;4323 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);4324 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);4325 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)4326 goto err;4327 reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);4328 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);4329 if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)4330 goto err;4331 if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)4332 goto err;4333 if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)4334 goto err;4335 break;4336 }4337 break;4338 4339 case STV090x_TSMODE_SERIAL_PUNCTURED:4340 case STV090x_TSMODE_SERIAL_CONTINUOUS:4341 default:4342 switch (state->config->ts2_mode) {4343 case STV090x_TSMODE_SERIAL_PUNCTURED:4344 case STV090x_TSMODE_SERIAL_CONTINUOUS:4345 default:4346 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)4347 goto err;4348 break;4349 4350 case STV090x_TSMODE_PARALLEL_PUNCTURED:4351 case STV090x_TSMODE_DVBCI:4352 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0a) < 0)4353 goto err;4354 break;4355 }4356 break;4357 }4358 } else {4359 switch (state->config->ts1_mode) {4360 case STV090x_TSMODE_PARALLEL_PUNCTURED:4361 case STV090x_TSMODE_DVBCI:4362 switch (state->config->ts2_mode) {4363 case STV090x_TSMODE_SERIAL_PUNCTURED:4364 case STV090x_TSMODE_SERIAL_CONTINUOUS:4365 default:4366 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10);4367 break;4368 4369 case STV090x_TSMODE_PARALLEL_PUNCTURED:4370 case STV090x_TSMODE_DVBCI:4371 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x16);4372 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);4373 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);4374 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)4375 goto err;4376 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);4377 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 0);4378 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)4379 goto err;4380 if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)4381 goto err;4382 if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)4383 goto err;4384 break;4385 }4386 break;4387 4388 case STV090x_TSMODE_SERIAL_PUNCTURED:4389 case STV090x_TSMODE_SERIAL_CONTINUOUS:4390 default:4391 switch (state->config->ts2_mode) {4392 case STV090x_TSMODE_SERIAL_PUNCTURED:4393 case STV090x_TSMODE_SERIAL_CONTINUOUS:4394 default:4395 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14);4396 break;4397 4398 case STV090x_TSMODE_PARALLEL_PUNCTURED:4399 case STV090x_TSMODE_DVBCI:4400 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x12);4401 break;4402 }4403 break;4404 }4405 }4406 4407 switch (state->config->ts1_mode) {4408 case STV090x_TSMODE_PARALLEL_PUNCTURED:4409 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);4410 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);4411 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);4412 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);4413 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4414 goto err;4415 break;4416 4417 case STV090x_TSMODE_DVBCI:4418 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);4419 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);4420 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);4421 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);4422 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4423 goto err;4424 break;4425 4426 case STV090x_TSMODE_SERIAL_PUNCTURED:4427 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);4428 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);4429 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);4430 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);4431 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4432 goto err;4433 break;4434 4435 case STV090x_TSMODE_SERIAL_CONTINUOUS:4436 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);4437 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);4438 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);4439 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);4440 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4441 goto err;4442 break;4443 4444 default:4445 break;4446 }4447 4448 switch (state->config->ts2_mode) {4449 case STV090x_TSMODE_PARALLEL_PUNCTURED:4450 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);4451 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);4452 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);4453 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);4454 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)4455 goto err;4456 break;4457 4458 case STV090x_TSMODE_DVBCI:4459 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);4460 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);4461 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);4462 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);4463 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)4464 goto err;4465 break;4466 4467 case STV090x_TSMODE_SERIAL_PUNCTURED:4468 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);4469 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);4470 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);4471 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);4472 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)4473 goto err;4474 break;4475 4476 case STV090x_TSMODE_SERIAL_CONTINUOUS:4477 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);4478 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);4479 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);4480 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);4481 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)4482 goto err;4483 break;4484 4485 default:4486 break;4487 }4488 4489 if (state->config->ts1_clk > 0) {4490 u32 speed;4491 4492 switch (state->config->ts1_mode) {4493 case STV090x_TSMODE_PARALLEL_PUNCTURED:4494 case STV090x_TSMODE_DVBCI:4495 default:4496 speed = state->internal->mclk /4497 (state->config->ts1_clk / 4);4498 if (speed < 0x08)4499 speed = 0x08;4500 if (speed > 0xFF)4501 speed = 0xFF;4502 break;4503 case STV090x_TSMODE_SERIAL_PUNCTURED:4504 case STV090x_TSMODE_SERIAL_CONTINUOUS:4505 speed = state->internal->mclk /4506 (state->config->ts1_clk / 32);4507 if (speed < 0x20)4508 speed = 0x20;4509 if (speed > 0xFF)4510 speed = 0xFF;4511 break;4512 }4513 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);4514 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);4515 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)4516 goto err;4517 if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0)4518 goto err;4519 }4520 4521 if (state->config->ts2_clk > 0) {4522 u32 speed;4523 4524 switch (state->config->ts2_mode) {4525 case STV090x_TSMODE_PARALLEL_PUNCTURED:4526 case STV090x_TSMODE_DVBCI:4527 default:4528 speed = state->internal->mclk /4529 (state->config->ts2_clk / 4);4530 if (speed < 0x08)4531 speed = 0x08;4532 if (speed > 0xFF)4533 speed = 0xFF;4534 break;4535 case STV090x_TSMODE_SERIAL_PUNCTURED:4536 case STV090x_TSMODE_SERIAL_CONTINUOUS:4537 speed = state->internal->mclk /4538 (state->config->ts2_clk / 32);4539 if (speed < 0x20)4540 speed = 0x20;4541 if (speed > 0xFF)4542 speed = 0xFF;4543 break;4544 }4545 reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);4546 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);4547 if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)4548 goto err;4549 if (stv090x_write_reg(state, STV090x_P2_TSSPEED, speed) < 0)4550 goto err;4551 }4552 4553 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);4554 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);4555 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)4556 goto err;4557 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);4558 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)4559 goto err;4560 4561 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);4562 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);4563 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4564 goto err;4565 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);4566 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4567 goto err;4568 4569 return 0;4570err:4571 dprintk(FE_ERROR, 1, "I/O error");4572 return -1;4573}4574 4575static int stv0903_set_tspath(struct stv090x_state *state)4576{4577 u32 reg;4578 4579 if (state->internal->dev_ver >= 0x20) {4580 switch (state->config->ts1_mode) {4581 case STV090x_TSMODE_PARALLEL_PUNCTURED:4582 case STV090x_TSMODE_DVBCI:4583 stv090x_write_reg(state, STV090x_TSGENERAL, 0x00);4584 break;4585 4586 case STV090x_TSMODE_SERIAL_PUNCTURED:4587 case STV090x_TSMODE_SERIAL_CONTINUOUS:4588 default:4589 stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c);4590 break;4591 }4592 } else {4593 switch (state->config->ts1_mode) {4594 case STV090x_TSMODE_PARALLEL_PUNCTURED:4595 case STV090x_TSMODE_DVBCI:4596 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10);4597 break;4598 4599 case STV090x_TSMODE_SERIAL_PUNCTURED:4600 case STV090x_TSMODE_SERIAL_CONTINUOUS:4601 default:4602 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14);4603 break;4604 }4605 }4606 4607 switch (state->config->ts1_mode) {4608 case STV090x_TSMODE_PARALLEL_PUNCTURED:4609 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);4610 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);4611 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);4612 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4613 goto err;4614 break;4615 4616 case STV090x_TSMODE_DVBCI:4617 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);4618 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);4619 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);4620 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4621 goto err;4622 break;4623 4624 case STV090x_TSMODE_SERIAL_PUNCTURED:4625 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);4626 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);4627 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);4628 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4629 goto err;4630 break;4631 4632 case STV090x_TSMODE_SERIAL_CONTINUOUS:4633 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);4634 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);4635 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);4636 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4637 goto err;4638 break;4639 4640 default:4641 break;4642 }4643 4644 if (state->config->ts1_clk > 0) {4645 u32 speed;4646 4647 switch (state->config->ts1_mode) {4648 case STV090x_TSMODE_PARALLEL_PUNCTURED:4649 case STV090x_TSMODE_DVBCI:4650 default:4651 speed = state->internal->mclk /4652 (state->config->ts1_clk / 4);4653 if (speed < 0x08)4654 speed = 0x08;4655 if (speed > 0xFF)4656 speed = 0xFF;4657 break;4658 case STV090x_TSMODE_SERIAL_PUNCTURED:4659 case STV090x_TSMODE_SERIAL_CONTINUOUS:4660 speed = state->internal->mclk /4661 (state->config->ts1_clk / 32);4662 if (speed < 0x20)4663 speed = 0x20;4664 if (speed > 0xFF)4665 speed = 0xFF;4666 break;4667 }4668 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);4669 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);4670 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)4671 goto err;4672 if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0)4673 goto err;4674 }4675 4676 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);4677 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);4678 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4679 goto err;4680 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);4681 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)4682 goto err;4683 4684 return 0;4685err:4686 dprintk(FE_ERROR, 1, "I/O error");4687 return -1;4688}4689 4690static int stv090x_init(struct dvb_frontend *fe)4691{4692 struct stv090x_state *state = fe->demodulator_priv;4693 const struct stv090x_config *config = state->config;4694 u32 reg;4695 4696 if (state->internal->mclk == 0) {4697 /* call tuner init to configure the tuner's clock output4698 divider directly before setting up the master clock of4699 the stv090x. */4700 if (stv090x_i2c_gate_ctrl(state, 1) < 0)4701 goto err;4702 4703 if (config->tuner_init) {4704 if (config->tuner_init(fe) < 0)4705 goto err_gateoff;4706 }4707 4708 if (stv090x_i2c_gate_ctrl(state, 0) < 0)4709 goto err;4710 4711 stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */4712 msleep(5);4713 if (stv090x_write_reg(state, STV090x_SYNTCTRL,4714 0x20 | config->clk_mode) < 0)4715 goto err;4716 stv090x_get_mclk(state);4717 }4718 4719 if (stv090x_wakeup(fe) < 0) {4720 dprintk(FE_ERROR, 1, "Error waking device");4721 goto err;4722 }4723 4724 if (stv090x_ldpc_mode(state, state->demod_mode) < 0)4725 goto err;4726 4727 reg = STV090x_READ_DEMOD(state, TNRCFG2);4728 STV090x_SETFIELD_Px(reg, TUN_IQSWAP_FIELD, state->inversion);4729 if (STV090x_WRITE_DEMOD(state, TNRCFG2, reg) < 0)4730 goto err;4731 reg = STV090x_READ_DEMOD(state, DEMOD);4732 STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);4733 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)4734 goto err;4735 4736 if (stv090x_i2c_gate_ctrl(state, 1) < 0)4737 goto err;4738 4739 if (config->tuner_set_mode) {4740 if (config->tuner_set_mode(fe, TUNER_WAKE) < 0)4741 goto err_gateoff;4742 }4743 4744 if (config->tuner_init) {4745 if (config->tuner_init(fe) < 0)4746 goto err_gateoff;4747 }4748 4749 if (stv090x_i2c_gate_ctrl(state, 0) < 0)4750 goto err;4751 4752 if (state->device == STV0900) {4753 if (stv0900_set_tspath(state) < 0)4754 goto err;4755 } else {4756 if (stv0903_set_tspath(state) < 0)4757 goto err;4758 }4759 4760 return 0;4761 4762err_gateoff:4763 stv090x_i2c_gate_ctrl(state, 0);4764err:4765 dprintk(FE_ERROR, 1, "I/O error");4766 return -1;4767}4768 4769static int stv090x_setup(struct dvb_frontend *fe)4770{4771 struct stv090x_state *state = fe->demodulator_priv;4772 const struct stv090x_config *config = state->config;4773 const struct stv090x_reg *stv090x_initval = NULL;4774 const struct stv090x_reg *stv090x_cut20_val = NULL;4775 unsigned long t1_size = 0, t2_size = 0;4776 u32 reg = 0;4777 4778 int i;4779 4780 if (state->device == STV0900) {4781 dprintk(FE_DEBUG, 1, "Initializing STV0900");4782 stv090x_initval = stv0900_initval;4783 t1_size = ARRAY_SIZE(stv0900_initval);4784 stv090x_cut20_val = stv0900_cut20_val;4785 t2_size = ARRAY_SIZE(stv0900_cut20_val);4786 } else if (state->device == STV0903) {4787 dprintk(FE_DEBUG, 1, "Initializing STV0903");4788 stv090x_initval = stv0903_initval;4789 t1_size = ARRAY_SIZE(stv0903_initval);4790 stv090x_cut20_val = stv0903_cut20_val;4791 t2_size = ARRAY_SIZE(stv0903_cut20_val);4792 }4793 4794 /* STV090x init */4795 4796 /* Stop Demod */4797 if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0)4798 goto err;4799 if (state->device == STV0900)4800 if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0)4801 goto err;4802 4803 msleep(5);4804 4805 /* Set No Tuner Mode */4806 if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0)4807 goto err;4808 if (state->device == STV0900)4809 if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0)4810 goto err;4811 4812 /* I2C repeater OFF */4813 STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level);4814 if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0)4815 goto err;4816 if (state->device == STV0900)4817 if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0)4818 goto err;4819 4820 if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */4821 goto err;4822 msleep(5);4823 if (stv090x_write_reg(state, STV090x_I2CCFG, 0x08) < 0) /* 1/41 oversampling */4824 goto err;4825 if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) /* enable PLL */4826 goto err;4827 msleep(5);4828 4829 /* write initval */4830 dprintk(FE_DEBUG, 1, "Setting up initial values");4831 for (i = 0; i < t1_size; i++) {4832 if (stv090x_write_reg(state, stv090x_initval[i].addr, stv090x_initval[i].data) < 0)4833 goto err;4834 }4835 4836 state->internal->dev_ver = stv090x_read_reg(state, STV090x_MID);4837 if (state->internal->dev_ver >= 0x20) {4838 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)4839 goto err;4840 4841 /* write cut20_val*/4842 dprintk(FE_DEBUG, 1, "Setting up Cut 2.0 initial values");4843 for (i = 0; i < t2_size; i++) {4844 if (stv090x_write_reg(state, stv090x_cut20_val[i].addr, stv090x_cut20_val[i].data) < 0)4845 goto err;4846 }4847 4848 } else if (state->internal->dev_ver < 0x20) {4849 dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!",4850 state->internal->dev_ver);4851 4852 goto err;4853 } else if (state->internal->dev_ver > 0x30) {4854 /* we shouldn't bail out from here */4855 dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!",4856 state->internal->dev_ver);4857 }4858 4859 /* ADC1 range */4860 reg = stv090x_read_reg(state, STV090x_TSTTNR1);4861 STV090x_SETFIELD(reg, ADC1_INMODE_FIELD,4862 (config->adc1_range == STV090x_ADC_1Vpp) ? 0 : 1);4863 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)4864 goto err;4865 4866 /* ADC2 range */4867 reg = stv090x_read_reg(state, STV090x_TSTTNR3);4868 STV090x_SETFIELD(reg, ADC2_INMODE_FIELD,4869 (config->adc2_range == STV090x_ADC_1Vpp) ? 0 : 1);4870 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)4871 goto err;4872 4873 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0)4874 goto err;4875 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)4876 goto err;4877 4878 return 0;4879err:4880 dprintk(FE_ERROR, 1, "I/O error");4881 return -1;4882}4883 4884static int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir,4885 u8 value, u8 xor_value)4886{4887 struct stv090x_state *state = fe->demodulator_priv;4888 u8 reg = 0;4889 4890 STV090x_SETFIELD(reg, GPIOx_OPD_FIELD, dir);4891 STV090x_SETFIELD(reg, GPIOx_CONFIG_FIELD, value);4892 STV090x_SETFIELD(reg, GPIOx_XOR_FIELD, xor_value);4893 4894 return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);4895}4896 4897static int stv090x_setup_compound(struct stv090x_state *state)4898{4899 struct stv090x_dev *temp_int;4900 4901 temp_int = find_dev(state->i2c,4902 state->config->address);4903 4904 if (temp_int && state->demod_mode == STV090x_DUAL) {4905 state->internal = temp_int->internal;4906 state->internal->num_used++;4907 dprintk(FE_INFO, 1, "Found Internal Structure!");4908 } else {4909 state->internal = kmalloc(sizeof(*state->internal), GFP_KERNEL);4910 if (!state->internal)4911 goto error;4912 temp_int = append_internal(state->internal);4913 if (!temp_int) {4914 kfree(state->internal);4915 goto error;4916 }4917 state->internal->num_used = 1;4918 state->internal->mclk = 0;4919 state->internal->dev_ver = 0;4920 state->internal->i2c_adap = state->i2c;4921 state->internal->i2c_addr = state->config->address;4922 dprintk(FE_INFO, 1, "Create New Internal Structure!");4923 4924 mutex_init(&state->internal->demod_lock);4925 mutex_init(&state->internal->tuner_lock);4926 4927 if (stv090x_setup(&state->frontend) < 0) {4928 dprintk(FE_ERROR, 1, "Error setting up device");4929 goto err_remove;4930 }4931 }4932 4933 if (state->internal->dev_ver >= 0x30)4934 state->frontend.ops.info.caps |= FE_CAN_MULTISTREAM;4935 4936 /* workaround for stuck DiSEqC output */4937 if (state->config->diseqc_envelope_mode)4938 stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);4939 4940 state->config->set_gpio = stv090x_set_gpio;4941 4942 dprintk(FE_ERROR, 1, "Probing %s demodulator(%d) Cut=0x%02x",4943 state->device == STV0900 ? "STV0900" : "STV0903",4944 state->config->demod,4945 state->internal->dev_ver);4946 4947 return 0;4948 4949error:4950 return -ENOMEM;4951err_remove:4952 remove_dev(state->internal);4953 kfree(state->internal);4954 return -ENODEV;4955}4956 4957static const struct dvb_frontend_ops stv090x_ops = {4958 .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },4959 .info = {4960 .name = "STV090x Multistandard",4961 .frequency_min_hz = 950 * MHz,4962 .frequency_max_hz = 2150 * MHz,4963 .symbol_rate_min = 1000000,4964 .symbol_rate_max = 45000000,4965 .caps = FE_CAN_INVERSION_AUTO |4966 FE_CAN_FEC_AUTO |4967 FE_CAN_QPSK |4968 FE_CAN_2G_MODULATION4969 },4970 4971 .release = stv090x_release,4972 .init = stv090x_init,4973 4974 .sleep = stv090x_sleep,4975 .get_frontend_algo = stv090x_frontend_algo,4976 4977 .diseqc_send_master_cmd = stv090x_send_diseqc_msg,4978 .diseqc_send_burst = stv090x_send_diseqc_burst,4979 .diseqc_recv_slave_reply = stv090x_recv_slave_reply,4980 .set_tone = stv090x_set_tone,4981 4982 .search = stv090x_search,4983 .read_status = stv090x_read_status,4984 .read_ber = stv090x_read_per,4985 .read_signal_strength = stv090x_read_signal_strength,4986 .read_snr = stv090x_read_cnr,4987};4988 4989static struct dvb_frontend *stv090x_get_dvb_frontend(struct i2c_client *client)4990{4991 struct stv090x_state *state = i2c_get_clientdata(client);4992 4993 dev_dbg(&client->dev, "\n");4994 4995 return &state->frontend;4996}4997 4998static int stv090x_probe(struct i2c_client *client)4999{5000 int ret = 0;5001 struct stv090x_config *config = client->dev.platform_data;5002 5003 struct stv090x_state *state = NULL;5004 5005 state = kzalloc(sizeof(*state), GFP_KERNEL);5006 if (!state) {5007 ret = -ENOMEM;5008 goto error;5009 }5010 5011 state->verbose = &verbose;5012 state->config = config;5013 state->i2c = client->adapter;5014 state->frontend.ops = stv090x_ops;5015 state->frontend.demodulator_priv = state;5016 state->demod = config->demod;5017 /* Single or Dual mode */5018 state->demod_mode = config->demod_mode;5019 state->device = config->device;5020 /* default */5021 state->rolloff = STV090x_RO_35;5022 5023 ret = stv090x_setup_compound(state);5024 if (ret)5025 goto error;5026 5027 i2c_set_clientdata(client, state);5028 5029 /* setup callbacks */5030 config->get_dvb_frontend = stv090x_get_dvb_frontend;5031 5032 return 0;5033 5034error:5035 kfree(state);5036 return ret;5037}5038 5039static void stv090x_remove(struct i2c_client *client)5040{5041 struct stv090x_state *state = i2c_get_clientdata(client);5042 5043 stv090x_release(&state->frontend);5044}5045 5046struct dvb_frontend *stv090x_attach(struct stv090x_config *config,5047 struct i2c_adapter *i2c,5048 enum stv090x_demodulator demod)5049{5050 int ret = 0;5051 struct stv090x_state *state = NULL;5052 5053 state = kzalloc(sizeof(*state), GFP_KERNEL);5054 if (!state)5055 goto error;5056 5057 state->verbose = &verbose;5058 state->config = config;5059 state->i2c = i2c;5060 state->frontend.ops = stv090x_ops;5061 state->frontend.demodulator_priv = state;5062 state->demod = demod;5063 /* Single or Dual mode */5064 state->demod_mode = config->demod_mode;5065 state->device = config->device;5066 /* default */5067 state->rolloff = STV090x_RO_35;5068 5069 ret = stv090x_setup_compound(state);5070 if (ret)5071 goto error;5072 5073 return &state->frontend;5074 5075error:5076 kfree(state);5077 return NULL;5078}5079EXPORT_SYMBOL_GPL(stv090x_attach);5080 5081static const struct i2c_device_id stv090x_id_table[] = {5082 { "stv090x" },5083 {}5084};5085MODULE_DEVICE_TABLE(i2c, stv090x_id_table);5086 5087static struct i2c_driver stv090x_driver = {5088 .driver = {5089 .name = "stv090x",5090 .suppress_bind_attrs = true,5091 },5092 .probe = stv090x_probe,5093 .remove = stv090x_remove,5094 .id_table = stv090x_id_table,5095};5096 5097module_i2c_driver(stv090x_driver);5098 5099MODULE_PARM_DESC(verbose, "Set Verbosity level");5100MODULE_AUTHOR("Manu Abraham");5101MODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend");5102MODULE_LICENSE("GPL");5103