// SPDX-License-Identifier: GPL-2.0 // // DVB device driver for em28xx // // (c) 2008-2011 Mauro Carvalho Chehab <mchehab@kernel.org> // // (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> // - Fixes for the driver to properly work with HVR-950 // - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick // - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600 // // (c) 2008 Aidan Thornton <makosoft@googlemail.com> // // (c) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> // // Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by: // (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> // (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
for (i = 0; i < num_packets; i++) { if (xfer_bulk) { if (urb->status < 0) {
print_err_status(dev, i, urb->status); if (urb->status != -EPROTO) continue;
} if (!urb->actual_length) continue;
dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
urb->actual_length);
} else { if (urb->iso_frame_desc[i].status < 0) {
print_err_status(dev, i,
urb->iso_frame_desc[i].status); if (urb->iso_frame_desc[i].status != -EPROTO) continue;
} if (!urb->iso_frame_desc[i].actual_length) continue;
dvb_dmx_swfilter(&dev->dvb->demux,
urb->transfer_buffer +
urb->iso_frame_desc[i].offset,
urb->iso_frame_desc[i].actual_length);
}
}
for (i = 0; i < ARRAY_SIZE(regs); i++)
i2c_master_send(&dev->i2c_client[dev->def_i2c_bus],
regs[i].r, regs[i].len);
em28xx_gpio_set(dev, hauppauge_hvr930c_end);
for (i = 0; i < ARRAY_SIZE(regs); i++)
i2c_master_send(&dev->i2c_client[dev->def_i2c_bus],
regs[i].r, regs[i].len);
em28xx_gpio_set(dev, terratec_h5_end);
};
staticvoid terratec_htc_stick_init(struct em28xx *dev)
{ int i;
/* If the analog part won't create RF connectors, DVB will do it */ if (!dev->has_video || dev->tuner_type == TUNER_ABSENT)
create_rf_connector = true;
result = dvb_create_media_graph(&dvb->adapter, create_rf_connector); if (result < 0) goto fail_create_graph;
/* pre-allocate DVB usb transfer buffers */ if (dev->dvb_xfer_bulk) {
result = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE,
dev->dvb_xfer_bulk,
EM28XX_DVB_NUM_BUFS,
512,
EM28XX_DVB_BULK_PACKET_MULTIPLIER);
} else {
result = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE,
dev->dvb_xfer_bulk,
EM28XX_DVB_NUM_BUFS,
dev->dvb_max_pkt_size_isoc,
EM28XX_DVB_NUM_ISOC_PACKETS);
} if (result) {
dev_err(&dev->intf->dev, "failed to pre-allocate USB transfer buffers for DVB.\n");
kfree(dvb);
dev->dvb = NULL; return result;
}
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,
0x0e,
&dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_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[dev->def_i2c_bus]); if (em28xx_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: case EM2882_BOARD_ZOLID_HYBRID_TV_STICK:
dvb->fe[0] = dvb_attach(zl10353_attach,
&em28xx_zl10353_xc3028_no_i2c_gate,
&dev->i2c_adap[dev->def_i2c_bus]); if (em28xx_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: /* * Those boards could have either a zl10353 or a mt352. * If the chip id isn't for zl10353, try mt352.
*/
dvb->fe[0] = dvb_attach(zl10353_attach,
&em28xx_zl10353_xc3028_no_i2c_gate,
&dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0])
dvb->fe[0] = dvb_attach(mt352_attach,
&terratec_xs_mt352_cfg,
&dev->i2c_adap[dev->def_i2c_bus]);
if (em28xx_attach_xc3028(0x61, dev) < 0) {
result = -EINVAL; goto out_free;
} break; case EM2870_BOARD_TERRATEC_XS_MT2060:
dvb->fe[0] = dvb_attach(zl10353_attach,
&em28xx_zl10353_no_i2c_gate_dev,
&dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0]) {
dvb_attach(mt2060_attach, dvb->fe[0],
&dev->i2c_adap[dev->def_i2c_bus],
&em28xx_mt2060_config, 1220);
} break; case EM2870_BOARD_KWORLD_355U:
dvb->fe[0] = dvb_attach(zl10353_attach,
&em28xx_zl10353_no_i2c_gate_dev,
&dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0])
dvb_attach(qt1010_attach, dvb->fe[0],
&dev->i2c_adap[dev->def_i2c_bus],
&em28xx_qt1010_config); 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[dev->def_i2c_bus]); if (em28xx_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,
0x0e,
&dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0]) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
&dev->i2c_adap[dev->def_i2c_bus],
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->def_i2c_bus],
&dev->intf->dev); if (em28xx_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[dev->def_i2c_bus],
0x48); if (dvb->fe[0]) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
&dev->i2c_adap[dev->def_i2c_bus],
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[dev->def_i2c_bus]); if (!dvb->fe[0]) {
result = -EINVAL; goto out_free;
} if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
&dev->i2c_adap[dev->def_i2c_bus],
&kworld_a340_config)) {
dvb_frontend_detach(dvb->fe[0]);
result = -EINVAL; goto out_free;
} break; case EM28174_BOARD_PCTV_290E: /* set default GPIO0 for LNA, used if GPIOLIB is undefined */
dvb->lna_gpio = CXD2820R_GPIO_E | CXD2820R_GPIO_O |
CXD2820R_GPIO_L;
dvb->fe[0] = dvb_attach(cxd2820r_attach,
&em28xx_cxd2820r_config,
&dev->i2c_adap[dev->def_i2c_bus],
&dvb->lna_gpio); if (dvb->fe[0]) { /* FE 0 attach tuner */ if (!dvb_attach(tda18271_attach,
dvb->fe[0],
0x60,
&dev->i2c_adap[dev->def_i2c_bus],
&em28xx_cxd2820r_tda18271_config)) {
dvb_frontend_detach(dvb->fe[0]);
result = -EINVAL; goto out_free;
}
#ifdef CONFIG_GPIOLIB /* enable LNA for DVB-T, DVB-T2 and DVB-C */
result = gpio_request_one(dvb->lna_gpio,
GPIOF_OUT_INIT_LOW, NULL); if (result)
dev_err(&dev->intf->dev, "gpio request failed %d\n",
result); else
gpio_free(dvb->lna_gpio);
result = 0; /* continue even set LNA fails */ #endif
dvb->fe[0]->ops.set_lna = em28xx_pctv_290e_set_lna;
}
break; case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C:
{ struct xc5000_config cfg = {};
hauppauge_hvr930c_init(dev);
dvb->fe[0] = dvb_attach(drxk_attach,
&hauppauge_930c_drxk,
&dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) {
result = -EINVAL; goto out_free;
} /* FIXME: do we need a pll semaphore? */
dvb->fe[0]->sec_priv = dvb;
sema_init(&dvb->pll_mutex, 1);
dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
if (dvb->fe[0]->ops.i2c_gate_ctrl)
dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); if (!dvb_attach(xc5000_attach, dvb->fe[0],
&dev->i2c_adap[dev->def_i2c_bus], &cfg)) {
result = -EINVAL; goto out_free;
} if (dvb->fe[0]->ops.i2c_gate_ctrl)
dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);
break;
} case EM2884_BOARD_TERRATEC_H5:
terratec_h5_init(dev);
dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk,
&dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) {
result = -EINVAL; goto out_free;
} /* FIXME: do we need a pll semaphore? */
dvb->fe[0]->sec_priv = dvb;
sema_init(&dvb->pll_mutex, 1);
dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
/* Attach tda18271 to DVB-C frontend */ if (dvb->fe[0]->ops.i2c_gate_ctrl)
dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0],
&dev->i2c_adap[dev->def_i2c_bus], 0x60)) {
result = -EINVAL; goto out_free;
} if (dvb->fe[0]->ops.i2c_gate_ctrl)
dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);
break; case EM2884_BOARD_C3TECH_DIGITAL_DUO:
dvb->fe[0] = dvb_attach(mb86a20s_attach,
&c3tech_duo_mb86a20s_config,
&dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0])
dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
&dev->i2c_adap[dev->def_i2c_bus],
&c3tech_duo_tda18271_config); break; case EM28174_BOARD_PCTV_460E:
result = em28174_dvb_init_pctv_460e(dev); if (result) goto out_free; break; case EM2874_BOARD_DELOCK_61959: case EM2874_BOARD_MAXMEDIA_UB425_TC: /* attach demodulator */
dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk,
&dev->i2c_adap[dev->def_i2c_bus]);
if (dvb->fe[0]) { /* disable I2C-gate */
dvb->fe[0]->ops.i2c_gate_ctrl = NULL;
/* attach tuner */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
&dev->i2c_adap[dev->def_i2c_bus],
&em28xx_cxd2820r_tda18271_config)) {
dvb_frontend_detach(dvb->fe[0]);
result = -EINVAL; goto out_free;
}
} break; case EM2884_BOARD_PCTV_510E: case EM2884_BOARD_PCTV_520E:
pctv_520e_init(dev);
if (dvb->fe[0]) { /* attach tuner */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
&dev->i2c_adap[dev->def_i2c_bus],
&em28xx_cxd2820r_tda18271_config)) {
dvb_frontend_detach(dvb->fe[0]);
result = -EINVAL; goto out_free;
}
} break; case EM2884_BOARD_ELGATO_EYETV_HYBRID_2008: case EM2884_BOARD_CINERGY_HTC_STICK: case EM2884_BOARD_TERRATEC_H6:
terratec_htc_stick_init(dev);
/* attach demodulator */
dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk,
&dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) {
result = -EINVAL; goto out_free;
}
/* Attach the demodulator. */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
&dev->i2c_adap[dev->def_i2c_bus],
&em28xx_cxd2820r_tda18271_config)) {
result = -EINVAL; goto out_free;
} break; case EM2884_BOARD_TERRATEC_HTC_USB_XS:
terratec_htc_usb_xs_init(dev);
/* attach demodulator */
dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk,
&dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) {
result = -EINVAL; goto out_free;
}
/* Attach the demodulator. */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
&dev->i2c_adap[dev->def_i2c_bus],
&em28xx_cxd2820r_tda18271_config)) {
result = -EINVAL; goto out_free;
} break; case EM2874_BOARD_KWORLD_UB435Q_V2:
dvb->fe[0] = dvb_attach(lgdt3305_attach,
&em2874_lgdt3305_dev,
&dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) {
result = -EINVAL; goto out_free;
}
/* Attach the demodulator. */ if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
&dev->i2c_adap[dev->def_i2c_bus],
&kworld_ub435q_v2_config)) {
result = -EINVAL; goto out_free;
} break; case EM2874_BOARD_KWORLD_UB435Q_V3:
{ struct i2c_adapter *adapter = &dev->i2c_adap[dev->def_i2c_bus];
dvb->fe[0] = dvb_attach(lgdt3305_attach,
&em2874_lgdt3305_nogate_dev,
&dev->i2c_adap[dev->def_i2c_bus]); if (!dvb->fe[0]) {
result = -EINVAL; goto out_free;
}
dvb->i2c_client_tuner = dvb_module_probe("tda18212", NULL,
adapter, 0x60,
&kworld_ub435q_v3_config); if (!dvb->i2c_client_tuner) {
dvb_frontend_detach(dvb->fe[0]);
result = -ENODEV; goto out_free;
} break;
} case EM2874_BOARD_PCTV_HD_MINI_80E:
dvb->fe[0] = dvb_attach(drx39xxj_attach,
&dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0]) {
dvb->fe[0] = dvb_attach(tda18271_attach, dvb->fe[0],
0x60,
&dev->i2c_adap[dev->def_i2c_bus],
&pinnacle_80e_dvb_config); if (!dvb->fe[0]) {
result = -EINVAL; goto out_free;
}
} break; case EM28178_BOARD_PCTV_461E:
result = em28178_dvb_init_pctv_461e(dev); if (result) goto out_free; break; case EM28178_BOARD_PCTV_461E_V2:
result = em28178_dvb_init_pctv_461e_v2(dev); if (result) goto out_free; break; case EM28178_BOARD_PCTV_292E:
result = em28178_dvb_init_pctv_292e(dev); if (result) goto out_free; break; case EM28178_BOARD_TERRATEC_T2_STICK_HD:
result = em28178_dvb_init_terratec_t2_stick_hd(dev); if (result) goto out_free; break; case EM28178_BOARD_PLEX_PX_BCUD:
result = em28178_dvb_init_plex_px_bcud(dev); if (result) goto out_free; break; case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB:
result = em28174_dvb_init_hauppauge_wintv_dualhd_dvb(dev); if (result) goto out_free; break; case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595:
result = em28174_dvb_init_hauppauge_wintv_dualhd_01595(dev); if (result) goto out_free; break; case EM2874_BOARD_HAUPPAUGE_USB_QUADHD:
result = em2874_dvb_init_hauppauge_usb_quadhd(dev); if (result) goto out_free; break; default:
dev_err(&dev->intf->dev, "The frontend of your DVB/ATSC card isn't supported yet\n"); break;
} if (!dvb->fe[0]) {
dev_err(&dev->intf->dev, "frontend initialization failed\n");
result = -EINVAL; goto out_free;
} /* define general-purpose callback pointer */
dvb->fe[0]->callback = em28xx_tuner_callback; if (dvb->fe[1])
dvb->fe[1]->callback = em28xx_tuner_callback;
/* register everything */
result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->intf->dev);
if (dev->disconnected) { /* * We cannot tell the device to sleep * once it has been unplugged.
*/ if (dvb->fe[0]) {
prevent_sleep(&dvb->fe[0]->ops);
dvb->fe[0]->exit = DVB_FE_DEVICE_REMOVED;
} if (dvb->fe[1]) {
prevent_sleep(&dvb->fe[1]->ops);
dvb->fe[1]->exit = DVB_FE_DEVICE_REMOVED;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.