Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.0-rc1 477 lines 15 kB view raw
1/* DVB USB compliant linux driver for mobile DVB-T USB devices based on 2 * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B) 3 * 4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) 5 * 6 * based on GPL code from DiBcom, which has 7 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the Free 11 * Software Foundation, version 2. 12 * 13 * see Documentation/dvb/README.dvb-usb for more information 14 */ 15#include "dibusb.h" 16 17DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 18 19static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) 20{ 21 struct dvb_usb_adapter *adap = fe->dvb->priv; 22 struct dibusb_state *st = adap->priv; 23 24 return st->ops.tuner_pass_ctrl(fe, enable, st->tuner_addr); 25} 26 27static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap) 28{ 29 struct dib3000_config demod_cfg; 30 struct dibusb_state *st = adap->priv; 31 32 demod_cfg.demod_address = 0x8; 33 34 if ((adap->fe = dvb_attach(dib3000mb_attach, &demod_cfg, 35 &adap->dev->i2c_adap, &st->ops)) == NULL) 36 return -ENODEV; 37 38 adap->fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl; 39 40 return 0; 41} 42 43static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap) 44{ 45 struct dibusb_state *st = adap->priv; 46 47 st->tuner_addr = 0x61; 48 49 dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap, 50 DVB_PLL_TUA6010XS); 51 return 0; 52} 53 54static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap) 55{ 56 struct dibusb_state *st = adap->priv; 57 58 st->tuner_addr = 0x60; 59 60 dvb_attach(dvb_pll_attach, adap->fe, 0x60, &adap->dev->i2c_adap, 61 DVB_PLL_TDA665X); 62 return 0; 63} 64 65/* Some of the Artec 1.1 device aren't equipped with the default tuner 66 * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures 67 * this out. */ 68static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap) 69{ 70 u8 b[2] = { 0,0 }, b2[1]; 71 int ret = 0; 72 struct i2c_msg msg[2] = { 73 { .flags = 0, .buf = b, .len = 2 }, 74 { .flags = I2C_M_RD, .buf = b2, .len = 1 }, 75 }; 76 struct dibusb_state *st = adap->priv; 77 78 /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */ 79 msg[0].addr = msg[1].addr = st->tuner_addr = 0x60; 80 81 if (adap->fe->ops.i2c_gate_ctrl) 82 adap->fe->ops.i2c_gate_ctrl(adap->fe,1); 83 84 if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) { 85 err("tuner i2c write failed."); 86 ret = -EREMOTEIO; 87 } 88 89 if (adap->fe->ops.i2c_gate_ctrl) 90 adap->fe->ops.i2c_gate_ctrl(adap->fe,0); 91 92 if (b2[0] == 0xfe) { 93 info("This device has the Thomson Cable onboard. Which is default."); 94 ret = dibusb_thomson_tuner_attach(adap); 95 } else { 96 info("This device has the Panasonic ENV77H11D5 onboard."); 97 ret = dibusb_panasonic_tuner_attach(adap); 98 } 99 100 return ret; 101} 102 103/* USB Driver stuff */ 104static struct dvb_usb_device_properties dibusb1_1_properties; 105static struct dvb_usb_device_properties dibusb1_1_an2235_properties; 106static struct dvb_usb_device_properties dibusb2_0b_properties; 107static struct dvb_usb_device_properties artec_t1_usb2_properties; 108 109static int dibusb_probe(struct usb_interface *intf, 110 const struct usb_device_id *id) 111{ 112 if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties, 113 THIS_MODULE, NULL, adapter_nr) || 114 0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties, 115 THIS_MODULE, NULL, adapter_nr) || 116 0 == dvb_usb_device_init(intf, &dibusb2_0b_properties, 117 THIS_MODULE, NULL, adapter_nr) || 118 0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties, 119 THIS_MODULE, NULL, adapter_nr)) 120 return 0; 121 122 return -EINVAL; 123} 124 125/* do not change the order of the ID table */ 126static struct usb_device_id dibusb_dib3000mb_table [] = { 127/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD) }, 128/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM) }, 129/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, 130/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, 131/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, 132/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) }, 133/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) }, 134/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, 135/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, 136/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) }, 137/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) }, 138/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) }, 139/* 12 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) }, 140/* 13 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) }, 141/* 14 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) }, 142/* 15 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_COLD) }, 143/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) }, 144/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) }, 145/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) }, 146/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, 147/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, 148/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, 149/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, 150/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, 151 152/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */ 153/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, 154/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, 155/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, 156 157/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, 158 159/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, 160/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, 161 162/* 163 * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices 164 * we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that 165 * have been left on the device. If you don't have such a device but an Artec 166 * device that's supposed to work with this driver but is not detected by it, 167 * free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config. 168 */ 169 170#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY 171/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, 172#endif 173 174 { } /* Terminating entry */ 175}; 176MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); 177 178static struct dvb_usb_device_properties dibusb1_1_properties = { 179 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 180 181 .usb_ctrl = CYPRESS_AN2135, 182 183 .firmware = "dvb-usb-dibusb-5.0.0.11.fw", 184 185 .num_adapters = 1, 186 .adapter = { 187 { 188 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, 189 .pid_filter_count = 16, 190 191 .streaming_ctrl = dibusb_streaming_ctrl, 192 .pid_filter = dibusb_pid_filter, 193 .pid_filter_ctrl = dibusb_pid_filter_ctrl, 194 .frontend_attach = dibusb_dib3000mb_frontend_attach, 195 .tuner_attach = dibusb_tuner_probe_and_attach, 196 197 /* parameter for the MPEG2-data transfer */ 198 .stream = { 199 .type = USB_BULK, 200 .count = 7, 201 .endpoint = 0x02, 202 .u = { 203 .bulk = { 204 .buffersize = 4096, 205 } 206 } 207 }, 208 .size_of_priv = sizeof(struct dibusb_state), 209 } 210 }, 211 212 .power_ctrl = dibusb_power_ctrl, 213 214 .rc.legacy = { 215 .rc_interval = DEFAULT_RC_INTERVAL, 216 .rc_map_table = rc_map_dibusb_table, 217 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ 218 .rc_query = dibusb_rc_query, 219 }, 220 221 .i2c_algo = &dibusb_i2c_algo, 222 223 .generic_bulk_ctrl_endpoint = 0x01, 224 225 .num_device_descs = 9, 226 .devices = { 227 { "AVerMedia AverTV DVBT USB1.1", 228 { &dibusb_dib3000mb_table[0], NULL }, 229 { &dibusb_dib3000mb_table[1], NULL }, 230 }, 231 { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)", 232 { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL}, 233 { &dibusb_dib3000mb_table[3], NULL }, 234 }, 235 { "DiBcom USB1.1 DVB-T reference design (MOD3000)", 236 { &dibusb_dib3000mb_table[5], NULL }, 237 { &dibusb_dib3000mb_table[6], NULL }, 238 }, 239 { "KWorld V-Stream XPERT DTV - DVB-T USB1.1", 240 { &dibusb_dib3000mb_table[7], NULL }, 241 { &dibusb_dib3000mb_table[8], NULL }, 242 }, 243 { "Grandtec USB1.1 DVB-T", 244 { &dibusb_dib3000mb_table[9], &dibusb_dib3000mb_table[11], NULL }, 245 { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL }, 246 }, 247 { "Unknown USB1.1 DVB-T device ???? please report the name to the author", 248 { &dibusb_dib3000mb_table[13], NULL }, 249 { &dibusb_dib3000mb_table[14], NULL }, 250 }, 251 { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device", 252 { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL}, 253 { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL}, 254 }, 255 { "Artec T1 USB1.1 TVBOX with AN2135", 256 { &dibusb_dib3000mb_table[19], NULL }, 257 { &dibusb_dib3000mb_table[20], NULL }, 258 }, 259 { "VideoWalker DVB-T USB", 260 { &dibusb_dib3000mb_table[25], NULL }, 261 { &dibusb_dib3000mb_table[26], NULL }, 262 }, 263 } 264}; 265 266static struct dvb_usb_device_properties dibusb1_1_an2235_properties = { 267 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 268 .usb_ctrl = CYPRESS_AN2235, 269 270 .firmware = "dvb-usb-dibusb-an2235-01.fw", 271 272 .num_adapters = 1, 273 .adapter = { 274 { 275 .caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER, 276 .pid_filter_count = 16, 277 278 .streaming_ctrl = dibusb_streaming_ctrl, 279 .pid_filter = dibusb_pid_filter, 280 .pid_filter_ctrl = dibusb_pid_filter_ctrl, 281 .frontend_attach = dibusb_dib3000mb_frontend_attach, 282 .tuner_attach = dibusb_tuner_probe_and_attach, 283 284 /* parameter for the MPEG2-data transfer */ 285 .stream = { 286 .type = USB_BULK, 287 .count = 7, 288 .endpoint = 0x02, 289 .u = { 290 .bulk = { 291 .buffersize = 4096, 292 } 293 } 294 }, 295 .size_of_priv = sizeof(struct dibusb_state), 296 }, 297 }, 298 .power_ctrl = dibusb_power_ctrl, 299 300 .rc.legacy = { 301 .rc_interval = DEFAULT_RC_INTERVAL, 302 .rc_map_table = rc_map_dibusb_table, 303 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ 304 .rc_query = dibusb_rc_query, 305 }, 306 307 .i2c_algo = &dibusb_i2c_algo, 308 309 .generic_bulk_ctrl_endpoint = 0x01, 310 311#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY 312 .num_device_descs = 2, 313#else 314 .num_device_descs = 1, 315#endif 316 .devices = { 317 { "Artec T1 USB1.1 TVBOX with AN2235", 318 { &dibusb_dib3000mb_table[21], NULL }, 319 { &dibusb_dib3000mb_table[22], NULL }, 320 }, 321#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY 322 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", 323 { &dibusb_dib3000mb_table[30], NULL }, 324 { NULL }, 325 }, 326 { NULL }, 327#endif 328 } 329}; 330 331static struct dvb_usb_device_properties dibusb2_0b_properties = { 332 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 333 334 .usb_ctrl = CYPRESS_FX2, 335 336 .firmware = "dvb-usb-adstech-usb2-02.fw", 337 338 .num_adapters = 1, 339 .adapter = { 340 { 341 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, 342 .pid_filter_count = 16, 343 344 .streaming_ctrl = dibusb2_0_streaming_ctrl, 345 .pid_filter = dibusb_pid_filter, 346 .pid_filter_ctrl = dibusb_pid_filter_ctrl, 347 .frontend_attach = dibusb_dib3000mb_frontend_attach, 348 .tuner_attach = dibusb_thomson_tuner_attach, 349 350 /* parameter for the MPEG2-data transfer */ 351 .stream = { 352 .type = USB_BULK, 353 .count = 7, 354 .endpoint = 0x06, 355 .u = { 356 .bulk = { 357 .buffersize = 4096, 358 } 359 } 360 }, 361 .size_of_priv = sizeof(struct dibusb_state), 362 } 363 }, 364 .power_ctrl = dibusb2_0_power_ctrl, 365 366 .rc.legacy = { 367 .rc_interval = DEFAULT_RC_INTERVAL, 368 .rc_map_table = rc_map_dibusb_table, 369 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ 370 .rc_query = dibusb_rc_query, 371 }, 372 373 .i2c_algo = &dibusb_i2c_algo, 374 375 .generic_bulk_ctrl_endpoint = 0x01, 376 377 .num_device_descs = 2, 378 .devices = { 379 { "KWorld/ADSTech Instant DVB-T USB2.0", 380 { &dibusb_dib3000mb_table[23], NULL }, 381 { &dibusb_dib3000mb_table[24], NULL }, 382 }, 383 { "KWorld Xpert DVB-T USB2.0", 384 { &dibusb_dib3000mb_table[27], NULL }, 385 { NULL } 386 }, 387 { NULL }, 388 } 389}; 390 391static struct dvb_usb_device_properties artec_t1_usb2_properties = { 392 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 393 394 .usb_ctrl = CYPRESS_FX2, 395 396 .firmware = "dvb-usb-dibusb-6.0.0.8.fw", 397 398 .num_adapters = 1, 399 .adapter = { 400 { 401 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, 402 .pid_filter_count = 16, 403 404 .streaming_ctrl = dibusb2_0_streaming_ctrl, 405 .pid_filter = dibusb_pid_filter, 406 .pid_filter_ctrl = dibusb_pid_filter_ctrl, 407 .frontend_attach = dibusb_dib3000mb_frontend_attach, 408 .tuner_attach = dibusb_tuner_probe_and_attach, 409 /* parameter for the MPEG2-data transfer */ 410 .stream = { 411 .type = USB_BULK, 412 .count = 7, 413 .endpoint = 0x06, 414 .u = { 415 .bulk = { 416 .buffersize = 4096, 417 } 418 } 419 }, 420 .size_of_priv = sizeof(struct dibusb_state), 421 } 422 }, 423 .power_ctrl = dibusb2_0_power_ctrl, 424 425 .rc.legacy = { 426 .rc_interval = DEFAULT_RC_INTERVAL, 427 .rc_map_table = rc_map_dibusb_table, 428 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ 429 .rc_query = dibusb_rc_query, 430 }, 431 432 .i2c_algo = &dibusb_i2c_algo, 433 434 .generic_bulk_ctrl_endpoint = 0x01, 435 436 .num_device_descs = 1, 437 .devices = { 438 { "Artec T1 USB2.0", 439 { &dibusb_dib3000mb_table[28], NULL }, 440 { &dibusb_dib3000mb_table[29], NULL }, 441 }, 442 { NULL }, 443 } 444}; 445 446static struct usb_driver dibusb_driver = { 447 .name = "dvb_usb_dibusb_mb", 448 .probe = dibusb_probe, 449 .disconnect = dvb_usb_device_exit, 450 .id_table = dibusb_dib3000mb_table, 451}; 452 453/* module stuff */ 454static int __init dibusb_module_init(void) 455{ 456 int result; 457 if ((result = usb_register(&dibusb_driver))) { 458 err("usb_register failed. Error number %d",result); 459 return result; 460 } 461 462 return 0; 463} 464 465static void __exit dibusb_module_exit(void) 466{ 467 /* deregister this driver from the USB subsystem */ 468 usb_deregister(&dibusb_driver); 469} 470 471module_init (dibusb_module_init); 472module_exit (dibusb_module_exit); 473 474MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); 475MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)"); 476MODULE_VERSION("1.0"); 477MODULE_LICENSE("GPL");