21 #include <linux/module.h>
22 #include <linux/pci.h>
24 #include <linux/i2c.h>
26 #include <linux/slab.h>
38 #define TM6000_BOARD_UNKNOWN 0
39 #define TM5600_BOARD_GENERIC 1
40 #define TM6000_BOARD_GENERIC 2
41 #define TM6010_BOARD_GENERIC 3
42 #define TM5600_BOARD_10MOONS_UT821 4
43 #define TM5600_BOARD_10MOONS_UT330 5
44 #define TM6000_BOARD_ADSTECH_DUAL_TV 6
45 #define TM6000_BOARD_FREECOM_AND_SIMILAR 7
46 #define TM6000_BOARD_ADSTECH_MINI_DUAL_TV 8
47 #define TM6010_BOARD_HAUPPAUGE_900H 9
48 #define TM6010_BOARD_BEHOLD_WANDER 10
49 #define TM6010_BOARD_BEHOLD_VOYAGER 11
50 #define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
51 #define TM6010_BOARD_TWINHAN_TU501 13
52 #define TM6010_BOARD_BEHOLD_WANDER_LITE 14
53 #define TM6010_BOARD_BEHOLD_VOYAGER_LITE 15
54 #define TM5600_BOARD_TERRATEC_GRABSTER 16
56 #define is_generic(model) ((model == TM6000_BOARD_UNKNOWN) || \
57 (model == TM5600_BOARD_GENERIC) || \
58 (model == TM6000_BOARD_GENERIC) || \
59 (model == TM6010_BOARD_GENERIC))
61 #define TM6000_MAXBOARDS 16
66 static unsigned long tm6000_devused;
92 .name =
"Unknown tm6000 video grabber",
116 .name =
"Generic tm5600 board",
118 .tuner_type = TUNER_XC2028,
119 .tuner_addr = 0xc2 >> 1,
143 .name =
"Generic tm6000 board",
144 .tuner_type = TUNER_XC2028,
145 .tuner_addr = 0xc2 >> 1,
169 .name =
"Generic tm6010 board",
171 .tuner_type = TUNER_XC2028,
172 .tuner_addr = 0xc2 >> 1,
173 .demod_addr = 0x1e >> 1,
206 .name =
"10Moons UT 821",
207 .tuner_type = TUNER_XC2028,
208 .eename = {
'1',
'0',
'M',
'O',
'O',
'N',
'S',
'5',
'6',
'0',
'0', 0xff, 0x45, 0x5b},
212 .tuner_addr = 0xc2 >> 1,
236 .name =
"10Moons UT 330",
237 .tuner_type = TUNER_PHILIPS_FQ1216AME_MK4,
238 .tuner_addr = 0xc8 >> 1,
261 .name =
"ADSTECH Dual TV USB",
262 .tuner_type = TUNER_XC2028,
263 .tuner_addr = 0xc8 >> 1,
287 .name =
"Freecom Hybrid Stick / Moka DVB-T Receiver Dual",
288 .tuner_type = TUNER_XC2028,
289 .tuner_addr = 0xc2 >> 1,
290 .demod_addr = 0x1e >> 1,
317 .name =
"ADSTECH Mini Dual TV USB",
318 .tuner_type = TUNER_XC2028,
319 .tuner_addr = 0xc8 >> 1,
320 .demod_addr = 0x1e >> 1,
346 .name =
"Hauppauge WinTV HVR-900H / WinTV USB2-Stick",
347 .eename = {
'H', 0,
'V', 0,
'R', 0,
'9', 0,
'0', 0,
'0', 0,
'H', 0 },
350 .tuner_type = TUNER_XC2028,
351 .tuner_addr = 0xc2 >> 1,
352 .demod_addr = 0x1e >> 1,
387 .name =
"Beholder Wander DVB-T/TV/FM USB2.0",
388 .tuner_type = TUNER_XC5000,
389 .tuner_addr = 0xc2 >> 1,
390 .demod_addr = 0x1e >> 1,
425 .name =
"Beholder Voyager TV/FM USB2.0",
426 .tuner_type = TUNER_XC5000,
427 .tuner_addr = 0xc2 >> 1,
461 .name =
"Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick",
462 .tuner_type = TUNER_XC2028,
463 .tuner_addr = 0xc2 >> 1,
464 .demod_addr = 0x1e >> 1,
504 .name =
"Terratec Grabster AV 150/250 MX",
506 .tuner_type = TUNER_ABSENT,
523 .name =
"Twinhan TU501(704D1)",
524 .tuner_type = TUNER_XC2028,
525 .tuner_addr = 0xc2 >> 1,
526 .demod_addr = 0x1e >> 1,
560 .name =
"Beholder Wander Lite DVB-T/TV/FM USB2.0",
561 .tuner_type = TUNER_XC5000,
562 .tuner_addr = 0xc2 >> 1,
563 .demod_addr = 0x1e >> 1,
590 .name =
"Beholder Voyager Lite TV/FM USB2.0",
591 .tuner_type = TUNER_XC5000,
592 .tuner_addr = 0xc2 >> 1,
649 if (!dev->
gpio.power_led)
654 switch (dev->
model) {
659 dev->
gpio.power_led, 0x00);
666 dev->
gpio.power_led, 0x01);
672 switch (dev->
model) {
677 dev->
gpio.power_led, 0x01);
684 dev->
gpio.power_led, 0x00);
702 dev->
gpio.tuner_reset, 0x01);
705 dev->
gpio.tuner_reset, 0x00);
708 dev->
gpio.tuner_reset, 0x01);
739 switch (dev->
model) {
742 dev->
gpio.tuner_reset, 0x01);
747 dev->
gpio.tuner_reset, 0x00);
752 dev->
gpio.tuner_reset, 0x01);
760 dev->
gpio.tuner_reset, 0x01);
763 dev->
gpio.tuner_reset, 0x00);
766 dev->
gpio.tuner_reset, 0x01);
771 dev->
gpio.tuner_reset, 0x00);
774 dev->
gpio.tuner_reset, 0x01);
811 switch (dev->
model) {
872 if (dev->
gpio.tuner_reset) {
876 for (i = 0; i < 2; i++) {
878 dev->
gpio.tuner_reset, 0x00);
886 dev->
gpio.tuner_reset, 0x01);
904 struct tuner_setup tun_setup;
910 memset(&tun_setup, 0,
sizeof(tun_setup));
914 tun_setup.mode_mask = 0;
915 if (dev->
caps.has_tuner)
916 tun_setup.mode_mask |= (T_ANALOG_TV | T_RADIO);
934 memset(&xc2028_cfg, 0,
sizeof(xc2028_cfg));
939 xc2028_cfg.tuner = TUNER_XC2028;
940 xc2028_cfg.priv = &
ctl;
942 switch (dev->
model) {
947 ctl.fname =
"xc3028L-v36.fw";
951 ctl.fname =
"xc3028-v27.fw";
953 ctl.fname =
"xc3028-v24.fw";
971 xc5000_cfg.tuner = TUNER_XC5000;
972 xc5000_cfg.priv = &
ctl;
984 static int fill_board_specific_data(
struct tm6000_core *dev)
1006 switch (dev->
model) {
1025 static void use_alternative_detection_method(
struct tm6000_core *dev)
1032 for (i = 0; i <
ARRAY_SIZE(tm6000_boards); i++) {
1033 if (!tm6000_boards[i].eename_size)
1054 tm6000_boards[model].
name, model);
1057 #if defined(CONFIG_MODULES) && defined(MODULE)
1063 request_module(
"tm6000-alsa");
1065 if (dev->
caps.has_dvb)
1066 request_module(
"tm6000-dvb");
1080 #define request_modules(dev)
1081 #define flush_request_modules(dev)
1084 static int tm6000_init_dev(
struct tm6000_core *dev)
1093 rc = fill_board_specific_data(dev);
1107 use_alternative_detection_method(dev);
1109 rc = fill_board_specific_data(dev);
1120 tm6000_config_tuner(dev);
1132 if (dev->
caps.has_tda9874)
1157 #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
1159 static void get_max_endpoint(
struct usb_device *
udev,
1160 struct usb_host_interface *alt,
1162 struct usb_host_endpoint *curr_e,
1166 unsigned int size = tmp & 0x7ff;
1172 tm_ep->
endp = curr_e;
1178 msgtype, curr_e->desc.bEndpointAddress,
1190 struct usb_device *usbdev;
1196 usbdev =
usb_get_dev(interface_to_usbdev(interface));
1225 dev->
model =
id->driver_info;
1232 switch (usbdev->speed) {
1248 for (i = 0; i < interface->num_altsetting; i++) {
1251 for (ep = 0; ep < interface->altsetting[
i].desc.bNumEndpoints; ep++) {
1252 struct usb_host_endpoint *
e;
1255 e = &interface->altsetting[
i].endpoint[ep];
1257 dir_out = ((e->desc.bEndpointAddress &
1262 interface->altsetting[i].desc.bInterfaceNumber,
1263 interface->altsetting[i].desc.bInterfaceClass);
1265 switch (e->desc.bmAttributes) {
1268 get_max_endpoint(usbdev,
1269 &interface->altsetting[i],
1273 get_max_endpoint(usbdev,
1274 &interface->altsetting[i],
1281 get_max_endpoint(usbdev,
1282 &interface->altsetting[i],
1286 get_max_endpoint(usbdev,
1287 &interface->altsetting[i],
1294 get_max_endpoint(usbdev,
1295 &interface->altsetting[i],
1299 get_max_endpoint(usbdev,
1300 &interface->altsetting[i],
1310 printk(
KERN_INFO "tm6000: New video device @ %s Mbps (%04x:%04x, ifnum %d)\n",
1314 interface->altsetting->desc.bInterfaceNumber);
1317 if (!dev->isoc_in.endp) {
1318 printk(
KERN_ERR "tm6000: probing error: no IN ISOC endpoint!\n");
1325 usb_set_intfdata(interface, dev);
1329 rc = tm6000_init_dev(dev);
1350 static void tm6000_usb_disconnect(
struct usb_interface *interface)
1352 struct tm6000_core *dev = usb_get_intfdata(interface);
1353 usb_set_intfdata(interface,
NULL);
1364 if (dev->
gpio.power_led) {
1365 switch (dev->
model) {
1371 dev->
gpio.power_led, 0x01);
1380 dev->
gpio.power_led, 0x00);
1402 static struct usb_driver tm6000_usb_driver = {
1404 .probe = tm6000_usb_probe,
1405 .disconnect = tm6000_usb_disconnect,
1406 .id_table = tm6000_id_table,