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