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 842 lines 24 kB view raw
1/* 2 * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B 3 * DiBcom (http://www.dibcom.fr/) 4 * 5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) 6 * 7 * based on GPL code from DibCom, which has 8 * 9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License as 13 * published by the Free Software Foundation, version 2. 14 * 15 * Acknowledgements 16 * 17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver 18 * sources, on which this driver (and the dvb-dibusb) are based. 19 * 20 * see Documentation/dvb/README.dibusb for more information 21 * 22 */ 23 24#include <linux/kernel.h> 25#include <linux/module.h> 26#include <linux/moduleparam.h> 27#include <linux/init.h> 28#include <linux/delay.h> 29#include <linux/string.h> 30#include <linux/slab.h> 31 32#include "dvb_frontend.h" 33 34#include "dib3000.h" 35#include "dib3000mb_priv.h" 36 37/* Version information */ 38#define DRIVER_VERSION "0.1" 39#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator" 40#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de" 41 42#ifdef CONFIG_DVB_DIBCOM_DEBUG 43static int debug; 44module_param(debug, int, 0644); 45MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able))."); 46#endif 47#define deb_info(args...) dprintk(0x01,args) 48#define deb_i2c(args...) dprintk(0x02,args) 49#define deb_srch(args...) dprintk(0x04,args) 50#define deb_info(args...) dprintk(0x01,args) 51#define deb_xfer(args...) dprintk(0x02,args) 52#define deb_setf(args...) dprintk(0x04,args) 53#define deb_getf(args...) dprintk(0x08,args) 54 55#ifdef CONFIG_DVB_DIBCOM_DEBUG 56static int debug; 57module_param(debug, int, 0644); 58MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able))."); 59#endif 60 61static int dib3000_read_reg(struct dib3000_state *state, u16 reg) 62{ 63 u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff }; 64 u8 rb[2]; 65 struct i2c_msg msg[] = { 66 { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 }, 67 { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 }, 68 }; 69 70 if (i2c_transfer(state->i2c, msg, 2) != 2) 71 deb_i2c("i2c read error\n"); 72 73 deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg, 74 (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]); 75 76 return (rb[0] << 8) | rb[1]; 77} 78 79static int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val) 80{ 81 u8 b[] = { 82 (reg >> 8) & 0xff, reg & 0xff, 83 (val >> 8) & 0xff, val & 0xff, 84 }; 85 struct i2c_msg msg[] = { 86 { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 } 87 }; 88 deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val); 89 90 return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0; 91} 92 93static int dib3000_search_status(u16 irq,u16 lock) 94{ 95 if (irq & 0x02) { 96 if (lock & 0x01) { 97 deb_srch("auto search succeeded\n"); 98 return 1; // auto search succeeded 99 } else { 100 deb_srch("auto search not successful\n"); 101 return 0; // auto search failed 102 } 103 } else if (irq & 0x01) { 104 deb_srch("auto search failed\n"); 105 return 0; // auto search failed 106 } 107 return -1; // try again 108} 109 110/* for auto search */ 111static u16 dib3000_seq[2][2][2] = /* fft,gua, inv */ 112 { /* fft */ 113 { /* gua */ 114 { 0, 1 }, /* 0 0 { 0,1 } */ 115 { 3, 9 }, /* 0 1 { 0,1 } */ 116 }, 117 { 118 { 2, 5 }, /* 1 0 { 0,1 } */ 119 { 6, 11 }, /* 1 1 { 0,1 } */ 120 } 121 }; 122 123static int dib3000mb_get_frontend(struct dvb_frontend* fe, 124 struct dvb_frontend_parameters *fep); 125 126static int dib3000mb_set_frontend(struct dvb_frontend* fe, 127 struct dvb_frontend_parameters *fep, int tuner) 128{ 129 struct dib3000_state* state = fe->demodulator_priv; 130 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; 131 fe_code_rate_t fe_cr = FEC_NONE; 132 int search_state, seq; 133 134 if (tuner && fe->ops.tuner_ops.set_params) { 135 fe->ops.tuner_ops.set_params(fe, fep); 136 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); 137 138 deb_setf("bandwidth: "); 139 switch (ofdm->bandwidth) { 140 case BANDWIDTH_8_MHZ: 141 deb_setf("8 MHz\n"); 142 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]); 143 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); 144 break; 145 case BANDWIDTH_7_MHZ: 146 deb_setf("7 MHz\n"); 147 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]); 148 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz); 149 break; 150 case BANDWIDTH_6_MHZ: 151 deb_setf("6 MHz\n"); 152 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]); 153 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz); 154 break; 155 case BANDWIDTH_AUTO: 156 return -EOPNOTSUPP; 157 default: 158 err("unkown bandwidth value."); 159 return -EINVAL; 160 } 161 } 162 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); 163 164 deb_setf("transmission mode: "); 165 switch (ofdm->transmission_mode) { 166 case TRANSMISSION_MODE_2K: 167 deb_setf("2k\n"); 168 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K); 169 break; 170 case TRANSMISSION_MODE_8K: 171 deb_setf("8k\n"); 172 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K); 173 break; 174 case TRANSMISSION_MODE_AUTO: 175 deb_setf("auto\n"); 176 break; 177 default: 178 return -EINVAL; 179 } 180 181 deb_setf("guard: "); 182 switch (ofdm->guard_interval) { 183 case GUARD_INTERVAL_1_32: 184 deb_setf("1_32\n"); 185 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32); 186 break; 187 case GUARD_INTERVAL_1_16: 188 deb_setf("1_16\n"); 189 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16); 190 break; 191 case GUARD_INTERVAL_1_8: 192 deb_setf("1_8\n"); 193 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8); 194 break; 195 case GUARD_INTERVAL_1_4: 196 deb_setf("1_4\n"); 197 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4); 198 break; 199 case GUARD_INTERVAL_AUTO: 200 deb_setf("auto\n"); 201 break; 202 default: 203 return -EINVAL; 204 } 205 206 deb_setf("inversion: "); 207 switch (fep->inversion) { 208 case INVERSION_OFF: 209 deb_setf("off\n"); 210 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF); 211 break; 212 case INVERSION_AUTO: 213 deb_setf("auto "); 214 break; 215 case INVERSION_ON: 216 deb_setf("on\n"); 217 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON); 218 break; 219 default: 220 return -EINVAL; 221 } 222 223 deb_setf("constellation: "); 224 switch (ofdm->constellation) { 225 case QPSK: 226 deb_setf("qpsk\n"); 227 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK); 228 break; 229 case QAM_16: 230 deb_setf("qam16\n"); 231 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM); 232 break; 233 case QAM_64: 234 deb_setf("qam64\n"); 235 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM); 236 break; 237 case QAM_AUTO: 238 break; 239 default: 240 return -EINVAL; 241 } 242 deb_setf("hierachy: "); 243 switch (ofdm->hierarchy_information) { 244 case HIERARCHY_NONE: 245 deb_setf("none "); 246 /* fall through */ 247 case HIERARCHY_1: 248 deb_setf("alpha=1\n"); 249 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1); 250 break; 251 case HIERARCHY_2: 252 deb_setf("alpha=2\n"); 253 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2); 254 break; 255 case HIERARCHY_4: 256 deb_setf("alpha=4\n"); 257 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4); 258 break; 259 case HIERARCHY_AUTO: 260 deb_setf("alpha=auto\n"); 261 break; 262 default: 263 return -EINVAL; 264 } 265 266 deb_setf("hierarchy: "); 267 if (ofdm->hierarchy_information == HIERARCHY_NONE) { 268 deb_setf("none\n"); 269 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF); 270 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP); 271 fe_cr = ofdm->code_rate_HP; 272 } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) { 273 deb_setf("on\n"); 274 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON); 275 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP); 276 fe_cr = ofdm->code_rate_LP; 277 } 278 deb_setf("fec: "); 279 switch (fe_cr) { 280 case FEC_1_2: 281 deb_setf("1_2\n"); 282 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2); 283 break; 284 case FEC_2_3: 285 deb_setf("2_3\n"); 286 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3); 287 break; 288 case FEC_3_4: 289 deb_setf("3_4\n"); 290 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4); 291 break; 292 case FEC_5_6: 293 deb_setf("5_6\n"); 294 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6); 295 break; 296 case FEC_7_8: 297 deb_setf("7_8\n"); 298 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8); 299 break; 300 case FEC_NONE: 301 deb_setf("none "); 302 break; 303 case FEC_AUTO: 304 deb_setf("auto\n"); 305 break; 306 default: 307 return -EINVAL; 308 } 309 310 seq = dib3000_seq 311 [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO] 312 [ofdm->guard_interval == GUARD_INTERVAL_AUTO] 313 [fep->inversion == INVERSION_AUTO]; 314 315 deb_setf("seq? %d\n", seq); 316 317 wr(DIB3000MB_REG_SEQ, seq); 318 319 wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE); 320 321 if (ofdm->transmission_mode == TRANSMISSION_MODE_2K) { 322 if (ofdm->guard_interval == GUARD_INTERVAL_1_8) { 323 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8); 324 } else { 325 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT); 326 } 327 328 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K); 329 } else { 330 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT); 331 } 332 333 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF); 334 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF); 335 wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF); 336 337 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high); 338 339 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE); 340 341 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL); 342 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); 343 344 /* wait for AGC lock */ 345 msleep(70); 346 347 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low); 348 349 /* something has to be auto searched */ 350 if (ofdm->constellation == QAM_AUTO || 351 ofdm->hierarchy_information == HIERARCHY_AUTO || 352 fe_cr == FEC_AUTO || 353 fep->inversion == INVERSION_AUTO) { 354 int as_count=0; 355 356 deb_setf("autosearch enabled.\n"); 357 358 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT); 359 360 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH); 361 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); 362 363 while ((search_state = 364 dib3000_search_status( 365 rd(DIB3000MB_REG_AS_IRQ_PENDING), 366 rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100) 367 msleep(1); 368 369 deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count); 370 371 if (search_state == 1) { 372 struct dvb_frontend_parameters feps; 373 if (dib3000mb_get_frontend(fe, &feps) == 0) { 374 deb_setf("reading tuning data from frontend succeeded.\n"); 375 return dib3000mb_set_frontend(fe, &feps, 0); 376 } 377 } 378 379 } else { 380 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL); 381 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); 382 } 383 384 return 0; 385} 386 387static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) 388{ 389 struct dib3000_state* state = fe->demodulator_priv; 390 391 deb_info("dib3000mb is getting up.\n"); 392 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP); 393 394 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC); 395 396 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE); 397 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST); 398 399 wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT); 400 401 wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON); 402 403 wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB); 404 wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB); 405 406 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]); 407 408 wr_foreach(dib3000mb_reg_impulse_noise, 409 dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]); 410 411 wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain); 412 413 wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT); 414 415 wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase); 416 417 wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration); 418 419 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low); 420 421 wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT); 422 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); 423 wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT); 424 wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]); 425 426 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); 427 428 wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68); 429 wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69); 430 wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71); 431 wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77); 432 wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78); 433 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT); 434 wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92); 435 wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96); 436 wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97); 437 wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106); 438 wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107); 439 wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108); 440 wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122); 441 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF); 442 wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT); 443 444 wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs); 445 446 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON); 447 wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB); 448 wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB); 449 450 wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE); 451 452 wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142); 453 wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188); 454 wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE); 455 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT); 456 wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146); 457 wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147); 458 459 wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); 460 461 return 0; 462} 463 464static int dib3000mb_get_frontend(struct dvb_frontend* fe, 465 struct dvb_frontend_parameters *fep) 466{ 467 struct dib3000_state* state = fe->demodulator_priv; 468 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; 469 fe_code_rate_t *cr; 470 u16 tps_val; 471 int inv_test1,inv_test2; 472 u32 dds_val, threshold = 0x800000; 473 474 if (!rd(DIB3000MB_REG_TPS_LOCK)) 475 return 0; 476 477 dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB); 478 deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB)); 479 if (dds_val < threshold) 480 inv_test1 = 0; 481 else if (dds_val == threshold) 482 inv_test1 = 1; 483 else 484 inv_test1 = 2; 485 486 dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB); 487 deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB)); 488 if (dds_val < threshold) 489 inv_test2 = 0; 490 else if (dds_val == threshold) 491 inv_test2 = 1; 492 else 493 inv_test2 = 2; 494 495 fep->inversion = 496 ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) || 497 ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ? 498 INVERSION_ON : INVERSION_OFF; 499 500 deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion); 501 502 switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) { 503 case DIB3000_CONSTELLATION_QPSK: 504 deb_getf("QPSK "); 505 ofdm->constellation = QPSK; 506 break; 507 case DIB3000_CONSTELLATION_16QAM: 508 deb_getf("QAM16 "); 509 ofdm->constellation = QAM_16; 510 break; 511 case DIB3000_CONSTELLATION_64QAM: 512 deb_getf("QAM64 "); 513 ofdm->constellation = QAM_64; 514 break; 515 default: 516 err("Unexpected constellation returned by TPS (%d)", tps_val); 517 break; 518 } 519 deb_getf("TPS: %d\n", tps_val); 520 521 if (rd(DIB3000MB_REG_TPS_HRCH)) { 522 deb_getf("HRCH ON\n"); 523 cr = &ofdm->code_rate_LP; 524 ofdm->code_rate_HP = FEC_NONE; 525 switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) { 526 case DIB3000_ALPHA_0: 527 deb_getf("HIERARCHY_NONE "); 528 ofdm->hierarchy_information = HIERARCHY_NONE; 529 break; 530 case DIB3000_ALPHA_1: 531 deb_getf("HIERARCHY_1 "); 532 ofdm->hierarchy_information = HIERARCHY_1; 533 break; 534 case DIB3000_ALPHA_2: 535 deb_getf("HIERARCHY_2 "); 536 ofdm->hierarchy_information = HIERARCHY_2; 537 break; 538 case DIB3000_ALPHA_4: 539 deb_getf("HIERARCHY_4 "); 540 ofdm->hierarchy_information = HIERARCHY_4; 541 break; 542 default: 543 err("Unexpected ALPHA value returned by TPS (%d)", tps_val); 544 break; 545 } 546 deb_getf("TPS: %d\n", tps_val); 547 548 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP); 549 } else { 550 deb_getf("HRCH OFF\n"); 551 cr = &ofdm->code_rate_HP; 552 ofdm->code_rate_LP = FEC_NONE; 553 ofdm->hierarchy_information = HIERARCHY_NONE; 554 555 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP); 556 } 557 558 switch (tps_val) { 559 case DIB3000_FEC_1_2: 560 deb_getf("FEC_1_2 "); 561 *cr = FEC_1_2; 562 break; 563 case DIB3000_FEC_2_3: 564 deb_getf("FEC_2_3 "); 565 *cr = FEC_2_3; 566 break; 567 case DIB3000_FEC_3_4: 568 deb_getf("FEC_3_4 "); 569 *cr = FEC_3_4; 570 break; 571 case DIB3000_FEC_5_6: 572 deb_getf("FEC_5_6 "); 573 *cr = FEC_4_5; 574 break; 575 case DIB3000_FEC_7_8: 576 deb_getf("FEC_7_8 "); 577 *cr = FEC_7_8; 578 break; 579 default: 580 err("Unexpected FEC returned by TPS (%d)", tps_val); 581 break; 582 } 583 deb_getf("TPS: %d\n",tps_val); 584 585 switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) { 586 case DIB3000_GUARD_TIME_1_32: 587 deb_getf("GUARD_INTERVAL_1_32 "); 588 ofdm->guard_interval = GUARD_INTERVAL_1_32; 589 break; 590 case DIB3000_GUARD_TIME_1_16: 591 deb_getf("GUARD_INTERVAL_1_16 "); 592 ofdm->guard_interval = GUARD_INTERVAL_1_16; 593 break; 594 case DIB3000_GUARD_TIME_1_8: 595 deb_getf("GUARD_INTERVAL_1_8 "); 596 ofdm->guard_interval = GUARD_INTERVAL_1_8; 597 break; 598 case DIB3000_GUARD_TIME_1_4: 599 deb_getf("GUARD_INTERVAL_1_4 "); 600 ofdm->guard_interval = GUARD_INTERVAL_1_4; 601 break; 602 default: 603 err("Unexpected Guard Time returned by TPS (%d)", tps_val); 604 break; 605 } 606 deb_getf("TPS: %d\n", tps_val); 607 608 switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) { 609 case DIB3000_TRANSMISSION_MODE_2K: 610 deb_getf("TRANSMISSION_MODE_2K "); 611 ofdm->transmission_mode = TRANSMISSION_MODE_2K; 612 break; 613 case DIB3000_TRANSMISSION_MODE_8K: 614 deb_getf("TRANSMISSION_MODE_8K "); 615 ofdm->transmission_mode = TRANSMISSION_MODE_8K; 616 break; 617 default: 618 err("unexpected transmission mode return by TPS (%d)", tps_val); 619 break; 620 } 621 deb_getf("TPS: %d\n", tps_val); 622 623 return 0; 624} 625 626static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat) 627{ 628 struct dib3000_state* state = fe->demodulator_priv; 629 630 *stat = 0; 631 632 if (rd(DIB3000MB_REG_AGC_LOCK)) 633 *stat |= FE_HAS_SIGNAL; 634 if (rd(DIB3000MB_REG_CARRIER_LOCK)) 635 *stat |= FE_HAS_CARRIER; 636 if (rd(DIB3000MB_REG_VIT_LCK)) 637 *stat |= FE_HAS_VITERBI; 638 if (rd(DIB3000MB_REG_TS_SYNC_LOCK)) 639 *stat |= (FE_HAS_SYNC | FE_HAS_LOCK); 640 641 deb_getf("actual status is %2x\n",*stat); 642 643 deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n", 644 rd(DIB3000MB_REG_TPS_LOCK), 645 rd(DIB3000MB_REG_TPS_QAM), 646 rd(DIB3000MB_REG_TPS_HRCH), 647 rd(DIB3000MB_REG_TPS_VIT_ALPHA), 648 rd(DIB3000MB_REG_TPS_CODE_RATE_HP), 649 rd(DIB3000MB_REG_TPS_CODE_RATE_LP), 650 rd(DIB3000MB_REG_TPS_GUARD_TIME), 651 rd(DIB3000MB_REG_TPS_FFT), 652 rd(DIB3000MB_REG_TPS_CELL_ID)); 653 654 //*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; 655 return 0; 656} 657 658static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber) 659{ 660 struct dib3000_state* state = fe->demodulator_priv; 661 662 *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB)); 663 return 0; 664} 665 666/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */ 667static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength) 668{ 669 struct dib3000_state* state = fe->demodulator_priv; 670 671 *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170; 672 return 0; 673} 674 675static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr) 676{ 677 struct dib3000_state* state = fe->demodulator_priv; 678 short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER); 679 int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) | 680 rd(DIB3000MB_REG_NOISE_POWER_LSB); 681 *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1); 682 return 0; 683} 684 685static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) 686{ 687 struct dib3000_state* state = fe->demodulator_priv; 688 689 *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE); 690 return 0; 691} 692 693static int dib3000mb_sleep(struct dvb_frontend* fe) 694{ 695 struct dib3000_state* state = fe->demodulator_priv; 696 deb_info("dib3000mb is going to bed.\n"); 697 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN); 698 return 0; 699} 700 701static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) 702{ 703 tune->min_delay_ms = 800; 704 return 0; 705} 706 707static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe) 708{ 709 return dib3000mb_fe_init(fe, 0); 710} 711 712static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) 713{ 714 return dib3000mb_set_frontend(fe, fep, 1); 715} 716 717static void dib3000mb_release(struct dvb_frontend* fe) 718{ 719 struct dib3000_state *state = fe->demodulator_priv; 720 kfree(state); 721} 722 723/* pid filter and transfer stuff */ 724static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff) 725{ 726 struct dib3000_state *state = fe->demodulator_priv; 727 pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0); 728 wr(index+DIB3000MB_REG_FIRST_PID,pid); 729 return 0; 730} 731 732static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff) 733{ 734 struct dib3000_state *state = fe->demodulator_priv; 735 736 deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling"); 737 if (onoff) { 738 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE); 739 } else { 740 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT); 741 } 742 return 0; 743} 744 745static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff) 746{ 747 struct dib3000_state *state = fe->demodulator_priv; 748 deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling"); 749 wr(DIB3000MB_REG_PID_PARSE,onoff); 750 return 0; 751} 752 753static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) 754{ 755 struct dib3000_state *state = fe->demodulator_priv; 756 if (onoff) { 757 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr)); 758 } else { 759 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr)); 760 } 761 return 0; 762} 763 764static struct dvb_frontend_ops dib3000mb_ops; 765 766struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, 767 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops) 768{ 769 struct dib3000_state* state = NULL; 770 771 /* allocate memory for the internal state */ 772 state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL); 773 if (state == NULL) 774 goto error; 775 776 /* setup the state */ 777 state->i2c = i2c; 778 memcpy(&state->config,config,sizeof(struct dib3000_config)); 779 780 /* check for the correct demod */ 781 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) 782 goto error; 783 784 if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID) 785 goto error; 786 787 /* create dvb_frontend */ 788 memcpy(&state->frontend.ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops)); 789 state->frontend.demodulator_priv = state; 790 791 /* set the xfer operations */ 792 xfer_ops->pid_parse = dib3000mb_pid_parse; 793 xfer_ops->fifo_ctrl = dib3000mb_fifo_control; 794 xfer_ops->pid_ctrl = dib3000mb_pid_control; 795 xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl; 796 797 return &state->frontend; 798 799error: 800 kfree(state); 801 return NULL; 802} 803 804static struct dvb_frontend_ops dib3000mb_ops = { 805 806 .info = { 807 .name = "DiBcom 3000M-B DVB-T", 808 .type = FE_OFDM, 809 .frequency_min = 44250000, 810 .frequency_max = 867250000, 811 .frequency_stepsize = 62500, 812 .caps = FE_CAN_INVERSION_AUTO | 813 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 814 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 815 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 816 FE_CAN_TRANSMISSION_MODE_AUTO | 817 FE_CAN_GUARD_INTERVAL_AUTO | 818 FE_CAN_RECOVER | 819 FE_CAN_HIERARCHY_AUTO, 820 }, 821 822 .release = dib3000mb_release, 823 824 .init = dib3000mb_fe_init_nonmobile, 825 .sleep = dib3000mb_sleep, 826 827 .set_frontend = dib3000mb_set_frontend_and_tuner, 828 .get_frontend = dib3000mb_get_frontend, 829 .get_tune_settings = dib3000mb_fe_get_tune_settings, 830 831 .read_status = dib3000mb_read_status, 832 .read_ber = dib3000mb_read_ber, 833 .read_signal_strength = dib3000mb_read_signal_strength, 834 .read_snr = dib3000mb_read_snr, 835 .read_ucblocks = dib3000mb_read_unc_blocks, 836}; 837 838MODULE_AUTHOR(DRIVER_AUTHOR); 839MODULE_DESCRIPTION(DRIVER_DESC); 840MODULE_LICENSE("GPL"); 841 842EXPORT_SYMBOL(dib3000mb_attach);