25 #include <linux/kernel.h>
26 #include <linux/module.h>
28 #include <linux/string.h>
29 #include <linux/slab.h>
32 #include <asm/div64.h>
34 #include <linux/i2c.h>
41 #define TONE_FREQ 22000
66 static int s5h1420_get_tune_settings(
struct dvb_frontend* fe,
74 #define dprintk(x...) do { \
76 printk(KERN_DEBUG "S5H1420: " x); \
84 { .
addr = state->
config->demod_address, .flags = 0, .buf =
b, .len = 2 },
85 { .addr = state->
config->demod_address, .flags = 0, .buf = &
reg, .len = 1 },
86 { .addr = state->
config->demod_address, .flags =
I2C_M_RD, .buf =
b, .len = 1 },
89 b[0] = (reg - 1) & 0xff;
90 b[1] = state->
shadow[(reg - 1) & 0xff];
92 if (state->
config->repeated_start_workaround) {
113 struct i2c_msg msg = { .addr = state->
config->demod_address, .flags = 0, .buf =
buf, .len = 2 };
119 dprintk(
"%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
131 dprintk(
"enter %s\n", __func__);
135 s5h1420_writereg(state, 0x3c,
136 (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
140 s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) | 0x03);
144 s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) & 0xfd);
148 dprintk(
"leave %s\n", __func__);
156 dprintk(
"enter %s\n", __func__);
159 s5h1420_writereg(state, 0x3b,
160 (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
164 s5h1420_writereg(state, 0x3b,
165 (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
168 dprintk(
"leave %s\n", __func__);
173 static int s5h1420_send_master_cmd (
struct dvb_frontend* fe,
182 dprintk(
"enter %s\n", __func__);
187 val = s5h1420_readreg(state, 0x3b);
188 s5h1420_writereg(state, 0x3b, 0x02);
192 for(i=0; i< cmd->
msg_len; i++) {
193 s5h1420_writereg(state, 0x3d + i, cmd->
msg[i]);
197 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) |
198 ((cmd->
msg_len-1) << 4) | 0x08);
203 if (!(s5h1420_readreg(state, 0x3b) & 0x08))
212 s5h1420_writereg(state, 0x3b, val);
214 dprintk(
"leave %s\n", __func__);
218 static int s5h1420_recv_slave_reply (
struct dvb_frontend* fe,
225 unsigned long timeout;
229 val = s5h1420_readreg(state, 0x3b);
230 s5h1420_writereg(state, 0x3b, 0x82);
236 if (!(s5h1420_readreg(state, 0x3b) & 0x80))
248 if (s5h1420_readreg(state, 0x49)) {
254 length = (s5h1420_readreg(state, 0x3b) & 0x70) >> 4;
255 if (
length >
sizeof(reply->msg)) {
262 for(i=0; i<
length; i++) {
263 reply->msg[
i] = s5h1420_readreg(state, 0x3d + i);
268 s5h1420_writereg(state, 0x3b, val);
278 unsigned long timeout;
281 val = s5h1420_readreg(state, 0x3b);
282 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x70) | 0x01);
286 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x04);
291 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
296 if (!(s5h1420_readreg(state, 0x3b) & 0x08))
305 s5h1420_writereg(state, 0x3b, val);
315 val = s5h1420_readreg(state, 0x14);
320 val = s5h1420_readreg(state, 0x36);
336 dprintk(
"enter %s\n", __func__);
342 *status = s5h1420_get_status_bits(state);
347 val = s5h1420_readreg(state,
Vit10);
348 if ((val & 0x07) == 0x03) {
350 s5h1420_writereg(state,
Vit09, 0x13);
352 s5h1420_writereg(state,
Vit09, 0x1b);
356 *status = s5h1420_get_status_bits(state);
364 u32 tmp = s5h1420_getsymbolrate(state);
365 switch (s5h1420_readreg(state,
Vit10) & 0x07) {
366 case 0: tmp = (tmp * 2 * 1) / 2;
break;
367 case 1: tmp = (tmp * 2 * 2) / 3;
break;
368 case 2: tmp = (tmp * 2 * 3) / 4;
break;
369 case 3: tmp = (tmp * 2 * 5) / 6;
break;
370 case 4: tmp = (tmp * 2 * 6) / 7;
break;
371 case 5: tmp = (tmp * 2 * 7) / 8;
break;
398 dprintk(
"for MPEG_CLK_INTL %d %x\n", tmp, val);
400 s5h1420_writereg(state,
FEC01, 0x18);
401 s5h1420_writereg(state,
FEC01, 0x10);
402 s5h1420_writereg(state,
FEC01, val);
405 val = s5h1420_readreg(state,
Mpeg02);
406 s5h1420_writereg(state,
Mpeg02, val | (1 << 6));
409 val = s5h1420_readreg(state,
QPSK01) & 0x7f;
410 s5h1420_writereg(state,
QPSK01, val);
414 if (s5h1420_getsymbolrate(state) >= 20000000) {
415 s5h1420_writereg(state,
Loop04, 0x8a);
416 s5h1420_writereg(state,
Loop05, 0x6a);
418 s5h1420_writereg(state,
Loop04, 0x58);
419 s5h1420_writereg(state,
Loop05, 0x27);
426 dprintk(
"leave %s\n", __func__);
435 s5h1420_writereg(state, 0x46, 0x1d);
438 *ber = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
443 static int s5h1420_read_signal_strength(
struct dvb_frontend* fe,
u16* strength)
447 u8 val = s5h1420_readreg(state, 0x15);
449 *strength = (
u16) ((val << 8) |
val);
454 static int s5h1420_read_ucblocks(
struct dvb_frontend* fe,
u32* ucblocks)
458 s5h1420_writereg(state, 0x46, 0x1f);
461 *ucblocks = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
469 s5h1420_writereg (state, 0x01, 0x08);
470 s5h1420_writereg (state, 0x01, 0x00);
474 static void s5h1420_setsymbolrate(
struct s5h1420_state* state,
480 dprintk(
"enter %s\n", __func__);
487 dprintk(
"symbol rate register: %06llx\n", (
unsigned long long)val);
489 v = s5h1420_readreg(state,
Loop01);
490 s5h1420_writereg(state,
Loop01, v & 0x7f);
491 s5h1420_writereg(state,
Tnco01, val >> 16);
492 s5h1420_writereg(state,
Tnco02, val >> 8);
493 s5h1420_writereg(state,
Tnco03, val & 0xff);
494 s5h1420_writereg(state,
Loop01, v | 0x80);
495 dprintk(
"leave %s\n", __func__);
503 static void s5h1420_setfreqoffset(
struct s5h1420_state* state,
int freqoffset)
508 dprintk(
"enter %s\n", __func__);
512 val = -(
int) ((freqoffset * (1<<24)) / (state->
fclk / 1000000));
514 dprintk(
"phase rotator/freqoffset: %d %06x\n", freqoffset, val);
516 v = s5h1420_readreg(state,
Loop01);
517 s5h1420_writereg(state,
Loop01, v & 0xbf);
518 s5h1420_writereg(state,
Pnco01, val >> 16);
519 s5h1420_writereg(state,
Pnco02, val >> 8);
520 s5h1420_writereg(state,
Pnco03, val & 0xff);
521 s5h1420_writereg(state,
Loop01, v | 0x40);
522 dprintk(
"leave %s\n", __func__);
525 static int s5h1420_getfreqoffset(
struct s5h1420_state* state)
529 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
530 val = s5h1420_readreg(state, 0x0e) << 16;
531 val |= s5h1420_readreg(state, 0x0f) << 8;
532 val |= s5h1420_readreg(state, 0x10);
533 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
540 val = (((-
val) * (state->
fclk/1000000)) / (1<<24));
545 static void s5h1420_setfec_inversion(
struct s5h1420_state* state,
551 dprintk(
"enter %s\n", __func__);
554 inversion = state->
config->invert ? 0x08 : 0;
556 inversion = state->
config->invert ? 0 : 0x08;
564 vit08 = 0x01; vit09 = 0x10;
568 vit08 = 0x02; vit09 = 0x11;
572 vit08 = 0x04; vit09 = 0x12;
576 vit08 = 0x08; vit09 = 0x13;
580 vit08 = 0x10; vit09 = 0x14;
584 vit08 = 0x20; vit09 = 0x15;
592 dprintk(
"fec: %02x %02x\n", vit08, vit09);
593 s5h1420_writereg(state,
Vit08, vit08);
594 s5h1420_writereg(state,
Vit09, vit09);
595 dprintk(
"leave %s\n", __func__);
600 switch(s5h1420_readreg(state, 0x32) & 0x07) {
625 if (s5h1420_readreg(state, 0x32) & 0x08)
631 static int s5h1420_set_frontend(
struct dvb_frontend *fe)
638 dprintk(
"enter %s\n", __func__);
641 s5h1420_get_tune_settings(fe, &fesettings);
643 if ((frequency_delta > -fesettings.max_drift) &&
644 (frequency_delta < fesettings.max_drift) &&
645 (frequency_delta != 0) &&
649 if (fe->
ops.tuner_ops.set_params) {
650 fe->
ops.tuner_ops.set_params(fe);
651 if (fe->
ops.i2c_gate_ctrl) fe->
ops.i2c_gate_ctrl(fe, 0);
653 if (fe->
ops.tuner_ops.get_frequency) {
655 fe->
ops.tuner_ops.get_frequency(fe, &tmp);
656 if (fe->
ops.i2c_gate_ctrl) fe->
ops.i2c_gate_ctrl(fe, 0);
657 s5h1420_setfreqoffset(state, p->
frequency - tmp);
659 s5h1420_setfreqoffset(state, 0);
667 s5h1420_reset(state);
671 state->
fclk = 80000000;
673 state->
fclk = 59000000;
675 state->
fclk = 86000000;
677 state->
fclk = 88000000;
679 state->
fclk = 44000000;
682 s5h1420_writereg(state,
PLL01, state->
fclk/1000000 - 8);
683 s5h1420_writereg(state,
PLL02, 0x40);
688 s5h1420_writereg(state,
QPSK01, 0xae | 0x10);
690 s5h1420_writereg(state,
QPSK01, 0xac | 0x10);
693 s5h1420_writereg(state,
CON_1, 0x00);
694 s5h1420_writereg(state,
QPSK02, 0x00);
695 s5h1420_writereg(state,
Pre01, 0xb0);
697 s5h1420_writereg(state,
Loop01, 0xF0);
698 s5h1420_writereg(state,
Loop02, 0x2a);
699 s5h1420_writereg(state,
Loop03, 0x79);
701 s5h1420_writereg(state,
Loop04, 0x79);
703 s5h1420_writereg(state,
Loop04, 0x58);
704 s5h1420_writereg(state,
Loop05, 0x6b);
707 s5h1420_writereg(state,
Post01, (0 << 6) | 0x10);
709 s5h1420_writereg(state,
Post01, (1 << 6) | 0x10);
711 s5h1420_writereg(state,
Post01, (3 << 6) | 0x10);
713 s5h1420_writereg(state,
Monitor12, 0x00);
715 s5h1420_writereg(state,
Sync01, 0x33);
716 s5h1420_writereg(state,
Mpeg01, state->
config->cdclk_polarity);
717 s5h1420_writereg(state,
Mpeg02, 0x3d);
718 s5h1420_writereg(state,
Err01, 0x03);
720 s5h1420_writereg(state,
Vit06, 0x6e);
721 s5h1420_writereg(state,
DiS03, 0x00);
722 s5h1420_writereg(state,
Rf01, 0x61);
725 if (fe->
ops.tuner_ops.set_params) {
726 fe->
ops.tuner_ops.set_params(fe);
727 if (fe->
ops.i2c_gate_ctrl)
728 fe->
ops.i2c_gate_ctrl(fe, 0);
729 s5h1420_setfreqoffset(state, 0);
733 s5h1420_setsymbolrate(state, p);
734 s5h1420_setfec_inversion(state, p);
737 s5h1420_writereg(state,
QPSK01, s5h1420_readreg(state,
QPSK01) | 1);
744 dprintk(
"leave %s\n", __func__);
748 static int s5h1420_get_frontend(
struct dvb_frontend* fe)
754 p->
inversion = s5h1420_getinversion(state);
761 static int s5h1420_get_tune_settings(
struct dvb_frontend* fe,
799 return s5h1420_writereg(state, 0x02, state->
CON_1_val | 1);
801 return s5h1420_writereg(state, 0x02, state->
CON_1_val & 0xfe);
810 s5h1420_writereg(state, 0x02, state->
CON_1_val);
812 s5h1420_reset(state);
821 return s5h1420_writereg(state, 0x02, state->
CON_1_val);
836 static int s5h1420_tuner_i2c_tuner_xfer(
struct i2c_adapter *i2c_adap,
struct i2c_msg msg[],
int num)
844 m[0].addr = state->
config->demod_address;
854 .master_xfer = s5h1420_tuner_i2c_tuner_xfer,
855 .functionality = s5h1420_tuner_i2c_func,
881 state->
fclk = 88000000;
887 i = s5h1420_readreg(state,
ID01);
893 for (i = 0; i < 0x50; i++)
894 state->
shadow[i] = s5h1420_readreg(state, i);
907 printk(
KERN_ERR "S5H1420/PN1010: tuner i2c bus could not be initialized\n");
922 .name =
"Samsung S5H1420/PnpNetwork PN1010 DVB-S",
923 .frequency_min = 950000,
924 .frequency_max = 2150000,
925 .frequency_stepsize = 125,
926 .frequency_tolerance = 29500,
927 .symbol_rate_min = 1000000,
928 .symbol_rate_max = 45000000,
936 .release = s5h1420_release,
938 .init = s5h1420_init,
939 .sleep = s5h1420_sleep,
940 .i2c_gate_ctrl = s5h1420_i2c_gate_ctrl,
942 .set_frontend = s5h1420_set_frontend,
943 .get_frontend = s5h1420_get_frontend,
944 .get_tune_settings = s5h1420_get_tune_settings,
946 .read_status = s5h1420_read_status,
947 .read_ber = s5h1420_read_ber,
948 .read_signal_strength = s5h1420_read_signal_strength,
949 .read_ucblocks = s5h1420_read_ucblocks,
951 .diseqc_send_master_cmd = s5h1420_send_master_cmd,
952 .diseqc_recv_slave_reply = s5h1420_recv_slave_reply,
953 .diseqc_send_burst = s5h1420_send_burst,
954 .set_tone = s5h1420_set_tone,
955 .set_voltage = s5h1420_set_voltage,