1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* Frontend part of the Linux driver for the Afatech 9005 |
3 | * USB1.1 DVB-T receiver. |
4 | * |
5 | * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) |
6 | * |
7 | * Thanks to Afatech who kindly provided information. |
8 | * |
9 | * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information |
10 | */ |
11 | #include "af9005.h" |
12 | #include "af9005-script.h" |
13 | #include "mt2060.h" |
14 | #include "qt1010.h" |
15 | #include <asm/div64.h> |
16 | |
17 | struct af9005_fe_state { |
18 | struct dvb_usb_device *d; |
19 | enum fe_status stat; |
20 | |
21 | /* retraining parameters */ |
22 | u32 original_fcw; |
23 | u16 original_rf_top; |
24 | u16 original_if_top; |
25 | u16 original_if_min; |
26 | u16 original_aci0_if_top; |
27 | u16 original_aci1_if_top; |
28 | u16 original_aci0_if_min; |
29 | u8 original_if_unplug_th; |
30 | u8 original_rf_unplug_th; |
31 | u8 original_dtop_if_unplug_th; |
32 | u8 original_dtop_rf_unplug_th; |
33 | |
34 | /* statistics */ |
35 | u32 pre_vit_error_count; |
36 | u32 pre_vit_bit_count; |
37 | u32 ber; |
38 | u32 post_vit_error_count; |
39 | u32 post_vit_bit_count; |
40 | u32 unc; |
41 | u16 abort_count; |
42 | |
43 | int opened; |
44 | int strong; |
45 | unsigned long next_status_check; |
46 | struct dvb_frontend frontend; |
47 | }; |
48 | |
49 | static int af9005_write_word_agc(struct dvb_usb_device *d, u16 reghi, |
50 | u16 reglo, u8 pos, u8 len, u16 value) |
51 | { |
52 | int ret; |
53 | |
54 | if ((ret = af9005_write_ofdm_register(d, reg: reglo, value: (u8) (value & 0xff)))) |
55 | return ret; |
56 | return af9005_write_register_bits(d, reg: reghi, pos, len, |
57 | value: (u8) ((value & 0x300) >> 8)); |
58 | } |
59 | |
60 | static int af9005_read_word_agc(struct dvb_usb_device *d, u16 reghi, |
61 | u16 reglo, u8 pos, u8 len, u16 * value) |
62 | { |
63 | int ret; |
64 | u8 temp0, temp1; |
65 | |
66 | if ((ret = af9005_read_ofdm_register(d, reg: reglo, value: &temp0))) |
67 | return ret; |
68 | if ((ret = af9005_read_ofdm_register(d, reg: reghi, value: &temp1))) |
69 | return ret; |
70 | switch (pos) { |
71 | case 0: |
72 | *value = ((u16) (temp1 & 0x03) << 8) + (u16) temp0; |
73 | break; |
74 | case 2: |
75 | *value = ((u16) (temp1 & 0x0C) << 6) + (u16) temp0; |
76 | break; |
77 | case 4: |
78 | *value = ((u16) (temp1 & 0x30) << 4) + (u16) temp0; |
79 | break; |
80 | case 6: |
81 | *value = ((u16) (temp1 & 0xC0) << 2) + (u16) temp0; |
82 | break; |
83 | default: |
84 | err("invalid pos in read word agc" ); |
85 | return -EINVAL; |
86 | } |
87 | return 0; |
88 | |
89 | } |
90 | |
91 | static int af9005_is_fecmon_available(struct dvb_frontend *fe, int *available) |
92 | { |
93 | struct af9005_fe_state *state = fe->demodulator_priv; |
94 | int ret; |
95 | u8 temp; |
96 | |
97 | *available = false; |
98 | |
99 | ret = af9005_read_register_bits(d: state->d, xd_p_fec_vtb_rsd_mon_en, |
100 | fec_vtb_rsd_mon_en_pos, |
101 | fec_vtb_rsd_mon_en_len, value: &temp); |
102 | if (ret) |
103 | return ret; |
104 | if (temp & 1) { |
105 | ret = |
106 | af9005_read_register_bits(d: state->d, |
107 | xd_p_reg_ofsm_read_rbc_en, |
108 | reg_ofsm_read_rbc_en_pos, |
109 | reg_ofsm_read_rbc_en_len, value: &temp); |
110 | if (ret) |
111 | return ret; |
112 | if ((temp & 1) == 0) |
113 | *available = true; |
114 | |
115 | } |
116 | return 0; |
117 | } |
118 | |
119 | static int af9005_get_post_vit_err_cw_count(struct dvb_frontend *fe, |
120 | u32 * post_err_count, |
121 | u32 * post_cw_count, |
122 | u16 * abort_count) |
123 | { |
124 | struct af9005_fe_state *state = fe->demodulator_priv; |
125 | int ret; |
126 | u32 err_count; |
127 | u32 cw_count; |
128 | u8 temp, temp0, temp1, temp2; |
129 | u16 loc_abort_count; |
130 | |
131 | *post_err_count = 0; |
132 | *post_cw_count = 0; |
133 | |
134 | /* check if error bit count is ready */ |
135 | ret = |
136 | af9005_read_register_bits(d: state->d, xd_r_fec_rsd_ber_rdy, |
137 | fec_rsd_ber_rdy_pos, fec_rsd_ber_rdy_len, |
138 | value: &temp); |
139 | if (ret) |
140 | return ret; |
141 | if (!temp) { |
142 | deb_info("rsd counter not ready\n" ); |
143 | return 100; |
144 | } |
145 | /* get abort count */ |
146 | ret = |
147 | af9005_read_ofdm_register(d: state->d, |
148 | xd_r_fec_rsd_abort_packet_cnt_7_0, |
149 | value: &temp0); |
150 | if (ret) |
151 | return ret; |
152 | ret = |
153 | af9005_read_ofdm_register(d: state->d, |
154 | xd_r_fec_rsd_abort_packet_cnt_15_8, |
155 | value: &temp1); |
156 | if (ret) |
157 | return ret; |
158 | loc_abort_count = ((u16) temp1 << 8) + temp0; |
159 | |
160 | /* get error count */ |
161 | ret = |
162 | af9005_read_ofdm_register(d: state->d, xd_r_fec_rsd_bit_err_cnt_7_0, |
163 | value: &temp0); |
164 | if (ret) |
165 | return ret; |
166 | ret = |
167 | af9005_read_ofdm_register(d: state->d, xd_r_fec_rsd_bit_err_cnt_15_8, |
168 | value: &temp1); |
169 | if (ret) |
170 | return ret; |
171 | ret = |
172 | af9005_read_ofdm_register(d: state->d, xd_r_fec_rsd_bit_err_cnt_23_16, |
173 | value: &temp2); |
174 | if (ret) |
175 | return ret; |
176 | err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0; |
177 | *post_err_count = err_count - (u32) loc_abort_count *8 * 8; |
178 | |
179 | /* get RSD packet number */ |
180 | ret = |
181 | af9005_read_ofdm_register(d: state->d, xd_p_fec_rsd_packet_unit_7_0, |
182 | value: &temp0); |
183 | if (ret) |
184 | return ret; |
185 | ret = |
186 | af9005_read_ofdm_register(d: state->d, xd_p_fec_rsd_packet_unit_15_8, |
187 | value: &temp1); |
188 | if (ret) |
189 | return ret; |
190 | cw_count = ((u32) temp1 << 8) + temp0; |
191 | if (cw_count == 0) { |
192 | err("wrong RSD packet count" ); |
193 | return -EIO; |
194 | } |
195 | deb_info("POST abort count %d err count %d rsd packets %d\n" , |
196 | loc_abort_count, err_count, cw_count); |
197 | *post_cw_count = cw_count - (u32) loc_abort_count; |
198 | *abort_count = loc_abort_count; |
199 | return 0; |
200 | |
201 | } |
202 | |
203 | static int af9005_get_post_vit_ber(struct dvb_frontend *fe, |
204 | u32 * post_err_count, u32 * post_cw_count, |
205 | u16 * abort_count) |
206 | { |
207 | u32 loc_cw_count = 0, loc_err_count; |
208 | u16 loc_abort_count = 0; |
209 | int ret; |
210 | |
211 | ret = |
212 | af9005_get_post_vit_err_cw_count(fe, post_err_count: &loc_err_count, post_cw_count: &loc_cw_count, |
213 | abort_count: &loc_abort_count); |
214 | if (ret) |
215 | return ret; |
216 | *post_err_count = loc_err_count; |
217 | *post_cw_count = loc_cw_count * 204 * 8; |
218 | *abort_count = loc_abort_count; |
219 | |
220 | return 0; |
221 | } |
222 | |
223 | static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe, |
224 | u32 * pre_err_count, |
225 | u32 * pre_bit_count) |
226 | { |
227 | struct af9005_fe_state *state = fe->demodulator_priv; |
228 | u8 temp, temp0, temp1, temp2; |
229 | u32 super_frame_count, x, bits; |
230 | int ret; |
231 | |
232 | ret = |
233 | af9005_read_register_bits(d: state->d, xd_r_fec_vtb_ber_rdy, |
234 | fec_vtb_ber_rdy_pos, fec_vtb_ber_rdy_len, |
235 | value: &temp); |
236 | if (ret) |
237 | return ret; |
238 | if (!temp) { |
239 | deb_info("viterbi counter not ready\n" ); |
240 | return 101; /* ERR_APO_VTB_COUNTER_NOT_READY; */ |
241 | } |
242 | ret = |
243 | af9005_read_ofdm_register(d: state->d, xd_r_fec_vtb_err_bit_cnt_7_0, |
244 | value: &temp0); |
245 | if (ret) |
246 | return ret; |
247 | ret = |
248 | af9005_read_ofdm_register(d: state->d, xd_r_fec_vtb_err_bit_cnt_15_8, |
249 | value: &temp1); |
250 | if (ret) |
251 | return ret; |
252 | ret = |
253 | af9005_read_ofdm_register(d: state->d, xd_r_fec_vtb_err_bit_cnt_23_16, |
254 | value: &temp2); |
255 | if (ret) |
256 | return ret; |
257 | *pre_err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0; |
258 | |
259 | ret = |
260 | af9005_read_ofdm_register(d: state->d, xd_p_fec_super_frm_unit_7_0, |
261 | value: &temp0); |
262 | if (ret) |
263 | return ret; |
264 | ret = |
265 | af9005_read_ofdm_register(d: state->d, xd_p_fec_super_frm_unit_15_8, |
266 | value: &temp1); |
267 | if (ret) |
268 | return ret; |
269 | super_frame_count = ((u32) temp1 << 8) + temp0; |
270 | if (super_frame_count == 0) { |
271 | deb_info("super frame count 0\n" ); |
272 | return 102; |
273 | } |
274 | |
275 | /* read fft mode */ |
276 | ret = |
277 | af9005_read_register_bits(d: state->d, xd_g_reg_tpsd_txmod, |
278 | reg_tpsd_txmod_pos, reg_tpsd_txmod_len, |
279 | value: &temp); |
280 | if (ret) |
281 | return ret; |
282 | if (temp == 0) { |
283 | /* 2K */ |
284 | x = 1512; |
285 | } else if (temp == 1) { |
286 | /* 8k */ |
287 | x = 6048; |
288 | } else { |
289 | err("Invalid fft mode" ); |
290 | return -EINVAL; |
291 | } |
292 | |
293 | /* read modulation mode */ |
294 | ret = |
295 | af9005_read_register_bits(d: state->d, xd_g_reg_tpsd_const, |
296 | reg_tpsd_const_pos, reg_tpsd_const_len, |
297 | value: &temp); |
298 | if (ret) |
299 | return ret; |
300 | switch (temp) { |
301 | case 0: /* QPSK */ |
302 | bits = 2; |
303 | break; |
304 | case 1: /* QAM_16 */ |
305 | bits = 4; |
306 | break; |
307 | case 2: /* QAM_64 */ |
308 | bits = 6; |
309 | break; |
310 | default: |
311 | err("invalid modulation mode" ); |
312 | return -EINVAL; |
313 | } |
314 | *pre_bit_count = super_frame_count * 68 * 4 * x * bits; |
315 | deb_info("PRE err count %d frame count %d bit count %d\n" , |
316 | *pre_err_count, super_frame_count, *pre_bit_count); |
317 | return 0; |
318 | } |
319 | |
320 | static int af9005_reset_pre_viterbi(struct dvb_frontend *fe) |
321 | { |
322 | struct af9005_fe_state *state = fe->demodulator_priv; |
323 | int ret; |
324 | |
325 | /* set super frame count to 1 */ |
326 | ret = |
327 | af9005_write_ofdm_register(d: state->d, xd_p_fec_super_frm_unit_7_0, |
328 | value: 1 & 0xff); |
329 | if (ret) |
330 | return ret; |
331 | ret = af9005_write_ofdm_register(d: state->d, xd_p_fec_super_frm_unit_15_8, |
332 | value: 1 >> 8); |
333 | if (ret) |
334 | return ret; |
335 | /* reset pre viterbi error count */ |
336 | ret = |
337 | af9005_write_register_bits(d: state->d, xd_p_fec_vtb_ber_rst, |
338 | fec_vtb_ber_rst_pos, fec_vtb_ber_rst_len, |
339 | value: 1); |
340 | |
341 | return ret; |
342 | } |
343 | |
344 | static int af9005_reset_post_viterbi(struct dvb_frontend *fe) |
345 | { |
346 | struct af9005_fe_state *state = fe->demodulator_priv; |
347 | int ret; |
348 | |
349 | /* set packet unit */ |
350 | ret = |
351 | af9005_write_ofdm_register(d: state->d, xd_p_fec_rsd_packet_unit_7_0, |
352 | value: 10000 & 0xff); |
353 | if (ret) |
354 | return ret; |
355 | ret = |
356 | af9005_write_ofdm_register(d: state->d, xd_p_fec_rsd_packet_unit_15_8, |
357 | value: 10000 >> 8); |
358 | if (ret) |
359 | return ret; |
360 | /* reset post viterbi error count */ |
361 | ret = |
362 | af9005_write_register_bits(d: state->d, xd_p_fec_rsd_ber_rst, |
363 | fec_rsd_ber_rst_pos, fec_rsd_ber_rst_len, |
364 | value: 1); |
365 | |
366 | return ret; |
367 | } |
368 | |
369 | static int af9005_get_statistic(struct dvb_frontend *fe) |
370 | { |
371 | struct af9005_fe_state *state = fe->demodulator_priv; |
372 | int ret, fecavailable; |
373 | u64 numerator, denominator; |
374 | |
375 | deb_info("GET STATISTIC\n" ); |
376 | ret = af9005_is_fecmon_available(fe, available: &fecavailable); |
377 | if (ret) |
378 | return ret; |
379 | if (!fecavailable) { |
380 | deb_info("fecmon not available\n" ); |
381 | return 0; |
382 | } |
383 | |
384 | ret = af9005_get_pre_vit_err_bit_count(fe, pre_err_count: &state->pre_vit_error_count, |
385 | pre_bit_count: &state->pre_vit_bit_count); |
386 | if (ret == 0) { |
387 | af9005_reset_pre_viterbi(fe); |
388 | if (state->pre_vit_bit_count > 0) { |
389 | /* according to v 0.0.4 of the dvb api ber should be a multiple |
390 | of 10E-9 so we have to multiply the error count by |
391 | 10E9=1000000000 */ |
392 | numerator = |
393 | (u64) state->pre_vit_error_count * (u64) 1000000000; |
394 | denominator = (u64) state->pre_vit_bit_count; |
395 | state->ber = do_div(numerator, denominator); |
396 | } else { |
397 | state->ber = 0xffffffff; |
398 | } |
399 | } |
400 | |
401 | ret = af9005_get_post_vit_ber(fe, post_err_count: &state->post_vit_error_count, |
402 | post_cw_count: &state->post_vit_bit_count, |
403 | abort_count: &state->abort_count); |
404 | if (ret == 0) { |
405 | ret = af9005_reset_post_viterbi(fe); |
406 | state->unc += state->abort_count; |
407 | if (ret) |
408 | return ret; |
409 | } |
410 | return 0; |
411 | } |
412 | |
413 | static int af9005_fe_refresh_state(struct dvb_frontend *fe) |
414 | { |
415 | struct af9005_fe_state *state = fe->demodulator_priv; |
416 | if (time_after(jiffies, state->next_status_check)) { |
417 | deb_info("REFRESH STATE\n" ); |
418 | |
419 | /* statistics */ |
420 | if (af9005_get_statistic(fe)) |
421 | err("get_statistic_failed" ); |
422 | state->next_status_check = jiffies + 250 * HZ / 1000; |
423 | } |
424 | return 0; |
425 | } |
426 | |
427 | static int af9005_fe_read_status(struct dvb_frontend *fe, |
428 | enum fe_status *stat) |
429 | { |
430 | struct af9005_fe_state *state = fe->demodulator_priv; |
431 | u8 temp; |
432 | int ret; |
433 | |
434 | if (fe->ops.tuner_ops.release == NULL) |
435 | return -ENODEV; |
436 | |
437 | *stat = 0; |
438 | ret = af9005_read_register_bits(d: state->d, xd_p_agc_lock, |
439 | agc_lock_pos, agc_lock_len, value: &temp); |
440 | if (ret) |
441 | return ret; |
442 | if (temp) |
443 | *stat |= FE_HAS_SIGNAL; |
444 | |
445 | ret = af9005_read_register_bits(d: state->d, xd_p_fd_tpsd_lock, |
446 | fd_tpsd_lock_pos, fd_tpsd_lock_len, |
447 | value: &temp); |
448 | if (ret) |
449 | return ret; |
450 | if (temp) |
451 | *stat |= FE_HAS_CARRIER; |
452 | |
453 | ret = af9005_read_register_bits(d: state->d, |
454 | xd_r_mp2if_sync_byte_locked, |
455 | mp2if_sync_byte_locked_pos, |
456 | mp2if_sync_byte_locked_pos, value: &temp); |
457 | if (ret) |
458 | return ret; |
459 | if (temp) |
460 | *stat |= FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK; |
461 | if (state->opened) |
462 | af9005_led_control(d: state->d, onoff: *stat & FE_HAS_LOCK); |
463 | |
464 | ret = |
465 | af9005_read_register_bits(d: state->d, xd_p_reg_strong_sginal_detected, |
466 | reg_strong_sginal_detected_pos, |
467 | reg_strong_sginal_detected_len, value: &temp); |
468 | if (ret) |
469 | return ret; |
470 | if (temp != state->strong) { |
471 | deb_info("adjust for strong signal %d\n" , temp); |
472 | state->strong = temp; |
473 | } |
474 | return 0; |
475 | } |
476 | |
477 | static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber) |
478 | { |
479 | struct af9005_fe_state *state = fe->demodulator_priv; |
480 | if (fe->ops.tuner_ops.release == NULL) |
481 | return -ENODEV; |
482 | af9005_fe_refresh_state(fe); |
483 | *ber = state->ber; |
484 | return 0; |
485 | } |
486 | |
487 | static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) |
488 | { |
489 | struct af9005_fe_state *state = fe->demodulator_priv; |
490 | if (fe->ops.tuner_ops.release == NULL) |
491 | return -ENODEV; |
492 | af9005_fe_refresh_state(fe); |
493 | *unc = state->unc; |
494 | return 0; |
495 | } |
496 | |
497 | static int af9005_fe_read_signal_strength(struct dvb_frontend *fe, |
498 | u16 * strength) |
499 | { |
500 | struct af9005_fe_state *state = fe->demodulator_priv; |
501 | int ret; |
502 | u8 if_gain, rf_gain; |
503 | |
504 | if (fe->ops.tuner_ops.release == NULL) |
505 | return -ENODEV; |
506 | ret = |
507 | af9005_read_ofdm_register(d: state->d, xd_r_reg_aagc_rf_gain, |
508 | value: &rf_gain); |
509 | if (ret) |
510 | return ret; |
511 | ret = |
512 | af9005_read_ofdm_register(d: state->d, xd_r_reg_aagc_if_gain, |
513 | value: &if_gain); |
514 | if (ret) |
515 | return ret; |
516 | /* this value has no real meaning, but i don't have the tables that relate |
517 | the rf and if gain with the dbm, so I just scale the value */ |
518 | *strength = (512 - rf_gain - if_gain) << 7; |
519 | return 0; |
520 | } |
521 | |
522 | static int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr) |
523 | { |
524 | /* the snr can be derived from the ber and the modulation |
525 | but I don't think this kind of complex calculations belong |
526 | in the driver. I may be wrong.... */ |
527 | return -ENOSYS; |
528 | } |
529 | |
530 | static int af9005_fe_program_cfoe(struct dvb_usb_device *d, u32 bw) |
531 | { |
532 | u8 temp0, temp1, temp2, temp3, buf[4]; |
533 | int ret; |
534 | u32 NS_coeff1_2048Nu; |
535 | u32 NS_coeff1_8191Nu; |
536 | u32 NS_coeff1_8192Nu; |
537 | u32 NS_coeff1_8193Nu; |
538 | u32 NS_coeff2_2k; |
539 | u32 NS_coeff2_8k; |
540 | |
541 | switch (bw) { |
542 | case 6000000: |
543 | NS_coeff1_2048Nu = 0x2ADB6DC; |
544 | NS_coeff1_8191Nu = 0xAB7313; |
545 | NS_coeff1_8192Nu = 0xAB6DB7; |
546 | NS_coeff1_8193Nu = 0xAB685C; |
547 | NS_coeff2_2k = 0x156DB6E; |
548 | NS_coeff2_8k = 0x55B6DC; |
549 | break; |
550 | |
551 | case 7000000: |
552 | NS_coeff1_2048Nu = 0x3200001; |
553 | NS_coeff1_8191Nu = 0xC80640; |
554 | NS_coeff1_8192Nu = 0xC80000; |
555 | NS_coeff1_8193Nu = 0xC7F9C0; |
556 | NS_coeff2_2k = 0x1900000; |
557 | NS_coeff2_8k = 0x640000; |
558 | break; |
559 | |
560 | case 8000000: |
561 | NS_coeff1_2048Nu = 0x3924926; |
562 | NS_coeff1_8191Nu = 0xE4996E; |
563 | NS_coeff1_8192Nu = 0xE49249; |
564 | NS_coeff1_8193Nu = 0xE48B25; |
565 | NS_coeff2_2k = 0x1C92493; |
566 | NS_coeff2_8k = 0x724925; |
567 | break; |
568 | default: |
569 | err("Invalid bandwidth %d." , bw); |
570 | return -EINVAL; |
571 | } |
572 | |
573 | /* |
574 | * write NS_coeff1_2048Nu |
575 | */ |
576 | |
577 | temp0 = (u8) (NS_coeff1_2048Nu & 0x000000FF); |
578 | temp1 = (u8) ((NS_coeff1_2048Nu & 0x0000FF00) >> 8); |
579 | temp2 = (u8) ((NS_coeff1_2048Nu & 0x00FF0000) >> 16); |
580 | temp3 = (u8) ((NS_coeff1_2048Nu & 0x03000000) >> 24); |
581 | |
582 | /* big endian to make 8051 happy */ |
583 | buf[0] = temp3; |
584 | buf[1] = temp2; |
585 | buf[2] = temp1; |
586 | buf[3] = temp0; |
587 | |
588 | /* cfoe_NS_2k_coeff1_25_24 */ |
589 | ret = af9005_write_ofdm_register(d, reg: 0xAE00, value: buf[0]); |
590 | if (ret) |
591 | return ret; |
592 | |
593 | /* cfoe_NS_2k_coeff1_23_16 */ |
594 | ret = af9005_write_ofdm_register(d, reg: 0xAE01, value: buf[1]); |
595 | if (ret) |
596 | return ret; |
597 | |
598 | /* cfoe_NS_2k_coeff1_15_8 */ |
599 | ret = af9005_write_ofdm_register(d, reg: 0xAE02, value: buf[2]); |
600 | if (ret) |
601 | return ret; |
602 | |
603 | /* cfoe_NS_2k_coeff1_7_0 */ |
604 | ret = af9005_write_ofdm_register(d, reg: 0xAE03, value: buf[3]); |
605 | if (ret) |
606 | return ret; |
607 | |
608 | /* |
609 | * write NS_coeff2_2k |
610 | */ |
611 | |
612 | temp0 = (u8) ((NS_coeff2_2k & 0x0000003F)); |
613 | temp1 = (u8) ((NS_coeff2_2k & 0x00003FC0) >> 6); |
614 | temp2 = (u8) ((NS_coeff2_2k & 0x003FC000) >> 14); |
615 | temp3 = (u8) ((NS_coeff2_2k & 0x01C00000) >> 22); |
616 | |
617 | /* big endian to make 8051 happy */ |
618 | buf[0] = temp3; |
619 | buf[1] = temp2; |
620 | buf[2] = temp1; |
621 | buf[3] = temp0; |
622 | |
623 | ret = af9005_write_ofdm_register(d, reg: 0xAE04, value: buf[0]); |
624 | if (ret) |
625 | return ret; |
626 | |
627 | ret = af9005_write_ofdm_register(d, reg: 0xAE05, value: buf[1]); |
628 | if (ret) |
629 | return ret; |
630 | |
631 | ret = af9005_write_ofdm_register(d, reg: 0xAE06, value: buf[2]); |
632 | if (ret) |
633 | return ret; |
634 | |
635 | ret = af9005_write_ofdm_register(d, reg: 0xAE07, value: buf[3]); |
636 | if (ret) |
637 | return ret; |
638 | |
639 | /* |
640 | * write NS_coeff1_8191Nu |
641 | */ |
642 | |
643 | temp0 = (u8) ((NS_coeff1_8191Nu & 0x000000FF)); |
644 | temp1 = (u8) ((NS_coeff1_8191Nu & 0x0000FF00) >> 8); |
645 | temp2 = (u8) ((NS_coeff1_8191Nu & 0x00FFC000) >> 16); |
646 | temp3 = (u8) ((NS_coeff1_8191Nu & 0x03000000) >> 24); |
647 | |
648 | /* big endian to make 8051 happy */ |
649 | buf[0] = temp3; |
650 | buf[1] = temp2; |
651 | buf[2] = temp1; |
652 | buf[3] = temp0; |
653 | |
654 | ret = af9005_write_ofdm_register(d, reg: 0xAE08, value: buf[0]); |
655 | if (ret) |
656 | return ret; |
657 | |
658 | ret = af9005_write_ofdm_register(d, reg: 0xAE09, value: buf[1]); |
659 | if (ret) |
660 | return ret; |
661 | |
662 | ret = af9005_write_ofdm_register(d, reg: 0xAE0A, value: buf[2]); |
663 | if (ret) |
664 | return ret; |
665 | |
666 | ret = af9005_write_ofdm_register(d, reg: 0xAE0B, value: buf[3]); |
667 | if (ret) |
668 | return ret; |
669 | |
670 | /* |
671 | * write NS_coeff1_8192Nu |
672 | */ |
673 | |
674 | temp0 = (u8) (NS_coeff1_8192Nu & 0x000000FF); |
675 | temp1 = (u8) ((NS_coeff1_8192Nu & 0x0000FF00) >> 8); |
676 | temp2 = (u8) ((NS_coeff1_8192Nu & 0x00FFC000) >> 16); |
677 | temp3 = (u8) ((NS_coeff1_8192Nu & 0x03000000) >> 24); |
678 | |
679 | /* big endian to make 8051 happy */ |
680 | buf[0] = temp3; |
681 | buf[1] = temp2; |
682 | buf[2] = temp1; |
683 | buf[3] = temp0; |
684 | |
685 | ret = af9005_write_ofdm_register(d, reg: 0xAE0C, value: buf[0]); |
686 | if (ret) |
687 | return ret; |
688 | |
689 | ret = af9005_write_ofdm_register(d, reg: 0xAE0D, value: buf[1]); |
690 | if (ret) |
691 | return ret; |
692 | |
693 | ret = af9005_write_ofdm_register(d, reg: 0xAE0E, value: buf[2]); |
694 | if (ret) |
695 | return ret; |
696 | |
697 | ret = af9005_write_ofdm_register(d, reg: 0xAE0F, value: buf[3]); |
698 | if (ret) |
699 | return ret; |
700 | |
701 | /* |
702 | * write NS_coeff1_8193Nu |
703 | */ |
704 | |
705 | temp0 = (u8) ((NS_coeff1_8193Nu & 0x000000FF)); |
706 | temp1 = (u8) ((NS_coeff1_8193Nu & 0x0000FF00) >> 8); |
707 | temp2 = (u8) ((NS_coeff1_8193Nu & 0x00FFC000) >> 16); |
708 | temp3 = (u8) ((NS_coeff1_8193Nu & 0x03000000) >> 24); |
709 | |
710 | /* big endian to make 8051 happy */ |
711 | buf[0] = temp3; |
712 | buf[1] = temp2; |
713 | buf[2] = temp1; |
714 | buf[3] = temp0; |
715 | |
716 | ret = af9005_write_ofdm_register(d, reg: 0xAE10, value: buf[0]); |
717 | if (ret) |
718 | return ret; |
719 | |
720 | ret = af9005_write_ofdm_register(d, reg: 0xAE11, value: buf[1]); |
721 | if (ret) |
722 | return ret; |
723 | |
724 | ret = af9005_write_ofdm_register(d, reg: 0xAE12, value: buf[2]); |
725 | if (ret) |
726 | return ret; |
727 | |
728 | ret = af9005_write_ofdm_register(d, reg: 0xAE13, value: buf[3]); |
729 | if (ret) |
730 | return ret; |
731 | |
732 | /* |
733 | * write NS_coeff2_8k |
734 | */ |
735 | |
736 | temp0 = (u8) ((NS_coeff2_8k & 0x0000003F)); |
737 | temp1 = (u8) ((NS_coeff2_8k & 0x00003FC0) >> 6); |
738 | temp2 = (u8) ((NS_coeff2_8k & 0x003FC000) >> 14); |
739 | temp3 = (u8) ((NS_coeff2_8k & 0x01C00000) >> 22); |
740 | |
741 | /* big endian to make 8051 happy */ |
742 | buf[0] = temp3; |
743 | buf[1] = temp2; |
744 | buf[2] = temp1; |
745 | buf[3] = temp0; |
746 | |
747 | ret = af9005_write_ofdm_register(d, reg: 0xAE14, value: buf[0]); |
748 | if (ret) |
749 | return ret; |
750 | |
751 | ret = af9005_write_ofdm_register(d, reg: 0xAE15, value: buf[1]); |
752 | if (ret) |
753 | return ret; |
754 | |
755 | ret = af9005_write_ofdm_register(d, reg: 0xAE16, value: buf[2]); |
756 | if (ret) |
757 | return ret; |
758 | |
759 | ret = af9005_write_ofdm_register(d, reg: 0xAE17, value: buf[3]); |
760 | return ret; |
761 | |
762 | } |
763 | |
764 | static int af9005_fe_select_bw(struct dvb_usb_device *d, u32 bw) |
765 | { |
766 | u8 temp; |
767 | switch (bw) { |
768 | case 6000000: |
769 | temp = 0; |
770 | break; |
771 | case 7000000: |
772 | temp = 1; |
773 | break; |
774 | case 8000000: |
775 | temp = 2; |
776 | break; |
777 | default: |
778 | err("Invalid bandwidth %d." , bw); |
779 | return -EINVAL; |
780 | } |
781 | return af9005_write_register_bits(d, xd_g_reg_bw, reg_bw_pos, |
782 | reg_bw_len, value: temp); |
783 | } |
784 | |
785 | static int af9005_fe_power(struct dvb_frontend *fe, int on) |
786 | { |
787 | struct af9005_fe_state *state = fe->demodulator_priv; |
788 | u8 temp = on; |
789 | int ret; |
790 | deb_info("power %s tuner\n" , on ? "on" : "off" ); |
791 | ret = af9005_send_command(d: state->d, command: 0x03, wbuf: &temp, wlen: 1, NULL, rlen: 0); |
792 | return ret; |
793 | } |
794 | |
795 | static struct mt2060_config af9005_mt2060_config = { |
796 | 0xC0 |
797 | }; |
798 | |
799 | static struct qt1010_config af9005_qt1010_config = { |
800 | 0xC4 |
801 | }; |
802 | |
803 | static int af9005_fe_init(struct dvb_frontend *fe) |
804 | { |
805 | struct af9005_fe_state *state = fe->demodulator_priv; |
806 | struct dvb_usb_adapter *adap = fe->dvb->priv; |
807 | int ret, i, scriptlen; |
808 | u8 temp, temp0 = 0, temp1 = 0, temp2 = 0; |
809 | u8 buf[2]; |
810 | u16 if1; |
811 | |
812 | deb_info("in af9005_fe_init\n" ); |
813 | |
814 | /* reset */ |
815 | deb_info("reset\n" ); |
816 | if ((ret = |
817 | af9005_write_register_bits(d: state->d, xd_I2C_reg_ofdm_rst_en, |
818 | pos: 4, len: 1, value: 0x01))) |
819 | return ret; |
820 | if ((ret = af9005_write_ofdm_register(d: state->d, APO_REG_RESET, value: 0))) |
821 | return ret; |
822 | /* clear ofdm reset */ |
823 | deb_info("clear ofdm reset\n" ); |
824 | for (i = 0; i < 150; i++) { |
825 | if ((ret = |
826 | af9005_read_ofdm_register(d: state->d, |
827 | xd_I2C_reg_ofdm_rst, value: &temp))) |
828 | return ret; |
829 | if (temp & (regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos)) |
830 | break; |
831 | msleep(msecs: 10); |
832 | } |
833 | if (i == 150) |
834 | return -ETIMEDOUT; |
835 | |
836 | /*FIXME in the dump |
837 | write B200 A9 |
838 | write xd_g_reg_ofsm_clk 7 |
839 | read eepr c6 (2) |
840 | read eepr c7 (2) |
841 | misc ctrl 3 -> 1 |
842 | read eepr ca (6) |
843 | write xd_g_reg_ofsm_clk 0 |
844 | write B200 a1 |
845 | */ |
846 | ret = af9005_write_ofdm_register(d: state->d, reg: 0xb200, value: 0xa9); |
847 | if (ret) |
848 | return ret; |
849 | ret = af9005_write_ofdm_register(d: state->d, xd_g_reg_ofsm_clk, value: 0x07); |
850 | if (ret) |
851 | return ret; |
852 | temp = 0x01; |
853 | ret = af9005_send_command(d: state->d, command: 0x03, wbuf: &temp, wlen: 1, NULL, rlen: 0); |
854 | if (ret) |
855 | return ret; |
856 | ret = af9005_write_ofdm_register(d: state->d, xd_g_reg_ofsm_clk, value: 0x00); |
857 | if (ret) |
858 | return ret; |
859 | ret = af9005_write_ofdm_register(d: state->d, reg: 0xb200, value: 0xa1); |
860 | if (ret) |
861 | return ret; |
862 | |
863 | temp = regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos; |
864 | if ((ret = |
865 | af9005_write_register_bits(d: state->d, xd_I2C_reg_ofdm_rst, |
866 | reg_ofdm_rst_pos, reg_ofdm_rst_len, value: 1))) |
867 | return ret; |
868 | ret = af9005_write_register_bits(d: state->d, xd_I2C_reg_ofdm_rst, |
869 | reg_ofdm_rst_pos, reg_ofdm_rst_len, value: 0); |
870 | |
871 | if (ret) |
872 | return ret; |
873 | /* don't know what register aefc is, but this is what the windows driver does */ |
874 | ret = af9005_write_ofdm_register(d: state->d, reg: 0xaefc, value: 0); |
875 | if (ret) |
876 | return ret; |
877 | |
878 | /* set stand alone chip */ |
879 | deb_info("set stand alone chip\n" ); |
880 | if ((ret = |
881 | af9005_write_register_bits(d: state->d, xd_p_reg_dca_stand_alone, |
882 | reg_dca_stand_alone_pos, |
883 | reg_dca_stand_alone_len, value: 1))) |
884 | return ret; |
885 | |
886 | /* set dca upper & lower chip */ |
887 | deb_info("set dca upper & lower chip\n" ); |
888 | if ((ret = |
889 | af9005_write_register_bits(d: state->d, xd_p_reg_dca_upper_chip, |
890 | reg_dca_upper_chip_pos, |
891 | reg_dca_upper_chip_len, value: 0))) |
892 | return ret; |
893 | if ((ret = |
894 | af9005_write_register_bits(d: state->d, xd_p_reg_dca_lower_chip, |
895 | reg_dca_lower_chip_pos, |
896 | reg_dca_lower_chip_len, value: 0))) |
897 | return ret; |
898 | |
899 | /* set 2wire master clock to 0x14 (for 60KHz) */ |
900 | deb_info("set 2wire master clock to 0x14 (for 60KHz)\n" ); |
901 | if ((ret = |
902 | af9005_write_ofdm_register(d: state->d, xd_I2C_i2c_m_period, value: 0x14))) |
903 | return ret; |
904 | |
905 | /* clear dca enable chip */ |
906 | deb_info("clear dca enable chip\n" ); |
907 | if ((ret = |
908 | af9005_write_register_bits(d: state->d, xd_p_reg_dca_en, |
909 | reg_dca_en_pos, reg_dca_en_len, value: 0))) |
910 | return ret; |
911 | /* FIXME these are register bits, but I don't know which ones */ |
912 | ret = af9005_write_ofdm_register(d: state->d, reg: 0xa16c, value: 1); |
913 | if (ret) |
914 | return ret; |
915 | ret = af9005_write_ofdm_register(d: state->d, reg: 0xa3c1, value: 0); |
916 | if (ret) |
917 | return ret; |
918 | |
919 | /* init other parameters: program cfoe and select bandwidth */ |
920 | deb_info("program cfoe\n" ); |
921 | ret = af9005_fe_program_cfoe(d: state->d, bw: 6000000); |
922 | if (ret) |
923 | return ret; |
924 | /* set read-update bit for modulation */ |
925 | deb_info("set read-update bit for modulation\n" ); |
926 | if ((ret = |
927 | af9005_write_register_bits(d: state->d, xd_p_reg_feq_read_update, |
928 | reg_feq_read_update_pos, |
929 | reg_feq_read_update_len, value: 1))) |
930 | return ret; |
931 | |
932 | /* sample code has a set MPEG TS code here |
933 | but sniffing reveals that it doesn't do it */ |
934 | |
935 | /* set read-update bit to 1 for DCA modulation */ |
936 | deb_info("set read-update bit 1 for DCA modulation\n" ); |
937 | if ((ret = |
938 | af9005_write_register_bits(d: state->d, xd_p_reg_dca_read_update, |
939 | reg_dca_read_update_pos, |
940 | reg_dca_read_update_len, value: 1))) |
941 | return ret; |
942 | |
943 | /* enable fec monitor */ |
944 | deb_info("enable fec monitor\n" ); |
945 | if ((ret = |
946 | af9005_write_register_bits(d: state->d, xd_p_fec_vtb_rsd_mon_en, |
947 | fec_vtb_rsd_mon_en_pos, |
948 | fec_vtb_rsd_mon_en_len, value: 1))) |
949 | return ret; |
950 | |
951 | /* FIXME should be register bits, I don't know which ones */ |
952 | ret = af9005_write_ofdm_register(d: state->d, reg: 0xa601, value: 0); |
953 | |
954 | /* set api_retrain_never_freeze */ |
955 | deb_info("set api_retrain_never_freeze\n" ); |
956 | if ((ret = af9005_write_ofdm_register(d: state->d, reg: 0xaefb, value: 0x01))) |
957 | return ret; |
958 | |
959 | /* load init script */ |
960 | deb_info("load init script\n" ); |
961 | scriptlen = sizeof(script) / sizeof(RegDesc); |
962 | for (i = 0; i < scriptlen; i++) { |
963 | if ((ret = |
964 | af9005_write_register_bits(d: state->d, reg: script[i].reg, |
965 | pos: script[i].pos, |
966 | len: script[i].len, value: script[i].val))) |
967 | return ret; |
968 | /* save 3 bytes of original fcw */ |
969 | if (script[i].reg == 0xae18) |
970 | temp2 = script[i].val; |
971 | if (script[i].reg == 0xae19) |
972 | temp1 = script[i].val; |
973 | if (script[i].reg == 0xae1a) |
974 | temp0 = script[i].val; |
975 | |
976 | /* save original unplug threshold */ |
977 | if (script[i].reg == xd_p_reg_unplug_th) |
978 | state->original_if_unplug_th = script[i].val; |
979 | if (script[i].reg == xd_p_reg_unplug_rf_gain_th) |
980 | state->original_rf_unplug_th = script[i].val; |
981 | if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th) |
982 | state->original_dtop_if_unplug_th = script[i].val; |
983 | if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th) |
984 | state->original_dtop_rf_unplug_th = script[i].val; |
985 | |
986 | } |
987 | state->original_fcw = |
988 | ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0; |
989 | |
990 | |
991 | /* save original TOPs */ |
992 | deb_info("save original TOPs\n" ); |
993 | |
994 | /* RF TOP */ |
995 | ret = |
996 | af9005_read_word_agc(d: state->d, |
997 | xd_p_reg_aagc_rf_top_numerator_9_8, |
998 | xd_p_reg_aagc_rf_top_numerator_7_0, pos: 0, len: 2, |
999 | value: &state->original_rf_top); |
1000 | if (ret) |
1001 | return ret; |
1002 | |
1003 | /* IF TOP */ |
1004 | ret = |
1005 | af9005_read_word_agc(d: state->d, |
1006 | xd_p_reg_aagc_if_top_numerator_9_8, |
1007 | xd_p_reg_aagc_if_top_numerator_7_0, pos: 0, len: 2, |
1008 | value: &state->original_if_top); |
1009 | if (ret) |
1010 | return ret; |
1011 | |
1012 | /* ACI 0 IF TOP */ |
1013 | ret = |
1014 | af9005_read_word_agc(d: state->d, reghi: 0xA60E, reglo: 0xA60A, pos: 4, len: 2, |
1015 | value: &state->original_aci0_if_top); |
1016 | if (ret) |
1017 | return ret; |
1018 | |
1019 | /* ACI 1 IF TOP */ |
1020 | ret = |
1021 | af9005_read_word_agc(d: state->d, reghi: 0xA60E, reglo: 0xA60B, pos: 6, len: 2, |
1022 | value: &state->original_aci1_if_top); |
1023 | if (ret) |
1024 | return ret; |
1025 | |
1026 | /* attach tuner and init */ |
1027 | if (fe->ops.tuner_ops.release == NULL) { |
1028 | /* read tuner and board id from eeprom */ |
1029 | ret = af9005_read_eeprom(d: adap->dev, address: 0xc6, values: buf, len: 2); |
1030 | if (ret) { |
1031 | err("Impossible to read EEPROM\n" ); |
1032 | return ret; |
1033 | } |
1034 | deb_info("Tuner id %d, board id %d\n" , buf[0], buf[1]); |
1035 | switch (buf[0]) { |
1036 | case 2: /* MT2060 */ |
1037 | /* read if1 from eeprom */ |
1038 | ret = af9005_read_eeprom(d: adap->dev, address: 0xc8, values: buf, len: 2); |
1039 | if (ret) { |
1040 | err("Impossible to read EEPROM\n" ); |
1041 | return ret; |
1042 | } |
1043 | if1 = (u16) (buf[0] << 8) + buf[1]; |
1044 | if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap, |
1045 | &af9005_mt2060_config, if1) == NULL) { |
1046 | deb_info("MT2060 attach failed\n" ); |
1047 | return -ENODEV; |
1048 | } |
1049 | break; |
1050 | case 3: /* QT1010 */ |
1051 | case 9: /* QT1010B */ |
1052 | if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap, |
1053 | &af9005_qt1010_config) ==NULL) { |
1054 | deb_info("QT1010 attach failed\n" ); |
1055 | return -ENODEV; |
1056 | } |
1057 | break; |
1058 | default: |
1059 | err("Unsupported tuner type %d" , buf[0]); |
1060 | return -ENODEV; |
1061 | } |
1062 | ret = fe->ops.tuner_ops.init(fe); |
1063 | if (ret) |
1064 | return ret; |
1065 | } |
1066 | |
1067 | deb_info("profit!\n" ); |
1068 | return 0; |
1069 | } |
1070 | |
1071 | static int af9005_fe_sleep(struct dvb_frontend *fe) |
1072 | { |
1073 | return af9005_fe_power(fe, on: 0); |
1074 | } |
1075 | |
1076 | static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) |
1077 | { |
1078 | struct af9005_fe_state *state = fe->demodulator_priv; |
1079 | |
1080 | if (acquire) { |
1081 | state->opened++; |
1082 | } else { |
1083 | |
1084 | state->opened--; |
1085 | if (!state->opened) |
1086 | af9005_led_control(d: state->d, onoff: 0); |
1087 | } |
1088 | return 0; |
1089 | } |
1090 | |
1091 | static int af9005_fe_set_frontend(struct dvb_frontend *fe) |
1092 | { |
1093 | struct dtv_frontend_properties *fep = &fe->dtv_property_cache; |
1094 | struct af9005_fe_state *state = fe->demodulator_priv; |
1095 | int ret; |
1096 | u8 temp, temp0, temp1, temp2; |
1097 | |
1098 | deb_info("af9005_fe_set_frontend freq %d bw %d\n" , fep->frequency, |
1099 | fep->bandwidth_hz); |
1100 | if (fe->ops.tuner_ops.release == NULL) { |
1101 | err("Tuner not attached" ); |
1102 | return -ENODEV; |
1103 | } |
1104 | |
1105 | deb_info("turn off led\n" ); |
1106 | /* not in the log */ |
1107 | ret = af9005_led_control(d: state->d, onoff: 0); |
1108 | if (ret) |
1109 | return ret; |
1110 | /* not sure about the bits */ |
1111 | ret = af9005_write_register_bits(d: state->d, XD_MP2IF_MISC, pos: 2, len: 1, value: 0); |
1112 | if (ret) |
1113 | return ret; |
1114 | |
1115 | /* set FCW to default value */ |
1116 | deb_info("set FCW to default value\n" ); |
1117 | temp0 = (u8) (state->original_fcw & 0x000000ff); |
1118 | temp1 = (u8) ((state->original_fcw & 0x0000ff00) >> 8); |
1119 | temp2 = (u8) ((state->original_fcw & 0x00ff0000) >> 16); |
1120 | ret = af9005_write_ofdm_register(d: state->d, reg: 0xae1a, value: temp0); |
1121 | if (ret) |
1122 | return ret; |
1123 | ret = af9005_write_ofdm_register(d: state->d, reg: 0xae19, value: temp1); |
1124 | if (ret) |
1125 | return ret; |
1126 | ret = af9005_write_ofdm_register(d: state->d, reg: 0xae18, value: temp2); |
1127 | if (ret) |
1128 | return ret; |
1129 | |
1130 | /* restore original TOPs */ |
1131 | deb_info("restore original TOPs\n" ); |
1132 | ret = |
1133 | af9005_write_word_agc(d: state->d, |
1134 | xd_p_reg_aagc_rf_top_numerator_9_8, |
1135 | xd_p_reg_aagc_rf_top_numerator_7_0, pos: 0, len: 2, |
1136 | value: state->original_rf_top); |
1137 | if (ret) |
1138 | return ret; |
1139 | ret = |
1140 | af9005_write_word_agc(d: state->d, |
1141 | xd_p_reg_aagc_if_top_numerator_9_8, |
1142 | xd_p_reg_aagc_if_top_numerator_7_0, pos: 0, len: 2, |
1143 | value: state->original_if_top); |
1144 | if (ret) |
1145 | return ret; |
1146 | ret = |
1147 | af9005_write_word_agc(d: state->d, reghi: 0xA60E, reglo: 0xA60A, pos: 4, len: 2, |
1148 | value: state->original_aci0_if_top); |
1149 | if (ret) |
1150 | return ret; |
1151 | ret = |
1152 | af9005_write_word_agc(d: state->d, reghi: 0xA60E, reglo: 0xA60B, pos: 6, len: 2, |
1153 | value: state->original_aci1_if_top); |
1154 | if (ret) |
1155 | return ret; |
1156 | |
1157 | /* select bandwidth */ |
1158 | deb_info("select bandwidth" ); |
1159 | ret = af9005_fe_select_bw(d: state->d, bw: fep->bandwidth_hz); |
1160 | if (ret) |
1161 | return ret; |
1162 | ret = af9005_fe_program_cfoe(d: state->d, bw: fep->bandwidth_hz); |
1163 | if (ret) |
1164 | return ret; |
1165 | |
1166 | /* clear easy mode flag */ |
1167 | deb_info("clear easy mode flag\n" ); |
1168 | ret = af9005_write_ofdm_register(d: state->d, reg: 0xaefd, value: 0); |
1169 | if (ret) |
1170 | return ret; |
1171 | |
1172 | /* set unplug threshold to original value */ |
1173 | deb_info("set unplug threshold to original value\n" ); |
1174 | ret = |
1175 | af9005_write_ofdm_register(d: state->d, xd_p_reg_unplug_th, |
1176 | value: state->original_if_unplug_th); |
1177 | if (ret) |
1178 | return ret; |
1179 | /* set tuner */ |
1180 | deb_info("set tuner\n" ); |
1181 | ret = fe->ops.tuner_ops.set_params(fe); |
1182 | if (ret) |
1183 | return ret; |
1184 | |
1185 | /* trigger ofsm */ |
1186 | deb_info("trigger ofsm\n" ); |
1187 | temp = 0; |
1188 | ret = af9005_write_tuner_registers(d: state->d, reg: 0xffff, values: &temp, len: 1); |
1189 | if (ret) |
1190 | return ret; |
1191 | |
1192 | /* clear retrain and freeze flag */ |
1193 | deb_info("clear retrain and freeze flag\n" ); |
1194 | ret = |
1195 | af9005_write_register_bits(d: state->d, |
1196 | xd_p_reg_api_retrain_request, |
1197 | reg_api_retrain_request_pos, len: 2, value: 0); |
1198 | if (ret) |
1199 | return ret; |
1200 | |
1201 | /* reset pre viterbi and post viterbi registers and statistics */ |
1202 | af9005_reset_pre_viterbi(fe); |
1203 | af9005_reset_post_viterbi(fe); |
1204 | state->pre_vit_error_count = 0; |
1205 | state->pre_vit_bit_count = 0; |
1206 | state->ber = 0; |
1207 | state->post_vit_error_count = 0; |
1208 | /* state->unc = 0; commented out since it should be ever increasing */ |
1209 | state->abort_count = 0; |
1210 | |
1211 | state->next_status_check = jiffies; |
1212 | state->strong = -1; |
1213 | |
1214 | return 0; |
1215 | } |
1216 | |
1217 | static int af9005_fe_get_frontend(struct dvb_frontend *fe, |
1218 | struct dtv_frontend_properties *fep) |
1219 | { |
1220 | struct af9005_fe_state *state = fe->demodulator_priv; |
1221 | int ret; |
1222 | u8 temp; |
1223 | |
1224 | /* mode */ |
1225 | ret = |
1226 | af9005_read_register_bits(d: state->d, xd_g_reg_tpsd_const, |
1227 | reg_tpsd_const_pos, reg_tpsd_const_len, |
1228 | value: &temp); |
1229 | if (ret) |
1230 | return ret; |
1231 | deb_info("===== fe_get_frontend_legacy = =============\n" ); |
1232 | deb_info("CONSTELLATION " ); |
1233 | switch (temp) { |
1234 | case 0: |
1235 | fep->modulation = QPSK; |
1236 | deb_info("QPSK\n" ); |
1237 | break; |
1238 | case 1: |
1239 | fep->modulation = QAM_16; |
1240 | deb_info("QAM_16\n" ); |
1241 | break; |
1242 | case 2: |
1243 | fep->modulation = QAM_64; |
1244 | deb_info("QAM_64\n" ); |
1245 | break; |
1246 | } |
1247 | |
1248 | /* tps hierarchy and alpha value */ |
1249 | ret = |
1250 | af9005_read_register_bits(d: state->d, xd_g_reg_tpsd_hier, |
1251 | reg_tpsd_hier_pos, reg_tpsd_hier_len, |
1252 | value: &temp); |
1253 | if (ret) |
1254 | return ret; |
1255 | deb_info("HIERARCHY " ); |
1256 | switch (temp) { |
1257 | case 0: |
1258 | fep->hierarchy = HIERARCHY_NONE; |
1259 | deb_info("NONE\n" ); |
1260 | break; |
1261 | case 1: |
1262 | fep->hierarchy = HIERARCHY_1; |
1263 | deb_info("1\n" ); |
1264 | break; |
1265 | case 2: |
1266 | fep->hierarchy = HIERARCHY_2; |
1267 | deb_info("2\n" ); |
1268 | break; |
1269 | case 3: |
1270 | fep->hierarchy = HIERARCHY_4; |
1271 | deb_info("4\n" ); |
1272 | break; |
1273 | } |
1274 | |
1275 | /* high/low priority */ |
1276 | ret = |
1277 | af9005_read_register_bits(d: state->d, xd_g_reg_dec_pri, |
1278 | reg_dec_pri_pos, reg_dec_pri_len, value: &temp); |
1279 | if (ret) |
1280 | return ret; |
1281 | /* if temp is set = high priority */ |
1282 | deb_info("PRIORITY %s\n" , temp ? "high" : "low" ); |
1283 | |
1284 | /* high coderate */ |
1285 | ret = |
1286 | af9005_read_register_bits(d: state->d, xd_g_reg_tpsd_hpcr, |
1287 | reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len, |
1288 | value: &temp); |
1289 | if (ret) |
1290 | return ret; |
1291 | deb_info("CODERATE HP " ); |
1292 | switch (temp) { |
1293 | case 0: |
1294 | fep->code_rate_HP = FEC_1_2; |
1295 | deb_info("FEC_1_2\n" ); |
1296 | break; |
1297 | case 1: |
1298 | fep->code_rate_HP = FEC_2_3; |
1299 | deb_info("FEC_2_3\n" ); |
1300 | break; |
1301 | case 2: |
1302 | fep->code_rate_HP = FEC_3_4; |
1303 | deb_info("FEC_3_4\n" ); |
1304 | break; |
1305 | case 3: |
1306 | fep->code_rate_HP = FEC_5_6; |
1307 | deb_info("FEC_5_6\n" ); |
1308 | break; |
1309 | case 4: |
1310 | fep->code_rate_HP = FEC_7_8; |
1311 | deb_info("FEC_7_8\n" ); |
1312 | break; |
1313 | } |
1314 | |
1315 | /* low coderate */ |
1316 | ret = |
1317 | af9005_read_register_bits(d: state->d, xd_g_reg_tpsd_lpcr, |
1318 | reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len, |
1319 | value: &temp); |
1320 | if (ret) |
1321 | return ret; |
1322 | deb_info("CODERATE LP " ); |
1323 | switch (temp) { |
1324 | case 0: |
1325 | fep->code_rate_LP = FEC_1_2; |
1326 | deb_info("FEC_1_2\n" ); |
1327 | break; |
1328 | case 1: |
1329 | fep->code_rate_LP = FEC_2_3; |
1330 | deb_info("FEC_2_3\n" ); |
1331 | break; |
1332 | case 2: |
1333 | fep->code_rate_LP = FEC_3_4; |
1334 | deb_info("FEC_3_4\n" ); |
1335 | break; |
1336 | case 3: |
1337 | fep->code_rate_LP = FEC_5_6; |
1338 | deb_info("FEC_5_6\n" ); |
1339 | break; |
1340 | case 4: |
1341 | fep->code_rate_LP = FEC_7_8; |
1342 | deb_info("FEC_7_8\n" ); |
1343 | break; |
1344 | } |
1345 | |
1346 | /* guard interval */ |
1347 | ret = |
1348 | af9005_read_register_bits(d: state->d, xd_g_reg_tpsd_gi, |
1349 | reg_tpsd_gi_pos, reg_tpsd_gi_len, value: &temp); |
1350 | if (ret) |
1351 | return ret; |
1352 | deb_info("GUARD INTERVAL " ); |
1353 | switch (temp) { |
1354 | case 0: |
1355 | fep->guard_interval = GUARD_INTERVAL_1_32; |
1356 | deb_info("1_32\n" ); |
1357 | break; |
1358 | case 1: |
1359 | fep->guard_interval = GUARD_INTERVAL_1_16; |
1360 | deb_info("1_16\n" ); |
1361 | break; |
1362 | case 2: |
1363 | fep->guard_interval = GUARD_INTERVAL_1_8; |
1364 | deb_info("1_8\n" ); |
1365 | break; |
1366 | case 3: |
1367 | fep->guard_interval = GUARD_INTERVAL_1_4; |
1368 | deb_info("1_4\n" ); |
1369 | break; |
1370 | } |
1371 | |
1372 | /* fft */ |
1373 | ret = |
1374 | af9005_read_register_bits(d: state->d, xd_g_reg_tpsd_txmod, |
1375 | reg_tpsd_txmod_pos, reg_tpsd_txmod_len, |
1376 | value: &temp); |
1377 | if (ret) |
1378 | return ret; |
1379 | deb_info("TRANSMISSION MODE " ); |
1380 | switch (temp) { |
1381 | case 0: |
1382 | fep->transmission_mode = TRANSMISSION_MODE_2K; |
1383 | deb_info("2K\n" ); |
1384 | break; |
1385 | case 1: |
1386 | fep->transmission_mode = TRANSMISSION_MODE_8K; |
1387 | deb_info("8K\n" ); |
1388 | break; |
1389 | } |
1390 | |
1391 | /* bandwidth */ |
1392 | ret = |
1393 | af9005_read_register_bits(d: state->d, xd_g_reg_bw, reg_bw_pos, |
1394 | reg_bw_len, value: &temp); |
1395 | deb_info("BANDWIDTH " ); |
1396 | switch (temp) { |
1397 | case 0: |
1398 | fep->bandwidth_hz = 6000000; |
1399 | deb_info("6\n" ); |
1400 | break; |
1401 | case 1: |
1402 | fep->bandwidth_hz = 7000000; |
1403 | deb_info("7\n" ); |
1404 | break; |
1405 | case 2: |
1406 | fep->bandwidth_hz = 8000000; |
1407 | deb_info("8\n" ); |
1408 | break; |
1409 | } |
1410 | return 0; |
1411 | } |
1412 | |
1413 | static void af9005_fe_release(struct dvb_frontend *fe) |
1414 | { |
1415 | struct af9005_fe_state *state = fe->demodulator_priv; |
1416 | kfree(objp: state); |
1417 | } |
1418 | |
1419 | static const struct dvb_frontend_ops af9005_fe_ops; |
1420 | |
1421 | struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) |
1422 | { |
1423 | struct af9005_fe_state *state = NULL; |
1424 | |
1425 | /* allocate memory for the internal state */ |
1426 | state = kzalloc(size: sizeof(struct af9005_fe_state), GFP_KERNEL); |
1427 | if (state == NULL) |
1428 | goto error; |
1429 | |
1430 | deb_info("attaching frontend af9005\n" ); |
1431 | |
1432 | state->d = d; |
1433 | state->opened = 0; |
1434 | |
1435 | memcpy(&state->frontend.ops, &af9005_fe_ops, |
1436 | sizeof(struct dvb_frontend_ops)); |
1437 | state->frontend.demodulator_priv = state; |
1438 | |
1439 | return &state->frontend; |
1440 | error: |
1441 | return NULL; |
1442 | } |
1443 | |
1444 | static const struct dvb_frontend_ops af9005_fe_ops = { |
1445 | .delsys = { SYS_DVBT }, |
1446 | .info = { |
1447 | .name = "AF9005 USB DVB-T" , |
1448 | .frequency_min_hz = 44250 * kHz, |
1449 | .frequency_max_hz = 867250 * kHz, |
1450 | .frequency_stepsize_hz = 250 * kHz, |
1451 | .caps = FE_CAN_INVERSION_AUTO | |
1452 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
1453 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
1454 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | |
1455 | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | |
1456 | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | |
1457 | FE_CAN_HIERARCHY_AUTO, |
1458 | }, |
1459 | |
1460 | .release = af9005_fe_release, |
1461 | |
1462 | .init = af9005_fe_init, |
1463 | .sleep = af9005_fe_sleep, |
1464 | .ts_bus_ctrl = af9005_ts_bus_ctrl, |
1465 | |
1466 | .set_frontend = af9005_fe_set_frontend, |
1467 | .get_frontend = af9005_fe_get_frontend, |
1468 | |
1469 | .read_status = af9005_fe_read_status, |
1470 | .read_ber = af9005_fe_read_ber, |
1471 | .read_signal_strength = af9005_fe_read_signal_strength, |
1472 | .read_snr = af9005_fe_read_snr, |
1473 | .read_ucblocks = af9005_fe_read_unc_blocks, |
1474 | }; |
1475 | |