1 /* 2 * 3 * device driver for Conexant 2388x based TV cards 4 * MPEG Transport Stream (DVB) routines 5 * 6 * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> 7 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 */ 23 24 #include <linux/module.h> 25 #include <linux/init.h> 26 #include <linux/device.h> 27 #include <linux/fs.h> 28 #include <linux/kthread.h> 29 #include <linux/file.h> 30 #include <linux/suspend.h> 31 32 #include "cx88.h" 33 #include "dvb-pll.h" 34 #include <media/v4l2-common.h> 35 36 #include "mt352.h" 37 #include "mt352_priv.h" 38 #include "cx88-vp3054-i2c.h" 39 #include "zl10353.h" 40 #include "cx22702.h" 41 #include "or51132.h" 42 #include "lgdt330x.h" 43 #include "s5h1409.h" 44 #include "xc4000.h" 45 #include "xc5000.h" 46 #include "nxt200x.h" 47 #include "cx24123.h" 48 #include "isl6421.h" 49 #include "tuner-simple.h" 50 #include "tda9887.h" 51 #include "s5h1411.h" 52 #include "stv0299.h" 53 #include "z0194a.h" 54 #include "stv0288.h" 55 #include "stb6000.h" 56 #include "cx24116.h" 57 #include "stv0900.h" 58 #include "stb6100.h" 59 #include "stb6100_proc.h" 60 #include "mb86a16.h" 61 #include "ts2020.h" 62 #include "ds3000.h" 63 64 MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 65 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 66 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 67 MODULE_LICENSE("GPL"); 68 MODULE_VERSION(CX88_VERSION); 69 70 static unsigned int debug; 71 module_param(debug, int, 0644); 72 MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); 73 74 static unsigned int dvb_buf_tscnt = 32; 75 module_param(dvb_buf_tscnt, int, 0644); 76 MODULE_PARM_DESC(dvb_buf_tscnt, "DVB Buffer TS count [dvb]"); 77 78 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 79 80 #define dprintk(level,fmt, arg...) if (debug >= level) \ 81 printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg) 82 83 /* ------------------------------------------------------------------ */ 84 85 static int dvb_buf_setup(struct videobuf_queue *q, 86 unsigned int *count, unsigned int *size) 87 { 88 struct cx8802_dev *dev = q->priv_data; 89 90 dev->ts_packet_size = 188 * 4; 91 dev->ts_packet_count = dvb_buf_tscnt; 92 93 *size = dev->ts_packet_size * dev->ts_packet_count; 94 *count = dvb_buf_tscnt; 95 return 0; 96 } 97 98 static int dvb_buf_prepare(struct videobuf_queue *q, 99 struct videobuf_buffer *vb, enum v4l2_field field) 100 { 101 struct cx8802_dev *dev = q->priv_data; 102 return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field); 103 } 104 105 static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 106 { 107 struct cx8802_dev *dev = q->priv_data; 108 cx8802_buf_queue(dev, (struct cx88_buffer*)vb); 109 } 110 111 static void dvb_buf_release(struct videobuf_queue *q, 112 struct videobuf_buffer *vb) 113 { 114 cx88_free_buffer(q, (struct cx88_buffer*)vb); 115 } 116 117 static const struct videobuf_queue_ops dvb_qops = { 118 .buf_setup = dvb_buf_setup, 119 .buf_prepare = dvb_buf_prepare, 120 .buf_queue = dvb_buf_queue, 121 .buf_release = dvb_buf_release, 122 }; 123 124 /* ------------------------------------------------------------------ */ 125 126 static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) 127 { 128 struct cx8802_dev *dev= fe->dvb->priv; 129 struct cx8802_driver *drv = NULL; 130 int ret = 0; 131 int fe_id; 132 133 fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe); 134 if (!fe_id) { 135 printk(KERN_ERR "%s() No frontend found\n", __func__); 136 return -EINVAL; 137 } 138 139 mutex_lock(&dev->core->lock); 140 drv = cx8802_get_driver(dev, CX88_MPEG_DVB); 141 if (drv) { 142 if (acquire){ 143 dev->frontends.active_fe_id = fe_id; 144 ret = drv->request_acquire(drv); 145 } else { 146 ret = drv->request_release(drv); 147 dev->frontends.active_fe_id = 0; 148 } 149 } 150 mutex_unlock(&dev->core->lock); 151 152 return ret; 153 } 154 155 static void cx88_dvb_gate_ctrl(struct cx88_core *core, int open) 156 { 157 struct videobuf_dvb_frontends *f; 158 struct videobuf_dvb_frontend *fe; 159 160 if (!core->dvbdev) 161 return; 162 163 f = &core->dvbdev->frontends; 164 165 if (!f) 166 return; 167 168 if (f->gate <= 1) /* undefined or fe0 */ 169 fe = videobuf_dvb_get_frontend(f, 1); 170 else 171 fe = videobuf_dvb_get_frontend(f, f->gate); 172 173 if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) 174 fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open); 175 } 176 177 /* ------------------------------------------------------------------ */ 178 179 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) 180 { 181 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 }; 182 static const u8 reset [] = { RESET, 0x80 }; 183 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; 184 static const u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; 185 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; 186 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; 187 188 mt352_write(fe, clock_config, sizeof(clock_config)); 189 udelay(200); 190 mt352_write(fe, reset, sizeof(reset)); 191 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); 192 193 mt352_write(fe, agc_cfg, sizeof(agc_cfg)); 194 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); 195 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); 196 return 0; 197 } 198 199 static int dvico_dual_demod_init(struct dvb_frontend *fe) 200 { 201 static const u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; 202 static const u8 reset [] = { RESET, 0x80 }; 203 static const u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; 204 static const u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; 205 static const u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; 206 static const u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; 207 208 mt352_write(fe, clock_config, sizeof(clock_config)); 209 udelay(200); 210 mt352_write(fe, reset, sizeof(reset)); 211 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); 212 213 mt352_write(fe, agc_cfg, sizeof(agc_cfg)); 214 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); 215 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); 216 217 return 0; 218 } 219 220 static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) 221 { 222 static const u8 clock_config [] = { 0x89, 0x38, 0x39 }; 223 static const u8 reset [] = { 0x50, 0x80 }; 224 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 225 static const u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, 226 0x00, 0xFF, 0x00, 0x40, 0x40 }; 227 static const u8 dntv_extra[] = { 0xB5, 0x7A }; 228 static const u8 capt_range_cfg[] = { 0x75, 0x32 }; 229 230 mt352_write(fe, clock_config, sizeof(clock_config)); 231 udelay(2000); 232 mt352_write(fe, reset, sizeof(reset)); 233 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); 234 235 mt352_write(fe, agc_cfg, sizeof(agc_cfg)); 236 udelay(2000); 237 mt352_write(fe, dntv_extra, sizeof(dntv_extra)); 238 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); 239 240 return 0; 241 } 242 243 static const struct mt352_config dvico_fusionhdtv = { 244 .demod_address = 0x0f, 245 .demod_init = dvico_fusionhdtv_demod_init, 246 }; 247 248 static const struct mt352_config dntv_live_dvbt_config = { 249 .demod_address = 0x0f, 250 .demod_init = dntv_live_dvbt_demod_init, 251 }; 252 253 static const struct mt352_config dvico_fusionhdtv_dual = { 254 .demod_address = 0x0f, 255 .demod_init = dvico_dual_demod_init, 256 }; 257 258 static const struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = { 259 .demod_address = (0x1e >> 1), 260 .no_tuner = 1, 261 .if2 = 45600, 262 }; 263 264 static struct mb86a16_config twinhan_vp1027 = { 265 .demod_address = 0x08, 266 }; 267 268 #if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054) 269 static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) 270 { 271 static const u8 clock_config [] = { 0x89, 0x38, 0x38 }; 272 static const u8 reset [] = { 0x50, 0x80 }; 273 static const u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 274 static const u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF, 275 0x00, 0xFF, 0x00, 0x40, 0x40 }; 276 static const u8 dntv_extra[] = { 0xB5, 0x7A }; 277 static const u8 capt_range_cfg[] = { 0x75, 0x32 }; 278 279 mt352_write(fe, clock_config, sizeof(clock_config)); 280 udelay(2000); 281 mt352_write(fe, reset, sizeof(reset)); 282 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); 283 284 mt352_write(fe, agc_cfg, sizeof(agc_cfg)); 285 udelay(2000); 286 mt352_write(fe, dntv_extra, sizeof(dntv_extra)); 287 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); 288 289 return 0; 290 } 291 292 static const struct mt352_config dntv_live_dvbt_pro_config = { 293 .demod_address = 0x0f, 294 .no_tuner = 1, 295 .demod_init = dntv_live_dvbt_pro_demod_init, 296 }; 297 #endif 298 299 static const struct zl10353_config dvico_fusionhdtv_hybrid = { 300 .demod_address = 0x0f, 301 .no_tuner = 1, 302 }; 303 304 static const struct zl10353_config dvico_fusionhdtv_xc3028 = { 305 .demod_address = 0x0f, 306 .if2 = 45600, 307 .no_tuner = 1, 308 }; 309 310 static const struct mt352_config dvico_fusionhdtv_mt352_xc3028 = { 311 .demod_address = 0x0f, 312 .if2 = 4560, 313 .no_tuner = 1, 314 .demod_init = dvico_fusionhdtv_demod_init, 315 }; 316 317 static const struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { 318 .demod_address = 0x0f, 319 }; 320 321 static const struct cx22702_config connexant_refboard_config = { 322 .demod_address = 0x43, 323 .output_mode = CX22702_SERIAL_OUTPUT, 324 }; 325 326 static const struct cx22702_config hauppauge_hvr_config = { 327 .demod_address = 0x63, 328 .output_mode = CX22702_SERIAL_OUTPUT, 329 }; 330 331 static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured) 332 { 333 struct cx8802_dev *dev= fe->dvb->priv; 334 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; 335 return 0; 336 } 337 338 static const struct or51132_config pchdtv_hd3000 = { 339 .demod_address = 0x15, 340 .set_ts_params = or51132_set_ts_param, 341 }; 342 343 static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) 344 { 345 struct cx8802_dev *dev= fe->dvb->priv; 346 struct cx88_core *core = dev->core; 347 348 dprintk(1, "%s: index = %d\n", __func__, index); 349 if (index == 0) 350 cx_clear(MO_GP0_IO, 8); 351 else 352 cx_set(MO_GP0_IO, 8); 353 return 0; 354 } 355 356 static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured) 357 { 358 struct cx8802_dev *dev= fe->dvb->priv; 359 if (is_punctured) 360 dev->ts_gen_cntrl |= 0x04; 361 else 362 dev->ts_gen_cntrl &= ~0x04; 363 return 0; 364 } 365 366 static struct lgdt330x_config fusionhdtv_3_gold = { 367 .demod_address = 0x0e, 368 .demod_chip = LGDT3302, 369 .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ 370 .set_ts_params = lgdt330x_set_ts_param, 371 }; 372 373 static const struct lgdt330x_config fusionhdtv_5_gold = { 374 .demod_address = 0x0e, 375 .demod_chip = LGDT3303, 376 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ 377 .set_ts_params = lgdt330x_set_ts_param, 378 }; 379 380 static const struct lgdt330x_config pchdtv_hd5500 = { 381 .demod_address = 0x59, 382 .demod_chip = LGDT3303, 383 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ 384 .set_ts_params = lgdt330x_set_ts_param, 385 }; 386 387 static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured) 388 { 389 struct cx8802_dev *dev= fe->dvb->priv; 390 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; 391 return 0; 392 } 393 394 static const struct nxt200x_config ati_hdtvwonder = { 395 .demod_address = 0x0a, 396 .set_ts_params = nxt200x_set_ts_param, 397 }; 398 399 static int cx24123_set_ts_param(struct dvb_frontend* fe, 400 int is_punctured) 401 { 402 struct cx8802_dev *dev= fe->dvb->priv; 403 dev->ts_gen_cntrl = 0x02; 404 return 0; 405 } 406 407 static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, 408 fe_sec_voltage_t voltage) 409 { 410 struct cx8802_dev *dev= fe->dvb->priv; 411 struct cx88_core *core = dev->core; 412 413 if (voltage == SEC_VOLTAGE_OFF) 414 cx_write(MO_GP0_IO, 0x000006fb); 415 else 416 cx_write(MO_GP0_IO, 0x000006f9); 417 418 if (core->prev_set_voltage) 419 return core->prev_set_voltage(fe, voltage); 420 return 0; 421 } 422 423 static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, 424 fe_sec_voltage_t voltage) 425 { 426 struct cx8802_dev *dev= fe->dvb->priv; 427 struct cx88_core *core = dev->core; 428 429 if (voltage == SEC_VOLTAGE_OFF) { 430 dprintk(1,"LNB Voltage OFF\n"); 431 cx_write(MO_GP0_IO, 0x0000efff); 432 } 433 434 if (core->prev_set_voltage) 435 return core->prev_set_voltage(fe, voltage); 436 return 0; 437 } 438 439 static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, 440 fe_sec_voltage_t voltage) 441 { 442 struct cx8802_dev *dev= fe->dvb->priv; 443 struct cx88_core *core = dev->core; 444 445 cx_set(MO_GP0_IO, 0x6040); 446 switch (voltage) { 447 case SEC_VOLTAGE_13: 448 cx_clear(MO_GP0_IO, 0x20); 449 break; 450 case SEC_VOLTAGE_18: 451 cx_set(MO_GP0_IO, 0x20); 452 break; 453 case SEC_VOLTAGE_OFF: 454 cx_clear(MO_GP0_IO, 0x20); 455 break; 456 } 457 458 if (core->prev_set_voltage) 459 return core->prev_set_voltage(fe, voltage); 460 return 0; 461 } 462 463 static int vp1027_set_voltage(struct dvb_frontend *fe, 464 fe_sec_voltage_t voltage) 465 { 466 struct cx8802_dev *dev = fe->dvb->priv; 467 struct cx88_core *core = dev->core; 468 469 switch (voltage) { 470 case SEC_VOLTAGE_13: 471 dprintk(1, "LNB SEC Voltage=13\n"); 472 cx_write(MO_GP0_IO, 0x00001220); 473 break; 474 case SEC_VOLTAGE_18: 475 dprintk(1, "LNB SEC Voltage=18\n"); 476 cx_write(MO_GP0_IO, 0x00001222); 477 break; 478 case SEC_VOLTAGE_OFF: 479 dprintk(1, "LNB Voltage OFF\n"); 480 cx_write(MO_GP0_IO, 0x00001230); 481 break; 482 } 483 484 if (core->prev_set_voltage) 485 return core->prev_set_voltage(fe, voltage); 486 return 0; 487 } 488 489 static const struct cx24123_config geniatech_dvbs_config = { 490 .demod_address = 0x55, 491 .set_ts_params = cx24123_set_ts_param, 492 }; 493 494 static const struct cx24123_config hauppauge_novas_config = { 495 .demod_address = 0x55, 496 .set_ts_params = cx24123_set_ts_param, 497 }; 498 499 static const struct cx24123_config kworld_dvbs_100_config = { 500 .demod_address = 0x15, 501 .set_ts_params = cx24123_set_ts_param, 502 .lnb_polarity = 1, 503 }; 504 505 static const struct s5h1409_config pinnacle_pctv_hd_800i_config = { 506 .demod_address = 0x32 >> 1, 507 .output_mode = S5H1409_PARALLEL_OUTPUT, 508 .gpio = S5H1409_GPIO_ON, 509 .qam_if = 44000, 510 .inversion = S5H1409_INVERSION_OFF, 511 .status_mode = S5H1409_DEMODLOCKING, 512 .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, 513 }; 514 515 static const struct s5h1409_config dvico_hdtv5_pci_nano_config = { 516 .demod_address = 0x32 >> 1, 517 .output_mode = S5H1409_SERIAL_OUTPUT, 518 .gpio = S5H1409_GPIO_OFF, 519 .inversion = S5H1409_INVERSION_OFF, 520 .status_mode = S5H1409_DEMODLOCKING, 521 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, 522 }; 523 524 static const struct s5h1409_config kworld_atsc_120_config = { 525 .demod_address = 0x32 >> 1, 526 .output_mode = S5H1409_SERIAL_OUTPUT, 527 .gpio = S5H1409_GPIO_OFF, 528 .inversion = S5H1409_INVERSION_OFF, 529 .status_mode = S5H1409_DEMODLOCKING, 530 .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, 531 }; 532 533 static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { 534 .i2c_address = 0x64, 535 .if_khz = 5380, 536 }; 537 538 static const struct zl10353_config cx88_pinnacle_hybrid_pctv = { 539 .demod_address = (0x1e >> 1), 540 .no_tuner = 1, 541 .if2 = 45600, 542 }; 543 544 static const struct zl10353_config cx88_geniatech_x8000_mt = { 545 .demod_address = (0x1e >> 1), 546 .no_tuner = 1, 547 .disable_i2c_gate_ctrl = 1, 548 }; 549 550 static const struct s5h1411_config dvico_fusionhdtv7_config = { 551 .output_mode = S5H1411_SERIAL_OUTPUT, 552 .gpio = S5H1411_GPIO_ON, 553 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, 554 .qam_if = S5H1411_IF_44000, 555 .vsb_if = S5H1411_IF_44000, 556 .inversion = S5H1411_INVERSION_OFF, 557 .status_mode = S5H1411_DEMODLOCKING 558 }; 559 560 static const struct xc5000_config dvico_fusionhdtv7_tuner_config = { 561 .i2c_address = 0xc2 >> 1, 562 .if_khz = 5380, 563 }; 564 565 static int attach_xc3028(u8 addr, struct cx8802_dev *dev) 566 { 567 struct dvb_frontend *fe; 568 struct videobuf_dvb_frontend *fe0 = NULL; 569 struct xc2028_ctrl ctl; 570 struct xc2028_config cfg = { 571 .i2c_adap = &dev->core->i2c_adap, 572 .i2c_addr = addr, 573 .ctrl = &ctl, 574 }; 575 576 /* Get the first frontend */ 577 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); 578 if (!fe0) 579 return -EINVAL; 580 581 if (!fe0->dvb.frontend) { 582 printk(KERN_ERR "%s/2: dvb frontend not attached. " 583 "Can't attach xc3028\n", 584 dev->core->name); 585 return -EINVAL; 586 } 587 588 /* 589 * Some xc3028 devices may be hidden by an I2C gate. This is known 590 * to happen with some s5h1409-based devices. 591 * Now that I2C gate is open, sets up xc3028 configuration 592 */ 593 cx88_setup_xc3028(dev->core, &ctl); 594 595 fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg); 596 if (!fe) { 597 printk(KERN_ERR "%s/2: xc3028 attach failed\n", 598 dev->core->name); 599 dvb_frontend_detach(fe0->dvb.frontend); 600 dvb_unregister_frontend(fe0->dvb.frontend); 601 fe0->dvb.frontend = NULL; 602 return -EINVAL; 603 } 604 605 printk(KERN_INFO "%s/2: xc3028 attached\n", 606 dev->core->name); 607 608 return 0; 609 } 610 611 static int attach_xc4000(struct cx8802_dev *dev, struct xc4000_config *cfg) 612 { 613 struct dvb_frontend *fe; 614 struct videobuf_dvb_frontend *fe0 = NULL; 615 616 /* Get the first frontend */ 617 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); 618 if (!fe0) 619 return -EINVAL; 620 621 if (!fe0->dvb.frontend) { 622 printk(KERN_ERR "%s/2: dvb frontend not attached. " 623 "Can't attach xc4000\n", 624 dev->core->name); 625 return -EINVAL; 626 } 627 628 fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, &dev->core->i2c_adap, 629 cfg); 630 if (!fe) { 631 printk(KERN_ERR "%s/2: xc4000 attach failed\n", 632 dev->core->name); 633 dvb_frontend_detach(fe0->dvb.frontend); 634 dvb_unregister_frontend(fe0->dvb.frontend); 635 fe0->dvb.frontend = NULL; 636 return -EINVAL; 637 } 638 639 printk(KERN_INFO "%s/2: xc4000 attached\n", dev->core->name); 640 641 return 0; 642 } 643 644 static int cx24116_set_ts_param(struct dvb_frontend *fe, 645 int is_punctured) 646 { 647 struct cx8802_dev *dev = fe->dvb->priv; 648 dev->ts_gen_cntrl = 0x2; 649 650 return 0; 651 } 652 653 static int stv0900_set_ts_param(struct dvb_frontend *fe, 654 int is_punctured) 655 { 656 struct cx8802_dev *dev = fe->dvb->priv; 657 dev->ts_gen_cntrl = 0; 658 659 return 0; 660 } 661 662 static int cx24116_reset_device(struct dvb_frontend *fe) 663 { 664 struct cx8802_dev *dev = fe->dvb->priv; 665 struct cx88_core *core = dev->core; 666 667 /* Reset the part */ 668 /* Put the cx24116 into reset */ 669 cx_write(MO_SRST_IO, 0); 670 msleep(10); 671 /* Take the cx24116 out of reset */ 672 cx_write(MO_SRST_IO, 1); 673 msleep(10); 674 675 return 0; 676 } 677 678 static const struct cx24116_config hauppauge_hvr4000_config = { 679 .demod_address = 0x05, 680 .set_ts_params = cx24116_set_ts_param, 681 .reset_device = cx24116_reset_device, 682 }; 683 684 static const struct cx24116_config tevii_s460_config = { 685 .demod_address = 0x55, 686 .set_ts_params = cx24116_set_ts_param, 687 .reset_device = cx24116_reset_device, 688 }; 689 690 static int ds3000_set_ts_param(struct dvb_frontend *fe, 691 int is_punctured) 692 { 693 struct cx8802_dev *dev = fe->dvb->priv; 694 dev->ts_gen_cntrl = 4; 695 696 return 0; 697 } 698 699 static struct ds3000_config tevii_ds3000_config = { 700 .demod_address = 0x68, 701 .set_ts_params = ds3000_set_ts_param, 702 }; 703 704 static struct ts2020_config tevii_ts2020_config = { 705 .tuner_address = 0x60, 706 .clk_out_div = 1, 707 }; 708 709 static const struct stv0900_config prof_7301_stv0900_config = { 710 .demod_address = 0x6a, 711 /* demod_mode = 0,*/ 712 .xtal = 27000000, 713 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ 714 .diseqc_mode = 2,/* 2/3 PWM */ 715 .tun1_maddress = 0,/* 0x60 */ 716 .tun1_adc = 0,/* 2 Vpp */ 717 .path1_mode = 3, 718 .set_ts_params = stv0900_set_ts_param, 719 }; 720 721 static const struct stb6100_config prof_7301_stb6100_config = { 722 .tuner_address = 0x60, 723 .refclock = 27000000, 724 }; 725 726 static const struct stv0299_config tevii_tuner_sharp_config = { 727 .demod_address = 0x68, 728 .inittab = sharp_z0194a_inittab, 729 .mclk = 88000000UL, 730 .invert = 1, 731 .skip_reinit = 0, 732 .lock_output = 1, 733 .volt13_op0_op1 = STV0299_VOLT13_OP1, 734 .min_delay_ms = 100, 735 .set_symbol_rate = sharp_z0194a_set_symbol_rate, 736 .set_ts_params = cx24116_set_ts_param, 737 }; 738 739 static const struct stv0288_config tevii_tuner_earda_config = { 740 .demod_address = 0x68, 741 .min_delay_ms = 100, 742 .set_ts_params = cx24116_set_ts_param, 743 }; 744 745 static int cx8802_alloc_frontends(struct cx8802_dev *dev) 746 { 747 struct cx88_core *core = dev->core; 748 struct videobuf_dvb_frontend *fe = NULL; 749 int i; 750 751 mutex_init(&dev->frontends.lock); 752 INIT_LIST_HEAD(&dev->frontends.felist); 753 754 if (!core->board.num_frontends) 755 return -ENODEV; 756 757 printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, 758 core->board.num_frontends); 759 for (i = 1; i <= core->board.num_frontends; i++) { 760 fe = videobuf_dvb_alloc_frontend(&dev->frontends, i); 761 if (!fe) { 762 printk(KERN_ERR "%s() failed to alloc\n", __func__); 763 videobuf_dvb_dealloc_frontends(&dev->frontends); 764 return -ENOMEM; 765 } 766 } 767 return 0; 768 } 769 770 771 772 static const u8 samsung_smt_7020_inittab[] = { 773 0x01, 0x15, 774 0x02, 0x00, 775 0x03, 0x00, 776 0x04, 0x7D, 777 0x05, 0x0F, 778 0x06, 0x02, 779 0x07, 0x00, 780 0x08, 0x60, 781 782 0x0A, 0xC2, 783 0x0B, 0x00, 784 0x0C, 0x01, 785 0x0D, 0x81, 786 0x0E, 0x44, 787 0x0F, 0x09, 788 0x10, 0x3C, 789 0x11, 0x84, 790 0x12, 0xDA, 791 0x13, 0x99, 792 0x14, 0x8D, 793 0x15, 0xCE, 794 0x16, 0xE8, 795 0x17, 0x43, 796 0x18, 0x1C, 797 0x19, 0x1B, 798 0x1A, 0x1D, 799 800 0x1C, 0x12, 801 0x1D, 0x00, 802 0x1E, 0x00, 803 0x1F, 0x00, 804 0x20, 0x00, 805 0x21, 0x00, 806 0x22, 0x00, 807 0x23, 0x00, 808 809 0x28, 0x02, 810 0x29, 0x28, 811 0x2A, 0x14, 812 0x2B, 0x0F, 813 0x2C, 0x09, 814 0x2D, 0x05, 815 816 0x31, 0x1F, 817 0x32, 0x19, 818 0x33, 0xFC, 819 0x34, 0x13, 820 0xff, 0xff, 821 }; 822 823 824 static int samsung_smt_7020_tuner_set_params(struct dvb_frontend *fe) 825 { 826 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 827 struct cx8802_dev *dev = fe->dvb->priv; 828 u8 buf[4]; 829 u32 div; 830 struct i2c_msg msg = { 831 .addr = 0x61, 832 .flags = 0, 833 .buf = buf, 834 .len = sizeof(buf) }; 835 836 div = c->frequency / 125; 837 838 buf[0] = (div >> 8) & 0x7f; 839 buf[1] = div & 0xff; 840 buf[2] = 0x84; /* 0xC4 */ 841 buf[3] = 0x00; 842 843 if (c->frequency < 1500000) 844 buf[3] |= 0x10; 845 846 if (fe->ops.i2c_gate_ctrl) 847 fe->ops.i2c_gate_ctrl(fe, 1); 848 849 if (i2c_transfer(&dev->core->i2c_adap, &msg, 1) != 1) 850 return -EIO; 851 852 return 0; 853 } 854 855 static int samsung_smt_7020_set_tone(struct dvb_frontend *fe, 856 fe_sec_tone_mode_t tone) 857 { 858 struct cx8802_dev *dev = fe->dvb->priv; 859 struct cx88_core *core = dev->core; 860 861 cx_set(MO_GP0_IO, 0x0800); 862 863 switch (tone) { 864 case SEC_TONE_ON: 865 cx_set(MO_GP0_IO, 0x08); 866 break; 867 case SEC_TONE_OFF: 868 cx_clear(MO_GP0_IO, 0x08); 869 break; 870 default: 871 return -EINVAL; 872 } 873 874 return 0; 875 } 876 877 static int samsung_smt_7020_set_voltage(struct dvb_frontend *fe, 878 fe_sec_voltage_t voltage) 879 { 880 struct cx8802_dev *dev = fe->dvb->priv; 881 struct cx88_core *core = dev->core; 882 883 u8 data; 884 struct i2c_msg msg = { 885 .addr = 8, 886 .flags = 0, 887 .buf = &data, 888 .len = sizeof(data) }; 889 890 cx_set(MO_GP0_IO, 0x8000); 891 892 switch (voltage) { 893 case SEC_VOLTAGE_OFF: 894 break; 895 case SEC_VOLTAGE_13: 896 data = ISL6421_EN1 | ISL6421_LLC1; 897 cx_clear(MO_GP0_IO, 0x80); 898 break; 899 case SEC_VOLTAGE_18: 900 data = ISL6421_EN1 | ISL6421_LLC1 | ISL6421_VSEL1; 901 cx_clear(MO_GP0_IO, 0x80); 902 break; 903 default: 904 return -EINVAL; 905 } 906 907 return (i2c_transfer(&dev->core->i2c_adap, &msg, 1) == 1) ? 0 : -EIO; 908 } 909 910 static int samsung_smt_7020_stv0299_set_symbol_rate(struct dvb_frontend *fe, 911 u32 srate, u32 ratio) 912 { 913 u8 aclk = 0; 914 u8 bclk = 0; 915 916 if (srate < 1500000) { 917 aclk = 0xb7; 918 bclk = 0x47; 919 } else if (srate < 3000000) { 920 aclk = 0xb7; 921 bclk = 0x4b; 922 } else if (srate < 7000000) { 923 aclk = 0xb7; 924 bclk = 0x4f; 925 } else if (srate < 14000000) { 926 aclk = 0xb7; 927 bclk = 0x53; 928 } else if (srate < 30000000) { 929 aclk = 0xb6; 930 bclk = 0x53; 931 } else if (srate < 45000000) { 932 aclk = 0xb4; 933 bclk = 0x51; 934 } 935 936 stv0299_writereg(fe, 0x13, aclk); 937 stv0299_writereg(fe, 0x14, bclk); 938 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); 939 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); 940 stv0299_writereg(fe, 0x21, ratio & 0xf0); 941 942 return 0; 943 } 944 945 946 static const struct stv0299_config samsung_stv0299_config = { 947 .demod_address = 0x68, 948 .inittab = samsung_smt_7020_inittab, 949 .mclk = 88000000UL, 950 .invert = 0, 951 .skip_reinit = 0, 952 .lock_output = STV0299_LOCKOUTPUT_LK, 953 .volt13_op0_op1 = STV0299_VOLT13_OP1, 954 .min_delay_ms = 100, 955 .set_symbol_rate = samsung_smt_7020_stv0299_set_symbol_rate, 956 }; 957 958 static int dvb_register(struct cx8802_dev *dev) 959 { 960 struct cx88_core *core = dev->core; 961 struct videobuf_dvb_frontend *fe0, *fe1 = NULL; 962 int mfe_shared = 0; /* bus not shared by default */ 963 int res = -EINVAL; 964 965 if (0 != core->i2c_rc) { 966 printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); 967 goto frontend_detach; 968 } 969 970 /* Get the first frontend */ 971 fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); 972 if (!fe0) 973 goto frontend_detach; 974 975 /* multi-frontend gate control is undefined or defaults to fe0 */ 976 dev->frontends.gate = 0; 977 978 /* Sets the gate control callback to be used by i2c command calls */ 979 core->gate_ctrl = cx88_dvb_gate_ctrl; 980 981 /* init frontend(s) */ 982 switch (core->boardnr) { 983 case CX88_BOARD_HAUPPAUGE_DVB_T1: 984 fe0->dvb.frontend = dvb_attach(cx22702_attach, 985 &connexant_refboard_config, 986 &core->i2c_adap); 987 if (fe0->dvb.frontend != NULL) { 988 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 989 0x61, &core->i2c_adap, 990 DVB_PLL_THOMSON_DTT759X)) 991 goto frontend_detach; 992 } 993 break; 994 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 995 case CX88_BOARD_CONEXANT_DVB_T1: 996 case CX88_BOARD_KWORLD_DVB_T_CX22702: 997 case CX88_BOARD_WINFAST_DTV1000: 998 fe0->dvb.frontend = dvb_attach(cx22702_attach, 999 &connexant_refboard_config, 1000 &core->i2c_adap); 1001 if (fe0->dvb.frontend != NULL) { 1002 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 1003 0x60, &core->i2c_adap, 1004 DVB_PLL_THOMSON_DTT7579)) 1005 goto frontend_detach; 1006 } 1007 break; 1008 case CX88_BOARD_WINFAST_DTV2000H: 1009 case CX88_BOARD_HAUPPAUGE_HVR1100: 1010 case CX88_BOARD_HAUPPAUGE_HVR1100LP: 1011 case CX88_BOARD_HAUPPAUGE_HVR1300: 1012 fe0->dvb.frontend = dvb_attach(cx22702_attach, 1013 &hauppauge_hvr_config, 1014 &core->i2c_adap); 1015 if (fe0->dvb.frontend != NULL) { 1016 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1017 &core->i2c_adap, 0x61, 1018 TUNER_PHILIPS_FMD1216ME_MK3)) 1019 goto frontend_detach; 1020 } 1021 break; 1022 case CX88_BOARD_WINFAST_DTV2000H_J: 1023 fe0->dvb.frontend = dvb_attach(cx22702_attach, 1024 &hauppauge_hvr_config, 1025 &core->i2c_adap); 1026 if (fe0->dvb.frontend != NULL) { 1027 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1028 &core->i2c_adap, 0x61, 1029 TUNER_PHILIPS_FMD1216MEX_MK3)) 1030 goto frontend_detach; 1031 } 1032 break; 1033 case CX88_BOARD_HAUPPAUGE_HVR3000: 1034 /* MFE frontend 1 */ 1035 mfe_shared = 1; 1036 dev->frontends.gate = 2; 1037 /* DVB-S init */ 1038 fe0->dvb.frontend = dvb_attach(cx24123_attach, 1039 &hauppauge_novas_config, 1040 &dev->core->i2c_adap); 1041 if (fe0->dvb.frontend) { 1042 if (!dvb_attach(isl6421_attach, 1043 fe0->dvb.frontend, 1044 &dev->core->i2c_adap, 1045 0x08, ISL6421_DCL, 0x00, false)) 1046 goto frontend_detach; 1047 } 1048 /* MFE frontend 2 */ 1049 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); 1050 if (!fe1) 1051 goto frontend_detach; 1052 /* DVB-T init */ 1053 fe1->dvb.frontend = dvb_attach(cx22702_attach, 1054 &hauppauge_hvr_config, 1055 &dev->core->i2c_adap); 1056 if (fe1->dvb.frontend) { 1057 fe1->dvb.frontend->id = 1; 1058 if (!dvb_attach(simple_tuner_attach, 1059 fe1->dvb.frontend, 1060 &dev->core->i2c_adap, 1061 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) 1062 goto frontend_detach; 1063 } 1064 break; 1065 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 1066 fe0->dvb.frontend = dvb_attach(mt352_attach, 1067 &dvico_fusionhdtv, 1068 &core->i2c_adap); 1069 if (fe0->dvb.frontend != NULL) { 1070 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 1071 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) 1072 goto frontend_detach; 1073 break; 1074 } 1075 /* ZL10353 replaces MT352 on later cards */ 1076 fe0->dvb.frontend = dvb_attach(zl10353_attach, 1077 &dvico_fusionhdtv_plus_v1_1, 1078 &core->i2c_adap); 1079 if (fe0->dvb.frontend != NULL) { 1080 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 1081 0x60, NULL, DVB_PLL_THOMSON_DTT7579)) 1082 goto frontend_detach; 1083 } 1084 break; 1085 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: 1086 /* The tin box says DEE1601, but it seems to be DTT7579 1087 * compatible, with a slightly different MT352 AGC gain. */ 1088 fe0->dvb.frontend = dvb_attach(mt352_attach, 1089 &dvico_fusionhdtv_dual, 1090 &core->i2c_adap); 1091 if (fe0->dvb.frontend != NULL) { 1092 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 1093 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) 1094 goto frontend_detach; 1095 break; 1096 } 1097 /* ZL10353 replaces MT352 on later cards */ 1098 fe0->dvb.frontend = dvb_attach(zl10353_attach, 1099 &dvico_fusionhdtv_plus_v1_1, 1100 &core->i2c_adap); 1101 if (fe0->dvb.frontend != NULL) { 1102 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 1103 0x61, NULL, DVB_PLL_THOMSON_DTT7579)) 1104 goto frontend_detach; 1105 } 1106 break; 1107 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: 1108 fe0->dvb.frontend = dvb_attach(mt352_attach, 1109 &dvico_fusionhdtv, 1110 &core->i2c_adap); 1111 if (fe0->dvb.frontend != NULL) { 1112 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 1113 0x61, NULL, DVB_PLL_LG_Z201)) 1114 goto frontend_detach; 1115 } 1116 break; 1117 case CX88_BOARD_KWORLD_DVB_T: 1118 case CX88_BOARD_DNTV_LIVE_DVB_T: 1119 case CX88_BOARD_ADSTECH_DVB_T_PCI: 1120 fe0->dvb.frontend = dvb_attach(mt352_attach, 1121 &dntv_live_dvbt_config, 1122 &core->i2c_adap); 1123 if (fe0->dvb.frontend != NULL) { 1124 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 1125 0x61, NULL, DVB_PLL_UNKNOWN_1)) 1126 goto frontend_detach; 1127 } 1128 break; 1129 case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: 1130 #if IS_ENABLED(CONFIG_VIDEO_CX88_VP3054) 1131 /* MT352 is on a secondary I2C bus made from some GPIO lines */ 1132 fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, 1133 &dev->vp3054->adap); 1134 if (fe0->dvb.frontend != NULL) { 1135 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1136 &core->i2c_adap, 0x61, 1137 TUNER_PHILIPS_FMD1216ME_MK3)) 1138 goto frontend_detach; 1139 } 1140 #else 1141 printk(KERN_ERR "%s/2: built without vp3054 support\n", 1142 core->name); 1143 #endif 1144 break; 1145 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: 1146 fe0->dvb.frontend = dvb_attach(zl10353_attach, 1147 &dvico_fusionhdtv_hybrid, 1148 &core->i2c_adap); 1149 if (fe0->dvb.frontend != NULL) { 1150 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1151 &core->i2c_adap, 0x61, 1152 TUNER_THOMSON_FE6600)) 1153 goto frontend_detach; 1154 } 1155 break; 1156 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: 1157 fe0->dvb.frontend = dvb_attach(zl10353_attach, 1158 &dvico_fusionhdtv_xc3028, 1159 &core->i2c_adap); 1160 if (fe0->dvb.frontend == NULL) 1161 fe0->dvb.frontend = dvb_attach(mt352_attach, 1162 &dvico_fusionhdtv_mt352_xc3028, 1163 &core->i2c_adap); 1164 /* 1165 * On this board, the demod provides the I2C bus pullup. 1166 * We must not permit gate_ctrl to be performed, or 1167 * the xc3028 cannot communicate on the bus. 1168 */ 1169 if (fe0->dvb.frontend) 1170 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; 1171 if (attach_xc3028(0x61, dev) < 0) 1172 goto frontend_detach; 1173 break; 1174 case CX88_BOARD_PCHDTV_HD3000: 1175 fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, 1176 &core->i2c_adap); 1177 if (fe0->dvb.frontend != NULL) { 1178 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1179 &core->i2c_adap, 0x61, 1180 TUNER_THOMSON_DTT761X)) 1181 goto frontend_detach; 1182 } 1183 break; 1184 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: 1185 dev->ts_gen_cntrl = 0x08; 1186 1187 /* Do a hardware reset of chip before using it. */ 1188 cx_clear(MO_GP0_IO, 1); 1189 mdelay(100); 1190 cx_set(MO_GP0_IO, 1); 1191 mdelay(200); 1192 1193 /* Select RF connector callback */ 1194 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; 1195 fe0->dvb.frontend = dvb_attach(lgdt330x_attach, 1196 &fusionhdtv_3_gold, 1197 &core->i2c_adap); 1198 if (fe0->dvb.frontend != NULL) { 1199 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1200 &core->i2c_adap, 0x61, 1201 TUNER_MICROTUNE_4042FI5)) 1202 goto frontend_detach; 1203 } 1204 break; 1205 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: 1206 dev->ts_gen_cntrl = 0x08; 1207 1208 /* Do a hardware reset of chip before using it. */ 1209 cx_clear(MO_GP0_IO, 1); 1210 mdelay(100); 1211 cx_set(MO_GP0_IO, 9); 1212 mdelay(200); 1213 fe0->dvb.frontend = dvb_attach(lgdt330x_attach, 1214 &fusionhdtv_3_gold, 1215 &core->i2c_adap); 1216 if (fe0->dvb.frontend != NULL) { 1217 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1218 &core->i2c_adap, 0x61, 1219 TUNER_THOMSON_DTT761X)) 1220 goto frontend_detach; 1221 } 1222 break; 1223 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: 1224 dev->ts_gen_cntrl = 0x08; 1225 1226 /* Do a hardware reset of chip before using it. */ 1227 cx_clear(MO_GP0_IO, 1); 1228 mdelay(100); 1229 cx_set(MO_GP0_IO, 1); 1230 mdelay(200); 1231 fe0->dvb.frontend = dvb_attach(lgdt330x_attach, 1232 &fusionhdtv_5_gold, 1233 &core->i2c_adap); 1234 if (fe0->dvb.frontend != NULL) { 1235 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1236 &core->i2c_adap, 0x61, 1237 TUNER_LG_TDVS_H06XF)) 1238 goto frontend_detach; 1239 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, 1240 &core->i2c_adap, 0x43)) 1241 goto frontend_detach; 1242 } 1243 break; 1244 case CX88_BOARD_PCHDTV_HD5500: 1245 dev->ts_gen_cntrl = 0x08; 1246 1247 /* Do a hardware reset of chip before using it. */ 1248 cx_clear(MO_GP0_IO, 1); 1249 mdelay(100); 1250 cx_set(MO_GP0_IO, 1); 1251 mdelay(200); 1252 fe0->dvb.frontend = dvb_attach(lgdt330x_attach, 1253 &pchdtv_hd5500, 1254 &core->i2c_adap); 1255 if (fe0->dvb.frontend != NULL) { 1256 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1257 &core->i2c_adap, 0x61, 1258 TUNER_LG_TDVS_H06XF)) 1259 goto frontend_detach; 1260 if (!dvb_attach(tda9887_attach, fe0->dvb.frontend, 1261 &core->i2c_adap, 0x43)) 1262 goto frontend_detach; 1263 } 1264 break; 1265 case CX88_BOARD_ATI_HDTVWONDER: 1266 fe0->dvb.frontend = dvb_attach(nxt200x_attach, 1267 &ati_hdtvwonder, 1268 &core->i2c_adap); 1269 if (fe0->dvb.frontend != NULL) { 1270 if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend, 1271 &core->i2c_adap, 0x61, 1272 TUNER_PHILIPS_TUV1236D)) 1273 goto frontend_detach; 1274 } 1275 break; 1276 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: 1277 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 1278 fe0->dvb.frontend = dvb_attach(cx24123_attach, 1279 &hauppauge_novas_config, 1280 &core->i2c_adap); 1281 if (fe0->dvb.frontend) { 1282 bool override_tone; 1283 1284 if (core->model == 92001) 1285 override_tone = true; 1286 else 1287 override_tone = false; 1288 1289 if (!dvb_attach(isl6421_attach, fe0->dvb.frontend, 1290 &core->i2c_adap, 0x08, ISL6421_DCL, 0x00, 1291 override_tone)) 1292 goto frontend_detach; 1293 } 1294 break; 1295 case CX88_BOARD_KWORLD_DVBS_100: 1296 fe0->dvb.frontend = dvb_attach(cx24123_attach, 1297 &kworld_dvbs_100_config, 1298 &core->i2c_adap); 1299 if (fe0->dvb.frontend) { 1300 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; 1301 fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; 1302 } 1303 break; 1304 case CX88_BOARD_GENIATECH_DVBS: 1305 fe0->dvb.frontend = dvb_attach(cx24123_attach, 1306 &geniatech_dvbs_config, 1307 &core->i2c_adap); 1308 if (fe0->dvb.frontend) { 1309 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; 1310 fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; 1311 } 1312 break; 1313 case CX88_BOARD_PINNACLE_PCTV_HD_800i: 1314 fe0->dvb.frontend = dvb_attach(s5h1409_attach, 1315 &pinnacle_pctv_hd_800i_config, 1316 &core->i2c_adap); 1317 if (fe0->dvb.frontend != NULL) { 1318 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, 1319 &core->i2c_adap, 1320 &pinnacle_pctv_hd_800i_tuner_config)) 1321 goto frontend_detach; 1322 } 1323 break; 1324 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: 1325 fe0->dvb.frontend = dvb_attach(s5h1409_attach, 1326 &dvico_hdtv5_pci_nano_config, 1327 &core->i2c_adap); 1328 if (fe0->dvb.frontend != NULL) { 1329 struct dvb_frontend *fe; 1330 struct xc2028_config cfg = { 1331 .i2c_adap = &core->i2c_adap, 1332 .i2c_addr = 0x61, 1333 }; 1334 static struct xc2028_ctrl ctl = { 1335 .fname = XC2028_DEFAULT_FIRMWARE, 1336 .max_len = 64, 1337 .scode_table = XC3028_FE_OREN538, 1338 }; 1339 1340 fe = dvb_attach(xc2028_attach, 1341 fe0->dvb.frontend, &cfg); 1342 if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) 1343 fe->ops.tuner_ops.set_config(fe, &ctl); 1344 } 1345 break; 1346 case CX88_BOARD_PINNACLE_HYBRID_PCTV: 1347 case CX88_BOARD_WINFAST_DTV1800H: 1348 fe0->dvb.frontend = dvb_attach(zl10353_attach, 1349 &cx88_pinnacle_hybrid_pctv, 1350 &core->i2c_adap); 1351 if (fe0->dvb.frontend) { 1352 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; 1353 if (attach_xc3028(0x61, dev) < 0) 1354 goto frontend_detach; 1355 } 1356 break; 1357 case CX88_BOARD_WINFAST_DTV1800H_XC4000: 1358 case CX88_BOARD_WINFAST_DTV2000H_PLUS: 1359 fe0->dvb.frontend = dvb_attach(zl10353_attach, 1360 &cx88_pinnacle_hybrid_pctv, 1361 &core->i2c_adap); 1362 if (fe0->dvb.frontend) { 1363 struct xc4000_config cfg = { 1364 .i2c_address = 0x61, 1365 .default_pm = 0, 1366 .dvb_amplitude = 134, 1367 .set_smoothedcvbs = 1, 1368 .if_khz = 4560 1369 }; 1370 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; 1371 if (attach_xc4000(dev, &cfg) < 0) 1372 goto frontend_detach; 1373 } 1374 break; 1375 case CX88_BOARD_GENIATECH_X8000_MT: 1376 dev->ts_gen_cntrl = 0x00; 1377 1378 fe0->dvb.frontend = dvb_attach(zl10353_attach, 1379 &cx88_geniatech_x8000_mt, 1380 &core->i2c_adap); 1381 if (attach_xc3028(0x61, dev) < 0) 1382 goto frontend_detach; 1383 break; 1384 case CX88_BOARD_KWORLD_ATSC_120: 1385 fe0->dvb.frontend = dvb_attach(s5h1409_attach, 1386 &kworld_atsc_120_config, 1387 &core->i2c_adap); 1388 if (attach_xc3028(0x61, dev) < 0) 1389 goto frontend_detach; 1390 break; 1391 case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: 1392 fe0->dvb.frontend = dvb_attach(s5h1411_attach, 1393 &dvico_fusionhdtv7_config, 1394 &core->i2c_adap); 1395 if (fe0->dvb.frontend != NULL) { 1396 if (!dvb_attach(xc5000_attach, fe0->dvb.frontend, 1397 &core->i2c_adap, 1398 &dvico_fusionhdtv7_tuner_config)) 1399 goto frontend_detach; 1400 } 1401 break; 1402 case CX88_BOARD_HAUPPAUGE_HVR4000: 1403 /* MFE frontend 1 */ 1404 mfe_shared = 1; 1405 dev->frontends.gate = 2; 1406 /* DVB-S/S2 Init */ 1407 fe0->dvb.frontend = dvb_attach(cx24116_attach, 1408 &hauppauge_hvr4000_config, 1409 &dev->core->i2c_adap); 1410 if (fe0->dvb.frontend) { 1411 if (!dvb_attach(isl6421_attach, 1412 fe0->dvb.frontend, 1413 &dev->core->i2c_adap, 1414 0x08, ISL6421_DCL, 0x00, false)) 1415 goto frontend_detach; 1416 } 1417 /* MFE frontend 2 */ 1418 fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2); 1419 if (!fe1) 1420 goto frontend_detach; 1421 /* DVB-T Init */ 1422 fe1->dvb.frontend = dvb_attach(cx22702_attach, 1423 &hauppauge_hvr_config, 1424 &dev->core->i2c_adap); 1425 if (fe1->dvb.frontend) { 1426 fe1->dvb.frontend->id = 1; 1427 if (!dvb_attach(simple_tuner_attach, 1428 fe1->dvb.frontend, 1429 &dev->core->i2c_adap, 1430 0x61, TUNER_PHILIPS_FMD1216ME_MK3)) 1431 goto frontend_detach; 1432 } 1433 break; 1434 case CX88_BOARD_HAUPPAUGE_HVR4000LITE: 1435 fe0->dvb.frontend = dvb_attach(cx24116_attach, 1436 &hauppauge_hvr4000_config, 1437 &dev->core->i2c_adap); 1438 if (fe0->dvb.frontend) { 1439 if (!dvb_attach(isl6421_attach, 1440 fe0->dvb.frontend, 1441 &dev->core->i2c_adap, 1442 0x08, ISL6421_DCL, 0x00, false)) 1443 goto frontend_detach; 1444 } 1445 break; 1446 case CX88_BOARD_PROF_6200: 1447 case CX88_BOARD_TBS_8910: 1448 case CX88_BOARD_TEVII_S420: 1449 fe0->dvb.frontend = dvb_attach(stv0299_attach, 1450 &tevii_tuner_sharp_config, 1451 &core->i2c_adap); 1452 if (fe0->dvb.frontend != NULL) { 1453 if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60, 1454 &core->i2c_adap, DVB_PLL_OPERA1)) 1455 goto frontend_detach; 1456 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; 1457 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1458 1459 } else { 1460 fe0->dvb.frontend = dvb_attach(stv0288_attach, 1461 &tevii_tuner_earda_config, 1462 &core->i2c_adap); 1463 if (fe0->dvb.frontend != NULL) { 1464 if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61, 1465 &core->i2c_adap)) 1466 goto frontend_detach; 1467 core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage; 1468 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1469 } 1470 } 1471 break; 1472 case CX88_BOARD_TEVII_S460: 1473 fe0->dvb.frontend = dvb_attach(cx24116_attach, 1474 &tevii_s460_config, 1475 &core->i2c_adap); 1476 if (fe0->dvb.frontend != NULL) 1477 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1478 break; 1479 case CX88_BOARD_TEVII_S464: 1480 fe0->dvb.frontend = dvb_attach(ds3000_attach, 1481 &tevii_ds3000_config, 1482 &core->i2c_adap); 1483 if (fe0->dvb.frontend != NULL) { 1484 dvb_attach(ts2020_attach, fe0->dvb.frontend, 1485 &tevii_ts2020_config, &core->i2c_adap); 1486 fe0->dvb.frontend->ops.set_voltage = 1487 tevii_dvbs_set_voltage; 1488 } 1489 break; 1490 case CX88_BOARD_OMICOM_SS4_PCI: 1491 case CX88_BOARD_TBS_8920: 1492 case CX88_BOARD_PROF_7300: 1493 case CX88_BOARD_SATTRADE_ST4200: 1494 fe0->dvb.frontend = dvb_attach(cx24116_attach, 1495 &hauppauge_hvr4000_config, 1496 &core->i2c_adap); 1497 if (fe0->dvb.frontend != NULL) 1498 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1499 break; 1500 case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII: 1501 fe0->dvb.frontend = dvb_attach(zl10353_attach, 1502 &cx88_terratec_cinergy_ht_pci_mkii_config, 1503 &core->i2c_adap); 1504 if (fe0->dvb.frontend) { 1505 fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL; 1506 if (attach_xc3028(0x61, dev) < 0) 1507 goto frontend_detach; 1508 } 1509 break; 1510 case CX88_BOARD_PROF_7301:{ 1511 struct dvb_tuner_ops *tuner_ops = NULL; 1512 1513 fe0->dvb.frontend = dvb_attach(stv0900_attach, 1514 &prof_7301_stv0900_config, 1515 &core->i2c_adap, 0); 1516 if (fe0->dvb.frontend != NULL) { 1517 if (!dvb_attach(stb6100_attach, fe0->dvb.frontend, 1518 &prof_7301_stb6100_config, 1519 &core->i2c_adap)) 1520 goto frontend_detach; 1521 1522 tuner_ops = &fe0->dvb.frontend->ops.tuner_ops; 1523 tuner_ops->set_frequency = stb6100_set_freq; 1524 tuner_ops->get_frequency = stb6100_get_freq; 1525 tuner_ops->set_bandwidth = stb6100_set_bandw; 1526 tuner_ops->get_bandwidth = stb6100_get_bandw; 1527 1528 core->prev_set_voltage = 1529 fe0->dvb.frontend->ops.set_voltage; 1530 fe0->dvb.frontend->ops.set_voltage = 1531 tevii_dvbs_set_voltage; 1532 } 1533 break; 1534 } 1535 case CX88_BOARD_SAMSUNG_SMT_7020: 1536 dev->ts_gen_cntrl = 0x08; 1537 1538 cx_set(MO_GP0_IO, 0x0101); 1539 1540 cx_clear(MO_GP0_IO, 0x01); 1541 mdelay(100); 1542 cx_set(MO_GP0_IO, 0x01); 1543 mdelay(200); 1544 1545 fe0->dvb.frontend = dvb_attach(stv0299_attach, 1546 &samsung_stv0299_config, 1547 &dev->core->i2c_adap); 1548 if (fe0->dvb.frontend) { 1549 fe0->dvb.frontend->ops.tuner_ops.set_params = 1550 samsung_smt_7020_tuner_set_params; 1551 fe0->dvb.frontend->tuner_priv = 1552 &dev->core->i2c_adap; 1553 fe0->dvb.frontend->ops.set_voltage = 1554 samsung_smt_7020_set_voltage; 1555 fe0->dvb.frontend->ops.set_tone = 1556 samsung_smt_7020_set_tone; 1557 } 1558 1559 break; 1560 case CX88_BOARD_TWINHAN_VP1027_DVBS: 1561 dev->ts_gen_cntrl = 0x00; 1562 fe0->dvb.frontend = dvb_attach(mb86a16_attach, 1563 &twinhan_vp1027, 1564 &core->i2c_adap); 1565 if (fe0->dvb.frontend) { 1566 core->prev_set_voltage = 1567 fe0->dvb.frontend->ops.set_voltage; 1568 fe0->dvb.frontend->ops.set_voltage = 1569 vp1027_set_voltage; 1570 } 1571 break; 1572 1573 default: 1574 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", 1575 core->name); 1576 break; 1577 } 1578 1579 if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) { 1580 printk(KERN_ERR 1581 "%s/2: frontend initialization failed\n", 1582 core->name); 1583 goto frontend_detach; 1584 } 1585 /* define general-purpose callback pointer */ 1586 fe0->dvb.frontend->callback = cx88_tuner_callback; 1587 1588 /* Ensure all frontends negotiate bus access */ 1589 fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; 1590 if (fe1) 1591 fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; 1592 1593 /* Put the analog decoder in standby to keep it quiet */ 1594 call_all(core, core, s_power, 0); 1595 1596 /* register everything */ 1597 res = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, 1598 &dev->pci->dev, adapter_nr, mfe_shared); 1599 if (res) 1600 goto frontend_detach; 1601 return res; 1602 1603 frontend_detach: 1604 core->gate_ctrl = NULL; 1605 videobuf_dvb_dealloc_frontends(&dev->frontends); 1606 return res; 1607 } 1608 1609 /* ----------------------------------------------------------- */ 1610 1611 /* CX8802 MPEG -> mini driver - We have been given the hardware */ 1612 static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) 1613 { 1614 struct cx88_core *core = drv->core; 1615 int err = 0; 1616 dprintk( 1, "%s\n", __func__); 1617 1618 switch (core->boardnr) { 1619 case CX88_BOARD_HAUPPAUGE_HVR1300: 1620 /* We arrive here with either the cx23416 or the cx22702 1621 * on the bus. Take the bus from the cx23416 and enable the 1622 * cx22702 demod 1623 */ 1624 /* Toggle reset on cx22702 leaving i2c active */ 1625 cx_set(MO_GP0_IO, 0x00000080); 1626 udelay(1000); 1627 cx_clear(MO_GP0_IO, 0x00000080); 1628 udelay(50); 1629 cx_set(MO_GP0_IO, 0x00000080); 1630 udelay(1000); 1631 /* enable the cx22702 pins */ 1632 cx_clear(MO_GP0_IO, 0x00000004); 1633 udelay(1000); 1634 break; 1635 1636 case CX88_BOARD_HAUPPAUGE_HVR3000: 1637 case CX88_BOARD_HAUPPAUGE_HVR4000: 1638 /* Toggle reset on cx22702 leaving i2c active */ 1639 cx_set(MO_GP0_IO, 0x00000080); 1640 udelay(1000); 1641 cx_clear(MO_GP0_IO, 0x00000080); 1642 udelay(50); 1643 cx_set(MO_GP0_IO, 0x00000080); 1644 udelay(1000); 1645 switch (core->dvbdev->frontends.active_fe_id) { 1646 case 1: /* DVB-S/S2 Enabled */ 1647 /* tri-state the cx22702 pins */ 1648 cx_set(MO_GP0_IO, 0x00000004); 1649 /* Take the cx24116/cx24123 out of reset */ 1650 cx_write(MO_SRST_IO, 1); 1651 core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */ 1652 break; 1653 case 2: /* DVB-T Enabled */ 1654 /* Put the cx24116/cx24123 into reset */ 1655 cx_write(MO_SRST_IO, 0); 1656 /* enable the cx22702 pins */ 1657 cx_clear(MO_GP0_IO, 0x00000004); 1658 core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */ 1659 break; 1660 } 1661 udelay(1000); 1662 break; 1663 1664 case CX88_BOARD_WINFAST_DTV2000H_PLUS: 1665 /* set RF input to AIR for DVB-T (GPIO 16) */ 1666 cx_write(MO_GP2_IO, 0x0101); 1667 break; 1668 1669 default: 1670 err = -ENODEV; 1671 } 1672 return err; 1673 } 1674 1675 /* CX8802 MPEG -> mini driver - We no longer have the hardware */ 1676 static int cx8802_dvb_advise_release(struct cx8802_driver *drv) 1677 { 1678 struct cx88_core *core = drv->core; 1679 int err = 0; 1680 dprintk( 1, "%s\n", __func__); 1681 1682 switch (core->boardnr) { 1683 case CX88_BOARD_HAUPPAUGE_HVR1300: 1684 /* Do Nothing, leave the cx22702 on the bus. */ 1685 break; 1686 case CX88_BOARD_HAUPPAUGE_HVR3000: 1687 case CX88_BOARD_HAUPPAUGE_HVR4000: 1688 break; 1689 default: 1690 err = -ENODEV; 1691 } 1692 return err; 1693 } 1694 1695 static int cx8802_dvb_probe(struct cx8802_driver *drv) 1696 { 1697 struct cx88_core *core = drv->core; 1698 struct cx8802_dev *dev = drv->core->dvbdev; 1699 int err; 1700 struct videobuf_dvb_frontend *fe; 1701 int i; 1702 1703 dprintk( 1, "%s\n", __func__); 1704 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", 1705 core->boardnr, 1706 core->name, 1707 core->pci_bus, 1708 core->pci_slot); 1709 1710 err = -ENODEV; 1711 if (!(core->board.mpeg & CX88_MPEG_DVB)) 1712 goto fail_core; 1713 1714 /* If vp3054 isn't enabled, a stub will just return 0 */ 1715 err = vp3054_i2c_probe(dev); 1716 if (0 != err) 1717 goto fail_core; 1718 1719 /* dvb stuff */ 1720 printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); 1721 dev->ts_gen_cntrl = 0x0c; 1722 1723 err = cx8802_alloc_frontends(dev); 1724 if (err) 1725 goto fail_core; 1726 1727 err = -ENODEV; 1728 for (i = 1; i <= core->board.num_frontends; i++) { 1729 fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i); 1730 if (fe == NULL) { 1731 printk(KERN_ERR "%s() failed to get frontend(%d)\n", 1732 __func__, i); 1733 goto fail_probe; 1734 } 1735 videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops, 1736 &dev->pci->dev, &dev->slock, 1737 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1738 V4L2_FIELD_TOP, 1739 sizeof(struct cx88_buffer), 1740 dev, NULL); 1741 /* init struct videobuf_dvb */ 1742 fe->dvb.name = dev->core->name; 1743 } 1744 1745 err = dvb_register(dev); 1746 if (err) 1747 /* frontends/adapter de-allocated in dvb_register */ 1748 printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", 1749 core->name, err); 1750 return err; 1751 fail_probe: 1752 videobuf_dvb_dealloc_frontends(&core->dvbdev->frontends); 1753 fail_core: 1754 return err; 1755 } 1756 1757 static int cx8802_dvb_remove(struct cx8802_driver *drv) 1758 { 1759 struct cx88_core *core = drv->core; 1760 struct cx8802_dev *dev = drv->core->dvbdev; 1761 1762 dprintk( 1, "%s\n", __func__); 1763 1764 videobuf_dvb_unregister_bus(&dev->frontends); 1765 1766 vp3054_i2c_remove(dev); 1767 1768 core->gate_ctrl = NULL; 1769 1770 return 0; 1771 } 1772 1773 static struct cx8802_driver cx8802_dvb_driver = { 1774 .type_id = CX88_MPEG_DVB, 1775 .hw_access = CX8802_DRVCTL_SHARED, 1776 .probe = cx8802_dvb_probe, 1777 .remove = cx8802_dvb_remove, 1778 .advise_acquire = cx8802_dvb_advise_acquire, 1779 .advise_release = cx8802_dvb_advise_release, 1780 }; 1781 1782 static int __init dvb_init(void) 1783 { 1784 printk(KERN_INFO "cx88/2: cx2388x dvb driver version %s loaded\n", 1785 CX88_VERSION); 1786 return cx8802_register_driver(&cx8802_dvb_driver); 1787 } 1788 1789 static void __exit dvb_fini(void) 1790 { 1791 cx8802_unregister_driver(&cx8802_dvb_driver); 1792 } 1793 1794 module_init(dvb_init); 1795 module_exit(dvb_fini); 1796