aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorAndrew de Quincey <adq_dvb@lidskialf.net>2005-09-09 16:02:31 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:57:38 -0400
commita9d6a80b41c04e8ff4c7442cc35f5df610863841 (patch)
tree39a3a0cec707c6b8d2c7219172e9287f04f5190a /drivers/media
parentcfbfce1566f11c0dbad8a16173f0448b0c78cecb (diff)
[PATCH] dvb: frontend: s5h1420: fixes
Misc. fixes. Signed-off-by: Andrew de Quincey <adq_dvb@lidskialf.net> Signed-off-by: Johannes Stezenbach <js@linuxtv.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c162
-rw-r--r--drivers/media/dvb/frontends/s5h1420.h3
-rw-r--r--drivers/media/dvb/ttpci/budget.c1
3 files changed, 97 insertions, 69 deletions
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index 4f396ac8de77..c7fe27fd530c 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -48,7 +48,8 @@ struct s5h1420_state {
48}; 48};
49 49
50static u32 s5h1420_getsymbolrate(struct s5h1420_state* state); 50static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
51static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings); 51static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
52 struct dvb_frontend_tune_settings* fesettings);
52 53
53 54
54static int debug = 0; 55static int debug = 0;
@@ -91,7 +92,8 @@ static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
91 92
92 switch(voltage) { 93 switch(voltage) {
93 case SEC_VOLTAGE_13: 94 case SEC_VOLTAGE_13:
94 s5h1420_writereg(state, 0x3c, (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02); 95 s5h1420_writereg(state, 0x3c,
96 (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
95 break; 97 break;
96 98
97 case SEC_VOLTAGE_18: 99 case SEC_VOLTAGE_18:
@@ -112,18 +114,21 @@ static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
112 114
113 switch(tone) { 115 switch(tone) {
114 case SEC_TONE_ON: 116 case SEC_TONE_ON:
115 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08); 117 s5h1420_writereg(state, 0x3b,
118 (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
116 break; 119 break;
117 120
118 case SEC_TONE_OFF: 121 case SEC_TONE_OFF:
119 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01); 122 s5h1420_writereg(state, 0x3b,
123 (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
120 break; 124 break;
121 } 125 }
122 126
123 return 0; 127 return 0;
124} 128}
125 129
126static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) 130static int s5h1420_send_master_cmd (struct dvb_frontend* fe,
131 struct dvb_diseqc_master_cmd* cmd)
127{ 132{
128 struct s5h1420_state* state = fe->demodulator_priv; 133 struct s5h1420_state* state = fe->demodulator_priv;
129 u8 val; 134 u8 val;
@@ -131,6 +136,9 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
131 unsigned long timeout; 136 unsigned long timeout;
132 int result = 0; 137 int result = 0;
133 138
139 if (cmd->msg_len > 8)
140 return -EINVAL;
141
134 /* setup for DISEQC */ 142 /* setup for DISEQC */
135 val = s5h1420_readreg(state, 0x3b); 143 val = s5h1420_readreg(state, 0x3b);
136 s5h1420_writereg(state, 0x3b, 0x02); 144 s5h1420_writereg(state, 0x3b, 0x02);
@@ -138,16 +146,17 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
138 146
139 /* write the DISEQC command bytes */ 147 /* write the DISEQC command bytes */
140 for(i=0; i< cmd->msg_len; i++) { 148 for(i=0; i< cmd->msg_len; i++) {
141 s5h1420_writereg(state, 0x3c + i, cmd->msg[i]); 149 s5h1420_writereg(state, 0x3d + i, cmd->msg[i]);
142 } 150 }
143 151
144 /* kick off transmission */ 152 /* kick off transmission */
145 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | ((cmd->msg_len-1) << 4) | 0x08); 153 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) |
154 ((cmd->msg_len-1) << 4) | 0x08);
146 155
147 /* wait for transmission to complete */ 156 /* wait for transmission to complete */
148 timeout = jiffies + ((100*HZ) / 1000); 157 timeout = jiffies + ((100*HZ) / 1000);
149 while(time_before(jiffies, timeout)) { 158 while(time_before(jiffies, timeout)) {
150 if (s5h1420_readreg(state, 0x3b) & 0x08) 159 if (!(s5h1420_readreg(state, 0x3b) & 0x08))
151 break; 160 break;
152 161
153 msleep(5); 162 msleep(5);
@@ -161,7 +170,8 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_m
161 return result; 170 return result;
162} 171}
163 172
164static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply) 173static int s5h1420_recv_slave_reply (struct dvb_frontend* fe,
174 struct dvb_diseqc_slave_reply* reply)
165{ 175{
166 struct s5h1420_state* state = fe->demodulator_priv; 176 struct s5h1420_state* state = fe->demodulator_priv;
167 u8 val; 177 u8 val;
@@ -205,7 +215,7 @@ static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_
205 215
206 /* extract data */ 216 /* extract data */
207 for(i=0; i< length; i++) { 217 for(i=0; i< length; i++) {
208 reply->msg[i] = s5h1420_readreg(state, 0x3c + i); 218 reply->msg[i] = s5h1420_readreg(state, 0x3d + i);
209 } 219 }
210 220
211exit: 221exit:
@@ -236,7 +246,7 @@ static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicm
236 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08); 246 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
237 247
238 /* wait for transmission to complete */ 248 /* wait for transmission to complete */
239 timeout = jiffies + ((20*HZ) / 1000); 249 timeout = jiffies + ((100*HZ) / 1000);
240 while(time_before(jiffies, timeout)) { 250 while(time_before(jiffies, timeout)) {
241 if (!(s5h1420_readreg(state, 0x3b) & 0x08)) 251 if (!(s5h1420_readreg(state, 0x3b) & 0x08))
242 break; 252 break;
@@ -259,9 +269,9 @@ static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state)
259 269
260 val = s5h1420_readreg(state, 0x14); 270 val = s5h1420_readreg(state, 0x14);
261 if (val & 0x02) 271 if (val & 0x02)
262 status |= FE_HAS_SIGNAL; // FIXME: not sure if this is right 272 status |= FE_HAS_SIGNAL;
263 if (val & 0x01) 273 if (val & 0x01)
264 status |= FE_HAS_CARRIER; // FIXME: not sure if this is right 274 status |= FE_HAS_CARRIER;
265 val = s5h1420_readreg(state, 0x36); 275 val = s5h1420_readreg(state, 0x36);
266 if (val & 0x01) 276 if (val & 0x01)
267 status |= FE_HAS_VITERBI; 277 status |= FE_HAS_VITERBI;
@@ -284,8 +294,8 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
284 /* determine lock state */ 294 /* determine lock state */
285 *status = s5h1420_get_status_bits(state); 295 *status = s5h1420_get_status_bits(state);
286 296
287 /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert the inversion, 297 /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert
288 wait a bit and check again */ 298 the inversion, wait a bit and check again */
289 if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) { 299 if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) {
290 val = s5h1420_readreg(state, 0x32); 300 val = s5h1420_readreg(state, 0x32);
291 if ((val & 0x07) == 0x03) { 301 if ((val & 0x07) == 0x03) {
@@ -330,6 +340,10 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
330 tmp = (tmp * 2 * 7) / 8; 340 tmp = (tmp * 2 * 7) / 8;
331 break; 341 break;
332 } 342 }
343 if (tmp == 0) {
344 printk("s5h1420: avoided division by 0\n");
345 tmp = 1;
346 }
333 tmp = state->fclk / tmp; 347 tmp = state->fclk / tmp;
334 348
335 /* set the MPEG_CLK_INTL for the calculated data rate */ 349 /* set the MPEG_CLK_INTL for the calculated data rate */
@@ -368,16 +382,21 @@ static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber)
368 382
369 s5h1420_writereg(state, 0x46, 0x1d); 383 s5h1420_writereg(state, 0x46, 0x1d);
370 mdelay(25); 384 mdelay(25);
371 return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47); 385
386 *ber = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
387
388 return 0;
372} 389}
373 390
374static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength) 391static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength)
375{ 392{
376 struct s5h1420_state* state = fe->demodulator_priv; 393 struct s5h1420_state* state = fe->demodulator_priv;
377 394
378 u8 val = 0xff - s5h1420_readreg(state, 0x15); 395 u8 val = s5h1420_readreg(state, 0x15);
379 396
380 return (int) ((val << 8) | val); 397 *strength = (u16) ((val << 8) | val);
398
399 return 0;
381} 400}
382 401
383static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) 402static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
@@ -386,7 +405,10 @@ static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
386 405
387 s5h1420_writereg(state, 0x46, 0x1f); 406 s5h1420_writereg(state, 0x46, 0x1f);
388 mdelay(25); 407 mdelay(25);
389 return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47); 408
409 *ucblocks = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
410
411 return 0;
390} 412}
391 413
392static void s5h1420_reset(struct s5h1420_state* state) 414static void s5h1420_reset(struct s5h1420_state* state)
@@ -396,11 +418,12 @@ static void s5h1420_reset(struct s5h1420_state* state)
396 udelay(10); 418 udelay(10);
397} 419}
398 420
399static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_frontend_parameters *p) 421static void s5h1420_setsymbolrate(struct s5h1420_state* state,
422 struct dvb_frontend_parameters *p)
400{ 423{
401 u64 val; 424 u64 val;
402 425
403 val = (p->u.qpsk.symbol_rate / 1000) * (1<<24); 426 val = ((u64) p->u.qpsk.symbol_rate / 1000ULL) * (1ULL<<24);
404 if (p->u.qpsk.symbol_rate <= 21000000) { 427 if (p->u.qpsk.symbol_rate <= 21000000) {
405 val *= 2; 428 val *= 2;
406 } 429 }
@@ -415,7 +438,7 @@ static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_fronte
415 438
416static u32 s5h1420_getsymbolrate(struct s5h1420_state* state) 439static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
417{ 440{
418 u64 val; 441 u64 val = 0;
419 int sampling = 2; 442 int sampling = 2;
420 443
421 if (s5h1420_readreg(state, 0x05) & 0x2) 444 if (s5h1420_readreg(state, 0x05) & 0x2)
@@ -427,10 +450,10 @@ static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
427 val |= s5h1420_readreg(state, 0x13); 450 val |= s5h1420_readreg(state, 0x13);
428 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7); 451 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
429 452
430 val *= (state->fclk / 1000); 453 val *= (state->fclk / 1000ULL);
431 do_div(val, ((1<<24) * sampling)); 454 do_div(val, ((1<<24) * sampling));
432 455
433 return (u32) (val * 1000); 456 return (u32) (val * 1000ULL);
434} 457}
435 458
436static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset) 459static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
@@ -463,46 +486,55 @@ static int s5h1420_getfreqoffset(struct s5h1420_state* state)
463 486
464 /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so 487 /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
465 * divide fclk by 1000000 to get the correct value. */ 488 * divide fclk by 1000000 to get the correct value. */
466 val = - ((val * (state->fclk/1000000)) / (1<<24)); 489 val = (((-val) * (state->fclk/1000000)) / (1<<24));
467 490
468 return val; 491 return val;
469} 492}
470 493
471static void s5h1420_setfec(struct s5h1420_state* state, struct dvb_frontend_parameters *p) 494static void s5h1420_setfec_inversion(struct s5h1420_state* state,
495 struct dvb_frontend_parameters *p)
472{ 496{
497 u8 inversion = 0;
498
499 if (p->inversion == INVERSION_OFF) {
500 inversion = state->config->invert ? 0x08 : 0;
501 } else if (p->inversion == INVERSION_ON) {
502 inversion = state->config->invert ? 0 : 0x08;
503 }
504
473 if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) { 505 if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
474 s5h1420_writereg(state, 0x31, 0x00);
475 s5h1420_writereg(state, 0x30, 0x3f); 506 s5h1420_writereg(state, 0x30, 0x3f);
507 s5h1420_writereg(state, 0x31, 0x00 | inversion);
476 } else { 508 } else {
477 switch(p->u.qpsk.fec_inner) { 509 switch(p->u.qpsk.fec_inner) {
478 case FEC_1_2: 510 case FEC_1_2:
479 s5h1420_writereg(state, 0x31, 0x10);
480 s5h1420_writereg(state, 0x30, 0x01); 511 s5h1420_writereg(state, 0x30, 0x01);
512 s5h1420_writereg(state, 0x31, 0x10 | inversion);
481 break; 513 break;
482 514
483 case FEC_2_3: 515 case FEC_2_3:
484 s5h1420_writereg(state, 0x31, 0x11);
485 s5h1420_writereg(state, 0x30, 0x02); 516 s5h1420_writereg(state, 0x30, 0x02);
517 s5h1420_writereg(state, 0x31, 0x11 | inversion);
486 break; 518 break;
487 519
488 case FEC_3_4: 520 case FEC_3_4:
489 s5h1420_writereg(state, 0x31, 0x12);
490 s5h1420_writereg(state, 0x30, 0x04); 521 s5h1420_writereg(state, 0x30, 0x04);
491 break; 522 s5h1420_writereg(state, 0x31, 0x12 | inversion);
523 break;
492 524
493 case FEC_5_6: 525 case FEC_5_6:
494 s5h1420_writereg(state, 0x31, 0x13);
495 s5h1420_writereg(state, 0x30, 0x08); 526 s5h1420_writereg(state, 0x30, 0x08);
527 s5h1420_writereg(state, 0x31, 0x13 | inversion);
496 break; 528 break;
497 529
498 case FEC_6_7: 530 case FEC_6_7:
499 s5h1420_writereg(state, 0x31, 0x14);
500 s5h1420_writereg(state, 0x30, 0x10); 531 s5h1420_writereg(state, 0x30, 0x10);
532 s5h1420_writereg(state, 0x31, 0x14 | inversion);
501 break; 533 break;
502 534
503 case FEC_7_8: 535 case FEC_7_8:
504 s5h1420_writereg(state, 0x31, 0x15);
505 s5h1420_writereg(state, 0x30, 0x20); 536 s5h1420_writereg(state, 0x30, 0x20);
537 s5h1420_writereg(state, 0x31, 0x15 | inversion);
506 break; 538 break;
507 539
508 default: 540 default:
@@ -536,22 +568,6 @@ static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
536 return FEC_NONE; 568 return FEC_NONE;
537} 569}
538 570
539static void s5h1420_setinversion(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
540{
541 if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
542 s5h1420_writereg(state, 0x31, 0x00);
543 s5h1420_writereg(state, 0x30, 0x3f);
544 } else {
545 u8 tmp = s5h1420_readreg(state, 0x31) & 0xf7;
546 tmp |= 0x10;
547
548 if (p->inversion == INVERSION_ON)
549 tmp |= 0x80;
550
551 s5h1420_writereg(state, 0x31, tmp);
552 }
553}
554
555static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state) 571static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
556{ 572{
557 if (s5h1420_readreg(state, 0x32) & 0x08) 573 if (s5h1420_readreg(state, 0x32) & 0x08)
@@ -560,35 +576,35 @@ static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
560 return INVERSION_OFF; 576 return INVERSION_OFF;
561} 577}
562 578
563static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) 579static int s5h1420_set_frontend(struct dvb_frontend* fe,
580 struct dvb_frontend_parameters *p)
564{ 581{
565 struct s5h1420_state* state = fe->demodulator_priv; 582 struct s5h1420_state* state = fe->demodulator_priv;
566 u32 frequency_delta; 583 int frequency_delta;
567 struct dvb_frontend_tune_settings fesettings; 584 struct dvb_frontend_tune_settings fesettings;
585 u32 tmp;
568 586
569 /* check if we should do a fast-tune */ 587 /* check if we should do a fast-tune */
570 memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); 588 memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters));
571 s5h1420_get_tune_settings(fe, &fesettings); 589 s5h1420_get_tune_settings(fe, &fesettings);
572 frequency_delta = p->frequency - state->tunedfreq; 590 frequency_delta = p->frequency - state->tunedfreq;
573 if ((frequency_delta > -fesettings.max_drift) && (frequency_delta < fesettings.max_drift) && 591 if ((frequency_delta > -fesettings.max_drift) &&
592 (frequency_delta < fesettings.max_drift) &&
574 (frequency_delta != 0) && 593 (frequency_delta != 0) &&
575 (state->fec_inner == p->u.qpsk.fec_inner) && 594 (state->fec_inner == p->u.qpsk.fec_inner) &&
576 (state->symbol_rate == p->u.qpsk.symbol_rate)) { 595 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
577 596
578 s5h1420_setfreqoffset(state, frequency_delta); 597 if (state->config->pll_set) {
598 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
599 state->config->pll_set(fe, p, &tmp);
600 s5h1420_setfreqoffset(state, p->frequency - tmp);
601 }
579 return 0; 602 return 0;
580 } 603 }
581 604
582 /* first of all, software reset */ 605 /* first of all, software reset */
583 s5h1420_reset(state); 606 s5h1420_reset(state);
584 607
585 /* set tuner PLL */
586 if (state->config->pll_set) {
587 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
588 state->config->pll_set(fe, p, &state->tunedfreq);
589 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
590 }
591
592 /* set s5h1420 fclk PLL according to desired symbol rate */ 608 /* set s5h1420 fclk PLL according to desired symbol rate */
593 if (p->u.qpsk.symbol_rate > 28000000) { 609 if (p->u.qpsk.symbol_rate > 28000000) {
594 state->fclk = 88000000; 610 state->fclk = 88000000;
@@ -609,8 +625,9 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
609 625
610 /* set misc registers */ 626 /* set misc registers */
611 s5h1420_writereg(state, 0x02, 0x00); 627 s5h1420_writereg(state, 0x02, 0x00);
628 s5h1420_writereg(state, 0x06, 0x00);
612 s5h1420_writereg(state, 0x07, 0xb0); 629 s5h1420_writereg(state, 0x07, 0xb0);
613 s5h1420_writereg(state, 0x0a, 0x67); 630 s5h1420_writereg(state, 0x0a, 0xe7);
614 s5h1420_writereg(state, 0x0b, 0x78); 631 s5h1420_writereg(state, 0x0b, 0x78);
615 s5h1420_writereg(state, 0x0c, 0x48); 632 s5h1420_writereg(state, 0x0c, 0x48);
616 s5h1420_writereg(state, 0x0d, 0x6b); 633 s5h1420_writereg(state, 0x0d, 0x6b);
@@ -626,21 +643,26 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
626 /* start QPSK */ 643 /* start QPSK */
627 s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1); 644 s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1);
628 645
629 /* set the frequency offset to adjust for PLL inaccuracy */ 646 /* set tuner PLL */
630 s5h1420_setfreqoffset(state, p->frequency - state->tunedfreq); 647 if (state->config->pll_set) {
648 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
649 state->config->pll_set(fe, p, &tmp);
650 s5h1420_setfreqoffset(state, 0);
651 }
631 652
632 /* set the reset of the parameters */ 653 /* set the reset of the parameters */
633 s5h1420_setsymbolrate(state, p); 654 s5h1420_setsymbolrate(state, p);
634 s5h1420_setinversion(state, p); 655 s5h1420_setfec_inversion(state, p);
635 s5h1420_setfec(state, p);
636 656
637 state->fec_inner = p->u.qpsk.fec_inner; 657 state->fec_inner = p->u.qpsk.fec_inner;
638 state->symbol_rate = p->u.qpsk.symbol_rate; 658 state->symbol_rate = p->u.qpsk.symbol_rate;
639 state->postlocked = 0; 659 state->postlocked = 0;
660 state->tunedfreq = p->frequency;
640 return 0; 661 return 0;
641} 662}
642 663
643static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) 664static int s5h1420_get_frontend(struct dvb_frontend* fe,
665 struct dvb_frontend_parameters *p)
644{ 666{
645 struct s5h1420_state* state = fe->demodulator_priv; 667 struct s5h1420_state* state = fe->demodulator_priv;
646 668
@@ -652,7 +674,8 @@ static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
652 return 0; 674 return 0;
653} 675}
654 676
655static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) 677static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
678 struct dvb_frontend_tune_settings* fesettings)
656{ 679{
657 if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) { 680 if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
658 fesettings->min_delay_ms = 50; 681 fesettings->min_delay_ms = 50;
@@ -717,7 +740,8 @@ static void s5h1420_release(struct dvb_frontend* fe)
717 740
718static struct dvb_frontend_ops s5h1420_ops; 741static struct dvb_frontend_ops s5h1420_ops;
719 742
720struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, struct i2c_adapter* i2c) 743struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
744 struct i2c_adapter* i2c)
721{ 745{
722 struct s5h1420_state* state = NULL; 746 struct s5h1420_state* state = NULL;
723 u8 identity; 747 u8 identity;
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
index b687fc77ceb3..872028ddf2a2 100644
--- a/drivers/media/dvb/frontends/s5h1420.h
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -30,6 +30,9 @@ struct s5h1420_config
30 /* the demodulator's i2c address */ 30 /* the demodulator's i2c address */
31 u8 demod_address; 31 u8 demod_address;
32 32
33 /* does the inversion require inversion? */
34 u8 invert:1;
35
33 /* PLL maintenance */ 36 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe); 37 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout); 38 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout);
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 5552ef501996..43d6c8268642 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -480,6 +480,7 @@ static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete
480 480
481static struct s5h1420_config s5h1420_config = { 481static struct s5h1420_config s5h1420_config = {
482 .demod_address = 0x53, 482 .demod_address = 0x53,
483 .invert = 1,
483 .pll_set = s5h1420_pll_set, 484 .pll_set = s5h1420_pll_set,
484}; 485};
485 486