static int dvb_init(struct em28xx *dev) { int result = 0; struct em28xx_dvb *dvb; if (!dev->board.has_dvb) { /* This device does not support the extension */ printk(KERN_INFO "em28xx_dvb: This device does not support the extension\n"); return 0; } dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); if (dvb == NULL) { em28xx_info("em28xx_dvb: memory allocation failed\n"); return -ENOMEM; } dev->dvb = dvb; dvb->fe[0] = dvb->fe[1] = NULL; mutex_lock(&dev->lock); em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); /* init frontend */ switch (dev->model) { case EM2874_BOARD_LEADERSHIP_ISDBT: dvb->fe[0] = dvb_attach(s921_attach, &sharp_isdbt, &dev->i2c_adap); if (!dvb->fe[0]) { result = -EINVAL; goto out_free; } break; case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: dvb->fe[0] = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_KWORLD_DVB_310U: dvb->fe[0] = dvb_attach(zl10353_attach, &em28xx_zl10353_with_xc3028, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2882_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_EMPIRE_DUAL_TV: dvb->fe[0] = dvb_attach(zl10353_attach, &em28xx_zl10353_xc3028_no_i2c_gate, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: case EM2881_BOARD_PINNACLE_HYBRID_PRO: case EM2882_BOARD_DIKOM_DK300: case EM2882_BOARD_KWORLD_VS_DVBT: dvb->fe[0] = dvb_attach(zl10353_attach, &em28xx_zl10353_xc3028_no_i2c_gate, &dev->i2c_adap); if (dvb->fe[0] == NULL) { /* This board could have either a zl10353 or a mt352. If the chip id isn't for zl10353, try mt352 */ dvb->fe[0] = dvb_attach(mt352_attach, &terratec_xs_mt352_cfg, &dev->i2c_adap); } if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2883_BOARD_KWORLD_HYBRID_330U: case EM2882_BOARD_EVGA_INDTUBE: dvb->fe[0] = dvb_attach(s5h1409_attach, &em28xx_s5h1409_with_xc3028, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2882_BOARD_KWORLD_ATSC_315U: dvb->fe[0] = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap); if (dvb->fe[0] != NULL) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0], &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) { result = -EINVAL; goto out_free; } } break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E: dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL, &dev->i2c_adap, &dev->udev->dev); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2870_BOARD_REDDO_DVB_C_USB_BOX: /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */ dvb->fe[0] = dvb_attach(tda10023_attach, &em28xx_tda10023_config, &dev->i2c_adap, 0x48); if (dvb->fe[0]) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0], &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) { result = -EINVAL; goto out_free; } } break; case EM2870_BOARD_KWORLD_A340: dvb->fe[0] = dvb_attach(lgdt3305_attach, &em2870_lgdt3304_dev, &dev->i2c_adap); if (dvb->fe[0] != NULL) dvb_attach(tda18271_attach, dvb->fe[0], 0x60, &dev->i2c_adap, &kworld_a340_config); break; case EM28174_BOARD_PCTV_290E: /* MFE * FE 0 = DVB-T/T2 + FE 1 = DVB-C, both sharing same tuner. */ /* FE 0 */ dvb->fe[0] = dvb_attach(cxd2820r_attach, &em28xx_cxd2820r_config, &dev->i2c_adap, NULL); if (dvb->fe[0]) { struct i2c_adapter *i2c_tuner; i2c_tuner = cxd2820r_get_tuner_i2c_adapter(dvb->fe[0]); /* FE 0 attach tuner */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, i2c_tuner, &em28xx_cxd2820r_tda18271_config)) { dvb_frontend_detach(dvb->fe[0]); result = -EINVAL; goto out_free; } /* FE 1. This dvb_attach() cannot fail. */ dvb->fe[1] = dvb_attach(cxd2820r_attach, NULL, NULL, dvb->fe[0]); dvb->fe[1]->id = 1; /* FE 1 attach tuner */ if (!dvb_attach(tda18271_attach, dvb->fe[1], 0x60, i2c_tuner, &em28xx_cxd2820r_tda18271_config)) { dvb_frontend_detach(dvb->fe[1]); /* leave FE 0 still active */ } } break; default: em28xx_errdev("/2: The frontend of your DVB/ATSC card" " isn't supported yet\n"); break; } if (NULL == dvb->fe[0]) { em28xx_errdev("/2: frontend initialization failed\n"); result = -EINVAL; goto out_free; } /* define general-purpose callback pointer */ dvb->fe[0]->callback = em28xx_tuner_callback; /* register everything */ result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); if (result < 0) goto out_free; em28xx_info("Successfully loaded em28xx-dvb\n"); ret: em28xx_set_mode(dev, EM28XX_SUSPEND); mutex_unlock(&dev->lock); return result; out_free: kfree(dvb); dev->dvb = NULL; goto ret; }
static int register_dvb(struct tm6000_core *dev) { int ret = -1; struct tm6000_dvb *dvb = dev->dvb; mutex_init(&dvb->mutex); dvb->streams = 0; /* attach the frontend */ ret = tm6000_dvb_attach_frontend(dev); if (ret < 0) { printk(KERN_ERR "tm6000: couldn't attach the frontend!\n"); goto err; } ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T", THIS_MODULE, &dev->udev->dev, adapter_nr); dvb->adapter.priv = dev; if (dvb->frontend) { switch (dev->tuner_type) { case TUNER_XC2028: { struct xc2028_config cfg = { .i2c_adap = &dev->i2c_adap, .i2c_addr = dev->tuner_addr, }; dvb->frontend->callback = tm6000_tuner_callback; ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); if (ret < 0) { printk(KERN_ERR "tm6000: couldn't register frontend\n"); goto adapter_err; } if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) { printk(KERN_ERR "tm6000: couldn't register " "frontend (xc3028)\n"); ret = -EINVAL; goto frontend_err; } printk(KERN_INFO "tm6000: XC2028/3028 asked to be " "attached to frontend!\n"); break; } case TUNER_XC5000: { struct xc5000_config cfg = { .i2c_address = dev->tuner_addr, }; dvb->frontend->callback = tm6000_xc5000_callback; ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); if (ret < 0) { printk(KERN_ERR "tm6000: couldn't register frontend\n"); goto adapter_err; } if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) { printk(KERN_ERR "tm6000: couldn't register " "frontend (xc5000)\n"); ret = -EINVAL; goto frontend_err; } printk(KERN_INFO "tm6000: XC5000 asked to be " "attached to frontend!\n"); break; } } } else printk(KERN_ERR "tm6000: no frontend found\n"); dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING; dvb->demux.priv = dev; dvb->demux.filternum = 8; dvb->demux.feednum = 8; dvb->demux.start_feed = tm6000_start_feed; dvb->demux.stop_feed = tm6000_stop_feed; dvb->demux.write_to_decoder = NULL; ret = dvb_dmx_init(&dvb->demux); if (ret < 0) { printk(KERN_ERR "tm6000: dvb_dmx_init failed (errno = %d)\n", ret); goto frontend_err; } dvb->dmxdev.filternum = dev->dvb->demux.filternum; dvb->dmxdev.demux = &dev->dvb->demux.dmx; dvb->dmxdev.capabilities = 0; ret = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); if (ret < 0) { printk(KERN_ERR "tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret); goto dvb_dmx_err; } return 0; dvb_dmx_err: dvb_dmx_release(&dvb->demux); frontend_err: if (dvb->frontend) { dvb_unregister_frontend(dvb->frontend); dvb_frontend_detach(dvb->frontend); } adapter_err: dvb_unregister_adapter(&dvb->adapter); err: return ret; } static void unregister_dvb(struct tm6000_core *dev) { struct tm6000_dvb *dvb = dev->dvb; if (dvb->bulk_urb != NULL) { struct urb *bulk_urb = dvb->bulk_urb; kfree(bulk_urb->transfer_buffer); bulk_urb->transfer_buffer = NULL; usb_unlink_urb(bulk_urb); usb_free_urb(bulk_urb); } /* mutex_lock(&tm6000_driver.open_close_mutex); */ if (dvb->frontend) { dvb_unregister_frontend(dvb->frontend); dvb_frontend_detach(dvb->frontend); } dvb_dmxdev_release(&dvb->dmxdev); dvb_dmx_release(&dvb->demux); dvb_unregister_adapter(&dvb->adapter); mutex_destroy(&dvb->mutex); /* mutex_unlock(&tm6000_driver.open_close_mutex); */ } static int dvb_init(struct tm6000_core *dev) { struct tm6000_dvb *dvb; int rc; if (!dev) return 0; if (!dev->caps.has_dvb) return 0; if (dev->udev->speed == USB_SPEED_FULL) { printk(KERN_INFO "This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)\n"); return 0; } dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL); if (!dvb) { printk(KERN_INFO "Cannot allocate memory\n"); return -ENOMEM; } dev->dvb = dvb; rc = register_dvb(dev); if (rc < 0) { kfree(dvb); dev->dvb = NULL; return 0; } return 0; } static int dvb_fini(struct tm6000_core *dev) { if (!dev) return 0; if (!dev->caps.has_dvb) return 0; if (dev->dvb) { unregister_dvb(dev); kfree(dev->dvb); dev->dvb = NULL; } return 0; } static struct tm6000_ops dvb_ops = { .type = TM6000_DVB, .name = "TM6000 dvb Extension", .init = dvb_init, .fini = dvb_fini, }; static int __init tm6000_dvb_register(void) { return tm6000_register_extension(&dvb_ops); } static void __exit tm6000_dvb_unregister(void) { tm6000_unregister_extension(&dvb_ops); } module_init(tm6000_dvb_register); module_exit(tm6000_dvb_unregister);
static int dvb_init(struct em28xx *dev) { int result = 0; struct em28xx_dvb *dvb; if (!dev->board.has_dvb) { /* This device does not support the extension */ printk(KERN_INFO "em28xx_dvb: This device does not support the extension\n"); return 0; } dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); if (dvb == NULL) { em28xx_info("em28xx_dvb: memory allocation failed\n"); return -ENOMEM; } dev->dvb = dvb; mutex_lock(&dev->lock); em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); /* init frontend */ switch (dev->model) { case EM2874_LEADERSHIP_ISDBT: dvb->frontend = dvb_attach(s921_attach, &sharp_isdbt, &dev->i2c_adap); if (!dvb->frontend) { result = -EINVAL; goto out_free; } break; case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: dvb->frontend = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_KWORLD_DVB_310U: dvb->frontend = dvb_attach(zl10353_attach, &em28xx_zl10353_with_xc3028, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2882_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_EMPIRE_DUAL_TV: dvb->frontend = dvb_attach(zl10353_attach, &em28xx_zl10353_xc3028_no_i2c_gate, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: case EM2881_BOARD_PINNACLE_HYBRID_PRO: case EM2882_BOARD_DIKOM_DK300: case EM2882_BOARD_KWORLD_VS_DVBT: dvb->frontend = dvb_attach(zl10353_attach, &em28xx_zl10353_xc3028_no_i2c_gate, &dev->i2c_adap); if (dvb->frontend == NULL) { /* This board could have either a zl10353 or a mt352. If the chip id isn't for zl10353, try mt352 */ dvb->frontend = dvb_attach(mt352_attach, &terratec_xs_mt352_cfg, &dev->i2c_adap); } if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2883_BOARD_KWORLD_HYBRID_330U: case EM2882_BOARD_EVGA_INDTUBE: dvb->frontend = dvb_attach(s5h1409_attach, &em28xx_s5h1409_with_xc3028, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2882_BOARD_KWORLD_ATSC_315U: dvb->frontend = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap); if (dvb->frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dvb->frontend, &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) { result = -EINVAL; goto out_free; } } break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: #ifdef EM28XX_DRX397XD_SUPPORT /* We don't have the config structure properly populated, so this is commented out for now */ dvb->frontend = dvb_attach(drx397xD_attach, &em28xx_drx397xD_with_xc3028, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; #endif case EM2870_BOARD_REDDO_DVB_C_USB_BOX: /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */ dvb->frontend = dvb_attach(tda10023_attach, &em28xx_tda10023_config, &dev->i2c_adap, 0x48); if (dvb->frontend) { if (!dvb_attach(simple_tuner_attach, dvb->frontend, &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) { result = -EINVAL; goto out_free; } } break; case EM2870_BOARD_KWORLD_A340: dvb->frontend = dvb_attach(lgdt3305_attach, &em2870_lgdt3304_dev, &dev->i2c_adap); if (dvb->frontend != NULL) dvb_attach(tda18271_attach, dvb->frontend, 0x60, &dev->i2c_adap, &kworld_a340_config); break; default: em28xx_errdev("/2: The frontend of your DVB/ATSC card" " isn't supported yet\n"); break; } if (NULL == dvb->frontend) { em28xx_errdev("/2: frontend initialization failed\n"); result = -EINVAL; goto out_free; } /* define general-purpose callback pointer */ dvb->frontend->callback = em28xx_tuner_callback; /* register everything */ result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); if (result < 0) goto out_free; em28xx_info("Successfully loaded em28xx-dvb\n"); ret: em28xx_set_mode(dev, EM28XX_SUSPEND); mutex_unlock(&dev->lock); return result; out_free: kfree(dvb); dev->dvb = NULL; goto ret; }
static int dvb_init(struct cx231xx *dev) { int result = 0; struct cx231xx_dvb *dvb; if (!dev->board.has_dvb) { /* This device does not support the extension */ return 0; } dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL); if (dvb == NULL) { printk(KERN_INFO "cx231xx_dvb: memory allocation failed\n"); return -ENOMEM; } dev->dvb = dvb; dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq; dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner; cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); /* init frontend */ switch (dev->model) { case CX231XX_BOARD_CNXT_RDE_250: /* dev->dvb->frontend = dvb_attach(s5h1411_attach, &dvico_s5h1411_config, &dev->i2c_bus[1].i2c_adap); */ dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach); if (dev->dvb->frontend == NULL) { printk(DRIVER_NAME ": Failed to attach dummy front end\n"); result = -EINVAL; goto out_free; } /* define general-purpose callback pointer */ dvb->frontend->callback = cx231xx_tuner_callback; if (!dvb_attach(xc5000_attach, dev->dvb->frontend, &dev->i2c_bus[1].i2c_adap, &cnxt_rde250_tunerconfig)) { result = -EINVAL; goto out_free; } break; case CX231XX_BOARD_CNXT_RDU_250: dev->dvb->frontend = dvb_attach(dvb_dummy_fe_ofdm_attach); if (dev->dvb->frontend == NULL) { printk(DRIVER_NAME ": Failed to attach dummy front end\n"); result = -EINVAL; goto out_free; } /* define general-purpose callback pointer */ dvb->frontend->callback = cx231xx_tuner_callback; if (!dvb_attach(xc5000_attach, dev->dvb->frontend, &dev->i2c_bus[1].i2c_adap, &cnxt_rde250_tunerconfig)) { result = -EINVAL; goto out_free; } break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" " isn't supported yet\n", dev->name); break; } if (NULL == dvb->frontend) { printk(KERN_ERR "%s/2: frontend initialization failed\n", dev->name); result = -EINVAL; goto out_free; } /* register everything */ result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); if (result < 0) goto out_free; cx231xx_set_mode(dev, CX231XX_SUSPEND); printk(KERN_INFO "Successfully loaded cx231xx-dvb\n"); return 0; out_free: cx231xx_set_mode(dev, CX231XX_SUSPEND); kfree(dvb); dev->dvb = NULL; return result; }
static int dvb_init(struct em28xx *dev) { int result = 0; struct em28xx_dvb *dvb; if (!dev->board.has_dvb) { return 0; } dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); if (dvb == NULL) { printk(KERN_INFO "em28xx_dvb: memory allocation failed\n"); return -ENOMEM; } dev->dvb = dvb; em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); switch (dev->model) { case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: dvb->frontend = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_KWORLD_DVB_310U: dvb->frontend = dvb_attach(zl10353_attach, &em28xx_zl10353_with_xc3028, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2880_BOARD_EMPIRE_DUAL_TV: dvb->frontend = dvb_attach(zl10353_attach, &em28xx_zl10353_xc3028_no_i2c_gate, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_TERRATEC_HYBRID_XS: case EM2881_BOARD_PINNACLE_HYBRID_PRO: dvb->frontend = dvb_attach(zl10353_attach, &em28xx_zl10353_xc3028_no_i2c_gate, &dev->i2c_adap); if (dvb->frontend == NULL) { dvb->frontend = dvb_attach(mt352_attach, &terratec_xs_mt352_cfg, &dev->i2c_adap); } if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2883_BOARD_KWORLD_HYBRID_330U: case EM2882_BOARD_EVGA_INDTUBE: dvb->frontend = dvb_attach(s5h1409_attach, &em28xx_s5h1409_with_xc3028, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2882_BOARD_KWORLD_ATSC_315U: dvb->frontend = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap); if (dvb->frontend != NULL) { if (!dvb_attach(simple_tuner_attach, dvb->frontend, &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) { result = -EINVAL; goto out_free; } } break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: #ifdef EM28XX_DRX397XD_SUPPORT dvb->frontend = dvb_attach(drx397xD_attach, &em28xx_drx397xD_with_xc3028, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; #endif case EM2870_BOARD_REDDO_DVB_C_USB_BOX: dvb->frontend = dvb_attach(tda10023_attach, &em28xx_tda10023_config, &dev->i2c_adap, 0x48); if (dvb->frontend) { if (!dvb_attach(simple_tuner_attach, dvb->frontend, &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) { result = -EINVAL; goto out_free; } } break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" " isn't supported yet\n", dev->name); break; } if (NULL == dvb->frontend) { printk(KERN_ERR "%s/2: frontend initialization failed\n", dev->name); result = -EINVAL; goto out_free; } dvb->frontend->callback = em28xx_tuner_callback; result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); if (result < 0) goto out_free; em28xx_set_mode(dev, EM28XX_SUSPEND); printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); return 0; out_free: em28xx_set_mode(dev, EM28XX_SUSPEND); kfree(dvb); dev->dvb = NULL; return result; }
static int dvb_init(struct em28xx *dev) { int result = 0; struct em28xx_dvb *dvb; if (!dev->has_dvb) { /* This device does not support the extension */ return 0; } dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); if (dvb == NULL) { printk(KERN_INFO "em28xx_dvb: memory allocation failed\n"); return -ENOMEM; } dev->dvb = dvb; em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); /* init frontend */ switch (dev->model) { case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: dvb->frontend = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: dvb->frontend = dvb_attach(zl10353_attach, &em28xx_zl10353_with_xc3028, &dev->i2c_adap); if (attach_xc3028(0x61, dev) < 0) { result = -EINVAL; goto out_free; } break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" " isn't supported yet\n", dev->name); break; } if (NULL == dvb->frontend) { printk(KERN_ERR "%s/2: frontend initialization failed\n", dev->name); result = -EINVAL; goto out_free; } /* register everything */ result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); if (result < 0) goto out_free; em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); return 0; out_free: em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); kfree(dvb); dev->dvb = NULL; return result; }