1/* 2 * Driver for the NXP SAA7164 PCIe bridge 3 * 4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22#include "saa7164.h" 23 24#include "tda10048.h" 25#include "tda18271.h" 26#include "s5h1411.h" 27 28#define DRIVER_NAME "saa7164" 29 30DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 31 32/* addr is in the card struct, get it from there */ 33static struct tda10048_config hauppauge_hvr2200_1_config = { 34 .demod_address = 0x10 >> 1, 35 .output_mode = TDA10048_SERIAL_OUTPUT, 36 .fwbulkwritelen = TDA10048_BULKWRITE_200, 37 .inversion = TDA10048_INVERSION_ON, 38 .dtv6_if_freq_khz = TDA10048_IF_3300, 39 .dtv7_if_freq_khz = TDA10048_IF_3500, 40 .dtv8_if_freq_khz = TDA10048_IF_4000, 41 .clk_freq_khz = TDA10048_CLK_16000, 42}; 43static struct tda10048_config hauppauge_hvr2200_2_config = { 44 .demod_address = 0x12 >> 1, 45 .output_mode = TDA10048_SERIAL_OUTPUT, 46 .fwbulkwritelen = TDA10048_BULKWRITE_200, 47 .inversion = TDA10048_INVERSION_ON, 48 .dtv6_if_freq_khz = TDA10048_IF_3300, 49 .dtv7_if_freq_khz = TDA10048_IF_3500, 50 .dtv8_if_freq_khz = TDA10048_IF_4000, 51 .clk_freq_khz = TDA10048_CLK_16000, 52}; 53 54static struct tda18271_std_map hauppauge_tda18271_std_map = { 55 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3, 56 .if_lvl = 6, .rfagc_top = 0x37 }, 57 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, 58 .if_lvl = 6, .rfagc_top = 0x37 }, 59}; 60 61static struct tda18271_config hauppauge_hvr22x0_tuner_config = { 62 .std_map = &hauppauge_tda18271_std_map, 63 .gate = TDA18271_GATE_ANALOG, 64 .role = TDA18271_MASTER, 65}; 66 67static struct tda18271_config hauppauge_hvr22x0s_tuner_config = { 68 .std_map = &hauppauge_tda18271_std_map, 69 .gate = TDA18271_GATE_ANALOG, 70 .role = TDA18271_SLAVE, 71 .output_opt = TDA18271_OUTPUT_LT_OFF, 72 .rf_cal_on_startup = 1 73}; 74 75static struct s5h1411_config hauppauge_s5h1411_config = { 76 .output_mode = S5H1411_SERIAL_OUTPUT, 77 .gpio = S5H1411_GPIO_ON, 78 .qam_if = S5H1411_IF_4000, 79 .vsb_if = S5H1411_IF_3250, 80 .inversion = S5H1411_INVERSION_ON, 81 .status_mode = S5H1411_DEMODLOCKING, 82 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, 83}; 84 85static int saa7164_dvb_stop_tsport(struct saa7164_tsport *port) 86{ 87 struct saa7164_dev *dev = port->dev; 88 int ret; 89 90 ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); 91 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { 92 printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n", 93 __func__, ret); 94 ret = -EIO; 95 } else { 96 dprintk(DBGLVL_DVB, "%s() Stopped\n", __func__); 97 ret = 0; 98 } 99 100 return ret; 101} 102 103static int saa7164_dvb_acquire_tsport(struct saa7164_tsport *port) 104{ 105 struct saa7164_dev *dev = port->dev; 106 int ret; 107 108 ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); 109 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { 110 printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n", 111 __func__, ret); 112 ret = -EIO; 113 } else { 114 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__); 115 ret = 0; 116 } 117 118 return ret; 119} 120 121static int saa7164_dvb_pause_tsport(struct saa7164_tsport *port) 122{ 123 struct saa7164_dev *dev = port->dev; 124 int ret; 125 126 ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); 127 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) { 128 printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n", 129 __func__, ret); 130 ret = -EIO; 131 } else { 132 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__); 133 ret = 0; 134 } 135 136 return ret; 137} 138 139/* Firmware is very windows centric, meaning you have to transition 140 * the part through AVStream / KS Windows stages, forwards or backwards. 141 * States are: stopped, acquired (h/w), paused, started. 142 */ 143static int saa7164_dvb_stop_streaming(struct saa7164_tsport *port) 144{ 145 struct saa7164_dev *dev = port->dev; 146 int ret; 147 148 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); 149 150 ret = saa7164_dvb_pause_tsport(port); 151 ret = saa7164_dvb_acquire_tsport(port); 152 ret = saa7164_dvb_stop_tsport(port); 153 154 return ret; 155} 156 157static int saa7164_dvb_cfg_tsport(struct saa7164_tsport *port) 158{ 159 tmHWStreamParameters_t *params = &port->hw_streamingparams; 160 struct saa7164_dev *dev = port->dev; 161 struct saa7164_buffer *buf; 162 struct list_head *c, *n; 163 int i = 0; 164 165 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); 166 167 saa7164_writel(port->pitch, params->pitch); 168 saa7164_writel(port->bufsize, params->pitch * params->numberoflines); 169 170 dprintk(DBGLVL_DVB, " configured:\n"); 171 dprintk(DBGLVL_DVB, " lmmio 0x%p\n", dev->lmmio); 172 dprintk(DBGLVL_DVB, " bufcounter 0x%x = 0x%x\n", port->bufcounter, 173 saa7164_readl(port->bufcounter)); 174 175 dprintk(DBGLVL_DVB, " pitch 0x%x = %d\n", port->pitch, 176 saa7164_readl(port->pitch)); 177 178 dprintk(DBGLVL_DVB, " bufsize 0x%x = %d\n", port->bufsize, 179 saa7164_readl(port->bufsize)); 180 181 dprintk(DBGLVL_DVB, " buffercount = %d\n", port->hwcfg.buffercount); 182 dprintk(DBGLVL_DVB, " bufoffset = 0x%x\n", port->bufoffset); 183 dprintk(DBGLVL_DVB, " bufptr32h = 0x%x\n", port->bufptr32h); 184 dprintk(DBGLVL_DVB, " bufptr32l = 0x%x\n", port->bufptr32l); 185 186 /* Poke the buffers and offsets into PCI space */ 187 mutex_lock(&port->dmaqueue_lock); 188 list_for_each_safe(c, n, &port->dmaqueue.list) { 189 buf = list_entry(c, struct saa7164_buffer, list); 190 191 /* TODO: Review this in light of 32v64 assignments */ 192 saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0); 193 saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i), 194 buf->pt_dma); 195 saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0); 196 197 dprintk(DBGLVL_DVB, 198 " buf[%d] offset 0x%llx (0x%x) " 199 "buf 0x%llx/%llx (0x%x/%x)\n", 200 i, 201 (u64)port->bufoffset + (i * sizeof(u32)), 202 saa7164_readl(port->bufoffset + (sizeof(u32) * i)), 203 (u64)port->bufptr32h + ((sizeof(u32) * 2) * i), 204 (u64)port->bufptr32l + ((sizeof(u32) * 2) * i), 205 saa7164_readl(port->bufptr32h + ((sizeof(u32) * i) 206 * 2)), 207 saa7164_readl(port->bufptr32l + ((sizeof(u32) * i) 208 * 2))); 209 210 if (i++ > port->hwcfg.buffercount) 211 BUG(); 212 213 } 214 mutex_unlock(&port->dmaqueue_lock); 215 216 return 0; 217} 218 219static int saa7164_dvb_start_tsport(struct saa7164_tsport *port) 220{ 221 struct saa7164_dev *dev = port->dev; 222 int ret = 0, result; 223 224 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); 225 226 saa7164_dvb_cfg_tsport(port); 227 228 /* Acquire the hardware */ 229 result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE); 230 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 231 printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n", 232 __func__, result); 233 234 /* Stop the hardware, regardless */ 235 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); 236 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 237 printk(KERN_ERR "%s() acquire/forced stop transition " 238 "failed, res = 0x%x\n", __func__, result); 239 } 240 ret = -EIO; 241 goto out; 242 } else 243 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__); 244 245 /* Pause the hardware */ 246 result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE); 247 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 248 printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n", 249 __func__, result); 250 251 /* Stop the hardware, regardless */ 252 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); 253 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 254 printk(KERN_ERR "%s() pause/forced stop transition " 255 "failed, res = 0x%x\n", __func__, result); 256 } 257 258 ret = -EIO; 259 goto out; 260 } else 261 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__); 262 263 /* Start the hardware */ 264 result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN); 265 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 266 printk(KERN_ERR "%s() run transition failed, result = 0x%x\n", 267 __func__, result); 268 269 /* Stop the hardware, regardless */ 270 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP); 271 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) { 272 printk(KERN_ERR "%s() run/forced stop transition " 273 "failed, res = 0x%x\n", __func__, result); 274 } 275 276 ret = -EIO; 277 } else 278 dprintk(DBGLVL_DVB, "%s() Running\n", __func__); 279 280out: 281 return ret; 282} 283 284static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed) 285{ 286 struct dvb_demux *demux = feed->demux; 287 struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv; 288 struct saa7164_dvb *dvb = &port->dvb; 289 struct saa7164_dev *dev = port->dev; 290 int ret = 0; 291 292 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); 293 294 if (!demux->dmx.frontend) 295 return -EINVAL; 296 297 if (dvb) { 298 mutex_lock(&dvb->lock); 299 if (dvb->feeding++ == 0) { 300 /* Start transport */ 301 ret = saa7164_dvb_start_tsport(port); 302 } 303 mutex_unlock(&dvb->lock); 304 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", 305 __func__, port->nr, dvb->feeding); 306 } 307 308 return ret; 309} 310 311static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed) 312{ 313 struct dvb_demux *demux = feed->demux; 314 struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv; 315 struct saa7164_dvb *dvb = &port->dvb; 316 struct saa7164_dev *dev = port->dev; 317 int ret = 0; 318 319 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); 320 321 if (dvb) { 322 mutex_lock(&dvb->lock); 323 if (--dvb->feeding == 0) { 324 /* Stop transport */ 325 ret = saa7164_dvb_stop_streaming(port); 326 } 327 mutex_unlock(&dvb->lock); 328 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n", 329 __func__, port->nr, dvb->feeding); 330 } 331 332 return ret; 333} 334 335static int dvb_register(struct saa7164_tsport *port) 336{ 337 struct saa7164_dvb *dvb = &port->dvb; 338 struct saa7164_dev *dev = port->dev; 339 struct saa7164_buffer *buf; 340 int result, i; 341 342 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr); 343 344 /* Sanity check that the PCI configuration space is active */ 345 if (port->hwcfg.BARLocation == 0) { 346 result = -ENOMEM; 347 printk(KERN_ERR "%s: dvb_register_adapter failed " 348 "(errno = %d), NO PCI configuration\n", 349 DRIVER_NAME, result); 350 goto fail_adapter; 351 } 352 353 /* Init and establish defaults */ 354 port->hw_streamingparams.bitspersample = 8; 355 port->hw_streamingparams.samplesperline = 188; 356 port->hw_streamingparams.numberoflines = 357 (SAA7164_TS_NUMBER_OF_LINES * 188) / 188; 358 359 port->hw_streamingparams.pitch = 188; 360 port->hw_streamingparams.linethreshold = 0; 361 port->hw_streamingparams.pagetablelistvirt = 0; 362 port->hw_streamingparams.pagetablelistphys = 0; 363 port->hw_streamingparams.numpagetables = 2 + 364 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE); 365 366 port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount; 367 368 /* Allocate the PCI resources */ 369 for (i = 0; i < port->hwcfg.buffercount; i++) { 370 buf = saa7164_buffer_alloc(port, 371 port->hw_streamingparams.numberoflines * 372 port->hw_streamingparams.pitch); 373 374 if (!buf) { 375 result = -ENOMEM; 376 printk(KERN_ERR "%s: dvb_register_adapter failed " 377 "(errno = %d), unable to allocate buffers\n", 378 DRIVER_NAME, result); 379 goto fail_adapter; 380 } 381 buf->nr = i; 382 383 mutex_lock(&port->dmaqueue_lock); 384 list_add_tail(&buf->list, &port->dmaqueue.list); 385 mutex_unlock(&port->dmaqueue_lock); 386 } 387 388 /* register adapter */ 389 result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE, 390 &dev->pci->dev, adapter_nr); 391 if (result < 0) { 392 printk(KERN_ERR "%s: dvb_register_adapter failed " 393 "(errno = %d)\n", DRIVER_NAME, result); 394 goto fail_adapter; 395 } 396 dvb->adapter.priv = port; 397 398 /* register frontend */ 399 result = dvb_register_frontend(&dvb->adapter, dvb->frontend); 400 if (result < 0) { 401 printk(KERN_ERR "%s: dvb_register_frontend failed " 402 "(errno = %d)\n", DRIVER_NAME, result); 403 goto fail_frontend; 404 } 405 406 /* register demux stuff */ 407 dvb->demux.dmx.capabilities = 408 DMX_TS_FILTERING | DMX_SECTION_FILTERING | 409 DMX_MEMORY_BASED_FILTERING; 410 dvb->demux.priv = port; 411 dvb->demux.filternum = 256; 412 dvb->demux.feednum = 256; 413 dvb->demux.start_feed = saa7164_dvb_start_feed; 414 dvb->demux.stop_feed = saa7164_dvb_stop_feed; 415 result = dvb_dmx_init(&dvb->demux); 416 if (result < 0) { 417 printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n", 418 DRIVER_NAME, result); 419 goto fail_dmx; 420 } 421 422 dvb->dmxdev.filternum = 256; 423 dvb->dmxdev.demux = &dvb->demux.dmx; 424 dvb->dmxdev.capabilities = 0; 425 result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); 426 if (result < 0) { 427 printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n", 428 DRIVER_NAME, result); 429 goto fail_dmxdev; 430 } 431 432 dvb->fe_hw.source = DMX_FRONTEND_0; 433 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); 434 if (result < 0) { 435 printk(KERN_ERR "%s: add_frontend failed " 436 "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result); 437 goto fail_fe_hw; 438 } 439 440 dvb->fe_mem.source = DMX_MEMORY_FE; 441 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); 442 if (result < 0) { 443 printk(KERN_ERR "%s: add_frontend failed " 444 "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result); 445 goto fail_fe_mem; 446 } 447 448 result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); 449 if (result < 0) { 450 printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n", 451 DRIVER_NAME, result); 452 goto fail_fe_conn; 453 } 454 455 /* register network adapter */ 456 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); 457 return 0; 458 459fail_fe_conn: 460 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); 461fail_fe_mem: 462 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); 463fail_fe_hw: 464 dvb_dmxdev_release(&dvb->dmxdev); 465fail_dmxdev: 466 dvb_dmx_release(&dvb->demux); 467fail_dmx: 468 dvb_unregister_frontend(dvb->frontend); 469fail_frontend: 470 dvb_frontend_detach(dvb->frontend); 471 dvb_unregister_adapter(&dvb->adapter); 472fail_adapter: 473 return result; 474} 475 476int saa7164_dvb_unregister(struct saa7164_tsport *port) 477{ 478 struct saa7164_dvb *dvb = &port->dvb; 479 struct saa7164_dev *dev = port->dev; 480 struct saa7164_buffer *b; 481 struct list_head *c, *n; 482 483 dprintk(DBGLVL_DVB, "%s()\n", __func__); 484 485 /* Remove any allocated buffers */ 486 mutex_lock(&port->dmaqueue_lock); 487 list_for_each_safe(c, n, &port->dmaqueue.list) { 488 b = list_entry(c, struct saa7164_buffer, list); 489 list_del(c); 490 saa7164_buffer_dealloc(port, b); 491 } 492 mutex_unlock(&port->dmaqueue_lock); 493 494 if (dvb->frontend == NULL) 495 return 0; 496 497 dvb_net_release(&dvb->net); 498 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); 499 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); 500 dvb_dmxdev_release(&dvb->dmxdev); 501 dvb_dmx_release(&dvb->demux); 502 dvb_unregister_frontend(dvb->frontend); 503 dvb_frontend_detach(dvb->frontend); 504 dvb_unregister_adapter(&dvb->adapter); 505 return 0; 506} 507 508/* All the DVB attach calls go here, this function get's modified 509 * for each new card. 510 */ 511int saa7164_dvb_register(struct saa7164_tsport *port) 512{ 513 struct saa7164_dev *dev = port->dev; 514 struct saa7164_dvb *dvb = &port->dvb; 515 struct saa7164_i2c *i2c_bus = NULL; 516 int ret; 517 518 dprintk(DBGLVL_DVB, "%s()\n", __func__); 519 520 /* init frontend */ 521 switch (dev->board) { 522 case SAA7164_BOARD_HAUPPAUGE_HVR2200: 523 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2: 524 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3: 525 i2c_bus = &dev->i2c_bus[port->nr + 1]; 526 switch (port->nr) { 527 case 0: 528 port->dvb.frontend = dvb_attach(tda10048_attach, 529 &hauppauge_hvr2200_1_config, 530 &i2c_bus->i2c_adap); 531 532 if (port->dvb.frontend != NULL) { 533 /* TODO: addr is in the card struct */ 534 dvb_attach(tda18271_attach, port->dvb.frontend, 535 0xc0 >> 1, &i2c_bus->i2c_adap, 536 &hauppauge_hvr22x0_tuner_config); 537 } 538 539 break; 540 case 1: 541 port->dvb.frontend = dvb_attach(tda10048_attach, 542 &hauppauge_hvr2200_2_config, 543 &i2c_bus->i2c_adap); 544 545 if (port->dvb.frontend != NULL) { 546 /* TODO: addr is in the card struct */ 547 dvb_attach(tda18271_attach, port->dvb.frontend, 548 0xc0 >> 1, &i2c_bus->i2c_adap, 549 &hauppauge_hvr22x0s_tuner_config); 550 } 551 552 break; 553 } 554 break; 555 case SAA7164_BOARD_HAUPPAUGE_HVR2250: 556 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2: 557 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3: 558 i2c_bus = &dev->i2c_bus[port->nr + 1]; 559 560 port->dvb.frontend = dvb_attach(s5h1411_attach, 561 &hauppauge_s5h1411_config, 562 &i2c_bus->i2c_adap); 563 564 if (port->dvb.frontend != NULL) { 565 if (port->nr == 0) { 566 /* Master TDA18271 */ 567 /* TODO: addr is in the card struct */ 568 dvb_attach(tda18271_attach, port->dvb.frontend, 569 0xc0 >> 1, &i2c_bus->i2c_adap, 570 &hauppauge_hvr22x0_tuner_config); 571 } else { 572 /* Slave TDA18271 */ 573 dvb_attach(tda18271_attach, port->dvb.frontend, 574 0xc0 >> 1, &i2c_bus->i2c_adap, 575 &hauppauge_hvr22x0s_tuner_config); 576 } 577 } 578 579 break; 580 default: 581 printk(KERN_ERR "%s: The frontend isn't supported\n", 582 dev->name); 583 break; 584 } 585 if (NULL == dvb->frontend) { 586 printk(KERN_ERR "%s() Frontend initialization failed\n", 587 __func__); 588 return -1; 589 } 590 591 /* Put the analog decoder in standby to keep it quiet */ 592 593 /* register everything */ 594 ret = dvb_register(port); 595 if (ret < 0) { 596 if (dvb->frontend->ops.release) 597 dvb->frontend->ops.release(dvb->frontend); 598 return ret; 599 } 600 601 return 0; 602} 603