Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.19 875 lines 25 kB view raw
1/* 2 * Driver for DiBcom DiB3000MC/P-demodulator. 3 * 4 * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/) 5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) 6 * 7 * This code is partially based on the previous dib3000mc.c . 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation, version 2. 12 */ 13 14#include <linux/kernel.h> 15#include <linux/i2c.h> 16//#include <linux/init.h> 17//#include <linux/delay.h> 18//#include <linux/string.h> 19//#include <linux/slab.h> 20 21#include "dvb_frontend.h" 22 23#include "dib3000mc.h" 24 25static int debug; 26module_param(debug, int, 0644); 27MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); 28 29#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); } } while (0) 30 31struct dib3000mc_state { 32 struct dvb_frontend demod; 33 struct dib3000mc_config *cfg; 34 35 u8 i2c_addr; 36 struct i2c_adapter *i2c_adap; 37 38 struct dibx000_i2c_master i2c_master; 39 40 u32 timf; 41 42 fe_bandwidth_t current_bandwidth; 43 44 u16 dev_id; 45}; 46 47static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg) 48{ 49 u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; 50 u8 rb[2]; 51 struct i2c_msg msg[2] = { 52 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, 53 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, 54 }; 55 56 if (i2c_transfer(state->i2c_adap, msg, 2) != 2) 57 dprintk("i2c read error on %d\n",reg); 58 59 return (rb[0] << 8) | rb[1]; 60} 61 62static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val) 63{ 64 u8 b[4] = { 65 (reg >> 8) & 0xff, reg & 0xff, 66 (val >> 8) & 0xff, val & 0xff, 67 }; 68 struct i2c_msg msg = { 69 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 70 }; 71 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 72} 73 74 75static int dib3000mc_identify(struct dib3000mc_state *state) 76{ 77 u16 value; 78 if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) { 79 dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value); 80 return -EREMOTEIO; 81 } 82 83 value = dib3000mc_read_word(state, 1026); 84 if (value != 0x3001 && value != 0x3002) { 85 dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value); 86 return -EREMOTEIO; 87 } 88 state->dev_id = value; 89 90 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id); 91 92 return 0; 93} 94 95static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset) 96{ 97 u32 timf; 98 99 if (state->timf == 0) { 100 timf = 1384402; // default value for 8MHz 101 if (update_offset) 102 msleep(200); // first time we do an update 103 } else 104 timf = state->timf; 105 106 timf *= (BW_INDEX_TO_KHZ(bw) / 1000); 107 108 if (update_offset) { 109 s16 tim_offs = dib3000mc_read_word(state, 416); 110 111 if (tim_offs & 0x2000) 112 tim_offs -= 0x4000; 113 114 if (nfft == 0) 115 tim_offs *= 4; 116 117 timf += tim_offs; 118 state->timf = timf / (BW_INDEX_TO_KHZ(bw) / 1000); 119 } 120 121 dprintk("timf: %d\n", timf); 122 123 dib3000mc_write_word(state, 23, timf >> 16); 124 dib3000mc_write_word(state, 24, timf & 0xffff); 125 126 return 0; 127} 128 129static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state) 130{ 131 u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb; 132 if (state->cfg->pwm3_inversion) { 133 reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0); 134 reg_52 |= (1 << 2); 135 } else { 136 reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0); 137 reg_52 |= (1 << 8); 138 } 139 dib3000mc_write_word(state, 51, reg_51); 140 dib3000mc_write_word(state, 52, reg_52); 141 142 if (state->cfg->use_pwm3) 143 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0)); 144 else 145 dib3000mc_write_word(state, 245, 0); 146 147 dib3000mc_write_word(state, 1040, 0x3); 148 return 0; 149} 150 151static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode) 152{ 153 int ret = 0; 154 u16 fifo_threshold = 1792; 155 u16 outreg = 0; 156 u16 outmode = 0; 157 u16 elecout = 1; 158 u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */ 159 160 dprintk("-I- Setting output mode for demod %p to %d\n", 161 &state->demod, mode); 162 163 switch (mode) { 164 case OUTMODE_HIGH_Z: // disable 165 elecout = 0; 166 break; 167 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock 168 outmode = 0; 169 break; 170 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock 171 outmode = 1; 172 break; 173 case OUTMODE_MPEG2_SERIAL: // STBs with serial input 174 outmode = 2; 175 break; 176 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding 177 elecout = 3; 178 /*ADDR @ 206 : 179 P_smo_error_discard [1;6:6] = 0 180 P_smo_rs_discard [1;5:5] = 0 181 P_smo_pid_parse [1;4:4] = 0 182 P_smo_fifo_flush [1;3:3] = 0 183 P_smo_mode [2;2:1] = 11 184 P_smo_ovf_prot [1;0:0] = 0 185 */ 186 smo_reg |= 3 << 1; 187 fifo_threshold = 512; 188 outmode = 5; 189 break; 190 case OUTMODE_DIVERSITY: 191 outmode = 4; 192 elecout = 1; 193 break; 194 default: 195 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod); 196 outmode = 0; 197 break; 198 } 199 200 if ((state->cfg->output_mpeg2_in_188_bytes)) 201 smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1 202 203 outreg = dib3000mc_read_word(state, 244) & 0x07FF; 204 outreg |= (outmode << 11); 205 ret |= dib3000mc_write_word(state, 244, outreg); 206 ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/ 207 ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */ 208 ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */ 209 return ret; 210} 211 212static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw) 213{ 214 struct dib3000mc_state *state = demod->demodulator_priv; 215 u16 bw_cfg[6] = { 0 }; 216 u16 imp_bw_cfg[3] = { 0 }; 217 u16 reg; 218 219/* settings here are for 27.7MHz */ 220 switch (bw) { 221 case BANDWIDTH_8_MHZ: 222 bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20; 223 imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7; 224 break; 225 226 case BANDWIDTH_7_MHZ: 227 bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7; 228 imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0; 229 break; 230 231 case BANDWIDTH_6_MHZ: 232 bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5; 233 imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089; 234 break; 235 236 case 255 /* BANDWIDTH_5_MHZ */: 237 bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500; 238 imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072; 239 break; 240 241 default: return -EINVAL; 242 } 243 244 for (reg = 6; reg < 12; reg++) 245 dib3000mc_write_word(state, reg, bw_cfg[reg - 6]); 246 dib3000mc_write_word(state, 12, 0x0000); 247 dib3000mc_write_word(state, 13, 0x03e8); 248 dib3000mc_write_word(state, 14, 0x0000); 249 dib3000mc_write_word(state, 15, 0x03f2); 250 dib3000mc_write_word(state, 16, 0x0001); 251 dib3000mc_write_word(state, 17, 0xb0d0); 252 // P_sec_len 253 dib3000mc_write_word(state, 18, 0x0393); 254 dib3000mc_write_word(state, 19, 0x8700); 255 256 for (reg = 55; reg < 58; reg++) 257 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]); 258 259 // Timing configuration 260 dib3000mc_set_timing(state, 0, bw, 0); 261 262 return 0; 263} 264 265static u16 impulse_noise_val[29] = 266 267{ 268 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3, 269 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2, 270 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd 271}; 272 273static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft) 274{ 275 u16 i; 276 for (i = 58; i < 87; i++) 277 dib3000mc_write_word(state, i, impulse_noise_val[i-58]); 278 279 if (nfft == 1) { 280 dib3000mc_write_word(state, 58, 0x3b); 281 dib3000mc_write_word(state, 84, 0x00); 282 dib3000mc_write_word(state, 85, 0x8200); 283 } 284 285 dib3000mc_write_word(state, 34, 0x1294); 286 dib3000mc_write_word(state, 35, 0x1ff8); 287 if (mode == 1) 288 dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10)); 289} 290 291static int dib3000mc_init(struct dvb_frontend *demod) 292{ 293 struct dib3000mc_state *state = demod->demodulator_priv; 294 struct dibx000_agc_config *agc = state->cfg->agc; 295 296 // Restart Configuration 297 dib3000mc_write_word(state, 1027, 0x8000); 298 dib3000mc_write_word(state, 1027, 0x0000); 299 300 // power up the demod + mobility configuration 301 dib3000mc_write_word(state, 140, 0x0000); 302 dib3000mc_write_word(state, 1031, 0); 303 304 if (state->cfg->mobile_mode) { 305 dib3000mc_write_word(state, 139, 0x0000); 306 dib3000mc_write_word(state, 141, 0x0000); 307 dib3000mc_write_word(state, 175, 0x0002); 308 dib3000mc_write_word(state, 1032, 0x0000); 309 } else { 310 dib3000mc_write_word(state, 139, 0x0001); 311 dib3000mc_write_word(state, 141, 0x0000); 312 dib3000mc_write_word(state, 175, 0x0000); 313 dib3000mc_write_word(state, 1032, 0x012C); 314 } 315 dib3000mc_write_word(state, 1033, 0x0000); 316 317 // P_clk_cfg 318 dib3000mc_write_word(state, 1037, 0x3130); 319 320 // other configurations 321 322 // P_ctrl_sfreq 323 dib3000mc_write_word(state, 33, (5 << 0)); 324 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0)); 325 326 // Phase noise control 327 // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange 328 dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0)); 329 330 if (state->cfg->phase_noise_mode == 0) 331 dib3000mc_write_word(state, 111, 0x00); 332 else 333 dib3000mc_write_word(state, 111, 0x02); 334 335 // P_agc_global 336 dib3000mc_write_word(state, 50, 0x8000); 337 338 // agc setup misc 339 dib3000mc_setup_pwm_state(state); 340 341 // P_agc_counter_lock 342 dib3000mc_write_word(state, 53, 0x87); 343 // P_agc_counter_unlock 344 dib3000mc_write_word(state, 54, 0x87); 345 346 /* agc */ 347 dib3000mc_write_word(state, 36, state->cfg->max_time); 348 dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0)); 349 dib3000mc_write_word(state, 38, state->cfg->pwm3_value); 350 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level); 351 352 // set_agc_loop_Bw 353 dib3000mc_write_word(state, 40, 0x0179); 354 dib3000mc_write_word(state, 41, 0x03f0); 355 356 dib3000mc_write_word(state, 42, agc->agc1_max); 357 dib3000mc_write_word(state, 43, agc->agc1_min); 358 dib3000mc_write_word(state, 44, agc->agc2_max); 359 dib3000mc_write_word(state, 45, agc->agc2_min); 360 dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2); 361 dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2); 362 dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2); 363 dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2); 364 365// Begin: TimeOut registers 366 // P_pha3_thres 367 dib3000mc_write_word(state, 110, 3277); 368 // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80 369 dib3000mc_write_word(state, 26, 0x6680); 370 // lock_mask0 371 dib3000mc_write_word(state, 1, 4); 372 // lock_mask1 373 dib3000mc_write_word(state, 2, 4); 374 // lock_mask2 375 dib3000mc_write_word(state, 3, 0x1000); 376 // P_search_maxtrial=1 377 dib3000mc_write_word(state, 5, 1); 378 379 dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ); 380 381 // div_lock_mask 382 dib3000mc_write_word(state, 4, 0x814); 383 384 dib3000mc_write_word(state, 21, (1 << 9) | 0x164); 385 dib3000mc_write_word(state, 22, 0x463d); 386 387 // Spurious rm cfg 388 // P_cspu_regul, P_cspu_win_cut 389 dib3000mc_write_word(state, 120, 0x200f); 390 // P_adp_selec_monit 391 dib3000mc_write_word(state, 134, 0); 392 393 // Fec cfg 394 dib3000mc_write_word(state, 195, 0x10); 395 396 // diversity register: P_dvsy_sync_wait.. 397 dib3000mc_write_word(state, 180, 0x2FF0); 398 399 // Impulse noise configuration 400 dib3000mc_set_impulse_noise(state, 0, 1); 401 402 // output mode set-up 403 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z); 404 405 /* close the i2c-gate */ 406 dib3000mc_write_word(state, 769, (1 << 7) ); 407 408 return 0; 409} 410 411static int dib3000mc_sleep(struct dvb_frontend *demod) 412{ 413 struct dib3000mc_state *state = demod->demodulator_priv; 414 415 dib3000mc_write_word(state, 1031, 0xFFFF); 416 dib3000mc_write_word(state, 1032, 0xFFFF); 417 dib3000mc_write_word(state, 1033, 0xFFF0); 418 419 return 0; 420} 421 422static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam) 423{ 424 u16 cfg[4] = { 0 },reg; 425 switch (qam) { 426 case 0: 427 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0; 428 break; 429 case 1: 430 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0; 431 break; 432 case 2: 433 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8; 434 break; 435 } 436 for (reg = 129; reg < 133; reg++) 437 dib3000mc_write_word(state, reg, cfg[reg - 129]); 438} 439 440static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq) 441{ 442 u16 tmp; 443 444 dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0); 445 446// if (boost) 447// dib3000mc_write_word(state, 100, (11 << 6) + 6); 448// else 449 dib3000mc_write_word(state, 100, (16 << 6) + 9); 450 451 dib3000mc_write_word(state, 1027, 0x0800); 452 dib3000mc_write_word(state, 1027, 0x0000); 453 454 //Default cfg isi offset adp 455 dib3000mc_write_word(state, 26, 0x6680); 456 dib3000mc_write_word(state, 29, 0x1273); 457 dib3000mc_write_word(state, 33, 5); 458 dib3000mc_set_adp_cfg(state, 1); 459 dib3000mc_write_word(state, 133, 15564); 460 461 dib3000mc_write_word(state, 12 , 0x0); 462 dib3000mc_write_word(state, 13 , 0x3e8); 463 dib3000mc_write_word(state, 14 , 0x0); 464 dib3000mc_write_word(state, 15 , 0x3f2); 465 466 dib3000mc_write_word(state, 93,0); 467 dib3000mc_write_word(state, 94,0); 468 dib3000mc_write_word(state, 95,0); 469 dib3000mc_write_word(state, 96,0); 470 dib3000mc_write_word(state, 97,0); 471 dib3000mc_write_word(state, 98,0); 472 473 dib3000mc_set_impulse_noise(state, 0, chan->nfft); 474 475 tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha; 476 dib3000mc_write_word(state, 0, tmp); 477 478 dib3000mc_write_word(state, 5, seq); 479 480 tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp); 481 if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp)) 482 tmp |= chan->vit_code_rate_hp << 1; 483 else 484 tmp |= chan->vit_code_rate_lp << 1; 485 dib3000mc_write_word(state, 181, tmp); 486 487 // diversity synchro delay 488 tmp = dib3000mc_read_word(state, 180) & 0x000f; 489 tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin 490 dib3000mc_write_word(state, 180, tmp); 491 492 // restart demod 493 tmp = dib3000mc_read_word(state, 0); 494 dib3000mc_write_word(state, 0, tmp | (1 << 9)); 495 dib3000mc_write_word(state, 0, tmp); 496 497 msleep(30); 498 499 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft); 500} 501 502static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan) 503{ 504 struct dib3000mc_state *state = demod->demodulator_priv; 505 u16 reg; 506// u32 val; 507 struct dibx000_ofdm_channel fchan; 508 509 INIT_OFDM_CHANNEL(&fchan); 510 fchan = *chan; 511 512 513 /* a channel for autosearch */ 514 reg = 0; 515 if (chan->nfft == -1 && chan->guard == -1) reg = 7; 516 if (chan->nfft == -1 && chan->guard != -1) reg = 2; 517 if (chan->nfft != -1 && chan->guard == -1) reg = 3; 518 519 fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2; 520 fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2; 521 fchan.vit_hrch = 0; fchan.vit_select_hp = 1; 522 523 dib3000mc_set_channel_cfg(state, &fchan, reg); 524 525 reg = dib3000mc_read_word(state, 0); 526 dib3000mc_write_word(state, 0, reg | (1 << 8)); 527 dib3000mc_read_word(state, 511); 528 dib3000mc_write_word(state, 0, reg); 529 530 return 0; 531} 532 533static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod) 534{ 535 struct dib3000mc_state *state = demod->demodulator_priv; 536 u16 irq_pending = dib3000mc_read_word(state, 511); 537 538 if (irq_pending & 0x1) // failed 539 return 1; 540 541 if (irq_pending & 0x2) // succeeded 542 return 2; 543 544 return 0; // still pending 545} 546 547static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch) 548{ 549 struct dib3000mc_state *state = demod->demodulator_priv; 550 551 // ** configure demod ** 552 dib3000mc_set_channel_cfg(state, ch, 0); 553 554 // activates isi 555 dib3000mc_write_word(state, 29, 0x1073); 556 557 dib3000mc_set_adp_cfg(state, (u8)ch->nqam); 558 559 if (ch->nfft == 1) { 560 dib3000mc_write_word(state, 26, 38528); 561 dib3000mc_write_word(state, 33, 8); 562 } else { 563 dib3000mc_write_word(state, 26, 30336); 564 dib3000mc_write_word(state, 33, 6); 565 } 566 567 if (dib3000mc_read_word(state, 509) & 0x80) 568 dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1); 569 570 return 0; 571} 572 573struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating) 574{ 575 struct dib3000mc_state *st = demod->demodulator_priv; 576 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating); 577} 578 579EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master); 580 581static int dib3000mc_get_frontend(struct dvb_frontend* fe, 582 struct dvb_frontend_parameters *fep) 583{ 584 struct dib3000mc_state *state = fe->demodulator_priv; 585 u16 tps = dib3000mc_read_word(state,458); 586 587 fep->inversion = INVERSION_AUTO; 588 589 fep->u.ofdm.bandwidth = state->current_bandwidth; 590 591 switch ((tps >> 8) & 0x1) { 592 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; 593 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; 594 } 595 596 switch (tps & 0x3) { 597 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; 598 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; 599 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; 600 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; 601 } 602 603 switch ((tps >> 13) & 0x3) { 604 case 0: fep->u.ofdm.constellation = QPSK; break; 605 case 1: fep->u.ofdm.constellation = QAM_16; break; 606 case 2: 607 default: fep->u.ofdm.constellation = QAM_64; break; 608 } 609 610 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ 611 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */ 612 613 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; 614 switch ((tps >> 5) & 0x7) { 615 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; 616 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; 617 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; 618 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; 619 case 7: 620 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; 621 622 } 623 624 switch ((tps >> 2) & 0x7) { 625 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; 626 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; 627 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; 628 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; 629 case 7: 630 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; 631 } 632 633 return 0; 634} 635 636static int dib3000mc_set_frontend(struct dvb_frontend* fe, 637 struct dvb_frontend_parameters *fep) 638{ 639 struct dib3000mc_state *state = fe->demodulator_priv; 640 struct dibx000_ofdm_channel ch; 641 642 INIT_OFDM_CHANNEL(&ch); 643 FEP2DIB(fep,&ch); 644 645 state->current_bandwidth = fep->u.ofdm.bandwidth; 646 dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth); 647 648 if (fe->ops.tuner_ops.set_params) { 649 fe->ops.tuner_ops.set_params(fe, fep); 650 msleep(100); 651 } 652 653 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || 654 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || 655 fep->u.ofdm.constellation == QAM_AUTO || 656 fep->u.ofdm.code_rate_HP == FEC_AUTO) { 657 int i = 100, found; 658 659 dib3000mc_autosearch_start(fe, &ch); 660 do { 661 msleep(1); 662 found = dib3000mc_autosearch_is_irq(fe); 663 } while (found == 0 && i--); 664 665 dprintk("autosearch returns: %d\n",found); 666 if (found == 0 || found == 1) 667 return 0; // no channel found 668 669 dib3000mc_get_frontend(fe, fep); 670 FEP2DIB(fep,&ch); 671 } 672 673 /* make this a config parameter */ 674 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO); 675 676 return dib3000mc_tune(fe, &ch); 677} 678 679static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat) 680{ 681 struct dib3000mc_state *state = fe->demodulator_priv; 682 u16 lock = dib3000mc_read_word(state, 509); 683 684 *stat = 0; 685 686 if (lock & 0x8000) 687 *stat |= FE_HAS_SIGNAL; 688 if (lock & 0x3000) 689 *stat |= FE_HAS_CARRIER; 690 if (lock & 0x0100) 691 *stat |= FE_HAS_VITERBI; 692 if (lock & 0x0010) 693 *stat |= FE_HAS_SYNC; 694 if (lock & 0x0008) 695 *stat |= FE_HAS_LOCK; 696 697 return 0; 698} 699 700static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber) 701{ 702 struct dib3000mc_state *state = fe->demodulator_priv; 703 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501); 704 return 0; 705} 706 707static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) 708{ 709 struct dib3000mc_state *state = fe->demodulator_priv; 710 *unc = dib3000mc_read_word(state, 508); 711 return 0; 712} 713 714static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 715{ 716 struct dib3000mc_state *state = fe->demodulator_priv; 717 u16 val = dib3000mc_read_word(state, 392); 718 *strength = 65535 - val; 719 return 0; 720} 721 722static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr) 723{ 724 *snr = 0x0000; 725 return 0; 726} 727 728static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) 729{ 730 tune->min_delay_ms = 1000; 731 return 0; 732} 733 734static void dib3000mc_release(struct dvb_frontend *fe) 735{ 736 struct dib3000mc_state *state = fe->demodulator_priv; 737 dibx000_exit_i2c_master(&state->i2c_master); 738 kfree(state); 739} 740 741int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff) 742{ 743 struct dib3000mc_state *state = fe->demodulator_priv; 744 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0); 745 return 0; 746} 747EXPORT_SYMBOL(dib3000mc_pid_control); 748 749int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff) 750{ 751 struct dib3000mc_state *state = fe->demodulator_priv; 752 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4); 753 tmp |= (onoff << 4); 754 return dib3000mc_write_word(state, 206, tmp); 755} 756EXPORT_SYMBOL(dib3000mc_pid_parse); 757 758void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg) 759{ 760 struct dib3000mc_state *state = fe->demodulator_priv; 761 state->cfg = cfg; 762} 763EXPORT_SYMBOL(dib3000mc_set_config); 764 765int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]) 766{ 767 struct dib3000mc_state st = { .i2c_adap = i2c }; 768 int k; 769 u8 new_addr; 770 771 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26}; 772 773 for (k = no_of_demods-1; k >= 0; k--) { 774 st.cfg = &cfg[k]; 775 776 /* designated i2c address */ 777 new_addr = DIB3000MC_I2C_ADDRESS[k]; 778 st.i2c_addr = new_addr; 779 if (dib3000mc_identify(&st) != 0) { 780 st.i2c_addr = default_addr; 781 if (dib3000mc_identify(&st) != 0) { 782 dprintk("-E- DiB3000P/MC #%d: not identified\n", k); 783 return -ENODEV; 784 } 785 } 786 787 dib3000mc_set_output_mode(&st, OUTMODE_MPEG2_PAR_CONT_CLK); 788 789 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0) 790 dib3000mc_write_word(&st, 1024, (new_addr << 3) | 0x1); 791 st.i2c_addr = new_addr; 792 } 793 794 for (k = 0; k < no_of_demods; k++) { 795 st.cfg = &cfg[k]; 796 st.i2c_addr = DIB3000MC_I2C_ADDRESS[k]; 797 798 dib3000mc_write_word(&st, 1024, st.i2c_addr << 3); 799 800 /* turn off data output */ 801 dib3000mc_set_output_mode(&st, OUTMODE_HIGH_Z); 802 } 803 return 0; 804} 805EXPORT_SYMBOL(dib3000mc_i2c_enumeration); 806 807static struct dvb_frontend_ops dib3000mc_ops; 808 809struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) 810{ 811 struct dvb_frontend *demod; 812 struct dib3000mc_state *st; 813 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL); 814 if (st == NULL) 815 return NULL; 816 817 st->cfg = cfg; 818 st->i2c_adap = i2c_adap; 819 st->i2c_addr = i2c_addr; 820 821 demod = &st->demod; 822 demod->demodulator_priv = st; 823 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); 824 825 if (dib3000mc_identify(st) != 0) 826 goto error; 827 828 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr); 829 830 dib3000mc_write_word(st, 1037, 0x3130); 831 832 return demod; 833 834error: 835 kfree(st); 836 return NULL; 837} 838EXPORT_SYMBOL(dib3000mc_attach); 839 840static struct dvb_frontend_ops dib3000mc_ops = { 841 .info = { 842 .name = "DiBcom 3000MC/P", 843 .type = FE_OFDM, 844 .frequency_min = 44250000, 845 .frequency_max = 867250000, 846 .frequency_stepsize = 62500, 847 .caps = FE_CAN_INVERSION_AUTO | 848 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 849 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 850 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 851 FE_CAN_TRANSMISSION_MODE_AUTO | 852 FE_CAN_GUARD_INTERVAL_AUTO | 853 FE_CAN_RECOVER | 854 FE_CAN_HIERARCHY_AUTO, 855 }, 856 857 .release = dib3000mc_release, 858 859 .init = dib3000mc_init, 860 .sleep = dib3000mc_sleep, 861 862 .set_frontend = dib3000mc_set_frontend, 863 .get_tune_settings = dib3000mc_fe_get_tune_settings, 864 .get_frontend = dib3000mc_get_frontend, 865 866 .read_status = dib3000mc_read_status, 867 .read_ber = dib3000mc_read_ber, 868 .read_signal_strength = dib3000mc_read_signal_strength, 869 .read_snr = dib3000mc_read_snr, 870 .read_ucblocks = dib3000mc_read_unc_blocks, 871}; 872 873MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 874MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator"); 875MODULE_LICENSE("GPL");