1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | Montage Technology DS3000 - DVBS/S2 Demodulator driver |
4 | Copyright (C) 2009-2012 Konstantin Dimitrov <kosio.dimitrov@gmail.com> |
5 | |
6 | Copyright (C) 2009-2012 TurboSight.com |
7 | |
8 | */ |
9 | |
10 | #include <linux/slab.h> |
11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> |
13 | #include <linux/moduleparam.h> |
14 | #include <linux/init.h> |
15 | #include <linux/firmware.h> |
16 | |
17 | #include <media/dvb_frontend.h> |
18 | #include "ts2020.h" |
19 | #include "ds3000.h" |
20 | |
21 | static int debug; |
22 | |
23 | #define dprintk(args...) \ |
24 | do { \ |
25 | if (debug) \ |
26 | printk(args); \ |
27 | } while (0) |
28 | |
29 | /* as of March 2009 current DS3000 firmware version is 1.78 */ |
30 | /* DS3000 FW v1.78 MD5: a32d17910c4f370073f9346e71d34b80 */ |
31 | #define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds3000.fw" |
32 | |
33 | #define DS3000_SAMPLE_RATE 96000 /* in kHz */ |
34 | |
35 | /* Register values to initialise the demod in DVB-S mode */ |
36 | static u8 ds3000_dvbs_init_tab[] = { |
37 | 0x23, 0x05, |
38 | 0x08, 0x03, |
39 | 0x0c, 0x00, |
40 | 0x21, 0x54, |
41 | 0x25, 0x82, |
42 | 0x27, 0x31, |
43 | 0x30, 0x08, |
44 | 0x31, 0x40, |
45 | 0x32, 0x32, |
46 | 0x33, 0x35, |
47 | 0x35, 0xff, |
48 | 0x3a, 0x00, |
49 | 0x37, 0x10, |
50 | 0x38, 0x10, |
51 | 0x39, 0x02, |
52 | 0x42, 0x60, |
53 | 0x4a, 0x40, |
54 | 0x4b, 0x04, |
55 | 0x4d, 0x91, |
56 | 0x5d, 0xc8, |
57 | 0x50, 0x77, |
58 | 0x51, 0x77, |
59 | 0x52, 0x36, |
60 | 0x53, 0x36, |
61 | 0x56, 0x01, |
62 | 0x63, 0x43, |
63 | 0x64, 0x30, |
64 | 0x65, 0x40, |
65 | 0x68, 0x26, |
66 | 0x69, 0x4c, |
67 | 0x70, 0x20, |
68 | 0x71, 0x70, |
69 | 0x72, 0x04, |
70 | 0x73, 0x00, |
71 | 0x70, 0x40, |
72 | 0x71, 0x70, |
73 | 0x72, 0x04, |
74 | 0x73, 0x00, |
75 | 0x70, 0x60, |
76 | 0x71, 0x70, |
77 | 0x72, 0x04, |
78 | 0x73, 0x00, |
79 | 0x70, 0x80, |
80 | 0x71, 0x70, |
81 | 0x72, 0x04, |
82 | 0x73, 0x00, |
83 | 0x70, 0xa0, |
84 | 0x71, 0x70, |
85 | 0x72, 0x04, |
86 | 0x73, 0x00, |
87 | 0x70, 0x1f, |
88 | 0x76, 0x00, |
89 | 0x77, 0xd1, |
90 | 0x78, 0x0c, |
91 | 0x79, 0x80, |
92 | 0x7f, 0x04, |
93 | 0x7c, 0x00, |
94 | 0x80, 0x86, |
95 | 0x81, 0xa6, |
96 | 0x85, 0x04, |
97 | 0xcd, 0xf4, |
98 | 0x90, 0x33, |
99 | 0xa0, 0x44, |
100 | 0xc0, 0x18, |
101 | 0xc3, 0x10, |
102 | 0xc4, 0x08, |
103 | 0xc5, 0x80, |
104 | 0xc6, 0x80, |
105 | 0xc7, 0x0a, |
106 | 0xc8, 0x1a, |
107 | 0xc9, 0x80, |
108 | 0xfe, 0x92, |
109 | 0xe0, 0xf8, |
110 | 0xe6, 0x8b, |
111 | 0xd0, 0x40, |
112 | 0xf8, 0x20, |
113 | 0xfa, 0x0f, |
114 | 0xfd, 0x20, |
115 | 0xad, 0x20, |
116 | 0xae, 0x07, |
117 | 0xb8, 0x00, |
118 | }; |
119 | |
120 | /* Register values to initialise the demod in DVB-S2 mode */ |
121 | static u8 ds3000_dvbs2_init_tab[] = { |
122 | 0x23, 0x0f, |
123 | 0x08, 0x07, |
124 | 0x0c, 0x00, |
125 | 0x21, 0x54, |
126 | 0x25, 0x82, |
127 | 0x27, 0x31, |
128 | 0x30, 0x08, |
129 | 0x31, 0x32, |
130 | 0x32, 0x32, |
131 | 0x33, 0x35, |
132 | 0x35, 0xff, |
133 | 0x3a, 0x00, |
134 | 0x37, 0x10, |
135 | 0x38, 0x10, |
136 | 0x39, 0x02, |
137 | 0x42, 0x60, |
138 | 0x4a, 0x80, |
139 | 0x4b, 0x04, |
140 | 0x4d, 0x81, |
141 | 0x5d, 0x88, |
142 | 0x50, 0x36, |
143 | 0x51, 0x36, |
144 | 0x52, 0x36, |
145 | 0x53, 0x36, |
146 | 0x63, 0x60, |
147 | 0x64, 0x10, |
148 | 0x65, 0x10, |
149 | 0x68, 0x04, |
150 | 0x69, 0x29, |
151 | 0x70, 0x20, |
152 | 0x71, 0x70, |
153 | 0x72, 0x04, |
154 | 0x73, 0x00, |
155 | 0x70, 0x40, |
156 | 0x71, 0x70, |
157 | 0x72, 0x04, |
158 | 0x73, 0x00, |
159 | 0x70, 0x60, |
160 | 0x71, 0x70, |
161 | 0x72, 0x04, |
162 | 0x73, 0x00, |
163 | 0x70, 0x80, |
164 | 0x71, 0x70, |
165 | 0x72, 0x04, |
166 | 0x73, 0x00, |
167 | 0x70, 0xa0, |
168 | 0x71, 0x70, |
169 | 0x72, 0x04, |
170 | 0x73, 0x00, |
171 | 0x70, 0x1f, |
172 | 0xa0, 0x44, |
173 | 0xc0, 0x08, |
174 | 0xc1, 0x10, |
175 | 0xc2, 0x08, |
176 | 0xc3, 0x10, |
177 | 0xc4, 0x08, |
178 | 0xc5, 0xf0, |
179 | 0xc6, 0xf0, |
180 | 0xc7, 0x0a, |
181 | 0xc8, 0x1a, |
182 | 0xc9, 0x80, |
183 | 0xca, 0x23, |
184 | 0xcb, 0x24, |
185 | 0xce, 0x74, |
186 | 0x90, 0x03, |
187 | 0x76, 0x80, |
188 | 0x77, 0x42, |
189 | 0x78, 0x0a, |
190 | 0x79, 0x80, |
191 | 0xad, 0x40, |
192 | 0xae, 0x07, |
193 | 0x7f, 0xd4, |
194 | 0x7c, 0x00, |
195 | 0x80, 0xa8, |
196 | 0x81, 0xda, |
197 | 0x7c, 0x01, |
198 | 0x80, 0xda, |
199 | 0x81, 0xec, |
200 | 0x7c, 0x02, |
201 | 0x80, 0xca, |
202 | 0x81, 0xeb, |
203 | 0x7c, 0x03, |
204 | 0x80, 0xba, |
205 | 0x81, 0xdb, |
206 | 0x85, 0x08, |
207 | 0x86, 0x00, |
208 | 0x87, 0x02, |
209 | 0x89, 0x80, |
210 | 0x8b, 0x44, |
211 | 0x8c, 0xaa, |
212 | 0x8a, 0x10, |
213 | 0xba, 0x00, |
214 | 0xf5, 0x04, |
215 | 0xfe, 0x44, |
216 | 0xd2, 0x32, |
217 | 0xb8, 0x00, |
218 | }; |
219 | |
220 | struct ds3000_state { |
221 | struct i2c_adapter *i2c; |
222 | const struct ds3000_config *config; |
223 | struct dvb_frontend frontend; |
224 | /* previous uncorrected block counter for DVB-S2 */ |
225 | u16 prevUCBS2; |
226 | }; |
227 | |
228 | static int ds3000_writereg(struct ds3000_state *state, int reg, int data) |
229 | { |
230 | u8 buf[] = { reg, data }; |
231 | struct i2c_msg msg = { .addr = state->config->demod_address, |
232 | .flags = 0, .buf = buf, .len = 2 }; |
233 | int err; |
234 | |
235 | dprintk("%s: write reg 0x%02x, value 0x%02x\n" , __func__, reg, data); |
236 | |
237 | err = i2c_transfer(adap: state->i2c, msgs: &msg, num: 1); |
238 | if (err != 1) { |
239 | printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x, value == 0x%02x)\n" , |
240 | __func__, err, reg, data); |
241 | return -EREMOTEIO; |
242 | } |
243 | |
244 | return 0; |
245 | } |
246 | |
247 | static int ds3000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
248 | { |
249 | struct ds3000_state *state = fe->demodulator_priv; |
250 | |
251 | if (enable) |
252 | ds3000_writereg(state, reg: 0x03, data: 0x12); |
253 | else |
254 | ds3000_writereg(state, reg: 0x03, data: 0x02); |
255 | |
256 | return 0; |
257 | } |
258 | |
259 | /* I2C write for 8k firmware load */ |
260 | static int ds3000_writeFW(struct ds3000_state *state, int reg, |
261 | const u8 *data, u16 len) |
262 | { |
263 | int i, ret = 0; |
264 | struct i2c_msg msg; |
265 | u8 *buf; |
266 | |
267 | buf = kmalloc(size: 33, GFP_KERNEL); |
268 | if (!buf) |
269 | return -ENOMEM; |
270 | |
271 | *(buf) = reg; |
272 | |
273 | msg.addr = state->config->demod_address; |
274 | msg.flags = 0; |
275 | msg.buf = buf; |
276 | msg.len = 33; |
277 | |
278 | for (i = 0; i < len; i += 32) { |
279 | memcpy(buf + 1, data + i, 32); |
280 | |
281 | dprintk("%s: write reg 0x%02x, len = %d\n" , __func__, reg, len); |
282 | |
283 | ret = i2c_transfer(adap: state->i2c, msgs: &msg, num: 1); |
284 | if (ret != 1) { |
285 | printk(KERN_ERR "%s: write error(err == %i, reg == 0x%02x\n" , |
286 | __func__, ret, reg); |
287 | ret = -EREMOTEIO; |
288 | goto error; |
289 | } |
290 | } |
291 | ret = 0; |
292 | |
293 | error: |
294 | kfree(objp: buf); |
295 | |
296 | return ret; |
297 | } |
298 | |
299 | static int ds3000_readreg(struct ds3000_state *state, u8 reg) |
300 | { |
301 | int ret; |
302 | u8 b0[] = { reg }; |
303 | u8 b1[] = { 0 }; |
304 | struct i2c_msg msg[] = { |
305 | { |
306 | .addr = state->config->demod_address, |
307 | .flags = 0, |
308 | .buf = b0, |
309 | .len = 1 |
310 | }, { |
311 | .addr = state->config->demod_address, |
312 | .flags = I2C_M_RD, |
313 | .buf = b1, |
314 | .len = 1 |
315 | } |
316 | }; |
317 | |
318 | ret = i2c_transfer(adap: state->i2c, msgs: msg, num: 2); |
319 | |
320 | if (ret != 2) { |
321 | printk(KERN_ERR "%s: reg=0x%x(error=%d)\n" , __func__, reg, ret); |
322 | return ret; |
323 | } |
324 | |
325 | dprintk("%s: read reg 0x%02x, value 0x%02x\n" , __func__, reg, b1[0]); |
326 | |
327 | return b1[0]; |
328 | } |
329 | |
330 | static int ds3000_load_firmware(struct dvb_frontend *fe, |
331 | const struct firmware *fw); |
332 | |
333 | static int ds3000_firmware_ondemand(struct dvb_frontend *fe) |
334 | { |
335 | struct ds3000_state *state = fe->demodulator_priv; |
336 | const struct firmware *fw; |
337 | int ret = 0; |
338 | |
339 | dprintk("%s()\n" , __func__); |
340 | |
341 | ret = ds3000_readreg(state, reg: 0xb2); |
342 | if (ret < 0) |
343 | return ret; |
344 | |
345 | /* Load firmware */ |
346 | /* request the firmware, this will block until someone uploads it */ |
347 | printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n" , __func__, |
348 | DS3000_DEFAULT_FIRMWARE); |
349 | ret = request_firmware(fw: &fw, DS3000_DEFAULT_FIRMWARE, |
350 | device: state->i2c->dev.parent); |
351 | printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n" , __func__); |
352 | if (ret) { |
353 | printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n" , |
354 | __func__); |
355 | return ret; |
356 | } |
357 | |
358 | ret = ds3000_load_firmware(fe, fw); |
359 | if (ret) |
360 | printk("%s: Writing firmware to device failed\n" , __func__); |
361 | |
362 | release_firmware(fw); |
363 | |
364 | dprintk("%s: Firmware upload %s\n" , __func__, |
365 | ret == 0 ? "complete" : "failed" ); |
366 | |
367 | return ret; |
368 | } |
369 | |
370 | static int ds3000_load_firmware(struct dvb_frontend *fe, |
371 | const struct firmware *fw) |
372 | { |
373 | struct ds3000_state *state = fe->demodulator_priv; |
374 | int ret = 0; |
375 | |
376 | dprintk("%s\n" , __func__); |
377 | dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n" , |
378 | fw->size, |
379 | fw->data[0], |
380 | fw->data[1], |
381 | fw->data[fw->size - 2], |
382 | fw->data[fw->size - 1]); |
383 | |
384 | /* Begin the firmware load process */ |
385 | ds3000_writereg(state, reg: 0xb2, data: 0x01); |
386 | /* write the entire firmware */ |
387 | ret = ds3000_writeFW(state, reg: 0xb0, data: fw->data, len: fw->size); |
388 | ds3000_writereg(state, reg: 0xb2, data: 0x00); |
389 | |
390 | return ret; |
391 | } |
392 | |
393 | static int ds3000_set_voltage(struct dvb_frontend *fe, |
394 | enum fe_sec_voltage voltage) |
395 | { |
396 | struct ds3000_state *state = fe->demodulator_priv; |
397 | u8 data; |
398 | |
399 | dprintk("%s(%d)\n" , __func__, voltage); |
400 | |
401 | data = ds3000_readreg(state, reg: 0xa2); |
402 | data |= 0x03; /* bit0 V/H, bit1 off/on */ |
403 | |
404 | switch (voltage) { |
405 | case SEC_VOLTAGE_18: |
406 | data &= ~0x03; |
407 | break; |
408 | case SEC_VOLTAGE_13: |
409 | data &= ~0x03; |
410 | data |= 0x01; |
411 | break; |
412 | case SEC_VOLTAGE_OFF: |
413 | break; |
414 | } |
415 | |
416 | ds3000_writereg(state, reg: 0xa2, data); |
417 | |
418 | return 0; |
419 | } |
420 | |
421 | static int ds3000_read_status(struct dvb_frontend *fe, enum fe_status *status) |
422 | { |
423 | struct ds3000_state *state = fe->demodulator_priv; |
424 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
425 | int lock; |
426 | |
427 | *status = 0; |
428 | |
429 | switch (c->delivery_system) { |
430 | case SYS_DVBS: |
431 | lock = ds3000_readreg(state, reg: 0xd1); |
432 | if ((lock & 0x07) == 0x07) |
433 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | |
434 | FE_HAS_VITERBI | FE_HAS_SYNC | |
435 | FE_HAS_LOCK; |
436 | |
437 | break; |
438 | case SYS_DVBS2: |
439 | lock = ds3000_readreg(state, reg: 0x0d); |
440 | if ((lock & 0x8f) == 0x8f) |
441 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | |
442 | FE_HAS_VITERBI | FE_HAS_SYNC | |
443 | FE_HAS_LOCK; |
444 | |
445 | break; |
446 | default: |
447 | return -EINVAL; |
448 | } |
449 | |
450 | if (state->config->set_lock_led) |
451 | state->config->set_lock_led(fe, *status == 0 ? 0 : 1); |
452 | |
453 | dprintk("%s: status = 0x%02x\n" , __func__, lock); |
454 | |
455 | return 0; |
456 | } |
457 | |
458 | /* read DS3000 BER value */ |
459 | static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber) |
460 | { |
461 | struct ds3000_state *state = fe->demodulator_priv; |
462 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
463 | u8 data; |
464 | u32 ber_reading, lpdc_frames; |
465 | |
466 | dprintk("%s()\n" , __func__); |
467 | |
468 | switch (c->delivery_system) { |
469 | case SYS_DVBS: |
470 | /* set the number of bytes checked during |
471 | BER estimation */ |
472 | ds3000_writereg(state, reg: 0xf9, data: 0x04); |
473 | /* read BER estimation status */ |
474 | data = ds3000_readreg(state, reg: 0xf8); |
475 | /* check if BER estimation is ready */ |
476 | if ((data & 0x10) == 0) { |
477 | /* this is the number of error bits, |
478 | to calculate the bit error rate |
479 | divide to 8388608 */ |
480 | *ber = (ds3000_readreg(state, reg: 0xf7) << 8) | |
481 | ds3000_readreg(state, reg: 0xf6); |
482 | /* start counting error bits */ |
483 | /* need to be set twice |
484 | otherwise it fails sometimes */ |
485 | data |= 0x10; |
486 | ds3000_writereg(state, reg: 0xf8, data); |
487 | ds3000_writereg(state, reg: 0xf8, data); |
488 | } else |
489 | /* used to indicate that BER estimation |
490 | is not ready, i.e. BER is unknown */ |
491 | *ber = 0xffffffff; |
492 | break; |
493 | case SYS_DVBS2: |
494 | /* read the number of LPDC decoded frames */ |
495 | lpdc_frames = (ds3000_readreg(state, reg: 0xd7) << 16) | |
496 | (ds3000_readreg(state, reg: 0xd6) << 8) | |
497 | ds3000_readreg(state, reg: 0xd5); |
498 | /* read the number of packets with bad CRC */ |
499 | ber_reading = (ds3000_readreg(state, reg: 0xf8) << 8) | |
500 | ds3000_readreg(state, reg: 0xf7); |
501 | if (lpdc_frames > 750) { |
502 | /* clear LPDC frame counters */ |
503 | ds3000_writereg(state, reg: 0xd1, data: 0x01); |
504 | /* clear bad packets counter */ |
505 | ds3000_writereg(state, reg: 0xf9, data: 0x01); |
506 | /* enable bad packets counter */ |
507 | ds3000_writereg(state, reg: 0xf9, data: 0x00); |
508 | /* enable LPDC frame counters */ |
509 | ds3000_writereg(state, reg: 0xd1, data: 0x00); |
510 | *ber = ber_reading; |
511 | } else |
512 | /* used to indicate that BER estimation is not ready, |
513 | i.e. BER is unknown */ |
514 | *ber = 0xffffffff; |
515 | break; |
516 | default: |
517 | return -EINVAL; |
518 | } |
519 | |
520 | return 0; |
521 | } |
522 | |
523 | static int ds3000_read_signal_strength(struct dvb_frontend *fe, |
524 | u16 *signal_strength) |
525 | { |
526 | if (fe->ops.tuner_ops.get_rf_strength) |
527 | fe->ops.tuner_ops.get_rf_strength(fe, signal_strength); |
528 | |
529 | return 0; |
530 | } |
531 | |
532 | /* calculate DS3000 snr value in dB */ |
533 | static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr) |
534 | { |
535 | struct ds3000_state *state = fe->demodulator_priv; |
536 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
537 | u8 snr_reading, snr_value; |
538 | u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp; |
539 | static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */ |
540 | 0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03, |
541 | 0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717, |
542 | 0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505 |
543 | }; |
544 | static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */ |
545 | 0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103, |
546 | 0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5, |
547 | 0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6, |
548 | 0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888, |
549 | 0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51, |
550 | 0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68, |
551 | 0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206, |
552 | 0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a, |
553 | 0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649, |
554 | 0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813, |
555 | 0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1, |
556 | 0x49e9, 0x4a20, 0x4a57 |
557 | }; |
558 | |
559 | dprintk("%s()\n" , __func__); |
560 | |
561 | switch (c->delivery_system) { |
562 | case SYS_DVBS: |
563 | snr_reading = ds3000_readreg(state, reg: 0xff); |
564 | snr_reading /= 8; |
565 | if (snr_reading == 0) |
566 | *snr = 0x0000; |
567 | else { |
568 | if (snr_reading > 20) |
569 | snr_reading = 20; |
570 | snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026; |
571 | /* cook the value to be suitable for szap-s2 |
572 | human readable output */ |
573 | *snr = snr_value * 8 * 655; |
574 | } |
575 | dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n" , __func__, |
576 | snr_reading, *snr); |
577 | break; |
578 | case SYS_DVBS2: |
579 | dvbs2_noise_reading = (ds3000_readreg(state, reg: 0x8c) & 0x3f) + |
580 | (ds3000_readreg(state, reg: 0x8d) << 4); |
581 | dvbs2_signal_reading = ds3000_readreg(state, reg: 0x8e); |
582 | tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1; |
583 | if (tmp == 0) { |
584 | *snr = 0x0000; |
585 | return 0; |
586 | } |
587 | if (dvbs2_noise_reading == 0) { |
588 | snr_value = 0x0013; |
589 | /* cook the value to be suitable for szap-s2 |
590 | human readable output */ |
591 | *snr = 0xffff; |
592 | return 0; |
593 | } |
594 | if (tmp > dvbs2_noise_reading) { |
595 | snr_reading = tmp / dvbs2_noise_reading; |
596 | if (snr_reading > 80) |
597 | snr_reading = 80; |
598 | snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000; |
599 | /* cook the value to be suitable for szap-s2 |
600 | human readable output */ |
601 | *snr = snr_value * 5 * 655; |
602 | } else { |
603 | snr_reading = dvbs2_noise_reading / tmp; |
604 | if (snr_reading > 80) |
605 | snr_reading = 80; |
606 | *snr = -(dvbs2_snr_tab[snr_reading - 1] / 1000); |
607 | } |
608 | dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n" , __func__, |
609 | snr_reading, *snr); |
610 | break; |
611 | default: |
612 | return -EINVAL; |
613 | } |
614 | |
615 | return 0; |
616 | } |
617 | |
618 | /* read DS3000 uncorrected blocks */ |
619 | static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
620 | { |
621 | struct ds3000_state *state = fe->demodulator_priv; |
622 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
623 | u8 data; |
624 | u16 _ucblocks; |
625 | |
626 | dprintk("%s()\n" , __func__); |
627 | |
628 | switch (c->delivery_system) { |
629 | case SYS_DVBS: |
630 | *ucblocks = (ds3000_readreg(state, reg: 0xf5) << 8) | |
631 | ds3000_readreg(state, reg: 0xf4); |
632 | data = ds3000_readreg(state, reg: 0xf8); |
633 | /* clear packet counters */ |
634 | data &= ~0x20; |
635 | ds3000_writereg(state, reg: 0xf8, data); |
636 | /* enable packet counters */ |
637 | data |= 0x20; |
638 | ds3000_writereg(state, reg: 0xf8, data); |
639 | break; |
640 | case SYS_DVBS2: |
641 | _ucblocks = (ds3000_readreg(state, reg: 0xe2) << 8) | |
642 | ds3000_readreg(state, reg: 0xe1); |
643 | if (_ucblocks > state->prevUCBS2) |
644 | *ucblocks = _ucblocks - state->prevUCBS2; |
645 | else |
646 | *ucblocks = state->prevUCBS2 - _ucblocks; |
647 | state->prevUCBS2 = _ucblocks; |
648 | break; |
649 | default: |
650 | return -EINVAL; |
651 | } |
652 | |
653 | return 0; |
654 | } |
655 | |
656 | static int ds3000_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) |
657 | { |
658 | struct ds3000_state *state = fe->demodulator_priv; |
659 | u8 data; |
660 | |
661 | dprintk("%s(%d)\n" , __func__, tone); |
662 | if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { |
663 | printk(KERN_ERR "%s: Invalid, tone=%d\n" , __func__, tone); |
664 | return -EINVAL; |
665 | } |
666 | |
667 | data = ds3000_readreg(state, reg: 0xa2); |
668 | data &= ~0xc0; |
669 | ds3000_writereg(state, reg: 0xa2, data); |
670 | |
671 | switch (tone) { |
672 | case SEC_TONE_ON: |
673 | dprintk("%s: setting tone on\n" , __func__); |
674 | data = ds3000_readreg(state, reg: 0xa1); |
675 | data &= ~0x43; |
676 | data |= 0x04; |
677 | ds3000_writereg(state, reg: 0xa1, data); |
678 | break; |
679 | case SEC_TONE_OFF: |
680 | dprintk("%s: setting tone off\n" , __func__); |
681 | data = ds3000_readreg(state, reg: 0xa2); |
682 | data |= 0x80; |
683 | ds3000_writereg(state, reg: 0xa2, data); |
684 | break; |
685 | } |
686 | |
687 | return 0; |
688 | } |
689 | |
690 | static int ds3000_send_diseqc_msg(struct dvb_frontend *fe, |
691 | struct dvb_diseqc_master_cmd *d) |
692 | { |
693 | struct ds3000_state *state = fe->demodulator_priv; |
694 | int i; |
695 | u8 data; |
696 | |
697 | /* Dump DiSEqC message */ |
698 | dprintk("%s(" , __func__); |
699 | for (i = 0 ; i < d->msg_len;) { |
700 | dprintk("0x%02x" , d->msg[i]); |
701 | if (++i < d->msg_len) |
702 | dprintk(", " ); |
703 | } |
704 | |
705 | /* enable DiSEqC message send pin */ |
706 | data = ds3000_readreg(state, reg: 0xa2); |
707 | data &= ~0xc0; |
708 | ds3000_writereg(state, reg: 0xa2, data); |
709 | |
710 | /* DiSEqC message */ |
711 | for (i = 0; i < d->msg_len; i++) |
712 | ds3000_writereg(state, reg: 0xa3 + i, data: d->msg[i]); |
713 | |
714 | data = ds3000_readreg(state, reg: 0xa1); |
715 | /* clear DiSEqC message length and status, |
716 | enable DiSEqC message send */ |
717 | data &= ~0xf8; |
718 | /* set DiSEqC mode, modulation active during 33 pulses, |
719 | set DiSEqC message length */ |
720 | data |= ((d->msg_len - 1) << 3) | 0x07; |
721 | ds3000_writereg(state, reg: 0xa1, data); |
722 | |
723 | /* wait up to 150ms for DiSEqC transmission to complete */ |
724 | for (i = 0; i < 15; i++) { |
725 | data = ds3000_readreg(state, reg: 0xa1); |
726 | if ((data & 0x40) == 0) |
727 | break; |
728 | msleep(msecs: 10); |
729 | } |
730 | |
731 | /* DiSEqC timeout after 150ms */ |
732 | if (i == 15) { |
733 | data = ds3000_readreg(state, reg: 0xa1); |
734 | data &= ~0x80; |
735 | data |= 0x40; |
736 | ds3000_writereg(state, reg: 0xa1, data); |
737 | |
738 | data = ds3000_readreg(state, reg: 0xa2); |
739 | data &= ~0xc0; |
740 | data |= 0x80; |
741 | ds3000_writereg(state, reg: 0xa2, data); |
742 | |
743 | return -ETIMEDOUT; |
744 | } |
745 | |
746 | data = ds3000_readreg(state, reg: 0xa2); |
747 | data &= ~0xc0; |
748 | data |= 0x80; |
749 | ds3000_writereg(state, reg: 0xa2, data); |
750 | |
751 | return 0; |
752 | } |
753 | |
754 | /* Send DiSEqC burst */ |
755 | static int ds3000_diseqc_send_burst(struct dvb_frontend *fe, |
756 | enum fe_sec_mini_cmd burst) |
757 | { |
758 | struct ds3000_state *state = fe->demodulator_priv; |
759 | int i; |
760 | u8 data; |
761 | |
762 | dprintk("%s()\n" , __func__); |
763 | |
764 | data = ds3000_readreg(state, reg: 0xa2); |
765 | data &= ~0xc0; |
766 | ds3000_writereg(state, reg: 0xa2, data); |
767 | |
768 | /* DiSEqC burst */ |
769 | if (burst == SEC_MINI_A) |
770 | /* Unmodulated tone burst */ |
771 | ds3000_writereg(state, reg: 0xa1, data: 0x02); |
772 | else if (burst == SEC_MINI_B) |
773 | /* Modulated tone burst */ |
774 | ds3000_writereg(state, reg: 0xa1, data: 0x01); |
775 | else |
776 | return -EINVAL; |
777 | |
778 | msleep(msecs: 13); |
779 | for (i = 0; i < 5; i++) { |
780 | data = ds3000_readreg(state, reg: 0xa1); |
781 | if ((data & 0x40) == 0) |
782 | break; |
783 | msleep(msecs: 1); |
784 | } |
785 | |
786 | if (i == 5) { |
787 | data = ds3000_readreg(state, reg: 0xa1); |
788 | data &= ~0x80; |
789 | data |= 0x40; |
790 | ds3000_writereg(state, reg: 0xa1, data); |
791 | |
792 | data = ds3000_readreg(state, reg: 0xa2); |
793 | data &= ~0xc0; |
794 | data |= 0x80; |
795 | ds3000_writereg(state, reg: 0xa2, data); |
796 | |
797 | return -ETIMEDOUT; |
798 | } |
799 | |
800 | data = ds3000_readreg(state, reg: 0xa2); |
801 | data &= ~0xc0; |
802 | data |= 0x80; |
803 | ds3000_writereg(state, reg: 0xa2, data); |
804 | |
805 | return 0; |
806 | } |
807 | |
808 | static void ds3000_release(struct dvb_frontend *fe) |
809 | { |
810 | struct ds3000_state *state = fe->demodulator_priv; |
811 | |
812 | if (state->config->set_lock_led) |
813 | state->config->set_lock_led(fe, 0); |
814 | |
815 | dprintk("%s\n" , __func__); |
816 | kfree(objp: state); |
817 | } |
818 | |
819 | static const struct dvb_frontend_ops ds3000_ops; |
820 | |
821 | struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, |
822 | struct i2c_adapter *i2c) |
823 | { |
824 | struct ds3000_state *state; |
825 | int ret; |
826 | |
827 | dprintk("%s\n" , __func__); |
828 | |
829 | /* allocate memory for the internal state */ |
830 | state = kzalloc(size: sizeof(*state), GFP_KERNEL); |
831 | if (!state) |
832 | return NULL; |
833 | |
834 | state->config = config; |
835 | state->i2c = i2c; |
836 | state->prevUCBS2 = 0; |
837 | |
838 | /* check if the demod is present */ |
839 | ret = ds3000_readreg(state, reg: 0x00) & 0xfe; |
840 | if (ret != 0xe0) { |
841 | kfree(objp: state); |
842 | printk(KERN_ERR "Invalid probe, probably not a DS3000\n" ); |
843 | return NULL; |
844 | } |
845 | |
846 | printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n" , |
847 | ds3000_readreg(state, 0x02), |
848 | ds3000_readreg(state, 0x01)); |
849 | |
850 | memcpy(&state->frontend.ops, &ds3000_ops, |
851 | sizeof(struct dvb_frontend_ops)); |
852 | state->frontend.demodulator_priv = state; |
853 | |
854 | /* |
855 | * Some devices like T480 starts with voltage on. Be sure |
856 | * to turn voltage off during init, as this can otherwise |
857 | * interfere with Unicable SCR systems. |
858 | */ |
859 | ds3000_set_voltage(fe: &state->frontend, voltage: SEC_VOLTAGE_OFF); |
860 | return &state->frontend; |
861 | } |
862 | EXPORT_SYMBOL_GPL(ds3000_attach); |
863 | |
864 | static int ds3000_set_carrier_offset(struct dvb_frontend *fe, |
865 | s32 carrier_offset_khz) |
866 | { |
867 | struct ds3000_state *state = fe->demodulator_priv; |
868 | s32 tmp; |
869 | |
870 | tmp = carrier_offset_khz; |
871 | tmp *= 65536; |
872 | tmp = (2 * tmp + DS3000_SAMPLE_RATE) / (2 * DS3000_SAMPLE_RATE); |
873 | |
874 | if (tmp < 0) |
875 | tmp += 65536; |
876 | |
877 | ds3000_writereg(state, reg: 0x5f, data: tmp >> 8); |
878 | ds3000_writereg(state, reg: 0x5e, data: tmp & 0xff); |
879 | |
880 | return 0; |
881 | } |
882 | |
883 | static int ds3000_set_frontend(struct dvb_frontend *fe) |
884 | { |
885 | struct ds3000_state *state = fe->demodulator_priv; |
886 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
887 | |
888 | int i; |
889 | enum fe_status status; |
890 | s32 offset_khz; |
891 | u32 frequency; |
892 | u16 value; |
893 | |
894 | dprintk("%s() " , __func__); |
895 | |
896 | if (state->config->set_ts_params) |
897 | state->config->set_ts_params(fe, 0); |
898 | /* Tune */ |
899 | if (fe->ops.tuner_ops.set_params) |
900 | fe->ops.tuner_ops.set_params(fe); |
901 | |
902 | /* ds3000 global reset */ |
903 | ds3000_writereg(state, reg: 0x07, data: 0x80); |
904 | ds3000_writereg(state, reg: 0x07, data: 0x00); |
905 | /* ds3000 built-in uC reset */ |
906 | ds3000_writereg(state, reg: 0xb2, data: 0x01); |
907 | /* ds3000 software reset */ |
908 | ds3000_writereg(state, reg: 0x00, data: 0x01); |
909 | |
910 | switch (c->delivery_system) { |
911 | case SYS_DVBS: |
912 | /* initialise the demod in DVB-S mode */ |
913 | for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2) |
914 | ds3000_writereg(state, |
915 | reg: ds3000_dvbs_init_tab[i], |
916 | data: ds3000_dvbs_init_tab[i + 1]); |
917 | value = ds3000_readreg(state, reg: 0xfe); |
918 | value &= 0xc0; |
919 | value |= 0x1b; |
920 | ds3000_writereg(state, reg: 0xfe, data: value); |
921 | break; |
922 | case SYS_DVBS2: |
923 | /* initialise the demod in DVB-S2 mode */ |
924 | for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2) |
925 | ds3000_writereg(state, |
926 | reg: ds3000_dvbs2_init_tab[i], |
927 | data: ds3000_dvbs2_init_tab[i + 1]); |
928 | if (c->symbol_rate >= 30000000) |
929 | ds3000_writereg(state, reg: 0xfe, data: 0x54); |
930 | else |
931 | ds3000_writereg(state, reg: 0xfe, data: 0x98); |
932 | break; |
933 | default: |
934 | return -EINVAL; |
935 | } |
936 | |
937 | /* enable 27MHz clock output */ |
938 | ds3000_writereg(state, reg: 0x29, data: 0x80); |
939 | /* enable ac coupling */ |
940 | ds3000_writereg(state, reg: 0x25, data: 0x8a); |
941 | |
942 | if ((c->symbol_rate < ds3000_ops.info.symbol_rate_min) || |
943 | (c->symbol_rate > ds3000_ops.info.symbol_rate_max)) { |
944 | dprintk("%s() symbol_rate %u out of range (%u ... %u)\n" , |
945 | __func__, c->symbol_rate, |
946 | ds3000_ops.info.symbol_rate_min, |
947 | ds3000_ops.info.symbol_rate_max); |
948 | return -EINVAL; |
949 | } |
950 | |
951 | /* enhance symbol rate performance */ |
952 | if ((c->symbol_rate / 1000) <= 5000) { |
953 | value = 29777 / (c->symbol_rate / 1000) + 1; |
954 | if (value % 2 != 0) |
955 | value++; |
956 | ds3000_writereg(state, reg: 0xc3, data: 0x0d); |
957 | ds3000_writereg(state, reg: 0xc8, data: value); |
958 | ds3000_writereg(state, reg: 0xc4, data: 0x10); |
959 | ds3000_writereg(state, reg: 0xc7, data: 0x0e); |
960 | } else if ((c->symbol_rate / 1000) <= 10000) { |
961 | value = 92166 / (c->symbol_rate / 1000) + 1; |
962 | if (value % 2 != 0) |
963 | value++; |
964 | ds3000_writereg(state, reg: 0xc3, data: 0x07); |
965 | ds3000_writereg(state, reg: 0xc8, data: value); |
966 | ds3000_writereg(state, reg: 0xc4, data: 0x09); |
967 | ds3000_writereg(state, reg: 0xc7, data: 0x12); |
968 | } else if ((c->symbol_rate / 1000) <= 20000) { |
969 | value = 64516 / (c->symbol_rate / 1000) + 1; |
970 | ds3000_writereg(state, reg: 0xc3, data: value); |
971 | ds3000_writereg(state, reg: 0xc8, data: 0x0e); |
972 | ds3000_writereg(state, reg: 0xc4, data: 0x07); |
973 | ds3000_writereg(state, reg: 0xc7, data: 0x18); |
974 | } else { |
975 | value = 129032 / (c->symbol_rate / 1000) + 1; |
976 | ds3000_writereg(state, reg: 0xc3, data: value); |
977 | ds3000_writereg(state, reg: 0xc8, data: 0x0a); |
978 | ds3000_writereg(state, reg: 0xc4, data: 0x05); |
979 | ds3000_writereg(state, reg: 0xc7, data: 0x24); |
980 | } |
981 | |
982 | /* normalized symbol rate rounded to the closest integer */ |
983 | value = (((c->symbol_rate / 1000) << 16) + |
984 | (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE; |
985 | ds3000_writereg(state, reg: 0x61, data: value & 0x00ff); |
986 | ds3000_writereg(state, reg: 0x62, data: (value & 0xff00) >> 8); |
987 | |
988 | /* co-channel interference cancellation disabled */ |
989 | ds3000_writereg(state, reg: 0x56, data: 0x00); |
990 | |
991 | /* equalizer disabled */ |
992 | ds3000_writereg(state, reg: 0x76, data: 0x00); |
993 | |
994 | /*ds3000_writereg(state, 0x08, 0x03); |
995 | ds3000_writereg(state, 0xfd, 0x22); |
996 | ds3000_writereg(state, 0x08, 0x07); |
997 | ds3000_writereg(state, 0xfd, 0x42); |
998 | ds3000_writereg(state, 0x08, 0x07);*/ |
999 | |
1000 | if (state->config->ci_mode) { |
1001 | switch (c->delivery_system) { |
1002 | case SYS_DVBS: |
1003 | default: |
1004 | ds3000_writereg(state, reg: 0xfd, data: 0x80); |
1005 | break; |
1006 | case SYS_DVBS2: |
1007 | ds3000_writereg(state, reg: 0xfd, data: 0x01); |
1008 | break; |
1009 | } |
1010 | } |
1011 | |
1012 | /* ds3000 out of software reset */ |
1013 | ds3000_writereg(state, reg: 0x00, data: 0x00); |
1014 | /* start ds3000 built-in uC */ |
1015 | ds3000_writereg(state, reg: 0xb2, data: 0x00); |
1016 | |
1017 | if (fe->ops.tuner_ops.get_frequency) { |
1018 | fe->ops.tuner_ops.get_frequency(fe, &frequency); |
1019 | offset_khz = frequency - c->frequency; |
1020 | ds3000_set_carrier_offset(fe, carrier_offset_khz: offset_khz); |
1021 | } |
1022 | |
1023 | for (i = 0; i < 30 ; i++) { |
1024 | ds3000_read_status(fe, status: &status); |
1025 | if (status & FE_HAS_LOCK) |
1026 | break; |
1027 | |
1028 | msleep(msecs: 10); |
1029 | } |
1030 | |
1031 | return 0; |
1032 | } |
1033 | |
1034 | static int ds3000_tune(struct dvb_frontend *fe, |
1035 | bool re_tune, |
1036 | unsigned int mode_flags, |
1037 | unsigned int *delay, |
1038 | enum fe_status *status) |
1039 | { |
1040 | if (re_tune) { |
1041 | int ret = ds3000_set_frontend(fe); |
1042 | if (ret) |
1043 | return ret; |
1044 | } |
1045 | |
1046 | *delay = HZ / 5; |
1047 | |
1048 | return ds3000_read_status(fe, status); |
1049 | } |
1050 | |
1051 | static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe) |
1052 | { |
1053 | struct ds3000_state *state = fe->demodulator_priv; |
1054 | |
1055 | if (state->config->set_lock_led) |
1056 | state->config->set_lock_led(fe, 0); |
1057 | |
1058 | dprintk("%s()\n" , __func__); |
1059 | return DVBFE_ALGO_HW; |
1060 | } |
1061 | |
1062 | /* |
1063 | * Initialise or wake up device |
1064 | * |
1065 | * Power config will reset and load initial firmware if required |
1066 | */ |
1067 | static int ds3000_initfe(struct dvb_frontend *fe) |
1068 | { |
1069 | struct ds3000_state *state = fe->demodulator_priv; |
1070 | int ret; |
1071 | |
1072 | dprintk("%s()\n" , __func__); |
1073 | /* hard reset */ |
1074 | ds3000_writereg(state, reg: 0x08, data: 0x01 | ds3000_readreg(state, reg: 0x08)); |
1075 | msleep(msecs: 1); |
1076 | |
1077 | /* Load the firmware if required */ |
1078 | ret = ds3000_firmware_ondemand(fe); |
1079 | if (ret != 0) { |
1080 | printk(KERN_ERR "%s: Unable initialize firmware\n" , __func__); |
1081 | return ret; |
1082 | } |
1083 | |
1084 | return 0; |
1085 | } |
1086 | |
1087 | static const struct dvb_frontend_ops ds3000_ops = { |
1088 | .delsys = { SYS_DVBS, SYS_DVBS2 }, |
1089 | .info = { |
1090 | .name = "Montage Technology DS3000" , |
1091 | .frequency_min_hz = 950 * MHz, |
1092 | .frequency_max_hz = 2150 * MHz, |
1093 | .frequency_stepsize_hz = 1011 * kHz, |
1094 | .frequency_tolerance_hz = 5 * MHz, |
1095 | .symbol_rate_min = 1000000, |
1096 | .symbol_rate_max = 45000000, |
1097 | .caps = FE_CAN_INVERSION_AUTO | |
1098 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
1099 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | |
1100 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
1101 | FE_CAN_2G_MODULATION | |
1102 | FE_CAN_QPSK | FE_CAN_RECOVER |
1103 | }, |
1104 | |
1105 | .release = ds3000_release, |
1106 | |
1107 | .init = ds3000_initfe, |
1108 | .i2c_gate_ctrl = ds3000_i2c_gate_ctrl, |
1109 | .read_status = ds3000_read_status, |
1110 | .read_ber = ds3000_read_ber, |
1111 | .read_signal_strength = ds3000_read_signal_strength, |
1112 | .read_snr = ds3000_read_snr, |
1113 | .read_ucblocks = ds3000_read_ucblocks, |
1114 | .set_voltage = ds3000_set_voltage, |
1115 | .set_tone = ds3000_set_tone, |
1116 | .diseqc_send_master_cmd = ds3000_send_diseqc_msg, |
1117 | .diseqc_send_burst = ds3000_diseqc_send_burst, |
1118 | .get_frontend_algo = ds3000_get_algo, |
1119 | |
1120 | .set_frontend = ds3000_set_frontend, |
1121 | .tune = ds3000_tune, |
1122 | }; |
1123 | |
1124 | module_param(debug, int, 0644); |
1125 | MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)" ); |
1126 | |
1127 | MODULE_DESCRIPTION("DVB Frontend module for Montage Technology DS3000 hardware" ); |
1128 | MODULE_AUTHOR("Konstantin Dimitrov <kosio.dimitrov@gmail.com>" ); |
1129 | MODULE_LICENSE("GPL" ); |
1130 | MODULE_FIRMWARE(DS3000_DEFAULT_FIRMWARE); |
1131 | |