Path: blob/master/drivers/media/dvb/dvb-usb/af9005-fe.c
15112 views
/* Frontend part of the Linux driver for the Afatech 90051* USB1.1 DVB-T receiver.2*3* Copyright (C) 2007 Luca Olivetti ([email protected])4*5* Thanks to Afatech who kindly provided information.6*7* This program is free software; you can redistribute it and/or modify8* it under the terms of the GNU General Public License as published by9* the Free Software Foundation; either version 2 of the License, or10* (at your option) any later version.11*12* This program is distributed in the hope that it will be useful,13* but WITHOUT ANY WARRANTY; without even the implied warranty of14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15* GNU General Public License for more details.16*17* You should have received a copy of the GNU General Public License18* along with this program; if not, write to the Free Software19* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.20*21* see Documentation/dvb/README.dvb-usb for more information22*/23#include "af9005.h"24#include "af9005-script.h"25#include "mt2060.h"26#include "qt1010.h"27#include <asm/div64.h>2829struct af9005_fe_state {30struct dvb_usb_device *d;31fe_status_t stat;3233/* retraining parameters */34u32 original_fcw;35u16 original_rf_top;36u16 original_if_top;37u16 original_if_min;38u16 original_aci0_if_top;39u16 original_aci1_if_top;40u16 original_aci0_if_min;41u8 original_if_unplug_th;42u8 original_rf_unplug_th;43u8 original_dtop_if_unplug_th;44u8 original_dtop_rf_unplug_th;4546/* statistics */47u32 pre_vit_error_count;48u32 pre_vit_bit_count;49u32 ber;50u32 post_vit_error_count;51u32 post_vit_bit_count;52u32 unc;53u16 abort_count;5455int opened;56int strong;57unsigned long next_status_check;58struct dvb_frontend frontend;59};6061static int af9005_write_word_agc(struct dvb_usb_device *d, u16 reghi,62u16 reglo, u8 pos, u8 len, u16 value)63{64int ret;65u8 temp;6667if ((ret = af9005_write_ofdm_register(d, reglo, (u8) (value & 0xff))))68return ret;69temp = (u8) ((value & 0x0300) >> 8);70return af9005_write_register_bits(d, reghi, pos, len,71(u8) ((value & 0x300) >> 8));72}7374static int af9005_read_word_agc(struct dvb_usb_device *d, u16 reghi,75u16 reglo, u8 pos, u8 len, u16 * value)76{77int ret;78u8 temp0, temp1;7980if ((ret = af9005_read_ofdm_register(d, reglo, &temp0)))81return ret;82if ((ret = af9005_read_ofdm_register(d, reghi, &temp1)))83return ret;84switch (pos) {85case 0:86*value = ((u16) (temp1 & 0x03) << 8) + (u16) temp0;87break;88case 2:89*value = ((u16) (temp1 & 0x0C) << 6) + (u16) temp0;90break;91case 4:92*value = ((u16) (temp1 & 0x30) << 4) + (u16) temp0;93break;94case 6:95*value = ((u16) (temp1 & 0xC0) << 2) + (u16) temp0;96break;97default:98err("invalid pos in read word agc");99return -EINVAL;100}101return 0;102103}104105static int af9005_is_fecmon_available(struct dvb_frontend *fe, int *available)106{107struct af9005_fe_state *state = fe->demodulator_priv;108int ret;109u8 temp;110111*available = false;112113ret = af9005_read_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,114fec_vtb_rsd_mon_en_pos,115fec_vtb_rsd_mon_en_len, &temp);116if (ret)117return ret;118if (temp & 1) {119ret =120af9005_read_register_bits(state->d,121xd_p_reg_ofsm_read_rbc_en,122reg_ofsm_read_rbc_en_pos,123reg_ofsm_read_rbc_en_len, &temp);124if (ret)125return ret;126if ((temp & 1) == 0)127*available = true;128129}130return 0;131}132133static int af9005_get_post_vit_err_cw_count(struct dvb_frontend *fe,134u32 * post_err_count,135u32 * post_cw_count,136u16 * abort_count)137{138struct af9005_fe_state *state = fe->demodulator_priv;139int ret;140u32 err_count;141u32 cw_count;142u8 temp, temp0, temp1, temp2;143u16 loc_abort_count;144145*post_err_count = 0;146*post_cw_count = 0;147148/* check if error bit count is ready */149ret =150af9005_read_register_bits(state->d, xd_r_fec_rsd_ber_rdy,151fec_rsd_ber_rdy_pos, fec_rsd_ber_rdy_len,152&temp);153if (ret)154return ret;155if (!temp) {156deb_info("rsd counter not ready\n");157return 100;158}159/* get abort count */160ret =161af9005_read_ofdm_register(state->d,162xd_r_fec_rsd_abort_packet_cnt_7_0,163&temp0);164if (ret)165return ret;166ret =167af9005_read_ofdm_register(state->d,168xd_r_fec_rsd_abort_packet_cnt_15_8,169&temp1);170if (ret)171return ret;172loc_abort_count = ((u16) temp1 << 8) + temp0;173174/* get error count */175ret =176af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_7_0,177&temp0);178if (ret)179return ret;180ret =181af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_15_8,182&temp1);183if (ret)184return ret;185ret =186af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_23_16,187&temp2);188if (ret)189return ret;190err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;191*post_err_count = err_count - (u32) loc_abort_count *8 * 8;192193/* get RSD packet number */194ret =195af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,196&temp0);197if (ret)198return ret;199ret =200af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,201&temp1);202if (ret)203return ret;204cw_count = ((u32) temp1 << 8) + temp0;205if (cw_count == 0) {206err("wrong RSD packet count");207return -EIO;208}209deb_info("POST abort count %d err count %d rsd packets %d\n",210loc_abort_count, err_count, cw_count);211*post_cw_count = cw_count - (u32) loc_abort_count;212*abort_count = loc_abort_count;213return 0;214215}216217static int af9005_get_post_vit_ber(struct dvb_frontend *fe,218u32 * post_err_count, u32 * post_cw_count,219u16 * abort_count)220{221u32 loc_cw_count = 0, loc_err_count;222u16 loc_abort_count = 0;223int ret;224225ret =226af9005_get_post_vit_err_cw_count(fe, &loc_err_count, &loc_cw_count,227&loc_abort_count);228if (ret)229return ret;230*post_err_count = loc_err_count;231*post_cw_count = loc_cw_count * 204 * 8;232*abort_count = loc_abort_count;233234return 0;235}236237static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe,238u32 * pre_err_count,239u32 * pre_bit_count)240{241struct af9005_fe_state *state = fe->demodulator_priv;242u8 temp, temp0, temp1, temp2;243u32 super_frame_count, x, bits;244int ret;245246ret =247af9005_read_register_bits(state->d, xd_r_fec_vtb_ber_rdy,248fec_vtb_ber_rdy_pos, fec_vtb_ber_rdy_len,249&temp);250if (ret)251return ret;252if (!temp) {253deb_info("viterbi counter not ready\n");254return 101; /* ERR_APO_VTB_COUNTER_NOT_READY; */255}256ret =257af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_7_0,258&temp0);259if (ret)260return ret;261ret =262af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_15_8,263&temp1);264if (ret)265return ret;266ret =267af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_23_16,268&temp2);269if (ret)270return ret;271*pre_err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;272273ret =274af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,275&temp0);276if (ret)277return ret;278ret =279af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,280&temp1);281if (ret)282return ret;283super_frame_count = ((u32) temp1 << 8) + temp0;284if (super_frame_count == 0) {285deb_info("super frame count 0\n");286return 102;287}288289/* read fft mode */290ret =291af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,292reg_tpsd_txmod_pos, reg_tpsd_txmod_len,293&temp);294if (ret)295return ret;296if (temp == 0) {297/* 2K */298x = 1512;299} else if (temp == 1) {300/* 8k */301x = 6048;302} else {303err("Invalid fft mode");304return -EINVAL;305}306307/* read constellation mode */308ret =309af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,310reg_tpsd_const_pos, reg_tpsd_const_len,311&temp);312if (ret)313return ret;314switch (temp) {315case 0: /* QPSK */316bits = 2;317break;318case 1: /* QAM_16 */319bits = 4;320break;321case 2: /* QAM_64 */322bits = 6;323break;324default:325err("invalid constellation mode");326return -EINVAL;327}328*pre_bit_count = super_frame_count * 68 * 4 * x * bits;329deb_info("PRE err count %d frame count %d bit count %d\n",330*pre_err_count, super_frame_count, *pre_bit_count);331return 0;332}333334static int af9005_reset_pre_viterbi(struct dvb_frontend *fe)335{336struct af9005_fe_state *state = fe->demodulator_priv;337int ret;338339/* set super frame count to 1 */340ret =341af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,3421 & 0xff);343if (ret)344return ret;345ret = af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,3461 >> 8);347if (ret)348return ret;349/* reset pre viterbi error count */350ret =351af9005_write_register_bits(state->d, xd_p_fec_vtb_ber_rst,352fec_vtb_ber_rst_pos, fec_vtb_ber_rst_len,3531);354355return ret;356}357358static int af9005_reset_post_viterbi(struct dvb_frontend *fe)359{360struct af9005_fe_state *state = fe->demodulator_priv;361int ret;362363/* set packet unit */364ret =365af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,36610000 & 0xff);367if (ret)368return ret;369ret =370af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,37110000 >> 8);372if (ret)373return ret;374/* reset post viterbi error count */375ret =376af9005_write_register_bits(state->d, xd_p_fec_rsd_ber_rst,377fec_rsd_ber_rst_pos, fec_rsd_ber_rst_len,3781);379380return ret;381}382383static int af9005_get_statistic(struct dvb_frontend *fe)384{385struct af9005_fe_state *state = fe->demodulator_priv;386int ret, fecavailable;387u64 numerator, denominator;388389deb_info("GET STATISTIC\n");390ret = af9005_is_fecmon_available(fe, &fecavailable);391if (ret)392return ret;393if (!fecavailable) {394deb_info("fecmon not available\n");395return 0;396}397398ret = af9005_get_pre_vit_err_bit_count(fe, &state->pre_vit_error_count,399&state->pre_vit_bit_count);400if (ret == 0) {401af9005_reset_pre_viterbi(fe);402if (state->pre_vit_bit_count > 0) {403/* according to v 0.0.4 of the dvb api ber should be a multiple404of 10E-9 so we have to multiply the error count by40510E9=1000000000 */406numerator =407(u64) state->pre_vit_error_count * (u64) 1000000000;408denominator = (u64) state->pre_vit_bit_count;409state->ber = do_div(numerator, denominator);410} else {411state->ber = 0xffffffff;412}413}414415ret = af9005_get_post_vit_ber(fe, &state->post_vit_error_count,416&state->post_vit_bit_count,417&state->abort_count);418if (ret == 0) {419ret = af9005_reset_post_viterbi(fe);420state->unc += state->abort_count;421if (ret)422return ret;423}424return 0;425}426427static int af9005_fe_refresh_state(struct dvb_frontend *fe)428{429struct af9005_fe_state *state = fe->demodulator_priv;430if (time_after(jiffies, state->next_status_check)) {431deb_info("REFRESH STATE\n");432433/* statistics */434if (af9005_get_statistic(fe))435err("get_statistic_failed");436state->next_status_check = jiffies + 250 * HZ / 1000;437}438return 0;439}440441static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat)442{443struct af9005_fe_state *state = fe->demodulator_priv;444u8 temp;445int ret;446447if (fe->ops.tuner_ops.release == NULL)448return -ENODEV;449450*stat = 0;451ret = af9005_read_register_bits(state->d, xd_p_agc_lock,452agc_lock_pos, agc_lock_len, &temp);453if (ret)454return ret;455if (temp)456*stat |= FE_HAS_SIGNAL;457458ret = af9005_read_register_bits(state->d, xd_p_fd_tpsd_lock,459fd_tpsd_lock_pos, fd_tpsd_lock_len,460&temp);461if (ret)462return ret;463if (temp)464*stat |= FE_HAS_CARRIER;465466ret = af9005_read_register_bits(state->d,467xd_r_mp2if_sync_byte_locked,468mp2if_sync_byte_locked_pos,469mp2if_sync_byte_locked_pos, &temp);470if (ret)471return ret;472if (temp)473*stat |= FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK;474if (state->opened)475af9005_led_control(state->d, *stat & FE_HAS_LOCK);476477ret =478af9005_read_register_bits(state->d, xd_p_reg_strong_sginal_detected,479reg_strong_sginal_detected_pos,480reg_strong_sginal_detected_len, &temp);481if (ret)482return ret;483if (temp != state->strong) {484deb_info("adjust for strong signal %d\n", temp);485state->strong = temp;486}487return 0;488}489490static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber)491{492struct af9005_fe_state *state = fe->demodulator_priv;493if (fe->ops.tuner_ops.release == NULL)494return -ENODEV;495af9005_fe_refresh_state(fe);496*ber = state->ber;497return 0;498}499500static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)501{502struct af9005_fe_state *state = fe->demodulator_priv;503if (fe->ops.tuner_ops.release == NULL)504return -ENODEV;505af9005_fe_refresh_state(fe);506*unc = state->unc;507return 0;508}509510static int af9005_fe_read_signal_strength(struct dvb_frontend *fe,511u16 * strength)512{513struct af9005_fe_state *state = fe->demodulator_priv;514int ret;515u8 if_gain, rf_gain;516517if (fe->ops.tuner_ops.release == NULL)518return -ENODEV;519ret =520af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain,521&rf_gain);522if (ret)523return ret;524ret =525af9005_read_ofdm_register(state->d, xd_r_reg_aagc_if_gain,526&if_gain);527if (ret)528return ret;529/* this value has no real meaning, but i don't have the tables that relate530the rf and if gain with the dbm, so I just scale the value */531*strength = (512 - rf_gain - if_gain) << 7;532return 0;533}534535static int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr)536{537/* the snr can be derived from the ber and the constellation538but I don't think this kind of complex calculations belong539in the driver. I may be wrong.... */540return -ENOSYS;541}542543static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw)544{545u8 temp0, temp1, temp2, temp3, buf[4];546int ret;547u32 NS_coeff1_2048Nu;548u32 NS_coeff1_8191Nu;549u32 NS_coeff1_8192Nu;550u32 NS_coeff1_8193Nu;551u32 NS_coeff2_2k;552u32 NS_coeff2_8k;553554switch (bw) {555case BANDWIDTH_6_MHZ:556NS_coeff1_2048Nu = 0x2ADB6DC;557NS_coeff1_8191Nu = 0xAB7313;558NS_coeff1_8192Nu = 0xAB6DB7;559NS_coeff1_8193Nu = 0xAB685C;560NS_coeff2_2k = 0x156DB6E;561NS_coeff2_8k = 0x55B6DC;562break;563564case BANDWIDTH_7_MHZ:565NS_coeff1_2048Nu = 0x3200001;566NS_coeff1_8191Nu = 0xC80640;567NS_coeff1_8192Nu = 0xC80000;568NS_coeff1_8193Nu = 0xC7F9C0;569NS_coeff2_2k = 0x1900000;570NS_coeff2_8k = 0x640000;571break;572573case BANDWIDTH_8_MHZ:574NS_coeff1_2048Nu = 0x3924926;575NS_coeff1_8191Nu = 0xE4996E;576NS_coeff1_8192Nu = 0xE49249;577NS_coeff1_8193Nu = 0xE48B25;578NS_coeff2_2k = 0x1C92493;579NS_coeff2_8k = 0x724925;580break;581default:582err("Invalid bandwidth %d.", bw);583return -EINVAL;584}585586/*587* write NS_coeff1_2048Nu588*/589590temp0 = (u8) (NS_coeff1_2048Nu & 0x000000FF);591temp1 = (u8) ((NS_coeff1_2048Nu & 0x0000FF00) >> 8);592temp2 = (u8) ((NS_coeff1_2048Nu & 0x00FF0000) >> 16);593temp3 = (u8) ((NS_coeff1_2048Nu & 0x03000000) >> 24);594595/* big endian to make 8051 happy */596buf[0] = temp3;597buf[1] = temp2;598buf[2] = temp1;599buf[3] = temp0;600601/* cfoe_NS_2k_coeff1_25_24 */602ret = af9005_write_ofdm_register(d, 0xAE00, buf[0]);603if (ret)604return ret;605606/* cfoe_NS_2k_coeff1_23_16 */607ret = af9005_write_ofdm_register(d, 0xAE01, buf[1]);608if (ret)609return ret;610611/* cfoe_NS_2k_coeff1_15_8 */612ret = af9005_write_ofdm_register(d, 0xAE02, buf[2]);613if (ret)614return ret;615616/* cfoe_NS_2k_coeff1_7_0 */617ret = af9005_write_ofdm_register(d, 0xAE03, buf[3]);618if (ret)619return ret;620621/*622* write NS_coeff2_2k623*/624625temp0 = (u8) ((NS_coeff2_2k & 0x0000003F));626temp1 = (u8) ((NS_coeff2_2k & 0x00003FC0) >> 6);627temp2 = (u8) ((NS_coeff2_2k & 0x003FC000) >> 14);628temp3 = (u8) ((NS_coeff2_2k & 0x01C00000) >> 22);629630/* big endian to make 8051 happy */631buf[0] = temp3;632buf[1] = temp2;633buf[2] = temp1;634buf[3] = temp0;635636ret = af9005_write_ofdm_register(d, 0xAE04, buf[0]);637if (ret)638return ret;639640ret = af9005_write_ofdm_register(d, 0xAE05, buf[1]);641if (ret)642return ret;643644ret = af9005_write_ofdm_register(d, 0xAE06, buf[2]);645if (ret)646return ret;647648ret = af9005_write_ofdm_register(d, 0xAE07, buf[3]);649if (ret)650return ret;651652/*653* write NS_coeff1_8191Nu654*/655656temp0 = (u8) ((NS_coeff1_8191Nu & 0x000000FF));657temp1 = (u8) ((NS_coeff1_8191Nu & 0x0000FF00) >> 8);658temp2 = (u8) ((NS_coeff1_8191Nu & 0x00FFC000) >> 16);659temp3 = (u8) ((NS_coeff1_8191Nu & 0x03000000) >> 24);660661/* big endian to make 8051 happy */662buf[0] = temp3;663buf[1] = temp2;664buf[2] = temp1;665buf[3] = temp0;666667ret = af9005_write_ofdm_register(d, 0xAE08, buf[0]);668if (ret)669return ret;670671ret = af9005_write_ofdm_register(d, 0xAE09, buf[1]);672if (ret)673return ret;674675ret = af9005_write_ofdm_register(d, 0xAE0A, buf[2]);676if (ret)677return ret;678679ret = af9005_write_ofdm_register(d, 0xAE0B, buf[3]);680if (ret)681return ret;682683/*684* write NS_coeff1_8192Nu685*/686687temp0 = (u8) (NS_coeff1_8192Nu & 0x000000FF);688temp1 = (u8) ((NS_coeff1_8192Nu & 0x0000FF00) >> 8);689temp2 = (u8) ((NS_coeff1_8192Nu & 0x00FFC000) >> 16);690temp3 = (u8) ((NS_coeff1_8192Nu & 0x03000000) >> 24);691692/* big endian to make 8051 happy */693buf[0] = temp3;694buf[1] = temp2;695buf[2] = temp1;696buf[3] = temp0;697698ret = af9005_write_ofdm_register(d, 0xAE0C, buf[0]);699if (ret)700return ret;701702ret = af9005_write_ofdm_register(d, 0xAE0D, buf[1]);703if (ret)704return ret;705706ret = af9005_write_ofdm_register(d, 0xAE0E, buf[2]);707if (ret)708return ret;709710ret = af9005_write_ofdm_register(d, 0xAE0F, buf[3]);711if (ret)712return ret;713714/*715* write NS_coeff1_8193Nu716*/717718temp0 = (u8) ((NS_coeff1_8193Nu & 0x000000FF));719temp1 = (u8) ((NS_coeff1_8193Nu & 0x0000FF00) >> 8);720temp2 = (u8) ((NS_coeff1_8193Nu & 0x00FFC000) >> 16);721temp3 = (u8) ((NS_coeff1_8193Nu & 0x03000000) >> 24);722723/* big endian to make 8051 happy */724buf[0] = temp3;725buf[1] = temp2;726buf[2] = temp1;727buf[3] = temp0;728729ret = af9005_write_ofdm_register(d, 0xAE10, buf[0]);730if (ret)731return ret;732733ret = af9005_write_ofdm_register(d, 0xAE11, buf[1]);734if (ret)735return ret;736737ret = af9005_write_ofdm_register(d, 0xAE12, buf[2]);738if (ret)739return ret;740741ret = af9005_write_ofdm_register(d, 0xAE13, buf[3]);742if (ret)743return ret;744745/*746* write NS_coeff2_8k747*/748749temp0 = (u8) ((NS_coeff2_8k & 0x0000003F));750temp1 = (u8) ((NS_coeff2_8k & 0x00003FC0) >> 6);751temp2 = (u8) ((NS_coeff2_8k & 0x003FC000) >> 14);752temp3 = (u8) ((NS_coeff2_8k & 0x01C00000) >> 22);753754/* big endian to make 8051 happy */755buf[0] = temp3;756buf[1] = temp2;757buf[2] = temp1;758buf[3] = temp0;759760ret = af9005_write_ofdm_register(d, 0xAE14, buf[0]);761if (ret)762return ret;763764ret = af9005_write_ofdm_register(d, 0xAE15, buf[1]);765if (ret)766return ret;767768ret = af9005_write_ofdm_register(d, 0xAE16, buf[2]);769if (ret)770return ret;771772ret = af9005_write_ofdm_register(d, 0xAE17, buf[3]);773return ret;774775}776777static int af9005_fe_select_bw(struct dvb_usb_device *d, fe_bandwidth_t bw)778{779u8 temp;780switch (bw) {781case BANDWIDTH_6_MHZ:782temp = 0;783break;784case BANDWIDTH_7_MHZ:785temp = 1;786break;787case BANDWIDTH_8_MHZ:788temp = 2;789break;790default:791err("Invalid bandwidth %d.", bw);792return -EINVAL;793}794return af9005_write_register_bits(d, xd_g_reg_bw, reg_bw_pos,795reg_bw_len, temp);796}797798static int af9005_fe_power(struct dvb_frontend *fe, int on)799{800struct af9005_fe_state *state = fe->demodulator_priv;801u8 temp = on;802int ret;803deb_info("power %s tuner\n", on ? "on" : "off");804ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);805return ret;806}807808static struct mt2060_config af9005_mt2060_config = {8090xC0810};811812static struct qt1010_config af9005_qt1010_config = {8130xC4814};815816static int af9005_fe_init(struct dvb_frontend *fe)817{818struct af9005_fe_state *state = fe->demodulator_priv;819struct dvb_usb_adapter *adap = fe->dvb->priv;820int ret, i, scriptlen;821u8 temp, temp0 = 0, temp1 = 0, temp2 = 0;822u8 buf[2];823u16 if1;824825deb_info("in af9005_fe_init\n");826827/* reset */828deb_info("reset\n");829if ((ret =830af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst_en,8314, 1, 0x01)))832return ret;833if ((ret = af9005_write_ofdm_register(state->d, APO_REG_RESET, 0)))834return ret;835/* clear ofdm reset */836deb_info("clear ofdm reset\n");837for (i = 0; i < 150; i++) {838if ((ret =839af9005_read_ofdm_register(state->d,840xd_I2C_reg_ofdm_rst, &temp)))841return ret;842if (temp & (regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos))843break;844msleep(10);845}846if (i == 150)847return -ETIMEDOUT;848849/*FIXME in the dump850write B200 A9851write xd_g_reg_ofsm_clk 7852read eepr c6 (2)853read eepr c7 (2)854misc ctrl 3 -> 1855read eepr ca (6)856write xd_g_reg_ofsm_clk 0857write B200 a1858*/859ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa9);860if (ret)861return ret;862ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x07);863if (ret)864return ret;865temp = 0x01;866ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);867if (ret)868return ret;869ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x00);870if (ret)871return ret;872ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa1);873if (ret)874return ret;875876temp = regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos;877if ((ret =878af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,879reg_ofdm_rst_pos, reg_ofdm_rst_len, 1)))880return ret;881ret = af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,882reg_ofdm_rst_pos, reg_ofdm_rst_len, 0);883884if (ret)885return ret;886/* don't know what register aefc is, but this is what the windows driver does */887ret = af9005_write_ofdm_register(state->d, 0xaefc, 0);888if (ret)889return ret;890891/* set stand alone chip */892deb_info("set stand alone chip\n");893if ((ret =894af9005_write_register_bits(state->d, xd_p_reg_dca_stand_alone,895reg_dca_stand_alone_pos,896reg_dca_stand_alone_len, 1)))897return ret;898899/* set dca upper & lower chip */900deb_info("set dca upper & lower chip\n");901if ((ret =902af9005_write_register_bits(state->d, xd_p_reg_dca_upper_chip,903reg_dca_upper_chip_pos,904reg_dca_upper_chip_len, 0)))905return ret;906if ((ret =907af9005_write_register_bits(state->d, xd_p_reg_dca_lower_chip,908reg_dca_lower_chip_pos,909reg_dca_lower_chip_len, 0)))910return ret;911912/* set 2wire master clock to 0x14 (for 60KHz) */913deb_info("set 2wire master clock to 0x14 (for 60KHz)\n");914if ((ret =915af9005_write_ofdm_register(state->d, xd_I2C_i2c_m_period, 0x14)))916return ret;917918/* clear dca enable chip */919deb_info("clear dca enable chip\n");920if ((ret =921af9005_write_register_bits(state->d, xd_p_reg_dca_en,922reg_dca_en_pos, reg_dca_en_len, 0)))923return ret;924/* FIXME these are register bits, but I don't know which ones */925ret = af9005_write_ofdm_register(state->d, 0xa16c, 1);926if (ret)927return ret;928ret = af9005_write_ofdm_register(state->d, 0xa3c1, 0);929if (ret)930return ret;931932/* init other parameters: program cfoe and select bandwidth */933deb_info("program cfoe\n");934if ((ret = af9005_fe_program_cfoe(state->d, BANDWIDTH_6_MHZ)))935return ret;936/* set read-update bit for constellation */937deb_info("set read-update bit for constellation\n");938if ((ret =939af9005_write_register_bits(state->d, xd_p_reg_feq_read_update,940reg_feq_read_update_pos,941reg_feq_read_update_len, 1)))942return ret;943944/* sample code has a set MPEG TS code here945but sniffing reveals that it doesn't do it */946947/* set read-update bit to 1 for DCA constellation */948deb_info("set read-update bit 1 for DCA constellation\n");949if ((ret =950af9005_write_register_bits(state->d, xd_p_reg_dca_read_update,951reg_dca_read_update_pos,952reg_dca_read_update_len, 1)))953return ret;954955/* enable fec monitor */956deb_info("enable fec monitor\n");957if ((ret =958af9005_write_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,959fec_vtb_rsd_mon_en_pos,960fec_vtb_rsd_mon_en_len, 1)))961return ret;962963/* FIXME should be register bits, I don't know which ones */964ret = af9005_write_ofdm_register(state->d, 0xa601, 0);965966/* set api_retrain_never_freeze */967deb_info("set api_retrain_never_freeze\n");968if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01)))969return ret;970971/* load init script */972deb_info("load init script\n");973scriptlen = sizeof(script) / sizeof(RegDesc);974for (i = 0; i < scriptlen; i++) {975if ((ret =976af9005_write_register_bits(state->d, script[i].reg,977script[i].pos,978script[i].len, script[i].val)))979return ret;980/* save 3 bytes of original fcw */981if (script[i].reg == 0xae18)982temp2 = script[i].val;983if (script[i].reg == 0xae19)984temp1 = script[i].val;985if (script[i].reg == 0xae1a)986temp0 = script[i].val;987988/* save original unplug threshold */989if (script[i].reg == xd_p_reg_unplug_th)990state->original_if_unplug_th = script[i].val;991if (script[i].reg == xd_p_reg_unplug_rf_gain_th)992state->original_rf_unplug_th = script[i].val;993if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th)994state->original_dtop_if_unplug_th = script[i].val;995if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th)996state->original_dtop_rf_unplug_th = script[i].val;997998}999state->original_fcw =1000((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0;100110021003/* save original TOPs */1004deb_info("save original TOPs\n");10051006/* RF TOP */1007ret =1008af9005_read_word_agc(state->d,1009xd_p_reg_aagc_rf_top_numerator_9_8,1010xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,1011&state->original_rf_top);1012if (ret)1013return ret;10141015/* IF TOP */1016ret =1017af9005_read_word_agc(state->d,1018xd_p_reg_aagc_if_top_numerator_9_8,1019xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,1020&state->original_if_top);1021if (ret)1022return ret;10231024/* ACI 0 IF TOP */1025ret =1026af9005_read_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,1027&state->original_aci0_if_top);1028if (ret)1029return ret;10301031/* ACI 1 IF TOP */1032ret =1033af9005_read_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,1034&state->original_aci1_if_top);1035if (ret)1036return ret;10371038/* attach tuner and init */1039if (fe->ops.tuner_ops.release == NULL) {1040/* read tuner and board id from eeprom */1041ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2);1042if (ret) {1043err("Impossible to read EEPROM\n");1044return ret;1045}1046deb_info("Tuner id %d, board id %d\n", buf[0], buf[1]);1047switch (buf[0]) {1048case 2: /* MT2060 */1049/* read if1 from eeprom */1050ret = af9005_read_eeprom(adap->dev, 0xc8, buf, 2);1051if (ret) {1052err("Impossible to read EEPROM\n");1053return ret;1054}1055if1 = (u16) (buf[0] << 8) + buf[1];1056if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap,1057&af9005_mt2060_config, if1) == NULL) {1058deb_info("MT2060 attach failed\n");1059return -ENODEV;1060}1061break;1062case 3: /* QT1010 */1063case 9: /* QT1010B */1064if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap,1065&af9005_qt1010_config) ==NULL) {1066deb_info("QT1010 attach failed\n");1067return -ENODEV;1068}1069break;1070default:1071err("Unsupported tuner type %d", buf[0]);1072return -ENODEV;1073}1074ret = fe->ops.tuner_ops.init(fe);1075if (ret)1076return ret;1077}10781079deb_info("profit!\n");1080return 0;1081}10821083static int af9005_fe_sleep(struct dvb_frontend *fe)1084{1085return af9005_fe_power(fe, 0);1086}10871088static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)1089{1090struct af9005_fe_state *state = fe->demodulator_priv;10911092if (acquire) {1093state->opened++;1094} else {10951096state->opened--;1097if (!state->opened)1098af9005_led_control(state->d, 0);1099}1100return 0;1101}11021103static int af9005_fe_set_frontend(struct dvb_frontend *fe,1104struct dvb_frontend_parameters *fep)1105{1106struct af9005_fe_state *state = fe->demodulator_priv;1107int ret;1108u8 temp, temp0, temp1, temp2;11091110deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency,1111fep->u.ofdm.bandwidth);1112if (fe->ops.tuner_ops.release == NULL) {1113err("Tuner not attached");1114return -ENODEV;1115}11161117deb_info("turn off led\n");1118/* not in the log */1119ret = af9005_led_control(state->d, 0);1120if (ret)1121return ret;1122/* not sure about the bits */1123ret = af9005_write_register_bits(state->d, XD_MP2IF_MISC, 2, 1, 0);1124if (ret)1125return ret;11261127/* set FCW to default value */1128deb_info("set FCW to default value\n");1129temp0 = (u8) (state->original_fcw & 0x000000ff);1130temp1 = (u8) ((state->original_fcw & 0x0000ff00) >> 8);1131temp2 = (u8) ((state->original_fcw & 0x00ff0000) >> 16);1132ret = af9005_write_ofdm_register(state->d, 0xae1a, temp0);1133if (ret)1134return ret;1135ret = af9005_write_ofdm_register(state->d, 0xae19, temp1);1136if (ret)1137return ret;1138ret = af9005_write_ofdm_register(state->d, 0xae18, temp2);1139if (ret)1140return ret;11411142/* restore original TOPs */1143deb_info("restore original TOPs\n");1144ret =1145af9005_write_word_agc(state->d,1146xd_p_reg_aagc_rf_top_numerator_9_8,1147xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,1148state->original_rf_top);1149if (ret)1150return ret;1151ret =1152af9005_write_word_agc(state->d,1153xd_p_reg_aagc_if_top_numerator_9_8,1154xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,1155state->original_if_top);1156if (ret)1157return ret;1158ret =1159af9005_write_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,1160state->original_aci0_if_top);1161if (ret)1162return ret;1163ret =1164af9005_write_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,1165state->original_aci1_if_top);1166if (ret)1167return ret;11681169/* select bandwidth */1170deb_info("select bandwidth");1171ret = af9005_fe_select_bw(state->d, fep->u.ofdm.bandwidth);1172if (ret)1173return ret;1174ret = af9005_fe_program_cfoe(state->d, fep->u.ofdm.bandwidth);1175if (ret)1176return ret;11771178/* clear easy mode flag */1179deb_info("clear easy mode flag\n");1180ret = af9005_write_ofdm_register(state->d, 0xaefd, 0);1181if (ret)1182return ret;11831184/* set unplug threshold to original value */1185deb_info("set unplug threshold to original value\n");1186ret =1187af9005_write_ofdm_register(state->d, xd_p_reg_unplug_th,1188state->original_if_unplug_th);1189if (ret)1190return ret;1191/* set tuner */1192deb_info("set tuner\n");1193ret = fe->ops.tuner_ops.set_params(fe, fep);1194if (ret)1195return ret;11961197/* trigger ofsm */1198deb_info("trigger ofsm\n");1199temp = 0;1200ret = af9005_write_tuner_registers(state->d, 0xffff, &temp, 1);1201if (ret)1202return ret;12031204/* clear retrain and freeze flag */1205deb_info("clear retrain and freeze flag\n");1206ret =1207af9005_write_register_bits(state->d,1208xd_p_reg_api_retrain_request,1209reg_api_retrain_request_pos, 2, 0);1210if (ret)1211return ret;12121213/* reset pre viterbi and post viterbi registers and statistics */1214af9005_reset_pre_viterbi(fe);1215af9005_reset_post_viterbi(fe);1216state->pre_vit_error_count = 0;1217state->pre_vit_bit_count = 0;1218state->ber = 0;1219state->post_vit_error_count = 0;1220/* state->unc = 0; commented out since it should be ever increasing */1221state->abort_count = 0;12221223state->next_status_check = jiffies;1224state->strong = -1;12251226return 0;1227}12281229static int af9005_fe_get_frontend(struct dvb_frontend *fe,1230struct dvb_frontend_parameters *fep)1231{1232struct af9005_fe_state *state = fe->demodulator_priv;1233int ret;1234u8 temp;12351236/* mode */1237ret =1238af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,1239reg_tpsd_const_pos, reg_tpsd_const_len,1240&temp);1241if (ret)1242return ret;1243deb_info("===== fe_get_frontend ==============\n");1244deb_info("CONSTELLATION ");1245switch (temp) {1246case 0:1247fep->u.ofdm.constellation = QPSK;1248deb_info("QPSK\n");1249break;1250case 1:1251fep->u.ofdm.constellation = QAM_16;1252deb_info("QAM_16\n");1253break;1254case 2:1255fep->u.ofdm.constellation = QAM_64;1256deb_info("QAM_64\n");1257break;1258}12591260/* tps hierarchy and alpha value */1261ret =1262af9005_read_register_bits(state->d, xd_g_reg_tpsd_hier,1263reg_tpsd_hier_pos, reg_tpsd_hier_len,1264&temp);1265if (ret)1266return ret;1267deb_info("HIERARCHY ");1268switch (temp) {1269case 0:1270fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;1271deb_info("NONE\n");1272break;1273case 1:1274fep->u.ofdm.hierarchy_information = HIERARCHY_1;1275deb_info("1\n");1276break;1277case 2:1278fep->u.ofdm.hierarchy_information = HIERARCHY_2;1279deb_info("2\n");1280break;1281case 3:1282fep->u.ofdm.hierarchy_information = HIERARCHY_4;1283deb_info("4\n");1284break;1285}12861287/* high/low priority */1288ret =1289af9005_read_register_bits(state->d, xd_g_reg_dec_pri,1290reg_dec_pri_pos, reg_dec_pri_len, &temp);1291if (ret)1292return ret;1293/* if temp is set = high priority */1294deb_info("PRIORITY %s\n", temp ? "high" : "low");12951296/* high coderate */1297ret =1298af9005_read_register_bits(state->d, xd_g_reg_tpsd_hpcr,1299reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len,1300&temp);1301if (ret)1302return ret;1303deb_info("CODERATE HP ");1304switch (temp) {1305case 0:1306fep->u.ofdm.code_rate_HP = FEC_1_2;1307deb_info("FEC_1_2\n");1308break;1309case 1:1310fep->u.ofdm.code_rate_HP = FEC_2_3;1311deb_info("FEC_2_3\n");1312break;1313case 2:1314fep->u.ofdm.code_rate_HP = FEC_3_4;1315deb_info("FEC_3_4\n");1316break;1317case 3:1318fep->u.ofdm.code_rate_HP = FEC_5_6;1319deb_info("FEC_5_6\n");1320break;1321case 4:1322fep->u.ofdm.code_rate_HP = FEC_7_8;1323deb_info("FEC_7_8\n");1324break;1325}13261327/* low coderate */1328ret =1329af9005_read_register_bits(state->d, xd_g_reg_tpsd_lpcr,1330reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len,1331&temp);1332if (ret)1333return ret;1334deb_info("CODERATE LP ");1335switch (temp) {1336case 0:1337fep->u.ofdm.code_rate_LP = FEC_1_2;1338deb_info("FEC_1_2\n");1339break;1340case 1:1341fep->u.ofdm.code_rate_LP = FEC_2_3;1342deb_info("FEC_2_3\n");1343break;1344case 2:1345fep->u.ofdm.code_rate_LP = FEC_3_4;1346deb_info("FEC_3_4\n");1347break;1348case 3:1349fep->u.ofdm.code_rate_LP = FEC_5_6;1350deb_info("FEC_5_6\n");1351break;1352case 4:1353fep->u.ofdm.code_rate_LP = FEC_7_8;1354deb_info("FEC_7_8\n");1355break;1356}13571358/* guard interval */1359ret =1360af9005_read_register_bits(state->d, xd_g_reg_tpsd_gi,1361reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp);1362if (ret)1363return ret;1364deb_info("GUARD INTERVAL ");1365switch (temp) {1366case 0:1367fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;1368deb_info("1_32\n");1369break;1370case 1:1371fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;1372deb_info("1_16\n");1373break;1374case 2:1375fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;1376deb_info("1_8\n");1377break;1378case 3:1379fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;1380deb_info("1_4\n");1381break;1382}13831384/* fft */1385ret =1386af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,1387reg_tpsd_txmod_pos, reg_tpsd_txmod_len,1388&temp);1389if (ret)1390return ret;1391deb_info("TRANSMISSION MODE ");1392switch (temp) {1393case 0:1394fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;1395deb_info("2K\n");1396break;1397case 1:1398fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;1399deb_info("8K\n");1400break;1401}14021403/* bandwidth */1404ret =1405af9005_read_register_bits(state->d, xd_g_reg_bw, reg_bw_pos,1406reg_bw_len, &temp);1407deb_info("BANDWIDTH ");1408switch (temp) {1409case 0:1410fep->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;1411deb_info("6\n");1412break;1413case 1:1414fep->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;1415deb_info("7\n");1416break;1417case 2:1418fep->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;1419deb_info("8\n");1420break;1421}1422return 0;1423}14241425static void af9005_fe_release(struct dvb_frontend *fe)1426{1427struct af9005_fe_state *state =1428(struct af9005_fe_state *)fe->demodulator_priv;1429kfree(state);1430}14311432static struct dvb_frontend_ops af9005_fe_ops;14331434struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d)1435{1436struct af9005_fe_state *state = NULL;14371438/* allocate memory for the internal state */1439state = kzalloc(sizeof(struct af9005_fe_state), GFP_KERNEL);1440if (state == NULL)1441goto error;14421443deb_info("attaching frontend af9005\n");14441445state->d = d;1446state->opened = 0;14471448memcpy(&state->frontend.ops, &af9005_fe_ops,1449sizeof(struct dvb_frontend_ops));1450state->frontend.demodulator_priv = state;14511452return &state->frontend;1453error:1454return NULL;1455}14561457static struct dvb_frontend_ops af9005_fe_ops = {1458.info = {1459.name = "AF9005 USB DVB-T",1460.type = FE_OFDM,1461.frequency_min = 44250000,1462.frequency_max = 867250000,1463.frequency_stepsize = 250000,1464.caps = FE_CAN_INVERSION_AUTO |1465FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |1466FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |1467FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |1468FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |1469FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |1470FE_CAN_HIERARCHY_AUTO,1471},14721473.release = af9005_fe_release,14741475.init = af9005_fe_init,1476.sleep = af9005_fe_sleep,1477.ts_bus_ctrl = af9005_ts_bus_ctrl,14781479.set_frontend = af9005_fe_set_frontend,1480.get_frontend = af9005_fe_get_frontend,14811482.read_status = af9005_fe_read_status,1483.read_ber = af9005_fe_read_ber,1484.read_signal_strength = af9005_fe_read_signal_strength,1485.read_snr = af9005_fe_read_snr,1486.read_ucblocks = af9005_fe_read_unc_blocks,1487};148814891490