saa7164-dvb.c (21482B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Driver for the NXP SAA7164 PCIe bridge 4 * 5 * Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com> 6 */ 7 8#include "saa7164.h" 9 10#include "tda10048.h" 11#include "tda18271.h" 12#include "s5h1411.h" 13#include "si2157.h" 14#include "si2168.h" 15#include "lgdt3306a.h" 16 17#define DRIVER_NAME "saa7164" 18 19DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 20 21/* addr is in the card struct, get it from there */ 22static struct tda10048_config hauppauge_hvr2200_1_config = { 23 .demod_address = 0x10 >> 1, 24 .output_mode = TDA10048_SERIAL_OUTPUT, 25 .fwbulkwritelen = TDA10048_BULKWRITE_200, 26 .inversion = TDA10048_INVERSION_ON, 27 .dtv6_if_freq_khz = TDA10048_IF_3300, 28 .dtv7_if_freq_khz = TDA10048_IF_3500, 29 .dtv8_if_freq_khz = TDA10048_IF_4000, 30 .clk_freq_khz = TDA10048_CLK_16000, 31}; 32static struct tda10048_config hauppauge_hvr2200_2_config = { 33 .demod_address = 0x12 >> 1, 34 .output_mode = TDA10048_SERIAL_OUTPUT, 35 .fwbulkwritelen = TDA10048_BULKWRITE_200, 36 .inversion = TDA10048_INVERSION_ON, 37 .dtv6_if_freq_khz = TDA10048_IF_3300, 38 .dtv7_if_freq_khz = TDA10048_IF_3500, 39 .dtv8_if_freq_khz = TDA10048_IF_4000, 40 .clk_freq_khz = TDA10048_CLK_16000, 41}; 42 43static struct tda18271_std_map hauppauge_tda18271_std_map = { 44 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3, 45 .if_lvl = 6, .rfagc_top = 0x37 }, 46 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, 47 .if_lvl = 6, .rfagc_top = 0x37 }, 48}; 49 50static struct tda18271_config hauppauge_hvr22x0_tuner_config = { 51 .std_map = &hauppauge_tda18271_std_map, 52 .gate = TDA18271_GATE_ANALOG, 53 .role = TDA18271_MASTER, 54}; 55 56static struct tda18271_config hauppauge_hvr22x0s_tuner_config = { 57 .std_map = &hauppauge_tda18271_std_map, 58 .gate = TDA18271_GATE_ANALOG, 59 .role = TDA18271_SLAVE, 60 .output_opt = TDA18271_OUTPUT_LT_OFF, 61 .rf_cal_on_startup = 1 62}; 63 64static struct s5h1411_config hauppauge_s5h1411_config = { 65 .output_mode = S5H1411_SERIAL_OUTPUT, 66 .gpio = S5H1411_GPIO_ON, 67 .qam_if = S5H1411_IF_4000, 68 .vsb_if = S5H1411_IF_3250, 69 .inversion = S5H1411_INVERSION_ON, 70 .status_mode = S5H1411_DEMODLOCKING, 71 .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, 72}; 73 74static struct lgdt3306a_config hauppauge_hvr2255a_config = { 75 .i2c_addr = 0xb2 >> 1, 76 .qam_if_khz = 4000, 77 .vsb_if_khz = 3250, 78 .deny_i2c_rptr = 1, /* Disabled */ 79 .spectral_inversion = 0, /* Disabled */ 80 .mpeg_mode = LGDT3306A_MPEG_SERIAL, 81 .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE, 82 .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH, 83 .xtalMHz = 25, /* 24 or 25 */ 84}; 85 86static struct lgdt3306a_config hauppauge_hvr2255b_config = { 87 .i2c_addr = 0x1c >> 1, 88 .qam_if_khz = 4000, 89 .vsb_if_khz = 3250, 90 .deny_i2c_rptr = 1, /* Disabled */ 91 .spectral_inversion = 0, /* Disabled */ 92 .mpeg_mode = LGDT3306A_MPEG_SERIAL, 93 .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE, 94 .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH, 95 .xtalMHz = 25, /* 24 or 25 */ 96}; 97 98static struct si2157_config hauppauge_hvr2255_tuner_config = { 99 .inversion = 1, 100 .if_port = 1, 101}; 102 103static int si2157_attach(struct saa7164_port *port, struct i2c_adapter *adapter, 104 struct dvb_frontend *fe, u8 addr8bit, struct si2157_config *cfg) 105{ 106 struct i2c_board_info bi; 107 struct i2c_client *tuner; 108 109 cfg->fe = fe; 110 111 memset(&bi, 0, sizeof(bi)); 112 113 strscpy(bi.type, "si2157", I2C_NAME_SIZE); 114 bi.platform_data = cfg; 115 bi.addr = addr8bit >> 1; 116 117 request_module(bi.type); 118 119 tuner = i2c_new_client_device(adapter, &bi); 120 if (!i2c_client_has_driver(tuner)) 121 return -ENODEV; 122 123 if (!try_module_get(tuner->dev.driver->owner)) { 124 i2c_unregister_device(tuner); 125 return -ENODEV; 126 } 127 128 port->i2c_client_tuner = tuner; 129 130 return 0; 131} 132 133static int saa7164_dvb_stop_port(struct saa7164_port *port) 134{ 135 struct saa7164_dev *dev = port->dev; 136 int ret; 137 138 ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); 139 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { 140 printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n", 141 __func__, ret); 142 ret = -EIO; 143 } else { 144 dprintk(DBGLVL_DVB, "%s() Stopped\n", __func__); 145 ret = 0; 146 } 147 148 return ret; 149} 150 151static int saa7164_dvb_acquire_port(struct saa7164_port *port) 152{ 153 struct saa7164_dev *dev = port->dev; 154 int ret; 155 156 ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); 157 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { 158 printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n", 159 __func__, ret); 160 ret = -EIO; 161 } else { 162 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__); 163 ret = 0; 164 } 165 166 return ret; 167} 168 169static int saa7164_dvb_pause_port(struct saa7164_port *port) 170{ 171 struct saa7164_dev *dev = port->dev; 172 int ret; 173 174 ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); 175 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { 176 printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n", 177 __func__, ret); 178 ret = -EIO; 179 } else { 180 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__); 181 ret = 0; 182 } 183 184 return ret; 185} 186 187/* Firmware is very windows centric, meaning you have to transition 188 * the part through AVStream / KS Windows stages, forwards or backwards. 189 * States are: stopped, acquired (h/w), paused, started. 190 */ 191static int saa7164_dvb_stop_streaming(struct saa7164_port *port) 192{ 193 struct saa7164_dev *dev = port->dev; 194 struct saa7164_buffer *buf; 195 struct list_head *p, *q; 196 int ret; 197 198 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); 199 200 ret = saa7164_dvb_pause_port(port); 201 ret = saa7164_dvb_acquire_port(port); 202 ret = saa7164_dvb_stop_port(port); 203 204 /* Mark the hardware buffers as free */ 205 mutex_lock(&port->dmaqueue_lock); 206 list_for_each_safe(p, q, &port->dmaqueue.list) { 207 buf = list_entry(p, struct saa7164_buffer, list); 208 buf->flags = SAA7164_BUFFER_FREE; 209 } 210 mutex_unlock(&port->dmaqueue_lock); 211 212 return ret; 213} 214 215static int saa7164_dvb_start_port(struct saa7164_port *port) 216{ 217 struct saa7164_dev *dev = port->dev; 218 int ret = 0, result; 219 220 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); 221 222 saa7164_buffer_cfg_port(port); 223 224 /* Acquire the hardware */ 225 result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); 226 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 227 printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n", 228 __func__, result); 229 230 /* Stop the hardware, regardless */ 231 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); 232 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 233 printk(KERN_ERR "%s() acquire/forced stop transition failed, res = 0x%x\n", 234 __func__, result); 235 } 236 ret = -EIO; 237 goto out; 238 } else 239 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__); 240 241 /* Pause the hardware */ 242 result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); 243 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 244 printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n", 245 __func__, result); 246 247 /* Stop the hardware, regardless */ 248 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); 249 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 250 printk(KERN_ERR "%s() pause/forced stop transition failed, res = 0x%x\n", 251 __func__, result); 252 } 253 254 ret = -EIO; 255 goto out; 256 } else 257 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__); 258 259 /* Start the hardware */ 260 result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN); 261 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 262 printk(KERN_ERR "%s() run transition failed, result = 0x%x\n", 263 __func__, result); 264 265 /* Stop the hardware, regardless */ 266 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); 267 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 268 printk(KERN_ERR "%s() run/forced stop transition failed, res = 0x%x\n", 269 __func__, result); 270 } 271 272 ret = -EIO; 273 } else 274 dprintk(DBGLVL_DVB, "%s() Running\n", __func__); 275 276out: 277 return ret; 278} 279 280static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed) 281{ 282 struct dvb_demux *demux = feed->demux; 283 struct saa7164_port *port = (struct saa7164_port *) demux->priv; 284 struct saa7164_dvb *dvb = &port->dvb; 285 struct saa7164_dev *dev = port->dev; 286 int ret = 0; 287 288 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); 289 290 if (!demux->dmx.frontend) 291 return -EINVAL; 292 293 if (dvb) { 294 mutex_lock(&dvb->lock); 295 if (dvb->feeding++ == 0) { 296 /* Start transport */ 297 ret = saa7164_dvb_start_port(port); 298 } 299 mutex_unlock(&dvb->lock); 300 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", 301 __func__, port->nr, dvb->feeding); 302 } 303 304 return ret; 305} 306 307static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed) 308{ 309 struct dvb_demux *demux = feed->demux; 310 struct saa7164_port *port = (struct saa7164_port *) demux->priv; 311 struct saa7164_dvb *dvb = &port->dvb; 312 struct saa7164_dev *dev = port->dev; 313 int ret = 0; 314 315 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); 316 317 if (dvb) { 318 mutex_lock(&dvb->lock); 319 if (--dvb->feeding == 0) { 320 /* Stop transport */ 321 ret = saa7164_dvb_stop_streaming(port); 322 } 323 mutex_unlock(&dvb->lock); 324 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", 325 __func__, port->nr, dvb->feeding); 326 } 327 328 return ret; 329} 330 331static int dvb_register(struct saa7164_port *port) 332{ 333 struct saa7164_dvb *dvb = &port->dvb; 334 struct saa7164_dev *dev = port->dev; 335 struct saa7164_buffer *buf; 336 int result, i; 337 338 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); 339 340 BUG_ON(port->type != SAA7164_MPEG_DVB); 341 342 /* Sanity check that the PCI configuration space is active */ 343 if (port->hwcfg.BARLocation == 0) { 344 result = -ENOMEM; 345 printk(KERN_ERR "%s: dvb_register_adapter failed (errno = %d), NO PCI configuration\n", 346 DRIVER_NAME, result); 347 goto fail_adapter; 348 } 349 350 /* Init and establish defaults */ 351 port->hw_streamingparams.bitspersample = 8; 352 port->hw_streamingparams.samplesperline = 188; 353 port->hw_streamingparams.numberoflines = 354 (SAA7164_TS_NUMBER_OF_LINES * 188) / 188; 355 356 port->hw_streamingparams.pitch = 188; 357 port->hw_streamingparams.linethreshold = 0; 358 port->hw_streamingparams.pagetablelistvirt = NULL; 359 port->hw_streamingparams.pagetablelistphys = NULL; 360 port->hw_streamingparams.numpagetables = 2 + 361 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE); 362 363 port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount; 364 365 /* Allocate the PCI resources */ 366 for (i = 0; i < port->hwcfg.buffercount; i++) { 367 buf = saa7164_buffer_alloc(port, 368 port->hw_streamingparams.numberoflines * 369 port->hw_streamingparams.pitch); 370 371 if (!buf) { 372 result = -ENOMEM; 373 printk(KERN_ERR "%s: dvb_register_adapter failed (errno = %d), unable to allocate buffers\n", 374 DRIVER_NAME, result); 375 goto fail_adapter; 376 } 377 378 mutex_lock(&port->dmaqueue_lock); 379 list_add_tail(&buf->list, &port->dmaqueue.list); 380 mutex_unlock(&port->dmaqueue_lock); 381 } 382 383 /* register adapter */ 384 result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE, 385 &dev->pci->dev, adapter_nr); 386 if (result < 0) { 387 printk(KERN_ERR "%s: dvb_register_adapter failed (errno = %d)\n", 388 DRIVER_NAME, result); 389 goto fail_adapter; 390 } 391 dvb->adapter.priv = port; 392 393 /* register frontend */ 394 result = dvb_register_frontend(&dvb->adapter, dvb->frontend); 395 if (result < 0) { 396 printk(KERN_ERR "%s: dvb_register_frontend failed (errno = %d)\n", 397 DRIVER_NAME, result); 398 goto fail_frontend; 399 } 400 401 /* register demux stuff */ 402 dvb->demux.dmx.capabilities = 403 DMX_TS_FILTERING | DMX_SECTION_FILTERING | 404 DMX_MEMORY_BASED_FILTERING; 405 dvb->demux.priv = port; 406 dvb->demux.filternum = 256; 407 dvb->demux.feednum = 256; 408 dvb->demux.start_feed = saa7164_dvb_start_feed; 409 dvb->demux.stop_feed = saa7164_dvb_stop_feed; 410 result = dvb_dmx_init(&dvb->demux); 411 if (result < 0) { 412 printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n", 413 DRIVER_NAME, result); 414 goto fail_dmx; 415 } 416 417 dvb->dmxdev.filternum = 256; 418 dvb->dmxdev.demux = &dvb->demux.dmx; 419 dvb->dmxdev.capabilities = 0; 420 result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); 421 if (result < 0) { 422 printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n", 423 DRIVER_NAME, result); 424 goto fail_dmxdev; 425 } 426 427 dvb->fe_hw.source = DMX_FRONTEND_0; 428 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); 429 if (result < 0) { 430 printk(KERN_ERR "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", 431 DRIVER_NAME, result); 432 goto fail_fe_hw; 433 } 434 435 dvb->fe_mem.source = DMX_MEMORY_FE; 436 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); 437 if (result < 0) { 438 printk(KERN_ERR "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", 439 DRIVER_NAME, result); 440 goto fail_fe_mem; 441 } 442 443 result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); 444 if (result < 0) { 445 printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n", 446 DRIVER_NAME, result); 447 goto fail_fe_conn; 448 } 449 450 /* register network adapter */ 451 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); 452 return 0; 453 454fail_fe_conn: 455 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); 456fail_fe_mem: 457 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); 458fail_fe_hw: 459 dvb_dmxdev_release(&dvb->dmxdev); 460fail_dmxdev: 461 dvb_dmx_release(&dvb->demux); 462fail_dmx: 463 dvb_unregister_frontend(dvb->frontend); 464fail_frontend: 465 dvb_frontend_detach(dvb->frontend); 466 dvb_unregister_adapter(&dvb->adapter); 467fail_adapter: 468 return result; 469} 470 471int saa7164_dvb_unregister(struct saa7164_port *port) 472{ 473 struct saa7164_dvb *dvb = &port->dvb; 474 struct saa7164_dev *dev = port->dev; 475 struct saa7164_buffer *b; 476 struct list_head *c, *n; 477 struct i2c_client *client; 478 479 dprintk(DBGLVL_DVB, "%s()\n", __func__); 480 481 BUG_ON(port->type != SAA7164_MPEG_DVB); 482 483 /* Remove any allocated buffers */ 484 mutex_lock(&port->dmaqueue_lock); 485 list_for_each_safe(c, n, &port->dmaqueue.list) { 486 b = list_entry(c, struct saa7164_buffer, list); 487 list_del(c); 488 saa7164_buffer_dealloc(b); 489 } 490 mutex_unlock(&port->dmaqueue_lock); 491 492 if (dvb->frontend == NULL) 493 return 0; 494 495 /* remove I2C client for tuner */ 496 client = port->i2c_client_tuner; 497 if (client) { 498 module_put(client->dev.driver->owner); 499 i2c_unregister_device(client); 500 } 501 502 /* remove I2C client for demodulator */ 503 client = port->i2c_client_demod; 504 if (client) { 505 module_put(client->dev.driver->owner); 506 i2c_unregister_device(client); 507 } 508 509 dvb_net_release(&dvb->net); 510 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); 511 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); 512 dvb_dmxdev_release(&dvb->dmxdev); 513 dvb_dmx_release(&dvb->demux); 514 dvb_unregister_frontend(dvb->frontend); 515 dvb_frontend_detach(dvb->frontend); 516 dvb_unregister_adapter(&dvb->adapter); 517 return 0; 518} 519 520/* All the DVB attach calls go here, this function gets modified 521 * for each new card. 522 */ 523int saa7164_dvb_register(struct saa7164_port *port) 524{ 525 struct saa7164_dev *dev = port->dev; 526 struct saa7164_dvb *dvb = &port->dvb; 527 struct saa7164_i2c *i2c_bus = NULL; 528 struct si2168_config si2168_config; 529 struct si2157_config si2157_config; 530 struct i2c_adapter *adapter; 531 struct i2c_board_info info; 532 struct i2c_client *client_demod; 533 struct i2c_client *client_tuner; 534 int ret; 535 536 dprintk(DBGLVL_DVB, "%s()\n", __func__); 537 538 /* init frontend */ 539 switch (dev->board) { 540 case SAA7164_BOARD_HAUPPAUGE_HVR2200: 541 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: 542 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: 543 case SAA7164_BOARD_HAUPPAUGE_HVR2200_4: 544 case SAA7164_BOARD_HAUPPAUGE_HVR2200_5: 545 i2c_bus = &dev->i2c_bus[port->nr + 1]; 546 switch (port->nr) { 547 case 0: 548 port->dvb.frontend = dvb_attach(tda10048_attach, 549 &hauppauge_hvr2200_1_config, 550 &i2c_bus->i2c_adap); 551 552 if (port->dvb.frontend != NULL) { 553 /* TODO: addr is in the card struct */ 554 dvb_attach(tda18271_attach, port->dvb.frontend, 555 0xc0 >> 1, &i2c_bus->i2c_adap, 556 &hauppauge_hvr22x0_tuner_config); 557 } 558 559 break; 560 case 1: 561 port->dvb.frontend = dvb_attach(tda10048_attach, 562 &hauppauge_hvr2200_2_config, 563 &i2c_bus->i2c_adap); 564 565 if (port->dvb.frontend != NULL) { 566 /* TODO: addr is in the card struct */ 567 dvb_attach(tda18271_attach, port->dvb.frontend, 568 0xc0 >> 1, &i2c_bus->i2c_adap, 569 &hauppauge_hvr22x0s_tuner_config); 570 } 571 572 break; 573 } 574 break; 575 case SAA7164_BOARD_HAUPPAUGE_HVR2250: 576 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: 577 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: 578 i2c_bus = &dev->i2c_bus[port->nr + 1]; 579 580 port->dvb.frontend = dvb_attach(s5h1411_attach, 581 &hauppauge_s5h1411_config, 582 &i2c_bus->i2c_adap); 583 584 if (port->dvb.frontend != NULL) { 585 if (port->nr == 0) { 586 /* Master TDA18271 */ 587 /* TODO: addr is in the card struct */ 588 dvb_attach(tda18271_attach, port->dvb.frontend, 589 0xc0 >> 1, &i2c_bus->i2c_adap, 590 &hauppauge_hvr22x0_tuner_config); 591 } else { 592 /* Slave TDA18271 */ 593 dvb_attach(tda18271_attach, port->dvb.frontend, 594 0xc0 >> 1, &i2c_bus->i2c_adap, 595 &hauppauge_hvr22x0s_tuner_config); 596 } 597 } 598 599 break; 600 case SAA7164_BOARD_HAUPPAUGE_HVR2255proto: 601 case SAA7164_BOARD_HAUPPAUGE_HVR2255: 602 i2c_bus = &dev->i2c_bus[2]; 603 604 if (port->nr == 0) { 605 port->dvb.frontend = dvb_attach(lgdt3306a_attach, 606 &hauppauge_hvr2255a_config, &i2c_bus->i2c_adap); 607 } else { 608 port->dvb.frontend = dvb_attach(lgdt3306a_attach, 609 &hauppauge_hvr2255b_config, &i2c_bus->i2c_adap); 610 } 611 612 if (port->dvb.frontend != NULL) { 613 614 if (port->nr == 0) { 615 si2157_attach(port, &dev->i2c_bus[0].i2c_adap, 616 port->dvb.frontend, 0xc0, 617 &hauppauge_hvr2255_tuner_config); 618 } else { 619 si2157_attach(port, &dev->i2c_bus[1].i2c_adap, 620 port->dvb.frontend, 0xc0, 621 &hauppauge_hvr2255_tuner_config); 622 } 623 } 624 break; 625 case SAA7164_BOARD_HAUPPAUGE_HVR2205: 626 627 if (port->nr == 0) { 628 /* attach frontend */ 629 memset(&si2168_config, 0, sizeof(si2168_config)); 630 si2168_config.i2c_adapter = &adapter; 631 si2168_config.fe = &port->dvb.frontend; 632 si2168_config.ts_mode = SI2168_TS_SERIAL; 633 memset(&info, 0, sizeof(struct i2c_board_info)); 634 strscpy(info.type, "si2168", I2C_NAME_SIZE); 635 info.addr = 0xc8 >> 1; 636 info.platform_data = &si2168_config; 637 request_module(info.type); 638 client_demod = i2c_new_client_device(&dev->i2c_bus[2].i2c_adap, &info); 639 if (!i2c_client_has_driver(client_demod)) 640 goto frontend_detach; 641 642 if (!try_module_get(client_demod->dev.driver->owner)) { 643 i2c_unregister_device(client_demod); 644 goto frontend_detach; 645 } 646 port->i2c_client_demod = client_demod; 647 648 /* attach tuner */ 649 memset(&si2157_config, 0, sizeof(si2157_config)); 650 si2157_config.if_port = 1; 651 si2157_config.fe = port->dvb.frontend; 652 memset(&info, 0, sizeof(struct i2c_board_info)); 653 strscpy(info.type, "si2157", I2C_NAME_SIZE); 654 info.addr = 0xc0 >> 1; 655 info.platform_data = &si2157_config; 656 request_module(info.type); 657 client_tuner = i2c_new_client_device(&dev->i2c_bus[0].i2c_adap, &info); 658 if (!i2c_client_has_driver(client_tuner)) { 659 module_put(client_demod->dev.driver->owner); 660 i2c_unregister_device(client_demod); 661 goto frontend_detach; 662 } 663 if (!try_module_get(client_tuner->dev.driver->owner)) { 664 i2c_unregister_device(client_tuner); 665 module_put(client_demod->dev.driver->owner); 666 i2c_unregister_device(client_demod); 667 goto frontend_detach; 668 } 669 port->i2c_client_tuner = client_tuner; 670 } else { 671 /* attach frontend */ 672 memset(&si2168_config, 0, sizeof(si2168_config)); 673 si2168_config.i2c_adapter = &adapter; 674 si2168_config.fe = &port->dvb.frontend; 675 si2168_config.ts_mode = SI2168_TS_SERIAL; 676 memset(&info, 0, sizeof(struct i2c_board_info)); 677 strscpy(info.type, "si2168", I2C_NAME_SIZE); 678 info.addr = 0xcc >> 1; 679 info.platform_data = &si2168_config; 680 request_module(info.type); 681 client_demod = i2c_new_client_device(&dev->i2c_bus[2].i2c_adap, &info); 682 if (!i2c_client_has_driver(client_demod)) 683 goto frontend_detach; 684 685 if (!try_module_get(client_demod->dev.driver->owner)) { 686 i2c_unregister_device(client_demod); 687 goto frontend_detach; 688 } 689 port->i2c_client_demod = client_demod; 690 691 /* attach tuner */ 692 memset(&si2157_config, 0, sizeof(si2157_config)); 693 si2157_config.fe = port->dvb.frontend; 694 si2157_config.if_port = 1; 695 memset(&info, 0, sizeof(struct i2c_board_info)); 696 strscpy(info.type, "si2157", I2C_NAME_SIZE); 697 info.addr = 0xc0 >> 1; 698 info.platform_data = &si2157_config; 699 request_module(info.type); 700 client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); 701 if (!i2c_client_has_driver(client_tuner)) { 702 module_put(client_demod->dev.driver->owner); 703 i2c_unregister_device(client_demod); 704 goto frontend_detach; 705 } 706 if (!try_module_get(client_tuner->dev.driver->owner)) { 707 i2c_unregister_device(client_tuner); 708 module_put(client_demod->dev.driver->owner); 709 i2c_unregister_device(client_demod); 710 goto frontend_detach; 711 } 712 port->i2c_client_tuner = client_tuner; 713 } 714 715 break; 716 default: 717 printk(KERN_ERR "%s: The frontend isn't supported\n", 718 dev->name); 719 break; 720 } 721 if (NULL == dvb->frontend) { 722 printk(KERN_ERR "%s() Frontend initialization failed\n", 723 __func__); 724 return -1; 725 } 726 727 /* register everything */ 728 ret = dvb_register(port); 729 if (ret < 0) { 730 if (dvb->frontend->ops.release) 731 dvb->frontend->ops.release(dvb->frontend); 732 return ret; 733 } 734 735 return 0; 736 737frontend_detach: 738 printk(KERN_ERR "%s() Frontend/I2C initialization failed\n", __func__); 739 return -1; 740}