18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* Frontend part of the Linux driver for the Afatech 9005 38c2ecf20Sopenharmony_ci * USB1.1 DVB-T receiver. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Thanks to Afatech who kindly provided information. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci#include "af9005.h" 128c2ecf20Sopenharmony_ci#include "af9005-script.h" 138c2ecf20Sopenharmony_ci#include "mt2060.h" 148c2ecf20Sopenharmony_ci#include "qt1010.h" 158c2ecf20Sopenharmony_ci#include <asm/div64.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistruct af9005_fe_state { 188c2ecf20Sopenharmony_ci struct dvb_usb_device *d; 198c2ecf20Sopenharmony_ci enum fe_status stat; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci /* retraining parameters */ 228c2ecf20Sopenharmony_ci u32 original_fcw; 238c2ecf20Sopenharmony_ci u16 original_rf_top; 248c2ecf20Sopenharmony_ci u16 original_if_top; 258c2ecf20Sopenharmony_ci u16 original_if_min; 268c2ecf20Sopenharmony_ci u16 original_aci0_if_top; 278c2ecf20Sopenharmony_ci u16 original_aci1_if_top; 288c2ecf20Sopenharmony_ci u16 original_aci0_if_min; 298c2ecf20Sopenharmony_ci u8 original_if_unplug_th; 308c2ecf20Sopenharmony_ci u8 original_rf_unplug_th; 318c2ecf20Sopenharmony_ci u8 original_dtop_if_unplug_th; 328c2ecf20Sopenharmony_ci u8 original_dtop_rf_unplug_th; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci /* statistics */ 358c2ecf20Sopenharmony_ci u32 pre_vit_error_count; 368c2ecf20Sopenharmony_ci u32 pre_vit_bit_count; 378c2ecf20Sopenharmony_ci u32 ber; 388c2ecf20Sopenharmony_ci u32 post_vit_error_count; 398c2ecf20Sopenharmony_ci u32 post_vit_bit_count; 408c2ecf20Sopenharmony_ci u32 unc; 418c2ecf20Sopenharmony_ci u16 abort_count; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci int opened; 448c2ecf20Sopenharmony_ci int strong; 458c2ecf20Sopenharmony_ci unsigned long next_status_check; 468c2ecf20Sopenharmony_ci struct dvb_frontend frontend; 478c2ecf20Sopenharmony_ci}; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic int af9005_write_word_agc(struct dvb_usb_device *d, u16 reghi, 508c2ecf20Sopenharmony_ci u16 reglo, u8 pos, u8 len, u16 value) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci int ret; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci if ((ret = af9005_write_ofdm_register(d, reglo, (u8) (value & 0xff)))) 558c2ecf20Sopenharmony_ci return ret; 568c2ecf20Sopenharmony_ci return af9005_write_register_bits(d, reghi, pos, len, 578c2ecf20Sopenharmony_ci (u8) ((value & 0x300) >> 8)); 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic int af9005_read_word_agc(struct dvb_usb_device *d, u16 reghi, 618c2ecf20Sopenharmony_ci u16 reglo, u8 pos, u8 len, u16 * value) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci int ret; 648c2ecf20Sopenharmony_ci u8 temp0, temp1; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci if ((ret = af9005_read_ofdm_register(d, reglo, &temp0))) 678c2ecf20Sopenharmony_ci return ret; 688c2ecf20Sopenharmony_ci if ((ret = af9005_read_ofdm_register(d, reghi, &temp1))) 698c2ecf20Sopenharmony_ci return ret; 708c2ecf20Sopenharmony_ci switch (pos) { 718c2ecf20Sopenharmony_ci case 0: 728c2ecf20Sopenharmony_ci *value = ((u16) (temp1 & 0x03) << 8) + (u16) temp0; 738c2ecf20Sopenharmony_ci break; 748c2ecf20Sopenharmony_ci case 2: 758c2ecf20Sopenharmony_ci *value = ((u16) (temp1 & 0x0C) << 6) + (u16) temp0; 768c2ecf20Sopenharmony_ci break; 778c2ecf20Sopenharmony_ci case 4: 788c2ecf20Sopenharmony_ci *value = ((u16) (temp1 & 0x30) << 4) + (u16) temp0; 798c2ecf20Sopenharmony_ci break; 808c2ecf20Sopenharmony_ci case 6: 818c2ecf20Sopenharmony_ci *value = ((u16) (temp1 & 0xC0) << 2) + (u16) temp0; 828c2ecf20Sopenharmony_ci break; 838c2ecf20Sopenharmony_ci default: 848c2ecf20Sopenharmony_ci err("invalid pos in read word agc"); 858c2ecf20Sopenharmony_ci return -EINVAL; 868c2ecf20Sopenharmony_ci } 878c2ecf20Sopenharmony_ci return 0; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistatic int af9005_is_fecmon_available(struct dvb_frontend *fe, int *available) 928c2ecf20Sopenharmony_ci{ 938c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 948c2ecf20Sopenharmony_ci int ret; 958c2ecf20Sopenharmony_ci u8 temp; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci *available = false; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci ret = af9005_read_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en, 1008c2ecf20Sopenharmony_ci fec_vtb_rsd_mon_en_pos, 1018c2ecf20Sopenharmony_ci fec_vtb_rsd_mon_en_len, &temp); 1028c2ecf20Sopenharmony_ci if (ret) 1038c2ecf20Sopenharmony_ci return ret; 1048c2ecf20Sopenharmony_ci if (temp & 1) { 1058c2ecf20Sopenharmony_ci ret = 1068c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, 1078c2ecf20Sopenharmony_ci xd_p_reg_ofsm_read_rbc_en, 1088c2ecf20Sopenharmony_ci reg_ofsm_read_rbc_en_pos, 1098c2ecf20Sopenharmony_ci reg_ofsm_read_rbc_en_len, &temp); 1108c2ecf20Sopenharmony_ci if (ret) 1118c2ecf20Sopenharmony_ci return ret; 1128c2ecf20Sopenharmony_ci if ((temp & 1) == 0) 1138c2ecf20Sopenharmony_ci *available = true; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci } 1168c2ecf20Sopenharmony_ci return 0; 1178c2ecf20Sopenharmony_ci} 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cistatic int af9005_get_post_vit_err_cw_count(struct dvb_frontend *fe, 1208c2ecf20Sopenharmony_ci u32 * post_err_count, 1218c2ecf20Sopenharmony_ci u32 * post_cw_count, 1228c2ecf20Sopenharmony_ci u16 * abort_count) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 1258c2ecf20Sopenharmony_ci int ret; 1268c2ecf20Sopenharmony_ci u32 err_count; 1278c2ecf20Sopenharmony_ci u32 cw_count; 1288c2ecf20Sopenharmony_ci u8 temp, temp0, temp1, temp2; 1298c2ecf20Sopenharmony_ci u16 loc_abort_count; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci *post_err_count = 0; 1328c2ecf20Sopenharmony_ci *post_cw_count = 0; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci /* check if error bit count is ready */ 1358c2ecf20Sopenharmony_ci ret = 1368c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_r_fec_rsd_ber_rdy, 1378c2ecf20Sopenharmony_ci fec_rsd_ber_rdy_pos, fec_rsd_ber_rdy_len, 1388c2ecf20Sopenharmony_ci &temp); 1398c2ecf20Sopenharmony_ci if (ret) 1408c2ecf20Sopenharmony_ci return ret; 1418c2ecf20Sopenharmony_ci if (!temp) { 1428c2ecf20Sopenharmony_ci deb_info("rsd counter not ready\n"); 1438c2ecf20Sopenharmony_ci return 100; 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci /* get abort count */ 1468c2ecf20Sopenharmony_ci ret = 1478c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, 1488c2ecf20Sopenharmony_ci xd_r_fec_rsd_abort_packet_cnt_7_0, 1498c2ecf20Sopenharmony_ci &temp0); 1508c2ecf20Sopenharmony_ci if (ret) 1518c2ecf20Sopenharmony_ci return ret; 1528c2ecf20Sopenharmony_ci ret = 1538c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, 1548c2ecf20Sopenharmony_ci xd_r_fec_rsd_abort_packet_cnt_15_8, 1558c2ecf20Sopenharmony_ci &temp1); 1568c2ecf20Sopenharmony_ci if (ret) 1578c2ecf20Sopenharmony_ci return ret; 1588c2ecf20Sopenharmony_ci loc_abort_count = ((u16) temp1 << 8) + temp0; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci /* get error count */ 1618c2ecf20Sopenharmony_ci ret = 1628c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_7_0, 1638c2ecf20Sopenharmony_ci &temp0); 1648c2ecf20Sopenharmony_ci if (ret) 1658c2ecf20Sopenharmony_ci return ret; 1668c2ecf20Sopenharmony_ci ret = 1678c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_15_8, 1688c2ecf20Sopenharmony_ci &temp1); 1698c2ecf20Sopenharmony_ci if (ret) 1708c2ecf20Sopenharmony_ci return ret; 1718c2ecf20Sopenharmony_ci ret = 1728c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_23_16, 1738c2ecf20Sopenharmony_ci &temp2); 1748c2ecf20Sopenharmony_ci if (ret) 1758c2ecf20Sopenharmony_ci return ret; 1768c2ecf20Sopenharmony_ci err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0; 1778c2ecf20Sopenharmony_ci *post_err_count = err_count - (u32) loc_abort_count *8 * 8; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci /* get RSD packet number */ 1808c2ecf20Sopenharmony_ci ret = 1818c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0, 1828c2ecf20Sopenharmony_ci &temp0); 1838c2ecf20Sopenharmony_ci if (ret) 1848c2ecf20Sopenharmony_ci return ret; 1858c2ecf20Sopenharmony_ci ret = 1868c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8, 1878c2ecf20Sopenharmony_ci &temp1); 1888c2ecf20Sopenharmony_ci if (ret) 1898c2ecf20Sopenharmony_ci return ret; 1908c2ecf20Sopenharmony_ci cw_count = ((u32) temp1 << 8) + temp0; 1918c2ecf20Sopenharmony_ci if (cw_count == 0) { 1928c2ecf20Sopenharmony_ci err("wrong RSD packet count"); 1938c2ecf20Sopenharmony_ci return -EIO; 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci deb_info("POST abort count %d err count %d rsd packets %d\n", 1968c2ecf20Sopenharmony_ci loc_abort_count, err_count, cw_count); 1978c2ecf20Sopenharmony_ci *post_cw_count = cw_count - (u32) loc_abort_count; 1988c2ecf20Sopenharmony_ci *abort_count = loc_abort_count; 1998c2ecf20Sopenharmony_ci return 0; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci} 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_cistatic int af9005_get_post_vit_ber(struct dvb_frontend *fe, 2048c2ecf20Sopenharmony_ci u32 * post_err_count, u32 * post_cw_count, 2058c2ecf20Sopenharmony_ci u16 * abort_count) 2068c2ecf20Sopenharmony_ci{ 2078c2ecf20Sopenharmony_ci u32 loc_cw_count = 0, loc_err_count; 2088c2ecf20Sopenharmony_ci u16 loc_abort_count = 0; 2098c2ecf20Sopenharmony_ci int ret; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci ret = 2128c2ecf20Sopenharmony_ci af9005_get_post_vit_err_cw_count(fe, &loc_err_count, &loc_cw_count, 2138c2ecf20Sopenharmony_ci &loc_abort_count); 2148c2ecf20Sopenharmony_ci if (ret) 2158c2ecf20Sopenharmony_ci return ret; 2168c2ecf20Sopenharmony_ci *post_err_count = loc_err_count; 2178c2ecf20Sopenharmony_ci *post_cw_count = loc_cw_count * 204 * 8; 2188c2ecf20Sopenharmony_ci *abort_count = loc_abort_count; 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci return 0; 2218c2ecf20Sopenharmony_ci} 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_cistatic int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe, 2248c2ecf20Sopenharmony_ci u32 * pre_err_count, 2258c2ecf20Sopenharmony_ci u32 * pre_bit_count) 2268c2ecf20Sopenharmony_ci{ 2278c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 2288c2ecf20Sopenharmony_ci u8 temp, temp0, temp1, temp2; 2298c2ecf20Sopenharmony_ci u32 super_frame_count, x, bits; 2308c2ecf20Sopenharmony_ci int ret; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci ret = 2338c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_r_fec_vtb_ber_rdy, 2348c2ecf20Sopenharmony_ci fec_vtb_ber_rdy_pos, fec_vtb_ber_rdy_len, 2358c2ecf20Sopenharmony_ci &temp); 2368c2ecf20Sopenharmony_ci if (ret) 2378c2ecf20Sopenharmony_ci return ret; 2388c2ecf20Sopenharmony_ci if (!temp) { 2398c2ecf20Sopenharmony_ci deb_info("viterbi counter not ready\n"); 2408c2ecf20Sopenharmony_ci return 101; /* ERR_APO_VTB_COUNTER_NOT_READY; */ 2418c2ecf20Sopenharmony_ci } 2428c2ecf20Sopenharmony_ci ret = 2438c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_7_0, 2448c2ecf20Sopenharmony_ci &temp0); 2458c2ecf20Sopenharmony_ci if (ret) 2468c2ecf20Sopenharmony_ci return ret; 2478c2ecf20Sopenharmony_ci ret = 2488c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_15_8, 2498c2ecf20Sopenharmony_ci &temp1); 2508c2ecf20Sopenharmony_ci if (ret) 2518c2ecf20Sopenharmony_ci return ret; 2528c2ecf20Sopenharmony_ci ret = 2538c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_23_16, 2548c2ecf20Sopenharmony_ci &temp2); 2558c2ecf20Sopenharmony_ci if (ret) 2568c2ecf20Sopenharmony_ci return ret; 2578c2ecf20Sopenharmony_ci *pre_err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci ret = 2608c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0, 2618c2ecf20Sopenharmony_ci &temp0); 2628c2ecf20Sopenharmony_ci if (ret) 2638c2ecf20Sopenharmony_ci return ret; 2648c2ecf20Sopenharmony_ci ret = 2658c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8, 2668c2ecf20Sopenharmony_ci &temp1); 2678c2ecf20Sopenharmony_ci if (ret) 2688c2ecf20Sopenharmony_ci return ret; 2698c2ecf20Sopenharmony_ci super_frame_count = ((u32) temp1 << 8) + temp0; 2708c2ecf20Sopenharmony_ci if (super_frame_count == 0) { 2718c2ecf20Sopenharmony_ci deb_info("super frame count 0\n"); 2728c2ecf20Sopenharmony_ci return 102; 2738c2ecf20Sopenharmony_ci } 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci /* read fft mode */ 2768c2ecf20Sopenharmony_ci ret = 2778c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod, 2788c2ecf20Sopenharmony_ci reg_tpsd_txmod_pos, reg_tpsd_txmod_len, 2798c2ecf20Sopenharmony_ci &temp); 2808c2ecf20Sopenharmony_ci if (ret) 2818c2ecf20Sopenharmony_ci return ret; 2828c2ecf20Sopenharmony_ci if (temp == 0) { 2838c2ecf20Sopenharmony_ci /* 2K */ 2848c2ecf20Sopenharmony_ci x = 1512; 2858c2ecf20Sopenharmony_ci } else if (temp == 1) { 2868c2ecf20Sopenharmony_ci /* 8k */ 2878c2ecf20Sopenharmony_ci x = 6048; 2888c2ecf20Sopenharmony_ci } else { 2898c2ecf20Sopenharmony_ci err("Invalid fft mode"); 2908c2ecf20Sopenharmony_ci return -EINVAL; 2918c2ecf20Sopenharmony_ci } 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci /* read modulation mode */ 2948c2ecf20Sopenharmony_ci ret = 2958c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_g_reg_tpsd_const, 2968c2ecf20Sopenharmony_ci reg_tpsd_const_pos, reg_tpsd_const_len, 2978c2ecf20Sopenharmony_ci &temp); 2988c2ecf20Sopenharmony_ci if (ret) 2998c2ecf20Sopenharmony_ci return ret; 3008c2ecf20Sopenharmony_ci switch (temp) { 3018c2ecf20Sopenharmony_ci case 0: /* QPSK */ 3028c2ecf20Sopenharmony_ci bits = 2; 3038c2ecf20Sopenharmony_ci break; 3048c2ecf20Sopenharmony_ci case 1: /* QAM_16 */ 3058c2ecf20Sopenharmony_ci bits = 4; 3068c2ecf20Sopenharmony_ci break; 3078c2ecf20Sopenharmony_ci case 2: /* QAM_64 */ 3088c2ecf20Sopenharmony_ci bits = 6; 3098c2ecf20Sopenharmony_ci break; 3108c2ecf20Sopenharmony_ci default: 3118c2ecf20Sopenharmony_ci err("invalid modulation mode"); 3128c2ecf20Sopenharmony_ci return -EINVAL; 3138c2ecf20Sopenharmony_ci } 3148c2ecf20Sopenharmony_ci *pre_bit_count = super_frame_count * 68 * 4 * x * bits; 3158c2ecf20Sopenharmony_ci deb_info("PRE err count %d frame count %d bit count %d\n", 3168c2ecf20Sopenharmony_ci *pre_err_count, super_frame_count, *pre_bit_count); 3178c2ecf20Sopenharmony_ci return 0; 3188c2ecf20Sopenharmony_ci} 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_cistatic int af9005_reset_pre_viterbi(struct dvb_frontend *fe) 3218c2ecf20Sopenharmony_ci{ 3228c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 3238c2ecf20Sopenharmony_ci int ret; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci /* set super frame count to 1 */ 3268c2ecf20Sopenharmony_ci ret = 3278c2ecf20Sopenharmony_ci af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0, 3288c2ecf20Sopenharmony_ci 1 & 0xff); 3298c2ecf20Sopenharmony_ci if (ret) 3308c2ecf20Sopenharmony_ci return ret; 3318c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8, 3328c2ecf20Sopenharmony_ci 1 >> 8); 3338c2ecf20Sopenharmony_ci if (ret) 3348c2ecf20Sopenharmony_ci return ret; 3358c2ecf20Sopenharmony_ci /* reset pre viterbi error count */ 3368c2ecf20Sopenharmony_ci ret = 3378c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, xd_p_fec_vtb_ber_rst, 3388c2ecf20Sopenharmony_ci fec_vtb_ber_rst_pos, fec_vtb_ber_rst_len, 3398c2ecf20Sopenharmony_ci 1); 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci return ret; 3428c2ecf20Sopenharmony_ci} 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_cistatic int af9005_reset_post_viterbi(struct dvb_frontend *fe) 3458c2ecf20Sopenharmony_ci{ 3468c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 3478c2ecf20Sopenharmony_ci int ret; 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci /* set packet unit */ 3508c2ecf20Sopenharmony_ci ret = 3518c2ecf20Sopenharmony_ci af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0, 3528c2ecf20Sopenharmony_ci 10000 & 0xff); 3538c2ecf20Sopenharmony_ci if (ret) 3548c2ecf20Sopenharmony_ci return ret; 3558c2ecf20Sopenharmony_ci ret = 3568c2ecf20Sopenharmony_ci af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8, 3578c2ecf20Sopenharmony_ci 10000 >> 8); 3588c2ecf20Sopenharmony_ci if (ret) 3598c2ecf20Sopenharmony_ci return ret; 3608c2ecf20Sopenharmony_ci /* reset post viterbi error count */ 3618c2ecf20Sopenharmony_ci ret = 3628c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, xd_p_fec_rsd_ber_rst, 3638c2ecf20Sopenharmony_ci fec_rsd_ber_rst_pos, fec_rsd_ber_rst_len, 3648c2ecf20Sopenharmony_ci 1); 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci return ret; 3678c2ecf20Sopenharmony_ci} 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_cistatic int af9005_get_statistic(struct dvb_frontend *fe) 3708c2ecf20Sopenharmony_ci{ 3718c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 3728c2ecf20Sopenharmony_ci int ret, fecavailable; 3738c2ecf20Sopenharmony_ci u64 numerator, denominator; 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci deb_info("GET STATISTIC\n"); 3768c2ecf20Sopenharmony_ci ret = af9005_is_fecmon_available(fe, &fecavailable); 3778c2ecf20Sopenharmony_ci if (ret) 3788c2ecf20Sopenharmony_ci return ret; 3798c2ecf20Sopenharmony_ci if (!fecavailable) { 3808c2ecf20Sopenharmony_ci deb_info("fecmon not available\n"); 3818c2ecf20Sopenharmony_ci return 0; 3828c2ecf20Sopenharmony_ci } 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci ret = af9005_get_pre_vit_err_bit_count(fe, &state->pre_vit_error_count, 3858c2ecf20Sopenharmony_ci &state->pre_vit_bit_count); 3868c2ecf20Sopenharmony_ci if (ret == 0) { 3878c2ecf20Sopenharmony_ci af9005_reset_pre_viterbi(fe); 3888c2ecf20Sopenharmony_ci if (state->pre_vit_bit_count > 0) { 3898c2ecf20Sopenharmony_ci /* according to v 0.0.4 of the dvb api ber should be a multiple 3908c2ecf20Sopenharmony_ci of 10E-9 so we have to multiply the error count by 3918c2ecf20Sopenharmony_ci 10E9=1000000000 */ 3928c2ecf20Sopenharmony_ci numerator = 3938c2ecf20Sopenharmony_ci (u64) state->pre_vit_error_count * (u64) 1000000000; 3948c2ecf20Sopenharmony_ci denominator = (u64) state->pre_vit_bit_count; 3958c2ecf20Sopenharmony_ci state->ber = do_div(numerator, denominator); 3968c2ecf20Sopenharmony_ci } else { 3978c2ecf20Sopenharmony_ci state->ber = 0xffffffff; 3988c2ecf20Sopenharmony_ci } 3998c2ecf20Sopenharmony_ci } 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci ret = af9005_get_post_vit_ber(fe, &state->post_vit_error_count, 4028c2ecf20Sopenharmony_ci &state->post_vit_bit_count, 4038c2ecf20Sopenharmony_ci &state->abort_count); 4048c2ecf20Sopenharmony_ci if (ret == 0) { 4058c2ecf20Sopenharmony_ci ret = af9005_reset_post_viterbi(fe); 4068c2ecf20Sopenharmony_ci state->unc += state->abort_count; 4078c2ecf20Sopenharmony_ci if (ret) 4088c2ecf20Sopenharmony_ci return ret; 4098c2ecf20Sopenharmony_ci } 4108c2ecf20Sopenharmony_ci return 0; 4118c2ecf20Sopenharmony_ci} 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_cistatic int af9005_fe_refresh_state(struct dvb_frontend *fe) 4148c2ecf20Sopenharmony_ci{ 4158c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 4168c2ecf20Sopenharmony_ci if (time_after(jiffies, state->next_status_check)) { 4178c2ecf20Sopenharmony_ci deb_info("REFRESH STATE\n"); 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_ci /* statistics */ 4208c2ecf20Sopenharmony_ci if (af9005_get_statistic(fe)) 4218c2ecf20Sopenharmony_ci err("get_statistic_failed"); 4228c2ecf20Sopenharmony_ci state->next_status_check = jiffies + 250 * HZ / 1000; 4238c2ecf20Sopenharmony_ci } 4248c2ecf20Sopenharmony_ci return 0; 4258c2ecf20Sopenharmony_ci} 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_cistatic int af9005_fe_read_status(struct dvb_frontend *fe, 4288c2ecf20Sopenharmony_ci enum fe_status *stat) 4298c2ecf20Sopenharmony_ci{ 4308c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 4318c2ecf20Sopenharmony_ci u8 temp; 4328c2ecf20Sopenharmony_ci int ret; 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci if (fe->ops.tuner_ops.release == NULL) 4358c2ecf20Sopenharmony_ci return -ENODEV; 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci *stat = 0; 4388c2ecf20Sopenharmony_ci ret = af9005_read_register_bits(state->d, xd_p_agc_lock, 4398c2ecf20Sopenharmony_ci agc_lock_pos, agc_lock_len, &temp); 4408c2ecf20Sopenharmony_ci if (ret) 4418c2ecf20Sopenharmony_ci return ret; 4428c2ecf20Sopenharmony_ci if (temp) 4438c2ecf20Sopenharmony_ci *stat |= FE_HAS_SIGNAL; 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci ret = af9005_read_register_bits(state->d, xd_p_fd_tpsd_lock, 4468c2ecf20Sopenharmony_ci fd_tpsd_lock_pos, fd_tpsd_lock_len, 4478c2ecf20Sopenharmony_ci &temp); 4488c2ecf20Sopenharmony_ci if (ret) 4498c2ecf20Sopenharmony_ci return ret; 4508c2ecf20Sopenharmony_ci if (temp) 4518c2ecf20Sopenharmony_ci *stat |= FE_HAS_CARRIER; 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci ret = af9005_read_register_bits(state->d, 4548c2ecf20Sopenharmony_ci xd_r_mp2if_sync_byte_locked, 4558c2ecf20Sopenharmony_ci mp2if_sync_byte_locked_pos, 4568c2ecf20Sopenharmony_ci mp2if_sync_byte_locked_pos, &temp); 4578c2ecf20Sopenharmony_ci if (ret) 4588c2ecf20Sopenharmony_ci return ret; 4598c2ecf20Sopenharmony_ci if (temp) 4608c2ecf20Sopenharmony_ci *stat |= FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK; 4618c2ecf20Sopenharmony_ci if (state->opened) 4628c2ecf20Sopenharmony_ci af9005_led_control(state->d, *stat & FE_HAS_LOCK); 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_ci ret = 4658c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_p_reg_strong_sginal_detected, 4668c2ecf20Sopenharmony_ci reg_strong_sginal_detected_pos, 4678c2ecf20Sopenharmony_ci reg_strong_sginal_detected_len, &temp); 4688c2ecf20Sopenharmony_ci if (ret) 4698c2ecf20Sopenharmony_ci return ret; 4708c2ecf20Sopenharmony_ci if (temp != state->strong) { 4718c2ecf20Sopenharmony_ci deb_info("adjust for strong signal %d\n", temp); 4728c2ecf20Sopenharmony_ci state->strong = temp; 4738c2ecf20Sopenharmony_ci } 4748c2ecf20Sopenharmony_ci return 0; 4758c2ecf20Sopenharmony_ci} 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_cistatic int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber) 4788c2ecf20Sopenharmony_ci{ 4798c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 4808c2ecf20Sopenharmony_ci if (fe->ops.tuner_ops.release == NULL) 4818c2ecf20Sopenharmony_ci return -ENODEV; 4828c2ecf20Sopenharmony_ci af9005_fe_refresh_state(fe); 4838c2ecf20Sopenharmony_ci *ber = state->ber; 4848c2ecf20Sopenharmony_ci return 0; 4858c2ecf20Sopenharmony_ci} 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_cistatic int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) 4888c2ecf20Sopenharmony_ci{ 4898c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 4908c2ecf20Sopenharmony_ci if (fe->ops.tuner_ops.release == NULL) 4918c2ecf20Sopenharmony_ci return -ENODEV; 4928c2ecf20Sopenharmony_ci af9005_fe_refresh_state(fe); 4938c2ecf20Sopenharmony_ci *unc = state->unc; 4948c2ecf20Sopenharmony_ci return 0; 4958c2ecf20Sopenharmony_ci} 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_cistatic int af9005_fe_read_signal_strength(struct dvb_frontend *fe, 4988c2ecf20Sopenharmony_ci u16 * strength) 4998c2ecf20Sopenharmony_ci{ 5008c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 5018c2ecf20Sopenharmony_ci int ret; 5028c2ecf20Sopenharmony_ci u8 if_gain, rf_gain; 5038c2ecf20Sopenharmony_ci 5048c2ecf20Sopenharmony_ci if (fe->ops.tuner_ops.release == NULL) 5058c2ecf20Sopenharmony_ci return -ENODEV; 5068c2ecf20Sopenharmony_ci ret = 5078c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain, 5088c2ecf20Sopenharmony_ci &rf_gain); 5098c2ecf20Sopenharmony_ci if (ret) 5108c2ecf20Sopenharmony_ci return ret; 5118c2ecf20Sopenharmony_ci ret = 5128c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, xd_r_reg_aagc_if_gain, 5138c2ecf20Sopenharmony_ci &if_gain); 5148c2ecf20Sopenharmony_ci if (ret) 5158c2ecf20Sopenharmony_ci return ret; 5168c2ecf20Sopenharmony_ci /* this value has no real meaning, but i don't have the tables that relate 5178c2ecf20Sopenharmony_ci the rf and if gain with the dbm, so I just scale the value */ 5188c2ecf20Sopenharmony_ci *strength = (512 - rf_gain - if_gain) << 7; 5198c2ecf20Sopenharmony_ci return 0; 5208c2ecf20Sopenharmony_ci} 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_cistatic int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr) 5238c2ecf20Sopenharmony_ci{ 5248c2ecf20Sopenharmony_ci /* the snr can be derived from the ber and the modulation 5258c2ecf20Sopenharmony_ci but I don't think this kind of complex calculations belong 5268c2ecf20Sopenharmony_ci in the driver. I may be wrong.... */ 5278c2ecf20Sopenharmony_ci return -ENOSYS; 5288c2ecf20Sopenharmony_ci} 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_cistatic int af9005_fe_program_cfoe(struct dvb_usb_device *d, u32 bw) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci u8 temp0, temp1, temp2, temp3, buf[4]; 5338c2ecf20Sopenharmony_ci int ret; 5348c2ecf20Sopenharmony_ci u32 NS_coeff1_2048Nu; 5358c2ecf20Sopenharmony_ci u32 NS_coeff1_8191Nu; 5368c2ecf20Sopenharmony_ci u32 NS_coeff1_8192Nu; 5378c2ecf20Sopenharmony_ci u32 NS_coeff1_8193Nu; 5388c2ecf20Sopenharmony_ci u32 NS_coeff2_2k; 5398c2ecf20Sopenharmony_ci u32 NS_coeff2_8k; 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci switch (bw) { 5428c2ecf20Sopenharmony_ci case 6000000: 5438c2ecf20Sopenharmony_ci NS_coeff1_2048Nu = 0x2ADB6DC; 5448c2ecf20Sopenharmony_ci NS_coeff1_8191Nu = 0xAB7313; 5458c2ecf20Sopenharmony_ci NS_coeff1_8192Nu = 0xAB6DB7; 5468c2ecf20Sopenharmony_ci NS_coeff1_8193Nu = 0xAB685C; 5478c2ecf20Sopenharmony_ci NS_coeff2_2k = 0x156DB6E; 5488c2ecf20Sopenharmony_ci NS_coeff2_8k = 0x55B6DC; 5498c2ecf20Sopenharmony_ci break; 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_ci case 7000000: 5528c2ecf20Sopenharmony_ci NS_coeff1_2048Nu = 0x3200001; 5538c2ecf20Sopenharmony_ci NS_coeff1_8191Nu = 0xC80640; 5548c2ecf20Sopenharmony_ci NS_coeff1_8192Nu = 0xC80000; 5558c2ecf20Sopenharmony_ci NS_coeff1_8193Nu = 0xC7F9C0; 5568c2ecf20Sopenharmony_ci NS_coeff2_2k = 0x1900000; 5578c2ecf20Sopenharmony_ci NS_coeff2_8k = 0x640000; 5588c2ecf20Sopenharmony_ci break; 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_ci case 8000000: 5618c2ecf20Sopenharmony_ci NS_coeff1_2048Nu = 0x3924926; 5628c2ecf20Sopenharmony_ci NS_coeff1_8191Nu = 0xE4996E; 5638c2ecf20Sopenharmony_ci NS_coeff1_8192Nu = 0xE49249; 5648c2ecf20Sopenharmony_ci NS_coeff1_8193Nu = 0xE48B25; 5658c2ecf20Sopenharmony_ci NS_coeff2_2k = 0x1C92493; 5668c2ecf20Sopenharmony_ci NS_coeff2_8k = 0x724925; 5678c2ecf20Sopenharmony_ci break; 5688c2ecf20Sopenharmony_ci default: 5698c2ecf20Sopenharmony_ci err("Invalid bandwidth %d.", bw); 5708c2ecf20Sopenharmony_ci return -EINVAL; 5718c2ecf20Sopenharmony_ci } 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci /* 5748c2ecf20Sopenharmony_ci * write NS_coeff1_2048Nu 5758c2ecf20Sopenharmony_ci */ 5768c2ecf20Sopenharmony_ci 5778c2ecf20Sopenharmony_ci temp0 = (u8) (NS_coeff1_2048Nu & 0x000000FF); 5788c2ecf20Sopenharmony_ci temp1 = (u8) ((NS_coeff1_2048Nu & 0x0000FF00) >> 8); 5798c2ecf20Sopenharmony_ci temp2 = (u8) ((NS_coeff1_2048Nu & 0x00FF0000) >> 16); 5808c2ecf20Sopenharmony_ci temp3 = (u8) ((NS_coeff1_2048Nu & 0x03000000) >> 24); 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci /* big endian to make 8051 happy */ 5838c2ecf20Sopenharmony_ci buf[0] = temp3; 5848c2ecf20Sopenharmony_ci buf[1] = temp2; 5858c2ecf20Sopenharmony_ci buf[2] = temp1; 5868c2ecf20Sopenharmony_ci buf[3] = temp0; 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci /* cfoe_NS_2k_coeff1_25_24 */ 5898c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE00, buf[0]); 5908c2ecf20Sopenharmony_ci if (ret) 5918c2ecf20Sopenharmony_ci return ret; 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci /* cfoe_NS_2k_coeff1_23_16 */ 5948c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE01, buf[1]); 5958c2ecf20Sopenharmony_ci if (ret) 5968c2ecf20Sopenharmony_ci return ret; 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_ci /* cfoe_NS_2k_coeff1_15_8 */ 5998c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE02, buf[2]); 6008c2ecf20Sopenharmony_ci if (ret) 6018c2ecf20Sopenharmony_ci return ret; 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci /* cfoe_NS_2k_coeff1_7_0 */ 6048c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE03, buf[3]); 6058c2ecf20Sopenharmony_ci if (ret) 6068c2ecf20Sopenharmony_ci return ret; 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ci /* 6098c2ecf20Sopenharmony_ci * write NS_coeff2_2k 6108c2ecf20Sopenharmony_ci */ 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_ci temp0 = (u8) ((NS_coeff2_2k & 0x0000003F)); 6138c2ecf20Sopenharmony_ci temp1 = (u8) ((NS_coeff2_2k & 0x00003FC0) >> 6); 6148c2ecf20Sopenharmony_ci temp2 = (u8) ((NS_coeff2_2k & 0x003FC000) >> 14); 6158c2ecf20Sopenharmony_ci temp3 = (u8) ((NS_coeff2_2k & 0x01C00000) >> 22); 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci /* big endian to make 8051 happy */ 6188c2ecf20Sopenharmony_ci buf[0] = temp3; 6198c2ecf20Sopenharmony_ci buf[1] = temp2; 6208c2ecf20Sopenharmony_ci buf[2] = temp1; 6218c2ecf20Sopenharmony_ci buf[3] = temp0; 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE04, buf[0]); 6248c2ecf20Sopenharmony_ci if (ret) 6258c2ecf20Sopenharmony_ci return ret; 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE05, buf[1]); 6288c2ecf20Sopenharmony_ci if (ret) 6298c2ecf20Sopenharmony_ci return ret; 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE06, buf[2]); 6328c2ecf20Sopenharmony_ci if (ret) 6338c2ecf20Sopenharmony_ci return ret; 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE07, buf[3]); 6368c2ecf20Sopenharmony_ci if (ret) 6378c2ecf20Sopenharmony_ci return ret; 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci /* 6408c2ecf20Sopenharmony_ci * write NS_coeff1_8191Nu 6418c2ecf20Sopenharmony_ci */ 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_ci temp0 = (u8) ((NS_coeff1_8191Nu & 0x000000FF)); 6448c2ecf20Sopenharmony_ci temp1 = (u8) ((NS_coeff1_8191Nu & 0x0000FF00) >> 8); 6458c2ecf20Sopenharmony_ci temp2 = (u8) ((NS_coeff1_8191Nu & 0x00FFC000) >> 16); 6468c2ecf20Sopenharmony_ci temp3 = (u8) ((NS_coeff1_8191Nu & 0x03000000) >> 24); 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci /* big endian to make 8051 happy */ 6498c2ecf20Sopenharmony_ci buf[0] = temp3; 6508c2ecf20Sopenharmony_ci buf[1] = temp2; 6518c2ecf20Sopenharmony_ci buf[2] = temp1; 6528c2ecf20Sopenharmony_ci buf[3] = temp0; 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE08, buf[0]); 6558c2ecf20Sopenharmony_ci if (ret) 6568c2ecf20Sopenharmony_ci return ret; 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE09, buf[1]); 6598c2ecf20Sopenharmony_ci if (ret) 6608c2ecf20Sopenharmony_ci return ret; 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE0A, buf[2]); 6638c2ecf20Sopenharmony_ci if (ret) 6648c2ecf20Sopenharmony_ci return ret; 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE0B, buf[3]); 6678c2ecf20Sopenharmony_ci if (ret) 6688c2ecf20Sopenharmony_ci return ret; 6698c2ecf20Sopenharmony_ci 6708c2ecf20Sopenharmony_ci /* 6718c2ecf20Sopenharmony_ci * write NS_coeff1_8192Nu 6728c2ecf20Sopenharmony_ci */ 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci temp0 = (u8) (NS_coeff1_8192Nu & 0x000000FF); 6758c2ecf20Sopenharmony_ci temp1 = (u8) ((NS_coeff1_8192Nu & 0x0000FF00) >> 8); 6768c2ecf20Sopenharmony_ci temp2 = (u8) ((NS_coeff1_8192Nu & 0x00FFC000) >> 16); 6778c2ecf20Sopenharmony_ci temp3 = (u8) ((NS_coeff1_8192Nu & 0x03000000) >> 24); 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_ci /* big endian to make 8051 happy */ 6808c2ecf20Sopenharmony_ci buf[0] = temp3; 6818c2ecf20Sopenharmony_ci buf[1] = temp2; 6828c2ecf20Sopenharmony_ci buf[2] = temp1; 6838c2ecf20Sopenharmony_ci buf[3] = temp0; 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE0C, buf[0]); 6868c2ecf20Sopenharmony_ci if (ret) 6878c2ecf20Sopenharmony_ci return ret; 6888c2ecf20Sopenharmony_ci 6898c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE0D, buf[1]); 6908c2ecf20Sopenharmony_ci if (ret) 6918c2ecf20Sopenharmony_ci return ret; 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE0E, buf[2]); 6948c2ecf20Sopenharmony_ci if (ret) 6958c2ecf20Sopenharmony_ci return ret; 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE0F, buf[3]); 6988c2ecf20Sopenharmony_ci if (ret) 6998c2ecf20Sopenharmony_ci return ret; 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ci /* 7028c2ecf20Sopenharmony_ci * write NS_coeff1_8193Nu 7038c2ecf20Sopenharmony_ci */ 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci temp0 = (u8) ((NS_coeff1_8193Nu & 0x000000FF)); 7068c2ecf20Sopenharmony_ci temp1 = (u8) ((NS_coeff1_8193Nu & 0x0000FF00) >> 8); 7078c2ecf20Sopenharmony_ci temp2 = (u8) ((NS_coeff1_8193Nu & 0x00FFC000) >> 16); 7088c2ecf20Sopenharmony_ci temp3 = (u8) ((NS_coeff1_8193Nu & 0x03000000) >> 24); 7098c2ecf20Sopenharmony_ci 7108c2ecf20Sopenharmony_ci /* big endian to make 8051 happy */ 7118c2ecf20Sopenharmony_ci buf[0] = temp3; 7128c2ecf20Sopenharmony_ci buf[1] = temp2; 7138c2ecf20Sopenharmony_ci buf[2] = temp1; 7148c2ecf20Sopenharmony_ci buf[3] = temp0; 7158c2ecf20Sopenharmony_ci 7168c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE10, buf[0]); 7178c2ecf20Sopenharmony_ci if (ret) 7188c2ecf20Sopenharmony_ci return ret; 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE11, buf[1]); 7218c2ecf20Sopenharmony_ci if (ret) 7228c2ecf20Sopenharmony_ci return ret; 7238c2ecf20Sopenharmony_ci 7248c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE12, buf[2]); 7258c2ecf20Sopenharmony_ci if (ret) 7268c2ecf20Sopenharmony_ci return ret; 7278c2ecf20Sopenharmony_ci 7288c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE13, buf[3]); 7298c2ecf20Sopenharmony_ci if (ret) 7308c2ecf20Sopenharmony_ci return ret; 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_ci /* 7338c2ecf20Sopenharmony_ci * write NS_coeff2_8k 7348c2ecf20Sopenharmony_ci */ 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci temp0 = (u8) ((NS_coeff2_8k & 0x0000003F)); 7378c2ecf20Sopenharmony_ci temp1 = (u8) ((NS_coeff2_8k & 0x00003FC0) >> 6); 7388c2ecf20Sopenharmony_ci temp2 = (u8) ((NS_coeff2_8k & 0x003FC000) >> 14); 7398c2ecf20Sopenharmony_ci temp3 = (u8) ((NS_coeff2_8k & 0x01C00000) >> 22); 7408c2ecf20Sopenharmony_ci 7418c2ecf20Sopenharmony_ci /* big endian to make 8051 happy */ 7428c2ecf20Sopenharmony_ci buf[0] = temp3; 7438c2ecf20Sopenharmony_ci buf[1] = temp2; 7448c2ecf20Sopenharmony_ci buf[2] = temp1; 7458c2ecf20Sopenharmony_ci buf[3] = temp0; 7468c2ecf20Sopenharmony_ci 7478c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE14, buf[0]); 7488c2ecf20Sopenharmony_ci if (ret) 7498c2ecf20Sopenharmony_ci return ret; 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE15, buf[1]); 7528c2ecf20Sopenharmony_ci if (ret) 7538c2ecf20Sopenharmony_ci return ret; 7548c2ecf20Sopenharmony_ci 7558c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE16, buf[2]); 7568c2ecf20Sopenharmony_ci if (ret) 7578c2ecf20Sopenharmony_ci return ret; 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(d, 0xAE17, buf[3]); 7608c2ecf20Sopenharmony_ci return ret; 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_ci} 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_cistatic int af9005_fe_select_bw(struct dvb_usb_device *d, u32 bw) 7658c2ecf20Sopenharmony_ci{ 7668c2ecf20Sopenharmony_ci u8 temp; 7678c2ecf20Sopenharmony_ci switch (bw) { 7688c2ecf20Sopenharmony_ci case 6000000: 7698c2ecf20Sopenharmony_ci temp = 0; 7708c2ecf20Sopenharmony_ci break; 7718c2ecf20Sopenharmony_ci case 7000000: 7728c2ecf20Sopenharmony_ci temp = 1; 7738c2ecf20Sopenharmony_ci break; 7748c2ecf20Sopenharmony_ci case 8000000: 7758c2ecf20Sopenharmony_ci temp = 2; 7768c2ecf20Sopenharmony_ci break; 7778c2ecf20Sopenharmony_ci default: 7788c2ecf20Sopenharmony_ci err("Invalid bandwidth %d.", bw); 7798c2ecf20Sopenharmony_ci return -EINVAL; 7808c2ecf20Sopenharmony_ci } 7818c2ecf20Sopenharmony_ci return af9005_write_register_bits(d, xd_g_reg_bw, reg_bw_pos, 7828c2ecf20Sopenharmony_ci reg_bw_len, temp); 7838c2ecf20Sopenharmony_ci} 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_cistatic int af9005_fe_power(struct dvb_frontend *fe, int on) 7868c2ecf20Sopenharmony_ci{ 7878c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 7888c2ecf20Sopenharmony_ci u8 temp = on; 7898c2ecf20Sopenharmony_ci int ret; 7908c2ecf20Sopenharmony_ci deb_info("power %s tuner\n", on ? "on" : "off"); 7918c2ecf20Sopenharmony_ci ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0); 7928c2ecf20Sopenharmony_ci return ret; 7938c2ecf20Sopenharmony_ci} 7948c2ecf20Sopenharmony_ci 7958c2ecf20Sopenharmony_cistatic struct mt2060_config af9005_mt2060_config = { 7968c2ecf20Sopenharmony_ci 0xC0 7978c2ecf20Sopenharmony_ci}; 7988c2ecf20Sopenharmony_ci 7998c2ecf20Sopenharmony_cistatic struct qt1010_config af9005_qt1010_config = { 8008c2ecf20Sopenharmony_ci 0xC4 8018c2ecf20Sopenharmony_ci}; 8028c2ecf20Sopenharmony_ci 8038c2ecf20Sopenharmony_cistatic int af9005_fe_init(struct dvb_frontend *fe) 8048c2ecf20Sopenharmony_ci{ 8058c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 8068c2ecf20Sopenharmony_ci struct dvb_usb_adapter *adap = fe->dvb->priv; 8078c2ecf20Sopenharmony_ci int ret, i, scriptlen; 8088c2ecf20Sopenharmony_ci u8 temp, temp0 = 0, temp1 = 0, temp2 = 0; 8098c2ecf20Sopenharmony_ci u8 buf[2]; 8108c2ecf20Sopenharmony_ci u16 if1; 8118c2ecf20Sopenharmony_ci 8128c2ecf20Sopenharmony_ci deb_info("in af9005_fe_init\n"); 8138c2ecf20Sopenharmony_ci 8148c2ecf20Sopenharmony_ci /* reset */ 8158c2ecf20Sopenharmony_ci deb_info("reset\n"); 8168c2ecf20Sopenharmony_ci if ((ret = 8178c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst_en, 8188c2ecf20Sopenharmony_ci 4, 1, 0x01))) 8198c2ecf20Sopenharmony_ci return ret; 8208c2ecf20Sopenharmony_ci if ((ret = af9005_write_ofdm_register(state->d, APO_REG_RESET, 0))) 8218c2ecf20Sopenharmony_ci return ret; 8228c2ecf20Sopenharmony_ci /* clear ofdm reset */ 8238c2ecf20Sopenharmony_ci deb_info("clear ofdm reset\n"); 8248c2ecf20Sopenharmony_ci for (i = 0; i < 150; i++) { 8258c2ecf20Sopenharmony_ci if ((ret = 8268c2ecf20Sopenharmony_ci af9005_read_ofdm_register(state->d, 8278c2ecf20Sopenharmony_ci xd_I2C_reg_ofdm_rst, &temp))) 8288c2ecf20Sopenharmony_ci return ret; 8298c2ecf20Sopenharmony_ci if (temp & (regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos)) 8308c2ecf20Sopenharmony_ci break; 8318c2ecf20Sopenharmony_ci msleep(10); 8328c2ecf20Sopenharmony_ci } 8338c2ecf20Sopenharmony_ci if (i == 150) 8348c2ecf20Sopenharmony_ci return -ETIMEDOUT; 8358c2ecf20Sopenharmony_ci 8368c2ecf20Sopenharmony_ci /*FIXME in the dump 8378c2ecf20Sopenharmony_ci write B200 A9 8388c2ecf20Sopenharmony_ci write xd_g_reg_ofsm_clk 7 8398c2ecf20Sopenharmony_ci read eepr c6 (2) 8408c2ecf20Sopenharmony_ci read eepr c7 (2) 8418c2ecf20Sopenharmony_ci misc ctrl 3 -> 1 8428c2ecf20Sopenharmony_ci read eepr ca (6) 8438c2ecf20Sopenharmony_ci write xd_g_reg_ofsm_clk 0 8448c2ecf20Sopenharmony_ci write B200 a1 8458c2ecf20Sopenharmony_ci */ 8468c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa9); 8478c2ecf20Sopenharmony_ci if (ret) 8488c2ecf20Sopenharmony_ci return ret; 8498c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x07); 8508c2ecf20Sopenharmony_ci if (ret) 8518c2ecf20Sopenharmony_ci return ret; 8528c2ecf20Sopenharmony_ci temp = 0x01; 8538c2ecf20Sopenharmony_ci ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0); 8548c2ecf20Sopenharmony_ci if (ret) 8558c2ecf20Sopenharmony_ci return ret; 8568c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x00); 8578c2ecf20Sopenharmony_ci if (ret) 8588c2ecf20Sopenharmony_ci return ret; 8598c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa1); 8608c2ecf20Sopenharmony_ci if (ret) 8618c2ecf20Sopenharmony_ci return ret; 8628c2ecf20Sopenharmony_ci 8638c2ecf20Sopenharmony_ci temp = regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos; 8648c2ecf20Sopenharmony_ci if ((ret = 8658c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, 8668c2ecf20Sopenharmony_ci reg_ofdm_rst_pos, reg_ofdm_rst_len, 1))) 8678c2ecf20Sopenharmony_ci return ret; 8688c2ecf20Sopenharmony_ci ret = af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, 8698c2ecf20Sopenharmony_ci reg_ofdm_rst_pos, reg_ofdm_rst_len, 0); 8708c2ecf20Sopenharmony_ci 8718c2ecf20Sopenharmony_ci if (ret) 8728c2ecf20Sopenharmony_ci return ret; 8738c2ecf20Sopenharmony_ci /* don't know what register aefc is, but this is what the windows driver does */ 8748c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, 0xaefc, 0); 8758c2ecf20Sopenharmony_ci if (ret) 8768c2ecf20Sopenharmony_ci return ret; 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci /* set stand alone chip */ 8798c2ecf20Sopenharmony_ci deb_info("set stand alone chip\n"); 8808c2ecf20Sopenharmony_ci if ((ret = 8818c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, xd_p_reg_dca_stand_alone, 8828c2ecf20Sopenharmony_ci reg_dca_stand_alone_pos, 8838c2ecf20Sopenharmony_ci reg_dca_stand_alone_len, 1))) 8848c2ecf20Sopenharmony_ci return ret; 8858c2ecf20Sopenharmony_ci 8868c2ecf20Sopenharmony_ci /* set dca upper & lower chip */ 8878c2ecf20Sopenharmony_ci deb_info("set dca upper & lower chip\n"); 8888c2ecf20Sopenharmony_ci if ((ret = 8898c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, xd_p_reg_dca_upper_chip, 8908c2ecf20Sopenharmony_ci reg_dca_upper_chip_pos, 8918c2ecf20Sopenharmony_ci reg_dca_upper_chip_len, 0))) 8928c2ecf20Sopenharmony_ci return ret; 8938c2ecf20Sopenharmony_ci if ((ret = 8948c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, xd_p_reg_dca_lower_chip, 8958c2ecf20Sopenharmony_ci reg_dca_lower_chip_pos, 8968c2ecf20Sopenharmony_ci reg_dca_lower_chip_len, 0))) 8978c2ecf20Sopenharmony_ci return ret; 8988c2ecf20Sopenharmony_ci 8998c2ecf20Sopenharmony_ci /* set 2wire master clock to 0x14 (for 60KHz) */ 9008c2ecf20Sopenharmony_ci deb_info("set 2wire master clock to 0x14 (for 60KHz)\n"); 9018c2ecf20Sopenharmony_ci if ((ret = 9028c2ecf20Sopenharmony_ci af9005_write_ofdm_register(state->d, xd_I2C_i2c_m_period, 0x14))) 9038c2ecf20Sopenharmony_ci return ret; 9048c2ecf20Sopenharmony_ci 9058c2ecf20Sopenharmony_ci /* clear dca enable chip */ 9068c2ecf20Sopenharmony_ci deb_info("clear dca enable chip\n"); 9078c2ecf20Sopenharmony_ci if ((ret = 9088c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, xd_p_reg_dca_en, 9098c2ecf20Sopenharmony_ci reg_dca_en_pos, reg_dca_en_len, 0))) 9108c2ecf20Sopenharmony_ci return ret; 9118c2ecf20Sopenharmony_ci /* FIXME these are register bits, but I don't know which ones */ 9128c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, 0xa16c, 1); 9138c2ecf20Sopenharmony_ci if (ret) 9148c2ecf20Sopenharmony_ci return ret; 9158c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, 0xa3c1, 0); 9168c2ecf20Sopenharmony_ci if (ret) 9178c2ecf20Sopenharmony_ci return ret; 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ci /* init other parameters: program cfoe and select bandwidth */ 9208c2ecf20Sopenharmony_ci deb_info("program cfoe\n"); 9218c2ecf20Sopenharmony_ci ret = af9005_fe_program_cfoe(state->d, 6000000); 9228c2ecf20Sopenharmony_ci if (ret) 9238c2ecf20Sopenharmony_ci return ret; 9248c2ecf20Sopenharmony_ci /* set read-update bit for modulation */ 9258c2ecf20Sopenharmony_ci deb_info("set read-update bit for modulation\n"); 9268c2ecf20Sopenharmony_ci if ((ret = 9278c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, xd_p_reg_feq_read_update, 9288c2ecf20Sopenharmony_ci reg_feq_read_update_pos, 9298c2ecf20Sopenharmony_ci reg_feq_read_update_len, 1))) 9308c2ecf20Sopenharmony_ci return ret; 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ci /* sample code has a set MPEG TS code here 9338c2ecf20Sopenharmony_ci but sniffing reveals that it doesn't do it */ 9348c2ecf20Sopenharmony_ci 9358c2ecf20Sopenharmony_ci /* set read-update bit to 1 for DCA modulation */ 9368c2ecf20Sopenharmony_ci deb_info("set read-update bit 1 for DCA modulation\n"); 9378c2ecf20Sopenharmony_ci if ((ret = 9388c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, xd_p_reg_dca_read_update, 9398c2ecf20Sopenharmony_ci reg_dca_read_update_pos, 9408c2ecf20Sopenharmony_ci reg_dca_read_update_len, 1))) 9418c2ecf20Sopenharmony_ci return ret; 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci /* enable fec monitor */ 9448c2ecf20Sopenharmony_ci deb_info("enable fec monitor\n"); 9458c2ecf20Sopenharmony_ci if ((ret = 9468c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en, 9478c2ecf20Sopenharmony_ci fec_vtb_rsd_mon_en_pos, 9488c2ecf20Sopenharmony_ci fec_vtb_rsd_mon_en_len, 1))) 9498c2ecf20Sopenharmony_ci return ret; 9508c2ecf20Sopenharmony_ci 9518c2ecf20Sopenharmony_ci /* FIXME should be register bits, I don't know which ones */ 9528c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, 0xa601, 0); 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_ci /* set api_retrain_never_freeze */ 9558c2ecf20Sopenharmony_ci deb_info("set api_retrain_never_freeze\n"); 9568c2ecf20Sopenharmony_ci if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01))) 9578c2ecf20Sopenharmony_ci return ret; 9588c2ecf20Sopenharmony_ci 9598c2ecf20Sopenharmony_ci /* load init script */ 9608c2ecf20Sopenharmony_ci deb_info("load init script\n"); 9618c2ecf20Sopenharmony_ci scriptlen = sizeof(script) / sizeof(RegDesc); 9628c2ecf20Sopenharmony_ci for (i = 0; i < scriptlen; i++) { 9638c2ecf20Sopenharmony_ci if ((ret = 9648c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, script[i].reg, 9658c2ecf20Sopenharmony_ci script[i].pos, 9668c2ecf20Sopenharmony_ci script[i].len, script[i].val))) 9678c2ecf20Sopenharmony_ci return ret; 9688c2ecf20Sopenharmony_ci /* save 3 bytes of original fcw */ 9698c2ecf20Sopenharmony_ci if (script[i].reg == 0xae18) 9708c2ecf20Sopenharmony_ci temp2 = script[i].val; 9718c2ecf20Sopenharmony_ci if (script[i].reg == 0xae19) 9728c2ecf20Sopenharmony_ci temp1 = script[i].val; 9738c2ecf20Sopenharmony_ci if (script[i].reg == 0xae1a) 9748c2ecf20Sopenharmony_ci temp0 = script[i].val; 9758c2ecf20Sopenharmony_ci 9768c2ecf20Sopenharmony_ci /* save original unplug threshold */ 9778c2ecf20Sopenharmony_ci if (script[i].reg == xd_p_reg_unplug_th) 9788c2ecf20Sopenharmony_ci state->original_if_unplug_th = script[i].val; 9798c2ecf20Sopenharmony_ci if (script[i].reg == xd_p_reg_unplug_rf_gain_th) 9808c2ecf20Sopenharmony_ci state->original_rf_unplug_th = script[i].val; 9818c2ecf20Sopenharmony_ci if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th) 9828c2ecf20Sopenharmony_ci state->original_dtop_if_unplug_th = script[i].val; 9838c2ecf20Sopenharmony_ci if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th) 9848c2ecf20Sopenharmony_ci state->original_dtop_rf_unplug_th = script[i].val; 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ci } 9878c2ecf20Sopenharmony_ci state->original_fcw = 9888c2ecf20Sopenharmony_ci ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0; 9898c2ecf20Sopenharmony_ci 9908c2ecf20Sopenharmony_ci 9918c2ecf20Sopenharmony_ci /* save original TOPs */ 9928c2ecf20Sopenharmony_ci deb_info("save original TOPs\n"); 9938c2ecf20Sopenharmony_ci 9948c2ecf20Sopenharmony_ci /* RF TOP */ 9958c2ecf20Sopenharmony_ci ret = 9968c2ecf20Sopenharmony_ci af9005_read_word_agc(state->d, 9978c2ecf20Sopenharmony_ci xd_p_reg_aagc_rf_top_numerator_9_8, 9988c2ecf20Sopenharmony_ci xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2, 9998c2ecf20Sopenharmony_ci &state->original_rf_top); 10008c2ecf20Sopenharmony_ci if (ret) 10018c2ecf20Sopenharmony_ci return ret; 10028c2ecf20Sopenharmony_ci 10038c2ecf20Sopenharmony_ci /* IF TOP */ 10048c2ecf20Sopenharmony_ci ret = 10058c2ecf20Sopenharmony_ci af9005_read_word_agc(state->d, 10068c2ecf20Sopenharmony_ci xd_p_reg_aagc_if_top_numerator_9_8, 10078c2ecf20Sopenharmony_ci xd_p_reg_aagc_if_top_numerator_7_0, 0, 2, 10088c2ecf20Sopenharmony_ci &state->original_if_top); 10098c2ecf20Sopenharmony_ci if (ret) 10108c2ecf20Sopenharmony_ci return ret; 10118c2ecf20Sopenharmony_ci 10128c2ecf20Sopenharmony_ci /* ACI 0 IF TOP */ 10138c2ecf20Sopenharmony_ci ret = 10148c2ecf20Sopenharmony_ci af9005_read_word_agc(state->d, 0xA60E, 0xA60A, 4, 2, 10158c2ecf20Sopenharmony_ci &state->original_aci0_if_top); 10168c2ecf20Sopenharmony_ci if (ret) 10178c2ecf20Sopenharmony_ci return ret; 10188c2ecf20Sopenharmony_ci 10198c2ecf20Sopenharmony_ci /* ACI 1 IF TOP */ 10208c2ecf20Sopenharmony_ci ret = 10218c2ecf20Sopenharmony_ci af9005_read_word_agc(state->d, 0xA60E, 0xA60B, 6, 2, 10228c2ecf20Sopenharmony_ci &state->original_aci1_if_top); 10238c2ecf20Sopenharmony_ci if (ret) 10248c2ecf20Sopenharmony_ci return ret; 10258c2ecf20Sopenharmony_ci 10268c2ecf20Sopenharmony_ci /* attach tuner and init */ 10278c2ecf20Sopenharmony_ci if (fe->ops.tuner_ops.release == NULL) { 10288c2ecf20Sopenharmony_ci /* read tuner and board id from eeprom */ 10298c2ecf20Sopenharmony_ci ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2); 10308c2ecf20Sopenharmony_ci if (ret) { 10318c2ecf20Sopenharmony_ci err("Impossible to read EEPROM\n"); 10328c2ecf20Sopenharmony_ci return ret; 10338c2ecf20Sopenharmony_ci } 10348c2ecf20Sopenharmony_ci deb_info("Tuner id %d, board id %d\n", buf[0], buf[1]); 10358c2ecf20Sopenharmony_ci switch (buf[0]) { 10368c2ecf20Sopenharmony_ci case 2: /* MT2060 */ 10378c2ecf20Sopenharmony_ci /* read if1 from eeprom */ 10388c2ecf20Sopenharmony_ci ret = af9005_read_eeprom(adap->dev, 0xc8, buf, 2); 10398c2ecf20Sopenharmony_ci if (ret) { 10408c2ecf20Sopenharmony_ci err("Impossible to read EEPROM\n"); 10418c2ecf20Sopenharmony_ci return ret; 10428c2ecf20Sopenharmony_ci } 10438c2ecf20Sopenharmony_ci if1 = (u16) (buf[0] << 8) + buf[1]; 10448c2ecf20Sopenharmony_ci if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap, 10458c2ecf20Sopenharmony_ci &af9005_mt2060_config, if1) == NULL) { 10468c2ecf20Sopenharmony_ci deb_info("MT2060 attach failed\n"); 10478c2ecf20Sopenharmony_ci return -ENODEV; 10488c2ecf20Sopenharmony_ci } 10498c2ecf20Sopenharmony_ci break; 10508c2ecf20Sopenharmony_ci case 3: /* QT1010 */ 10518c2ecf20Sopenharmony_ci case 9: /* QT1010B */ 10528c2ecf20Sopenharmony_ci if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap, 10538c2ecf20Sopenharmony_ci &af9005_qt1010_config) ==NULL) { 10548c2ecf20Sopenharmony_ci deb_info("QT1010 attach failed\n"); 10558c2ecf20Sopenharmony_ci return -ENODEV; 10568c2ecf20Sopenharmony_ci } 10578c2ecf20Sopenharmony_ci break; 10588c2ecf20Sopenharmony_ci default: 10598c2ecf20Sopenharmony_ci err("Unsupported tuner type %d", buf[0]); 10608c2ecf20Sopenharmony_ci return -ENODEV; 10618c2ecf20Sopenharmony_ci } 10628c2ecf20Sopenharmony_ci ret = fe->ops.tuner_ops.init(fe); 10638c2ecf20Sopenharmony_ci if (ret) 10648c2ecf20Sopenharmony_ci return ret; 10658c2ecf20Sopenharmony_ci } 10668c2ecf20Sopenharmony_ci 10678c2ecf20Sopenharmony_ci deb_info("profit!\n"); 10688c2ecf20Sopenharmony_ci return 0; 10698c2ecf20Sopenharmony_ci} 10708c2ecf20Sopenharmony_ci 10718c2ecf20Sopenharmony_cistatic int af9005_fe_sleep(struct dvb_frontend *fe) 10728c2ecf20Sopenharmony_ci{ 10738c2ecf20Sopenharmony_ci return af9005_fe_power(fe, 0); 10748c2ecf20Sopenharmony_ci} 10758c2ecf20Sopenharmony_ci 10768c2ecf20Sopenharmony_cistatic int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) 10778c2ecf20Sopenharmony_ci{ 10788c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 10798c2ecf20Sopenharmony_ci 10808c2ecf20Sopenharmony_ci if (acquire) { 10818c2ecf20Sopenharmony_ci state->opened++; 10828c2ecf20Sopenharmony_ci } else { 10838c2ecf20Sopenharmony_ci 10848c2ecf20Sopenharmony_ci state->opened--; 10858c2ecf20Sopenharmony_ci if (!state->opened) 10868c2ecf20Sopenharmony_ci af9005_led_control(state->d, 0); 10878c2ecf20Sopenharmony_ci } 10888c2ecf20Sopenharmony_ci return 0; 10898c2ecf20Sopenharmony_ci} 10908c2ecf20Sopenharmony_ci 10918c2ecf20Sopenharmony_cistatic int af9005_fe_set_frontend(struct dvb_frontend *fe) 10928c2ecf20Sopenharmony_ci{ 10938c2ecf20Sopenharmony_ci struct dtv_frontend_properties *fep = &fe->dtv_property_cache; 10948c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 10958c2ecf20Sopenharmony_ci int ret; 10968c2ecf20Sopenharmony_ci u8 temp, temp0, temp1, temp2; 10978c2ecf20Sopenharmony_ci 10988c2ecf20Sopenharmony_ci deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency, 10998c2ecf20Sopenharmony_ci fep->bandwidth_hz); 11008c2ecf20Sopenharmony_ci if (fe->ops.tuner_ops.release == NULL) { 11018c2ecf20Sopenharmony_ci err("Tuner not attached"); 11028c2ecf20Sopenharmony_ci return -ENODEV; 11038c2ecf20Sopenharmony_ci } 11048c2ecf20Sopenharmony_ci 11058c2ecf20Sopenharmony_ci deb_info("turn off led\n"); 11068c2ecf20Sopenharmony_ci /* not in the log */ 11078c2ecf20Sopenharmony_ci ret = af9005_led_control(state->d, 0); 11088c2ecf20Sopenharmony_ci if (ret) 11098c2ecf20Sopenharmony_ci return ret; 11108c2ecf20Sopenharmony_ci /* not sure about the bits */ 11118c2ecf20Sopenharmony_ci ret = af9005_write_register_bits(state->d, XD_MP2IF_MISC, 2, 1, 0); 11128c2ecf20Sopenharmony_ci if (ret) 11138c2ecf20Sopenharmony_ci return ret; 11148c2ecf20Sopenharmony_ci 11158c2ecf20Sopenharmony_ci /* set FCW to default value */ 11168c2ecf20Sopenharmony_ci deb_info("set FCW to default value\n"); 11178c2ecf20Sopenharmony_ci temp0 = (u8) (state->original_fcw & 0x000000ff); 11188c2ecf20Sopenharmony_ci temp1 = (u8) ((state->original_fcw & 0x0000ff00) >> 8); 11198c2ecf20Sopenharmony_ci temp2 = (u8) ((state->original_fcw & 0x00ff0000) >> 16); 11208c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, 0xae1a, temp0); 11218c2ecf20Sopenharmony_ci if (ret) 11228c2ecf20Sopenharmony_ci return ret; 11238c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, 0xae19, temp1); 11248c2ecf20Sopenharmony_ci if (ret) 11258c2ecf20Sopenharmony_ci return ret; 11268c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, 0xae18, temp2); 11278c2ecf20Sopenharmony_ci if (ret) 11288c2ecf20Sopenharmony_ci return ret; 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_ci /* restore original TOPs */ 11318c2ecf20Sopenharmony_ci deb_info("restore original TOPs\n"); 11328c2ecf20Sopenharmony_ci ret = 11338c2ecf20Sopenharmony_ci af9005_write_word_agc(state->d, 11348c2ecf20Sopenharmony_ci xd_p_reg_aagc_rf_top_numerator_9_8, 11358c2ecf20Sopenharmony_ci xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2, 11368c2ecf20Sopenharmony_ci state->original_rf_top); 11378c2ecf20Sopenharmony_ci if (ret) 11388c2ecf20Sopenharmony_ci return ret; 11398c2ecf20Sopenharmony_ci ret = 11408c2ecf20Sopenharmony_ci af9005_write_word_agc(state->d, 11418c2ecf20Sopenharmony_ci xd_p_reg_aagc_if_top_numerator_9_8, 11428c2ecf20Sopenharmony_ci xd_p_reg_aagc_if_top_numerator_7_0, 0, 2, 11438c2ecf20Sopenharmony_ci state->original_if_top); 11448c2ecf20Sopenharmony_ci if (ret) 11458c2ecf20Sopenharmony_ci return ret; 11468c2ecf20Sopenharmony_ci ret = 11478c2ecf20Sopenharmony_ci af9005_write_word_agc(state->d, 0xA60E, 0xA60A, 4, 2, 11488c2ecf20Sopenharmony_ci state->original_aci0_if_top); 11498c2ecf20Sopenharmony_ci if (ret) 11508c2ecf20Sopenharmony_ci return ret; 11518c2ecf20Sopenharmony_ci ret = 11528c2ecf20Sopenharmony_ci af9005_write_word_agc(state->d, 0xA60E, 0xA60B, 6, 2, 11538c2ecf20Sopenharmony_ci state->original_aci1_if_top); 11548c2ecf20Sopenharmony_ci if (ret) 11558c2ecf20Sopenharmony_ci return ret; 11568c2ecf20Sopenharmony_ci 11578c2ecf20Sopenharmony_ci /* select bandwidth */ 11588c2ecf20Sopenharmony_ci deb_info("select bandwidth"); 11598c2ecf20Sopenharmony_ci ret = af9005_fe_select_bw(state->d, fep->bandwidth_hz); 11608c2ecf20Sopenharmony_ci if (ret) 11618c2ecf20Sopenharmony_ci return ret; 11628c2ecf20Sopenharmony_ci ret = af9005_fe_program_cfoe(state->d, fep->bandwidth_hz); 11638c2ecf20Sopenharmony_ci if (ret) 11648c2ecf20Sopenharmony_ci return ret; 11658c2ecf20Sopenharmony_ci 11668c2ecf20Sopenharmony_ci /* clear easy mode flag */ 11678c2ecf20Sopenharmony_ci deb_info("clear easy mode flag\n"); 11688c2ecf20Sopenharmony_ci ret = af9005_write_ofdm_register(state->d, 0xaefd, 0); 11698c2ecf20Sopenharmony_ci if (ret) 11708c2ecf20Sopenharmony_ci return ret; 11718c2ecf20Sopenharmony_ci 11728c2ecf20Sopenharmony_ci /* set unplug threshold to original value */ 11738c2ecf20Sopenharmony_ci deb_info("set unplug threshold to original value\n"); 11748c2ecf20Sopenharmony_ci ret = 11758c2ecf20Sopenharmony_ci af9005_write_ofdm_register(state->d, xd_p_reg_unplug_th, 11768c2ecf20Sopenharmony_ci state->original_if_unplug_th); 11778c2ecf20Sopenharmony_ci if (ret) 11788c2ecf20Sopenharmony_ci return ret; 11798c2ecf20Sopenharmony_ci /* set tuner */ 11808c2ecf20Sopenharmony_ci deb_info("set tuner\n"); 11818c2ecf20Sopenharmony_ci ret = fe->ops.tuner_ops.set_params(fe); 11828c2ecf20Sopenharmony_ci if (ret) 11838c2ecf20Sopenharmony_ci return ret; 11848c2ecf20Sopenharmony_ci 11858c2ecf20Sopenharmony_ci /* trigger ofsm */ 11868c2ecf20Sopenharmony_ci deb_info("trigger ofsm\n"); 11878c2ecf20Sopenharmony_ci temp = 0; 11888c2ecf20Sopenharmony_ci ret = af9005_write_tuner_registers(state->d, 0xffff, &temp, 1); 11898c2ecf20Sopenharmony_ci if (ret) 11908c2ecf20Sopenharmony_ci return ret; 11918c2ecf20Sopenharmony_ci 11928c2ecf20Sopenharmony_ci /* clear retrain and freeze flag */ 11938c2ecf20Sopenharmony_ci deb_info("clear retrain and freeze flag\n"); 11948c2ecf20Sopenharmony_ci ret = 11958c2ecf20Sopenharmony_ci af9005_write_register_bits(state->d, 11968c2ecf20Sopenharmony_ci xd_p_reg_api_retrain_request, 11978c2ecf20Sopenharmony_ci reg_api_retrain_request_pos, 2, 0); 11988c2ecf20Sopenharmony_ci if (ret) 11998c2ecf20Sopenharmony_ci return ret; 12008c2ecf20Sopenharmony_ci 12018c2ecf20Sopenharmony_ci /* reset pre viterbi and post viterbi registers and statistics */ 12028c2ecf20Sopenharmony_ci af9005_reset_pre_viterbi(fe); 12038c2ecf20Sopenharmony_ci af9005_reset_post_viterbi(fe); 12048c2ecf20Sopenharmony_ci state->pre_vit_error_count = 0; 12058c2ecf20Sopenharmony_ci state->pre_vit_bit_count = 0; 12068c2ecf20Sopenharmony_ci state->ber = 0; 12078c2ecf20Sopenharmony_ci state->post_vit_error_count = 0; 12088c2ecf20Sopenharmony_ci /* state->unc = 0; commented out since it should be ever increasing */ 12098c2ecf20Sopenharmony_ci state->abort_count = 0; 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_ci state->next_status_check = jiffies; 12128c2ecf20Sopenharmony_ci state->strong = -1; 12138c2ecf20Sopenharmony_ci 12148c2ecf20Sopenharmony_ci return 0; 12158c2ecf20Sopenharmony_ci} 12168c2ecf20Sopenharmony_ci 12178c2ecf20Sopenharmony_cistatic int af9005_fe_get_frontend(struct dvb_frontend *fe, 12188c2ecf20Sopenharmony_ci struct dtv_frontend_properties *fep) 12198c2ecf20Sopenharmony_ci{ 12208c2ecf20Sopenharmony_ci struct af9005_fe_state *state = fe->demodulator_priv; 12218c2ecf20Sopenharmony_ci int ret; 12228c2ecf20Sopenharmony_ci u8 temp; 12238c2ecf20Sopenharmony_ci 12248c2ecf20Sopenharmony_ci /* mode */ 12258c2ecf20Sopenharmony_ci ret = 12268c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_g_reg_tpsd_const, 12278c2ecf20Sopenharmony_ci reg_tpsd_const_pos, reg_tpsd_const_len, 12288c2ecf20Sopenharmony_ci &temp); 12298c2ecf20Sopenharmony_ci if (ret) 12308c2ecf20Sopenharmony_ci return ret; 12318c2ecf20Sopenharmony_ci deb_info("===== fe_get_frontend_legacy = =============\n"); 12328c2ecf20Sopenharmony_ci deb_info("CONSTELLATION "); 12338c2ecf20Sopenharmony_ci switch (temp) { 12348c2ecf20Sopenharmony_ci case 0: 12358c2ecf20Sopenharmony_ci fep->modulation = QPSK; 12368c2ecf20Sopenharmony_ci deb_info("QPSK\n"); 12378c2ecf20Sopenharmony_ci break; 12388c2ecf20Sopenharmony_ci case 1: 12398c2ecf20Sopenharmony_ci fep->modulation = QAM_16; 12408c2ecf20Sopenharmony_ci deb_info("QAM_16\n"); 12418c2ecf20Sopenharmony_ci break; 12428c2ecf20Sopenharmony_ci case 2: 12438c2ecf20Sopenharmony_ci fep->modulation = QAM_64; 12448c2ecf20Sopenharmony_ci deb_info("QAM_64\n"); 12458c2ecf20Sopenharmony_ci break; 12468c2ecf20Sopenharmony_ci } 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_ci /* tps hierarchy and alpha value */ 12498c2ecf20Sopenharmony_ci ret = 12508c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_g_reg_tpsd_hier, 12518c2ecf20Sopenharmony_ci reg_tpsd_hier_pos, reg_tpsd_hier_len, 12528c2ecf20Sopenharmony_ci &temp); 12538c2ecf20Sopenharmony_ci if (ret) 12548c2ecf20Sopenharmony_ci return ret; 12558c2ecf20Sopenharmony_ci deb_info("HIERARCHY "); 12568c2ecf20Sopenharmony_ci switch (temp) { 12578c2ecf20Sopenharmony_ci case 0: 12588c2ecf20Sopenharmony_ci fep->hierarchy = HIERARCHY_NONE; 12598c2ecf20Sopenharmony_ci deb_info("NONE\n"); 12608c2ecf20Sopenharmony_ci break; 12618c2ecf20Sopenharmony_ci case 1: 12628c2ecf20Sopenharmony_ci fep->hierarchy = HIERARCHY_1; 12638c2ecf20Sopenharmony_ci deb_info("1\n"); 12648c2ecf20Sopenharmony_ci break; 12658c2ecf20Sopenharmony_ci case 2: 12668c2ecf20Sopenharmony_ci fep->hierarchy = HIERARCHY_2; 12678c2ecf20Sopenharmony_ci deb_info("2\n"); 12688c2ecf20Sopenharmony_ci break; 12698c2ecf20Sopenharmony_ci case 3: 12708c2ecf20Sopenharmony_ci fep->hierarchy = HIERARCHY_4; 12718c2ecf20Sopenharmony_ci deb_info("4\n"); 12728c2ecf20Sopenharmony_ci break; 12738c2ecf20Sopenharmony_ci } 12748c2ecf20Sopenharmony_ci 12758c2ecf20Sopenharmony_ci /* high/low priority */ 12768c2ecf20Sopenharmony_ci ret = 12778c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_g_reg_dec_pri, 12788c2ecf20Sopenharmony_ci reg_dec_pri_pos, reg_dec_pri_len, &temp); 12798c2ecf20Sopenharmony_ci if (ret) 12808c2ecf20Sopenharmony_ci return ret; 12818c2ecf20Sopenharmony_ci /* if temp is set = high priority */ 12828c2ecf20Sopenharmony_ci deb_info("PRIORITY %s\n", temp ? "high" : "low"); 12838c2ecf20Sopenharmony_ci 12848c2ecf20Sopenharmony_ci /* high coderate */ 12858c2ecf20Sopenharmony_ci ret = 12868c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_g_reg_tpsd_hpcr, 12878c2ecf20Sopenharmony_ci reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len, 12888c2ecf20Sopenharmony_ci &temp); 12898c2ecf20Sopenharmony_ci if (ret) 12908c2ecf20Sopenharmony_ci return ret; 12918c2ecf20Sopenharmony_ci deb_info("CODERATE HP "); 12928c2ecf20Sopenharmony_ci switch (temp) { 12938c2ecf20Sopenharmony_ci case 0: 12948c2ecf20Sopenharmony_ci fep->code_rate_HP = FEC_1_2; 12958c2ecf20Sopenharmony_ci deb_info("FEC_1_2\n"); 12968c2ecf20Sopenharmony_ci break; 12978c2ecf20Sopenharmony_ci case 1: 12988c2ecf20Sopenharmony_ci fep->code_rate_HP = FEC_2_3; 12998c2ecf20Sopenharmony_ci deb_info("FEC_2_3\n"); 13008c2ecf20Sopenharmony_ci break; 13018c2ecf20Sopenharmony_ci case 2: 13028c2ecf20Sopenharmony_ci fep->code_rate_HP = FEC_3_4; 13038c2ecf20Sopenharmony_ci deb_info("FEC_3_4\n"); 13048c2ecf20Sopenharmony_ci break; 13058c2ecf20Sopenharmony_ci case 3: 13068c2ecf20Sopenharmony_ci fep->code_rate_HP = FEC_5_6; 13078c2ecf20Sopenharmony_ci deb_info("FEC_5_6\n"); 13088c2ecf20Sopenharmony_ci break; 13098c2ecf20Sopenharmony_ci case 4: 13108c2ecf20Sopenharmony_ci fep->code_rate_HP = FEC_7_8; 13118c2ecf20Sopenharmony_ci deb_info("FEC_7_8\n"); 13128c2ecf20Sopenharmony_ci break; 13138c2ecf20Sopenharmony_ci } 13148c2ecf20Sopenharmony_ci 13158c2ecf20Sopenharmony_ci /* low coderate */ 13168c2ecf20Sopenharmony_ci ret = 13178c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_g_reg_tpsd_lpcr, 13188c2ecf20Sopenharmony_ci reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len, 13198c2ecf20Sopenharmony_ci &temp); 13208c2ecf20Sopenharmony_ci if (ret) 13218c2ecf20Sopenharmony_ci return ret; 13228c2ecf20Sopenharmony_ci deb_info("CODERATE LP "); 13238c2ecf20Sopenharmony_ci switch (temp) { 13248c2ecf20Sopenharmony_ci case 0: 13258c2ecf20Sopenharmony_ci fep->code_rate_LP = FEC_1_2; 13268c2ecf20Sopenharmony_ci deb_info("FEC_1_2\n"); 13278c2ecf20Sopenharmony_ci break; 13288c2ecf20Sopenharmony_ci case 1: 13298c2ecf20Sopenharmony_ci fep->code_rate_LP = FEC_2_3; 13308c2ecf20Sopenharmony_ci deb_info("FEC_2_3\n"); 13318c2ecf20Sopenharmony_ci break; 13328c2ecf20Sopenharmony_ci case 2: 13338c2ecf20Sopenharmony_ci fep->code_rate_LP = FEC_3_4; 13348c2ecf20Sopenharmony_ci deb_info("FEC_3_4\n"); 13358c2ecf20Sopenharmony_ci break; 13368c2ecf20Sopenharmony_ci case 3: 13378c2ecf20Sopenharmony_ci fep->code_rate_LP = FEC_5_6; 13388c2ecf20Sopenharmony_ci deb_info("FEC_5_6\n"); 13398c2ecf20Sopenharmony_ci break; 13408c2ecf20Sopenharmony_ci case 4: 13418c2ecf20Sopenharmony_ci fep->code_rate_LP = FEC_7_8; 13428c2ecf20Sopenharmony_ci deb_info("FEC_7_8\n"); 13438c2ecf20Sopenharmony_ci break; 13448c2ecf20Sopenharmony_ci } 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_ci /* guard interval */ 13478c2ecf20Sopenharmony_ci ret = 13488c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_g_reg_tpsd_gi, 13498c2ecf20Sopenharmony_ci reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp); 13508c2ecf20Sopenharmony_ci if (ret) 13518c2ecf20Sopenharmony_ci return ret; 13528c2ecf20Sopenharmony_ci deb_info("GUARD INTERVAL "); 13538c2ecf20Sopenharmony_ci switch (temp) { 13548c2ecf20Sopenharmony_ci case 0: 13558c2ecf20Sopenharmony_ci fep->guard_interval = GUARD_INTERVAL_1_32; 13568c2ecf20Sopenharmony_ci deb_info("1_32\n"); 13578c2ecf20Sopenharmony_ci break; 13588c2ecf20Sopenharmony_ci case 1: 13598c2ecf20Sopenharmony_ci fep->guard_interval = GUARD_INTERVAL_1_16; 13608c2ecf20Sopenharmony_ci deb_info("1_16\n"); 13618c2ecf20Sopenharmony_ci break; 13628c2ecf20Sopenharmony_ci case 2: 13638c2ecf20Sopenharmony_ci fep->guard_interval = GUARD_INTERVAL_1_8; 13648c2ecf20Sopenharmony_ci deb_info("1_8\n"); 13658c2ecf20Sopenharmony_ci break; 13668c2ecf20Sopenharmony_ci case 3: 13678c2ecf20Sopenharmony_ci fep->guard_interval = GUARD_INTERVAL_1_4; 13688c2ecf20Sopenharmony_ci deb_info("1_4\n"); 13698c2ecf20Sopenharmony_ci break; 13708c2ecf20Sopenharmony_ci } 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_ci /* fft */ 13738c2ecf20Sopenharmony_ci ret = 13748c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod, 13758c2ecf20Sopenharmony_ci reg_tpsd_txmod_pos, reg_tpsd_txmod_len, 13768c2ecf20Sopenharmony_ci &temp); 13778c2ecf20Sopenharmony_ci if (ret) 13788c2ecf20Sopenharmony_ci return ret; 13798c2ecf20Sopenharmony_ci deb_info("TRANSMISSION MODE "); 13808c2ecf20Sopenharmony_ci switch (temp) { 13818c2ecf20Sopenharmony_ci case 0: 13828c2ecf20Sopenharmony_ci fep->transmission_mode = TRANSMISSION_MODE_2K; 13838c2ecf20Sopenharmony_ci deb_info("2K\n"); 13848c2ecf20Sopenharmony_ci break; 13858c2ecf20Sopenharmony_ci case 1: 13868c2ecf20Sopenharmony_ci fep->transmission_mode = TRANSMISSION_MODE_8K; 13878c2ecf20Sopenharmony_ci deb_info("8K\n"); 13888c2ecf20Sopenharmony_ci break; 13898c2ecf20Sopenharmony_ci } 13908c2ecf20Sopenharmony_ci 13918c2ecf20Sopenharmony_ci /* bandwidth */ 13928c2ecf20Sopenharmony_ci ret = 13938c2ecf20Sopenharmony_ci af9005_read_register_bits(state->d, xd_g_reg_bw, reg_bw_pos, 13948c2ecf20Sopenharmony_ci reg_bw_len, &temp); 13958c2ecf20Sopenharmony_ci deb_info("BANDWIDTH "); 13968c2ecf20Sopenharmony_ci switch (temp) { 13978c2ecf20Sopenharmony_ci case 0: 13988c2ecf20Sopenharmony_ci fep->bandwidth_hz = 6000000; 13998c2ecf20Sopenharmony_ci deb_info("6\n"); 14008c2ecf20Sopenharmony_ci break; 14018c2ecf20Sopenharmony_ci case 1: 14028c2ecf20Sopenharmony_ci fep->bandwidth_hz = 7000000; 14038c2ecf20Sopenharmony_ci deb_info("7\n"); 14048c2ecf20Sopenharmony_ci break; 14058c2ecf20Sopenharmony_ci case 2: 14068c2ecf20Sopenharmony_ci fep->bandwidth_hz = 8000000; 14078c2ecf20Sopenharmony_ci deb_info("8\n"); 14088c2ecf20Sopenharmony_ci break; 14098c2ecf20Sopenharmony_ci } 14108c2ecf20Sopenharmony_ci return 0; 14118c2ecf20Sopenharmony_ci} 14128c2ecf20Sopenharmony_ci 14138c2ecf20Sopenharmony_cistatic void af9005_fe_release(struct dvb_frontend *fe) 14148c2ecf20Sopenharmony_ci{ 14158c2ecf20Sopenharmony_ci struct af9005_fe_state *state = 14168c2ecf20Sopenharmony_ci (struct af9005_fe_state *)fe->demodulator_priv; 14178c2ecf20Sopenharmony_ci kfree(state); 14188c2ecf20Sopenharmony_ci} 14198c2ecf20Sopenharmony_ci 14208c2ecf20Sopenharmony_cistatic const struct dvb_frontend_ops af9005_fe_ops; 14218c2ecf20Sopenharmony_ci 14228c2ecf20Sopenharmony_cistruct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) 14238c2ecf20Sopenharmony_ci{ 14248c2ecf20Sopenharmony_ci struct af9005_fe_state *state = NULL; 14258c2ecf20Sopenharmony_ci 14268c2ecf20Sopenharmony_ci /* allocate memory for the internal state */ 14278c2ecf20Sopenharmony_ci state = kzalloc(sizeof(struct af9005_fe_state), GFP_KERNEL); 14288c2ecf20Sopenharmony_ci if (state == NULL) 14298c2ecf20Sopenharmony_ci goto error; 14308c2ecf20Sopenharmony_ci 14318c2ecf20Sopenharmony_ci deb_info("attaching frontend af9005\n"); 14328c2ecf20Sopenharmony_ci 14338c2ecf20Sopenharmony_ci state->d = d; 14348c2ecf20Sopenharmony_ci state->opened = 0; 14358c2ecf20Sopenharmony_ci 14368c2ecf20Sopenharmony_ci memcpy(&state->frontend.ops, &af9005_fe_ops, 14378c2ecf20Sopenharmony_ci sizeof(struct dvb_frontend_ops)); 14388c2ecf20Sopenharmony_ci state->frontend.demodulator_priv = state; 14398c2ecf20Sopenharmony_ci 14408c2ecf20Sopenharmony_ci return &state->frontend; 14418c2ecf20Sopenharmony_ci error: 14428c2ecf20Sopenharmony_ci return NULL; 14438c2ecf20Sopenharmony_ci} 14448c2ecf20Sopenharmony_ci 14458c2ecf20Sopenharmony_cistatic const struct dvb_frontend_ops af9005_fe_ops = { 14468c2ecf20Sopenharmony_ci .delsys = { SYS_DVBT }, 14478c2ecf20Sopenharmony_ci .info = { 14488c2ecf20Sopenharmony_ci .name = "AF9005 USB DVB-T", 14498c2ecf20Sopenharmony_ci .frequency_min_hz = 44250 * kHz, 14508c2ecf20Sopenharmony_ci .frequency_max_hz = 867250 * kHz, 14518c2ecf20Sopenharmony_ci .frequency_stepsize_hz = 250 * kHz, 14528c2ecf20Sopenharmony_ci .caps = FE_CAN_INVERSION_AUTO | 14538c2ecf20Sopenharmony_ci FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 14548c2ecf20Sopenharmony_ci FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 14558c2ecf20Sopenharmony_ci FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | 14568c2ecf20Sopenharmony_ci FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | 14578c2ecf20Sopenharmony_ci FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | 14588c2ecf20Sopenharmony_ci FE_CAN_HIERARCHY_AUTO, 14598c2ecf20Sopenharmony_ci }, 14608c2ecf20Sopenharmony_ci 14618c2ecf20Sopenharmony_ci .release = af9005_fe_release, 14628c2ecf20Sopenharmony_ci 14638c2ecf20Sopenharmony_ci .init = af9005_fe_init, 14648c2ecf20Sopenharmony_ci .sleep = af9005_fe_sleep, 14658c2ecf20Sopenharmony_ci .ts_bus_ctrl = af9005_ts_bus_ctrl, 14668c2ecf20Sopenharmony_ci 14678c2ecf20Sopenharmony_ci .set_frontend = af9005_fe_set_frontend, 14688c2ecf20Sopenharmony_ci .get_frontend = af9005_fe_get_frontend, 14698c2ecf20Sopenharmony_ci 14708c2ecf20Sopenharmony_ci .read_status = af9005_fe_read_status, 14718c2ecf20Sopenharmony_ci .read_ber = af9005_fe_read_ber, 14728c2ecf20Sopenharmony_ci .read_signal_strength = af9005_fe_read_signal_strength, 14738c2ecf20Sopenharmony_ci .read_snr = af9005_fe_read_snr, 14748c2ecf20Sopenharmony_ci .read_ucblocks = af9005_fe_read_unc_blocks, 14758c2ecf20Sopenharmony_ci}; 1476