brintos

brintos / linux-shallow public Read only

0
0
Text · 14.0 KiB · 2cd88ca Raw
490 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* DVB USB compliant linux driver for mobile DVB-T USB devices based on3 * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B)4 *5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)6 *7 * based on GPL code from DiBcom, which has8 * Copyright (C) 2004 Amaury Demol for DiBcom9 *10 * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information11 */12#include "dibusb.h"13 14DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);15 16static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)17{18	struct dvb_usb_adapter *adap = fe->dvb->priv;19	struct dibusb_state *st = adap->priv;20 21	return st->ops.tuner_pass_ctrl(fe, enable, st->tuner_addr);22}23 24static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap)25{26	struct dib3000_config demod_cfg;27	struct dibusb_state *st = adap->priv;28 29	demod_cfg.demod_address = 0x8;30 31	adap->fe_adap[0].fe = dvb_attach(dib3000mb_attach, &demod_cfg,32					 &adap->dev->i2c_adap, &st->ops);33	if ((adap->fe_adap[0].fe) == NULL)34		return -ENODEV;35 36	adap->fe_adap[0].fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl;37 38	return 0;39}40 41static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap)42{43	struct dibusb_state *st = adap->priv;44 45	st->tuner_addr = 0x61;46 47	dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap,48		   DVB_PLL_TUA6010XS);49	return 0;50}51 52static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap)53{54	struct dibusb_state *st = adap->priv;55 56	st->tuner_addr = 0x60;57 58	dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap,59		   DVB_PLL_TDA665X);60	return 0;61}62 63/* Some of the Artec 1.1 device aren't equipped with the default tuner64 * (Thomson Cable), but with a Panasonic ENV77H11D5.  This function figures65 * this out. */66static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap)67{68	u8 b[2] = { 0,0 }, b2[1];69	int ret = 0;70	struct i2c_msg msg[2] = {71		{ .flags = 0,        .buf = b,  .len = 2 },72		{ .flags = I2C_M_RD, .buf = b2, .len = 1 },73	};74	struct dibusb_state *st = adap->priv;75 76	/* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */77	msg[0].addr = msg[1].addr = st->tuner_addr = 0x60;78 79	if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)80		adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1);81 82	if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {83		err("tuner i2c write failed.");84		return -EREMOTEIO;85	}86 87	if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)88		adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0);89 90	if (b2[0] == 0xfe) {91		info("This device has the Thomson Cable onboard. Which is default.");92		ret = dibusb_thomson_tuner_attach(adap);93	} else {94		info("This device has the Panasonic ENV77H11D5 onboard.");95		ret = dibusb_panasonic_tuner_attach(adap);96	}97 98	return ret;99}100 101/* USB Driver stuff */102static struct dvb_usb_device_properties dibusb1_1_properties;103static struct dvb_usb_device_properties dibusb1_1_an2235_properties;104static struct dvb_usb_device_properties dibusb2_0b_properties;105static struct dvb_usb_device_properties artec_t1_usb2_properties;106 107static int dibusb_probe(struct usb_interface *intf,108		const struct usb_device_id *id)109{110	if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties,111				     THIS_MODULE, NULL, adapter_nr) ||112	    0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties,113				     THIS_MODULE, NULL, adapter_nr) ||114	    0 == dvb_usb_device_init(intf, &dibusb2_0b_properties,115				     THIS_MODULE, NULL, adapter_nr) ||116	    0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties,117				     THIS_MODULE, NULL, adapter_nr))118		return 0;119 120	return -EINVAL;121}122 123/* do not change the order of the ID table */124enum {125	WIDEVIEW_DVBT_USB_COLD,126	WIDEVIEW_DVBT_USB_WARM,127	COMPRO_DVBU2000_COLD,128	COMPRO_DVBU2000_WARM,129	COMPRO_DVBU2000_UNK_COLD,130	DIBCOM_MOD3000_COLD,131	DIBCOM_MOD3000_WARM,132	EMPIA_VSTREAM_COLD,133	EMPIA_VSTREAM_WARM,134	GRANDTEC_DVBT_USB_COLD,135	GRANDTEC_DVBT_USB_WARM,136	GRANDTEC_MOD3000_COLD,137	GRANDTEC_MOD3000_WARM,138	UNK_HYPER_PALTEK_COLD,139	UNK_HYPER_PALTEK_WARM,140	VISIONPLUS_VP7041_COLD,141	VISIONPLUS_VP7041_WARM,142	TWINHAN_VP7041_COLD,143	TWINHAN_VP7041_WARM,144	ULTIMA_TVBOX_COLD,145	ULTIMA_TVBOX_WARM,146	ULTIMA_TVBOX_AN2235_COLD,147	ULTIMA_TVBOX_AN2235_WARM,148	ADSTECH_USB2_COLD,149	ADSTECH_USB2_WARM,150	KYE_DVB_T_COLD,151	KYE_DVB_T_WARM,152	KWORLD_VSTREAM_COLD,153	ULTIMA_TVBOX_USB2_COLD,154	ULTIMA_TVBOX_USB2_WARM,155	ULTIMA_TVBOX_ANCHOR_COLD,156};157 158static struct usb_device_id dibusb_dib3000mb_table[] = {159	DVB_USB_DEV(WIDEVIEW, WIDEVIEW_DVBT_USB_COLD),160	DVB_USB_DEV(WIDEVIEW, WIDEVIEW_DVBT_USB_WARM),161	DVB_USB_DEV(COMPRO, COMPRO_DVBU2000_COLD),162	DVB_USB_DEV(COMPRO, COMPRO_DVBU2000_WARM),163	DVB_USB_DEV(COMPRO_UNK, COMPRO_DVBU2000_UNK_COLD),164	DVB_USB_DEV(DIBCOM, DIBCOM_MOD3000_COLD),165	DVB_USB_DEV(DIBCOM, DIBCOM_MOD3000_WARM),166	DVB_USB_DEV(EMPIA, EMPIA_VSTREAM_COLD),167	DVB_USB_DEV(EMPIA, EMPIA_VSTREAM_WARM),168	DVB_USB_DEV(GRANDTEC, GRANDTEC_DVBT_USB_COLD),169	DVB_USB_DEV(GRANDTEC, GRANDTEC_DVBT_USB_WARM),170	DVB_USB_DEV(GRANDTEC, GRANDTEC_MOD3000_COLD),171	DVB_USB_DEV(GRANDTEC, GRANDTEC_MOD3000_WARM),172	DVB_USB_DEV(HYPER_PALTEK, UNK_HYPER_PALTEK_COLD),173	DVB_USB_DEV(HYPER_PALTEK, UNK_HYPER_PALTEK_WARM),174	DVB_USB_DEV(VISIONPLUS, VISIONPLUS_VP7041_COLD),175	DVB_USB_DEV(VISIONPLUS, VISIONPLUS_VP7041_WARM),176	DVB_USB_DEV(TWINHAN, TWINHAN_VP7041_COLD),177	DVB_USB_DEV(TWINHAN, TWINHAN_VP7041_WARM),178	DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_COLD),179	DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_WARM),180	DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_AN2235_COLD),181	DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_AN2235_WARM),182	DVB_USB_DEV(ADSTECH, ADSTECH_USB2_COLD),183	DVB_USB_DEV(ADSTECH, ADSTECH_USB2_WARM),184	DVB_USB_DEV(KYE, KYE_DVB_T_COLD),185	DVB_USB_DEV(KYE, KYE_DVB_T_WARM),186	DVB_USB_DEV(KWORLD, KWORLD_VSTREAM_COLD),187	DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_USB2_COLD),188	DVB_USB_DEV(ULTIMA_ELECTRONIC, ULTIMA_TVBOX_USB2_WARM),189#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY190	DVB_USB_DEV(ANCHOR, ULTIMA_TVBOX_ANCHOR_COLD),191#endif192	{ }193};194 195MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);196 197static struct dvb_usb_device_properties dibusb1_1_properties = {198	.caps =  DVB_USB_IS_AN_I2C_ADAPTER,199 200	.usb_ctrl = CYPRESS_AN2135,201 202	.firmware = "dvb-usb-dibusb-5.0.0.11.fw",203 204	.num_adapters = 1,205	.adapter = {206		{207		.num_frontends = 1,208		.fe = {{209			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,210			.pid_filter_count = 16,211 212			.streaming_ctrl   = dibusb_streaming_ctrl,213			.pid_filter       = dibusb_pid_filter,214			.pid_filter_ctrl  = dibusb_pid_filter_ctrl,215			.frontend_attach  = dibusb_dib3000mb_frontend_attach,216			.tuner_attach     = dibusb_tuner_probe_and_attach,217 218			/* parameter for the MPEG2-data transfer */219			.stream = {220				.type = USB_BULK,221				.count = 7,222				.endpoint = 0x02,223				.u = {224					.bulk = {225						.buffersize = 4096,226					}227				}228			},229		}},230			.size_of_priv     = sizeof(struct dibusb_state),231		}232	},233 234	.power_ctrl       = dibusb_power_ctrl,235 236	.rc.legacy = {237		.rc_interval      = DEFAULT_RC_INTERVAL,238		.rc_map_table     = rc_map_dibusb_table,239		.rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */240		.rc_query         = dibusb_rc_query,241	},242 243	.i2c_algo         = &dibusb_i2c_algo,244 245	.generic_bulk_ctrl_endpoint = 0x01,246 247	.num_device_descs = 9,248	.devices = {249		{	"AVerMedia AverTV DVBT USB1.1",250			{ &dibusb_dib3000mb_table[WIDEVIEW_DVBT_USB_COLD],  NULL },251			{ &dibusb_dib3000mb_table[WIDEVIEW_DVBT_USB_WARM],  NULL },252		},253		{	"Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",254			{ &dibusb_dib3000mb_table[COMPRO_DVBU2000_COLD], &dibusb_dib3000mb_table[COMPRO_DVBU2000_UNK_COLD], NULL},255			{ &dibusb_dib3000mb_table[COMPRO_DVBU2000_WARM], NULL },256		},257		{	"DiBcom USB1.1 DVB-T reference design (MOD3000)",258			{ &dibusb_dib3000mb_table[DIBCOM_MOD3000_COLD],  NULL },259			{ &dibusb_dib3000mb_table[DIBCOM_MOD3000_WARM],  NULL },260		},261		{	"KWorld V-Stream XPERT DTV - DVB-T USB1.1",262			{ &dibusb_dib3000mb_table[EMPIA_VSTREAM_COLD], NULL },263			{ &dibusb_dib3000mb_table[EMPIA_VSTREAM_WARM], NULL },264		},265		{	"Grandtec USB1.1 DVB-T",266			{ &dibusb_dib3000mb_table[GRANDTEC_DVBT_USB_COLD],  &dibusb_dib3000mb_table[GRANDTEC_MOD3000_COLD], NULL },267			{ &dibusb_dib3000mb_table[GRANDTEC_DVBT_USB_WARM], &dibusb_dib3000mb_table[GRANDTEC_MOD3000_WARM], NULL },268		},269		{	"Unknown USB1.1 DVB-T device ???? please report the name to the author",270			{ &dibusb_dib3000mb_table[UNK_HYPER_PALTEK_COLD], NULL },271			{ &dibusb_dib3000mb_table[UNK_HYPER_PALTEK_WARM], NULL },272		},273		{	"TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",274			{ &dibusb_dib3000mb_table[VISIONPLUS_VP7041_COLD], &dibusb_dib3000mb_table[TWINHAN_VP7041_COLD], NULL},275			{ &dibusb_dib3000mb_table[VISIONPLUS_VP7041_WARM], &dibusb_dib3000mb_table[TWINHAN_VP7041_WARM], NULL},276		},277		{	"Artec T1 USB1.1 TVBOX with AN2135",278			{ &dibusb_dib3000mb_table[ULTIMA_TVBOX_COLD], NULL },279			{ &dibusb_dib3000mb_table[ULTIMA_TVBOX_WARM], NULL },280		},281		{	"VideoWalker DVB-T USB",282			{ &dibusb_dib3000mb_table[KYE_DVB_T_COLD], NULL },283			{ &dibusb_dib3000mb_table[KYE_DVB_T_WARM], NULL },284		},285	}286};287 288static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {289	.caps = DVB_USB_IS_AN_I2C_ADAPTER,290	.usb_ctrl = CYPRESS_AN2235,291 292	.firmware = "dvb-usb-dibusb-an2235-01.fw",293 294	.num_adapters = 1,295	.adapter = {296		{297		.num_frontends = 1,298		.fe = {{299			.caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER,300			.pid_filter_count = 16,301 302			.streaming_ctrl   = dibusb_streaming_ctrl,303			.pid_filter       = dibusb_pid_filter,304			.pid_filter_ctrl  = dibusb_pid_filter_ctrl,305			.frontend_attach  = dibusb_dib3000mb_frontend_attach,306			.tuner_attach     = dibusb_tuner_probe_and_attach,307 308			/* parameter for the MPEG2-data transfer */309			.stream = {310				.type = USB_BULK,311				.count = 7,312				.endpoint = 0x02,313				.u = {314					.bulk = {315						.buffersize = 4096,316					}317				}318			},319		}},320			.size_of_priv     = sizeof(struct dibusb_state),321		},322	},323	.power_ctrl       = dibusb_power_ctrl,324 325	.rc.legacy = {326		.rc_interval      = DEFAULT_RC_INTERVAL,327		.rc_map_table     = rc_map_dibusb_table,328		.rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */329		.rc_query         = dibusb_rc_query,330	},331 332	.i2c_algo         = &dibusb_i2c_algo,333 334	.generic_bulk_ctrl_endpoint = 0x01,335 336#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY337	.num_device_descs = 2,338#else339	.num_device_descs = 1,340#endif341	.devices = {342		{	"Artec T1 USB1.1 TVBOX with AN2235",343			{ &dibusb_dib3000mb_table[ULTIMA_TVBOX_AN2235_COLD], NULL },344			{ &dibusb_dib3000mb_table[ULTIMA_TVBOX_AN2235_WARM], NULL },345		},346#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY347		{	"Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",348			{ &dibusb_dib3000mb_table[ULTIMA_TVBOX_ANCHOR_COLD], NULL },349			{ NULL },350		},351		{ NULL },352#endif353	}354};355 356static struct dvb_usb_device_properties dibusb2_0b_properties = {357	.caps = DVB_USB_IS_AN_I2C_ADAPTER,358 359	.usb_ctrl = CYPRESS_FX2,360 361	.firmware = "dvb-usb-adstech-usb2-02.fw",362 363	.num_adapters = 1,364	.adapter = {365		{366		.num_frontends = 1,367		.fe = {{368			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,369			.pid_filter_count = 16,370 371			.streaming_ctrl   = dibusb2_0_streaming_ctrl,372			.pid_filter       = dibusb_pid_filter,373			.pid_filter_ctrl  = dibusb_pid_filter_ctrl,374			.frontend_attach  = dibusb_dib3000mb_frontend_attach,375			.tuner_attach     = dibusb_thomson_tuner_attach,376 377			/* parameter for the MPEG2-data transfer */378			.stream = {379				.type = USB_BULK,380				.count = 7,381				.endpoint = 0x06,382				.u = {383					.bulk = {384						.buffersize = 4096,385					}386				}387			},388		}},389			.size_of_priv     = sizeof(struct dibusb_state),390		}391	},392	.power_ctrl       = dibusb2_0_power_ctrl,393 394	.rc.legacy = {395		.rc_interval      = DEFAULT_RC_INTERVAL,396		.rc_map_table     = rc_map_dibusb_table,397		.rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */398		.rc_query         = dibusb_rc_query,399	},400 401	.i2c_algo         = &dibusb_i2c_algo,402 403	.generic_bulk_ctrl_endpoint = 0x01,404 405	.num_device_descs = 2,406	.devices = {407		{	"KWorld/ADSTech Instant DVB-T USB2.0",408			{ &dibusb_dib3000mb_table[ADSTECH_USB2_COLD], NULL },409			{ &dibusb_dib3000mb_table[ADSTECH_USB2_WARM], NULL },410		},411		{	"KWorld Xpert DVB-T USB2.0",412			{ &dibusb_dib3000mb_table[KWORLD_VSTREAM_COLD], NULL },413			{ NULL }414		},415		{ NULL },416	}417};418 419static struct dvb_usb_device_properties artec_t1_usb2_properties = {420	.caps = DVB_USB_IS_AN_I2C_ADAPTER,421 422	.usb_ctrl = CYPRESS_FX2,423 424	.firmware = "dvb-usb-dibusb-6.0.0.8.fw",425 426	.num_adapters = 1,427	.adapter = {428		{429		.num_frontends = 1,430		.fe = {{431			.caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,432			.pid_filter_count = 16,433 434			.streaming_ctrl   = dibusb2_0_streaming_ctrl,435			.pid_filter       = dibusb_pid_filter,436			.pid_filter_ctrl  = dibusb_pid_filter_ctrl,437			.frontend_attach  = dibusb_dib3000mb_frontend_attach,438			.tuner_attach     = dibusb_tuner_probe_and_attach,439			/* parameter for the MPEG2-data transfer */440			.stream = {441				.type = USB_BULK,442				.count = 7,443				.endpoint = 0x06,444				.u = {445					.bulk = {446						.buffersize = 4096,447					}448				}449			},450		}},451			.size_of_priv     = sizeof(struct dibusb_state),452		}453	},454	.power_ctrl       = dibusb2_0_power_ctrl,455 456	.rc.legacy = {457		.rc_interval      = DEFAULT_RC_INTERVAL,458		.rc_map_table     = rc_map_dibusb_table,459		.rc_map_size      = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */460		.rc_query         = dibusb_rc_query,461	},462 463	.i2c_algo         = &dibusb_i2c_algo,464 465	.generic_bulk_ctrl_endpoint = 0x01,466 467	.num_device_descs = 1,468	.devices = {469		{	"Artec T1 USB2.0",470			{ &dibusb_dib3000mb_table[ULTIMA_TVBOX_USB2_COLD], NULL },471			{ &dibusb_dib3000mb_table[ULTIMA_TVBOX_USB2_WARM], NULL },472		},473		{ NULL },474	}475};476 477static struct usb_driver dibusb_driver = {478	.name		= "dvb_usb_dibusb_mb",479	.probe		= dibusb_probe,480	.disconnect = dvb_usb_device_exit,481	.id_table	= dibusb_dib3000mb_table,482};483 484module_usb_driver(dibusb_driver);485 486MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");487MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");488MODULE_VERSION("1.0");489MODULE_LICENSE("GPL");490