1 // SPDX-License-Identifier: GPL-2.0-or-later
3 Driver for ST STV0288 demodulator
4 Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
6 Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com>
7 Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
8 Removed stb6000 specific tuner code and revised some
10 2010-09-01 Josef Pavlik <josef@pavlik.it>
11 Fixed diseqc_msg, diseqc_burst and set_tone problems
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/string.h>
20 #include <linux/slab.h>
21 #include <linux/jiffies.h>
22 #include <asm/div64.h>
24 #include <media/dvb_frontend.h>
27 struct stv0288_state
{
28 struct i2c_adapter
*i2c
;
29 const struct stv0288_config
*config
;
30 struct dvb_frontend frontend
;
35 enum fe_code_rate fec_inner
;
40 #define STATUS_UCBLOCKS 1
43 static int debug_legacy_dish_switch
;
44 #define dprintk(args...) \
47 printk(KERN_DEBUG "stv0288: " args); \
51 static int stv0288_writeregI(struct stv0288_state
*state
, u8 reg
, u8 data
)
54 u8 buf
[] = { reg
, data
};
55 struct i2c_msg msg
= {
56 .addr
= state
->config
->demod_address
,
62 ret
= i2c_transfer(state
->i2c
, &msg
, 1);
65 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
66 __func__
, reg
, data
, ret
);
68 return (ret
!= 1) ? -EREMOTEIO
: 0;
71 static int stv0288_write(struct dvb_frontend
*fe
, const u8 buf
[], int len
)
73 struct stv0288_state
*state
= fe
->demodulator_priv
;
78 return stv0288_writeregI(state
, buf
[0], buf
[1]);
81 static u8
stv0288_readreg(struct stv0288_state
*state
, u8 reg
)
86 struct i2c_msg msg
[] = {
88 .addr
= state
->config
->demod_address
,
93 .addr
= state
->config
->demod_address
,
100 ret
= i2c_transfer(state
->i2c
, msg
, 2);
103 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
109 static int stv0288_set_symbolrate(struct dvb_frontend
*fe
, u32 srate
)
111 struct stv0288_state
*state
= fe
->demodulator_priv
;
115 if ((srate
< 1000000) || (srate
> 45000000))
118 stv0288_writeregI(state
, 0x22, 0);
119 stv0288_writeregI(state
, 0x23, 0);
120 stv0288_writeregI(state
, 0x2b, 0xff);
121 stv0288_writeregI(state
, 0x2c, 0xf7);
123 temp
= (unsigned int)srate
/ 1000;
128 b
[0] = (unsigned char)((temp
>> 12) & 0xff);
129 b
[1] = (unsigned char)((temp
>> 4) & 0xff);
130 b
[2] = (unsigned char)((temp
<< 4) & 0xf0);
131 stv0288_writeregI(state
, 0x28, 0x80); /* SFRH */
132 stv0288_writeregI(state
, 0x29, 0); /* SFRM */
133 stv0288_writeregI(state
, 0x2a, 0); /* SFRL */
135 stv0288_writeregI(state
, 0x28, b
[0]);
136 stv0288_writeregI(state
, 0x29, b
[1]);
137 stv0288_writeregI(state
, 0x2a, b
[2]);
138 dprintk("stv0288: stv0288_set_symbolrate\n");
143 static int stv0288_send_diseqc_msg(struct dvb_frontend
*fe
,
144 struct dvb_diseqc_master_cmd
*m
)
146 struct stv0288_state
*state
= fe
->demodulator_priv
;
150 dprintk("%s\n", __func__
);
152 stv0288_writeregI(state
, 0x09, 0);
154 stv0288_writeregI(state
, 0x05, 0x12);/* modulated mode, single shot */
156 for (i
= 0; i
< m
->msg_len
; i
++) {
157 if (stv0288_writeregI(state
, 0x06, m
->msg
[i
]))
160 msleep(m
->msg_len
*12);
164 static int stv0288_send_diseqc_burst(struct dvb_frontend
*fe
,
165 enum fe_sec_mini_cmd burst
)
167 struct stv0288_state
*state
= fe
->demodulator_priv
;
169 dprintk("%s\n", __func__
);
171 if (stv0288_writeregI(state
, 0x05, 0x03))/* burst mode, single shot */
174 if (stv0288_writeregI(state
, 0x06, burst
== SEC_MINI_A
? 0x00 : 0xff))
178 if (stv0288_writeregI(state
, 0x05, 0x12))
184 static int stv0288_set_tone(struct dvb_frontend
*fe
, enum fe_sec_tone_mode tone
)
186 struct stv0288_state
*state
= fe
->demodulator_priv
;
190 if (stv0288_writeregI(state
, 0x05, 0x10))/* cont carrier */
195 if (stv0288_writeregI(state
, 0x05, 0x12))/* burst mode off*/
205 static u8 stv0288_inittab
[] = {
314 static int stv0288_set_voltage(struct dvb_frontend
*fe
,
315 enum fe_sec_voltage volt
)
317 dprintk("%s: %s\n", __func__
,
318 volt
== SEC_VOLTAGE_13
? "SEC_VOLTAGE_13" :
319 volt
== SEC_VOLTAGE_18
? "SEC_VOLTAGE_18" : "??");
324 static int stv0288_init(struct dvb_frontend
*fe
)
326 struct stv0288_state
*state
= fe
->demodulator_priv
;
331 dprintk("stv0288: init chip\n");
332 stv0288_writeregI(state
, 0x41, 0x04);
335 /* we have default inittab */
336 if (state
->config
->inittab
== NULL
) {
337 for (i
= 0; !(stv0288_inittab
[i
] == 0xff &&
338 stv0288_inittab
[i
+ 1] == 0xff); i
+= 2)
339 stv0288_writeregI(state
, stv0288_inittab
[i
],
340 stv0288_inittab
[i
+ 1]);
342 for (i
= 0; ; i
+= 2) {
343 reg
= state
->config
->inittab
[i
];
344 val
= state
->config
->inittab
[i
+1];
345 if (reg
== 0xff && val
== 0xff)
347 stv0288_writeregI(state
, reg
, val
);
353 static int stv0288_read_status(struct dvb_frontend
*fe
, enum fe_status
*status
)
355 struct stv0288_state
*state
= fe
->demodulator_priv
;
357 u8 sync
= stv0288_readreg(state
, 0x24);
361 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__
, sync
);
365 *status
|= FE_HAS_CARRIER
| FE_HAS_SIGNAL
;
367 *status
|= FE_HAS_VITERBI
;
369 *status
|= FE_HAS_LOCK
;
370 dprintk("stv0288 has locked\n");
376 static int stv0288_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
378 struct stv0288_state
*state
= fe
->demodulator_priv
;
380 if (state
->errmode
!= STATUS_BER
)
382 *ber
= (stv0288_readreg(state
, 0x26) << 8) |
383 stv0288_readreg(state
, 0x27);
384 dprintk("stv0288_read_ber %d\n", *ber
);
390 static int stv0288_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
392 struct stv0288_state
*state
= fe
->demodulator_priv
;
394 s32 signal
= 0xffff - ((stv0288_readreg(state
, 0x10) << 8));
397 signal
= signal
* 5 / 4;
398 *strength
= (signal
> 0xffff) ? 0xffff : (signal
< 0) ? 0 : signal
;
399 dprintk("stv0288_read_signal_strength %d\n", *strength
);
403 static int stv0288_sleep(struct dvb_frontend
*fe
)
405 struct stv0288_state
*state
= fe
->demodulator_priv
;
407 stv0288_writeregI(state
, 0x41, 0x84);
408 state
->initialised
= 0;
412 static int stv0288_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
414 struct stv0288_state
*state
= fe
->demodulator_priv
;
416 s32 xsnr
= 0xffff - ((stv0288_readreg(state
, 0x2d) << 8)
417 | stv0288_readreg(state
, 0x2e));
418 xsnr
= 3 * (xsnr
- 0xa100);
419 *snr
= (xsnr
> 0xffff) ? 0xffff : (xsnr
< 0) ? 0 : xsnr
;
420 dprintk("stv0288_read_snr %d\n", *snr
);
425 static int stv0288_read_ucblocks(struct dvb_frontend
*fe
, u32
*ucblocks
)
427 struct stv0288_state
*state
= fe
->demodulator_priv
;
429 if (state
->errmode
!= STATUS_BER
)
431 *ucblocks
= (stv0288_readreg(state
, 0x26) << 8) |
432 stv0288_readreg(state
, 0x27);
433 dprintk("stv0288_read_ber %d\n", *ucblocks
);
438 static int stv0288_set_frontend(struct dvb_frontend
*fe
)
440 struct stv0288_state
*state
= fe
->demodulator_priv
;
441 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
444 unsigned char tda
[3];
445 u8 reg
, time_out
= 0;
447 dprintk("%s : FE_SET_FRONTEND\n", __func__
);
449 if (c
->delivery_system
!= SYS_DVBS
) {
450 dprintk("%s: unsupported delivery system selected (%d)\n",
451 __func__
, c
->delivery_system
);
455 if (state
->config
->set_ts_params
)
456 state
->config
->set_ts_params(fe
, 0);
458 /* only frequency & symbol_rate are used for tuner*/
459 if (fe
->ops
.tuner_ops
.set_params
) {
460 fe
->ops
.tuner_ops
.set_params(fe
);
461 if (fe
->ops
.i2c_gate_ctrl
)
462 fe
->ops
.i2c_gate_ctrl(fe
, 0);
466 stv0288_set_symbolrate(fe
, c
->symbol_rate
);
467 /* Carrier lock control register */
468 stv0288_writeregI(state
, 0x15, 0xc5);
470 tda
[2] = 0x0; /* CFRL */
471 for (tm
= -9; tm
< 7;) {
473 reg
= stv0288_readreg(state
, 0x24);
488 tda
[1] = (unsigned char)tm
;
489 stv0288_writeregI(state
, 0x2b, tda
[1]);
490 stv0288_writeregI(state
, 0x2c, tda
[2]);
493 state
->tuner_frequency
= c
->frequency
;
494 state
->fec_inner
= FEC_AUTO
;
495 state
->symbol_rate
= c
->symbol_rate
;
500 static int stv0288_i2c_gate_ctrl(struct dvb_frontend
*fe
, int enable
)
502 struct stv0288_state
*state
= fe
->demodulator_priv
;
505 stv0288_writeregI(state
, 0x01, 0xb5);
507 stv0288_writeregI(state
, 0x01, 0x35);
514 static void stv0288_release(struct dvb_frontend
*fe
)
516 struct stv0288_state
*state
= fe
->demodulator_priv
;
520 static const struct dvb_frontend_ops stv0288_ops
= {
521 .delsys
= { SYS_DVBS
},
523 .name
= "ST STV0288 DVB-S",
524 .frequency_min_hz
= 950 * MHz
,
525 .frequency_max_hz
= 2150 * MHz
,
526 .frequency_stepsize_hz
= 1 * MHz
,
527 .symbol_rate_min
= 1000000,
528 .symbol_rate_max
= 45000000,
529 .symbol_rate_tolerance
= 500, /* ppm */
530 .caps
= FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
531 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
|
536 .release
= stv0288_release
,
537 .init
= stv0288_init
,
538 .sleep
= stv0288_sleep
,
539 .write
= stv0288_write
,
540 .i2c_gate_ctrl
= stv0288_i2c_gate_ctrl
,
541 .read_status
= stv0288_read_status
,
542 .read_ber
= stv0288_read_ber
,
543 .read_signal_strength
= stv0288_read_signal_strength
,
544 .read_snr
= stv0288_read_snr
,
545 .read_ucblocks
= stv0288_read_ucblocks
,
546 .diseqc_send_master_cmd
= stv0288_send_diseqc_msg
,
547 .diseqc_send_burst
= stv0288_send_diseqc_burst
,
548 .set_tone
= stv0288_set_tone
,
549 .set_voltage
= stv0288_set_voltage
,
551 .set_frontend
= stv0288_set_frontend
,
554 struct dvb_frontend
*stv0288_attach(const struct stv0288_config
*config
,
555 struct i2c_adapter
*i2c
)
557 struct stv0288_state
*state
= NULL
;
560 /* allocate memory for the internal state */
561 state
= kzalloc(sizeof(struct stv0288_state
), GFP_KERNEL
);
565 /* setup the state */
566 state
->config
= config
;
568 state
->initialised
= 0;
569 state
->tuner_frequency
= 0;
570 state
->symbol_rate
= 0;
571 state
->fec_inner
= 0;
572 state
->errmode
= STATUS_BER
;
574 stv0288_writeregI(state
, 0x41, 0x04);
576 id
= stv0288_readreg(state
, 0x00);
577 dprintk("stv0288 id %x\n", id
);
579 /* register 0x00 contains 0x11 for STV0288 */
583 /* create dvb_frontend */
584 memcpy(&state
->frontend
.ops
, &stv0288_ops
,
585 sizeof(struct dvb_frontend_ops
));
586 state
->frontend
.demodulator_priv
= state
;
587 return &state
->frontend
;
594 EXPORT_SYMBOL(stv0288_attach
);
596 module_param(debug_legacy_dish_switch
, int, 0444);
597 MODULE_PARM_DESC(debug_legacy_dish_switch
,
598 "Enable timing analysis for Dish Network legacy switches");
600 module_param(debug
, int, 0644);
601 MODULE_PARM_DESC(debug
, "Turn on/off frontend debugging (default:off).");
603 MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
604 MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
605 MODULE_LICENSE("GPL");