1 // SPDX-License-Identifier: GPL-2.0-or-later
3 Driver for Spase SP8870 demodulator
5 Copyright (C) 1999 Juergen Peitz
10 * This driver needs external firmware. Please use the command
11 * "<kerneldir>/scripts/get_dvb_firmware alps_tdlb7" to
12 * download/extract it, and then copy it to /usr/lib/hotplug/firmware
13 * or /lib/firmware (depending on configuration of firmware hotplug).
15 #define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/device.h>
20 #include <linux/firmware.h>
21 #include <linux/delay.h>
22 #include <linux/string.h>
23 #include <linux/slab.h>
25 #include <media/dvb_frontend.h>
31 struct i2c_adapter
* i2c
;
33 const struct sp8870_config
* config
;
35 struct dvb_frontend frontend
;
37 /* demodulator private data */
42 #define dprintk(args...) \
44 if (debug) printk(KERN_DEBUG "sp8870: " args); \
47 /* firmware size for sp8870 */
48 #define SP8870_FIRMWARE_SIZE 16382
50 /* starting point for firmware in file 'Sc_main.mc' */
51 #define SP8870_FIRMWARE_OFFSET 0x0A
53 static int sp8870_writereg (struct sp8870_state
* state
, u16 reg
, u16 data
)
55 u8 buf
[] = { reg
>> 8, reg
& 0xff, data
>> 8, data
& 0xff };
56 struct i2c_msg msg
= { .addr
= state
->config
->demod_address
, .flags
= 0, .buf
= buf
, .len
= 4 };
59 if ((err
= i2c_transfer (state
->i2c
, &msg
, 1)) != 1) {
60 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__
, err
, reg
, data
);
67 static int sp8870_readreg (struct sp8870_state
* state
, u16 reg
)
70 u8 b0
[] = { reg
>> 8 , reg
& 0xff };
72 struct i2c_msg msg
[] = { { .addr
= state
->config
->demod_address
, .flags
= 0, .buf
= b0
, .len
= 2 },
73 { .addr
= state
->config
->demod_address
, .flags
= I2C_M_RD
, .buf
= b1
, .len
= 2 } };
75 ret
= i2c_transfer (state
->i2c
, msg
, 2);
78 dprintk("%s: readreg error (ret == %i)\n", __func__
, ret
);
82 return (b1
[0] << 8 | b1
[1]);
85 static int sp8870_firmware_upload (struct sp8870_state
* state
, const struct firmware
*fw
)
88 const char *fw_buf
= fw
->data
;
94 dprintk ("%s: ...\n", __func__
);
96 if (fw
->size
< SP8870_FIRMWARE_SIZE
+ SP8870_FIRMWARE_OFFSET
)
99 // system controller stop
100 sp8870_writereg(state
, 0x0F00, 0x0000);
102 // instruction RAM register hiword
103 sp8870_writereg(state
, 0x8F08, ((SP8870_FIRMWARE_SIZE
/ 2) & 0xFFFF));
105 // instruction RAM MWR
106 sp8870_writereg(state
, 0x8F0A, ((SP8870_FIRMWARE_SIZE
/ 2) >> 16));
108 // do firmware upload
109 fw_pos
= SP8870_FIRMWARE_OFFSET
;
110 while (fw_pos
< SP8870_FIRMWARE_SIZE
+ SP8870_FIRMWARE_OFFSET
){
111 tx_len
= (fw_pos
<= SP8870_FIRMWARE_SIZE
+ SP8870_FIRMWARE_OFFSET
- 252) ? 252 : SP8870_FIRMWARE_SIZE
+ SP8870_FIRMWARE_OFFSET
- fw_pos
;
112 // write register 0xCF0A
115 memcpy(&tx_buf
[2], fw_buf
+ fw_pos
, tx_len
);
116 msg
.addr
= state
->config
->demod_address
;
119 msg
.len
= tx_len
+ 2;
120 if ((err
= i2c_transfer (state
->i2c
, &msg
, 1)) != 1) {
121 printk("%s: firmware upload failed!\n", __func__
);
122 printk ("%s: i2c error (err == %i)\n", __func__
, err
);
128 dprintk ("%s: done!\n", __func__
);
132 static void sp8870_microcontroller_stop (struct sp8870_state
* state
)
134 sp8870_writereg(state
, 0x0F08, 0x000);
135 sp8870_writereg(state
, 0x0F09, 0x000);
137 // microcontroller STOP
138 sp8870_writereg(state
, 0x0F00, 0x000);
141 static void sp8870_microcontroller_start (struct sp8870_state
* state
)
143 sp8870_writereg(state
, 0x0F08, 0x000);
144 sp8870_writereg(state
, 0x0F09, 0x000);
146 // microcontroller START
147 sp8870_writereg(state
, 0x0F00, 0x001);
148 // not documented but if we don't read 0x0D01 out here
149 // we don't get a correct data valid signal
150 sp8870_readreg(state
, 0x0D01);
153 static int sp8870_read_data_valid_signal(struct sp8870_state
* state
)
155 return (sp8870_readreg(state
, 0x0D02) > 0);
158 static int configure_reg0xc05 (struct dtv_frontend_properties
*p
, u16
*reg0xc05
)
160 int known_parameters
= 1;
164 switch (p
->modulation
) {
168 *reg0xc05
|= (1 << 10);
171 *reg0xc05
|= (2 << 10);
174 known_parameters
= 0;
180 switch (p
->hierarchy
) {
184 *reg0xc05
|= (1 << 7);
187 *reg0xc05
|= (2 << 7);
190 *reg0xc05
|= (3 << 7);
193 known_parameters
= 0;
199 switch (p
->code_rate_HP
) {
203 *reg0xc05
|= (1 << 3);
206 *reg0xc05
|= (2 << 3);
209 *reg0xc05
|= (3 << 3);
212 *reg0xc05
|= (4 << 3);
215 known_parameters
= 0;
221 if (known_parameters
)
222 *reg0xc05
|= (2 << 1); /* use specified parameters */
224 *reg0xc05
|= (1 << 1); /* enable autoprobing */
229 static int sp8870_wake_up(struct sp8870_state
* state
)
231 // enable TS output and interface pins
232 return sp8870_writereg(state
, 0xC18, 0x00D);
235 static int sp8870_set_frontend_parameters(struct dvb_frontend
*fe
)
237 struct dtv_frontend_properties
*p
= &fe
->dtv_property_cache
;
238 struct sp8870_state
* state
= fe
->demodulator_priv
;
242 if ((err
= configure_reg0xc05(p
, ®0xc05
)))
245 // system controller stop
246 sp8870_microcontroller_stop(state
);
248 // set tuner parameters
249 if (fe
->ops
.tuner_ops
.set_params
) {
250 fe
->ops
.tuner_ops
.set_params(fe
);
251 if (fe
->ops
.i2c_gate_ctrl
) fe
->ops
.i2c_gate_ctrl(fe
, 0);
254 // sample rate correction bit [23..17]
255 sp8870_writereg(state
, 0x0319, 0x000A);
257 // sample rate correction bit [16..0]
258 sp8870_writereg(state
, 0x031A, 0x0AAB);
260 // integer carrier offset
261 sp8870_writereg(state
, 0x0309, 0x0400);
263 // fractional carrier offset
264 sp8870_writereg(state
, 0x030A, 0x0000);
266 // filter for 6/7/8 Mhz channel
267 if (p
->bandwidth_hz
== 6000000)
268 sp8870_writereg(state
, 0x0311, 0x0002);
269 else if (p
->bandwidth_hz
== 7000000)
270 sp8870_writereg(state
, 0x0311, 0x0001);
272 sp8870_writereg(state
, 0x0311, 0x0000);
274 // scan order: 2k first = 0x0000, 8k first = 0x0001
275 if (p
->transmission_mode
== TRANSMISSION_MODE_2K
)
276 sp8870_writereg(state
, 0x0338, 0x0000);
278 sp8870_writereg(state
, 0x0338, 0x0001);
280 sp8870_writereg(state
, 0xc05, reg0xc05
);
282 // read status reg in order to clear pending irqs
283 err
= sp8870_readreg(state
, 0x200);
287 // system controller start
288 sp8870_microcontroller_start(state
);
293 static int sp8870_init (struct dvb_frontend
* fe
)
295 struct sp8870_state
* state
= fe
->demodulator_priv
;
296 const struct firmware
*fw
= NULL
;
298 sp8870_wake_up(state
);
299 if (state
->initialised
) return 0;
300 state
->initialised
= 1;
302 dprintk ("%s\n", __func__
);
305 /* request the firmware, this will block until someone uploads it */
306 printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE
);
307 if (state
->config
->request_firmware(fe
, &fw
, SP8870_DEFAULT_FIRMWARE
)) {
308 printk("sp8870: no firmware upload (timeout or file not found?)\n");
312 if (sp8870_firmware_upload(state
, fw
)) {
313 printk("sp8870: writing firmware to device failed\n");
314 release_firmware(fw
);
317 release_firmware(fw
);
318 printk("sp8870: firmware upload complete\n");
320 /* enable TS output and interface pins */
321 sp8870_writereg(state
, 0xc18, 0x00d);
323 // system controller stop
324 sp8870_microcontroller_stop(state
);
327 sp8870_writereg(state
, 0x0301, 0x0003);
329 // Reed Solomon parity bytes passed to output
330 sp8870_writereg(state
, 0x0C13, 0x0001);
332 // MPEG clock is suppressed if no valid data
333 sp8870_writereg(state
, 0x0C14, 0x0001);
335 /* bit 0x010: enable data valid signal */
336 sp8870_writereg(state
, 0x0D00, 0x010);
337 sp8870_writereg(state
, 0x0D01, 0x000);
342 static int sp8870_read_status(struct dvb_frontend
*fe
,
343 enum fe_status
*fe_status
)
345 struct sp8870_state
* state
= fe
->demodulator_priv
;
351 status
= sp8870_readreg (state
, 0x0200);
355 signal
= sp8870_readreg (state
, 0x0303);
360 *fe_status
|= FE_HAS_SIGNAL
;
362 *fe_status
|= FE_HAS_SYNC
;
364 *fe_status
|= FE_HAS_LOCK
| FE_HAS_CARRIER
| FE_HAS_VITERBI
;
369 static int sp8870_read_ber (struct dvb_frontend
* fe
, u32
* ber
)
371 struct sp8870_state
* state
= fe
->demodulator_priv
;
377 ret
= sp8870_readreg(state
, 0xC08);
383 ret
= sp8870_readreg(state
, 0xC07);
396 static int sp8870_read_signal_strength(struct dvb_frontend
* fe
, u16
* signal
)
398 struct sp8870_state
* state
= fe
->demodulator_priv
;
404 ret
= sp8870_readreg (state
, 0x306);
410 ret
= sp8870_readreg (state
, 0x303);
417 *signal
= 0xFFFF - tmp
;
422 static int sp8870_read_uncorrected_blocks (struct dvb_frontend
* fe
, u32
* ublocks
)
424 struct sp8870_state
* state
= fe
->demodulator_priv
;
429 ret
= sp8870_readreg(state
, 0xC0C);
441 /* number of trials to recover from lockup */
443 /* maximum checks for data valid signal */
444 #define MAXCHECKS 100
446 /* only for debugging: counter for detected lockups */
448 /* only for debugging: counter for channel switches */
451 static int sp8870_set_frontend(struct dvb_frontend
*fe
)
453 struct dtv_frontend_properties
*p
= &fe
->dtv_property_cache
;
454 struct sp8870_state
* state
= fe
->demodulator_priv
;
457 The firmware of the sp8870 sometimes locks up after setting frontend parameters.
458 We try to detect this by checking the data valid signal.
459 If it is not set after MAXCHECKS we try to recover the lockup by setting
460 the frontend parameters again.
468 dprintk("%s: frequency = %i\n", __func__
, p
->frequency
);
470 for (trials
= 1; trials
<= MAXTRIALS
; trials
++) {
472 err
= sp8870_set_frontend_parameters(fe
);
476 for (check_count
= 0; check_count
< MAXCHECKS
; check_count
++) {
477 // valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
478 valid
= sp8870_read_data_valid_signal(state
);
480 dprintk("%s: delay = %i usec\n",
481 __func__
, check_count
* 10);
491 printk("%s: firmware crash!!!!!!\n", __func__
);
498 printk("%s: firmware lockup!!!\n", __func__
);
499 printk("%s: recovered after %i trial(s))\n", __func__
, trials
- 1);
504 printk("%s: switches = %i lockups = %i\n", __func__
, switches
, lockups
);
510 static int sp8870_sleep(struct dvb_frontend
* fe
)
512 struct sp8870_state
* state
= fe
->demodulator_priv
;
514 // tristate TS output and disable interface pins
515 return sp8870_writereg(state
, 0xC18, 0x000);
518 static int sp8870_get_tune_settings(struct dvb_frontend
* fe
, struct dvb_frontend_tune_settings
* fesettings
)
520 fesettings
->min_delay_ms
= 350;
521 fesettings
->step_size
= 0;
522 fesettings
->max_drift
= 0;
526 static int sp8870_i2c_gate_ctrl(struct dvb_frontend
* fe
, int enable
)
528 struct sp8870_state
* state
= fe
->demodulator_priv
;
531 return sp8870_writereg(state
, 0x206, 0x001);
533 return sp8870_writereg(state
, 0x206, 0x000);
537 static void sp8870_release(struct dvb_frontend
* fe
)
539 struct sp8870_state
* state
= fe
->demodulator_priv
;
543 static const struct dvb_frontend_ops sp8870_ops
;
545 struct dvb_frontend
* sp8870_attach(const struct sp8870_config
* config
,
546 struct i2c_adapter
* i2c
)
548 struct sp8870_state
* state
= NULL
;
550 /* allocate memory for the internal state */
551 state
= kzalloc(sizeof(struct sp8870_state
), GFP_KERNEL
);
552 if (state
== NULL
) goto error
;
554 /* setup the state */
555 state
->config
= config
;
557 state
->initialised
= 0;
559 /* check if the demod is there */
560 if (sp8870_readreg(state
, 0x0200) < 0) goto error
;
562 /* create dvb_frontend */
563 memcpy(&state
->frontend
.ops
, &sp8870_ops
, sizeof(struct dvb_frontend_ops
));
564 state
->frontend
.demodulator_priv
= state
;
565 return &state
->frontend
;
572 static const struct dvb_frontend_ops sp8870_ops
= {
573 .delsys
= { SYS_DVBT
},
575 .name
= "Spase SP8870 DVB-T",
576 .frequency_min_hz
= 470 * MHz
,
577 .frequency_max_hz
= 860 * MHz
,
578 .frequency_stepsize_hz
= 166666,
579 .caps
= FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
|
580 FE_CAN_FEC_3_4
| FE_CAN_FEC_5_6
|
581 FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
582 FE_CAN_QPSK
| FE_CAN_QAM_16
|
583 FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
584 FE_CAN_HIERARCHY_AUTO
| FE_CAN_RECOVER
587 .release
= sp8870_release
,
590 .sleep
= sp8870_sleep
,
591 .i2c_gate_ctrl
= sp8870_i2c_gate_ctrl
,
593 .set_frontend
= sp8870_set_frontend
,
594 .get_tune_settings
= sp8870_get_tune_settings
,
596 .read_status
= sp8870_read_status
,
597 .read_ber
= sp8870_read_ber
,
598 .read_signal_strength
= sp8870_read_signal_strength
,
599 .read_ucblocks
= sp8870_read_uncorrected_blocks
,
602 module_param(debug
, int, 0644);
603 MODULE_PARM_DESC(debug
, "Turn on/off frontend debugging (default:off).");
605 MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
606 MODULE_AUTHOR("Juergen Peitz");
607 MODULE_LICENSE("GPL");
609 EXPORT_SYMBOL(sp8870_attach
);