aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig119
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile33
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c182
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c295
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.h30
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c272
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c350
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c116
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h122
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c261
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.h65
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u-fe.c208
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c233
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.h56
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-common.h46
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-dvb.c210
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-firmware.c100
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c118
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h89
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c215
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c181
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c325
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h329
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c236
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c162
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045-fe.c196
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c288
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.h78
28 files changed, 4915 insertions, 0 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
new file mode 100644
index 000000000000..612e5b087b1c
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -0,0 +1,119 @@
1config DVB_USB
2 tristate "Support for various USB DVB devices"
3 depends on DVB_CORE && USB
4 select FW_LOADER
5 help
6 By enabling this you will be able to choose the various supported
7 USB1.1 and USB2.0 DVB devices.
8
9 Almost every USB device needs a firmware, please look into
10 <file:Documentation/dvb/README.dvb-usb>.
11
12 For a complete list of supported USB devices see the LinuxTV DVB Wiki:
13 <http://www.linuxtv.org/wiki/index.php/DVB_USB>
14
15 Say Y if you own a USB DVB device.
16
17config DVB_USB_DEBUG
18 bool "Enable extended debug support for all DVB-USB devices"
19 depends on DVB_USB
20 help
21 Say Y if you want to enable debugging. See modinfo dvb-usb (and the
22 appropriate drivers) for debug levels.
23
24config DVB_USB_A800
25 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
26 depends on DVB_USB
27 select DVB_DIB3000MC
28 help
29 Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
30
31config DVB_USB_DIBUSB_MB
32 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
33 depends on DVB_USB
34 select DVB_DIB3000MB
35 help
36 Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
37 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
38
39 Devices supported by this driver:
40 TwinhanDTV USB-Ter (VP7041)
41 TwinhanDTV Magic Box (VP7041e)
42 KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
43 Hama DVB-T USB1.1-Box
44 DiBcom USB1.1 reference devices (non-public)
45 Ultima Electronic/Artec T1 USB TVBOX
46 Compro Videomate DVB-U2000 - DVB-T USB
47 Grandtec DVB-T USB
48 Avermedia AverTV DVBT USB1.1
49 Artec T1 USB1.1 boxes
50
51 The VP7041 seems to be identical to "CTS Portable" (Chinese
52 Television System).
53
54 Say Y if you own such a device and want to use it. You should build it as
55 a module.
56
57config DVB_USB_DIBUSB_MC
58 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
59 depends on DVB_USB
60 select DVB_DIB3000MC
61 help
62 Support for 2.0 DVB-T receivers based on reference designs made by
63 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
64
65 Devices supported by this driver:
66 DiBcom USB2.0 reference devices (non-public)
67 Artec T1 USB2.0 boxes
68
69 Say Y if you own such a device and want to use it. You should build it as
70 a module.
71
72config DVB_USB_UMT_010
73 tristate "HanfTek UMT-010 DVB-T USB2.0 support"
74 depends on DVB_USB
75 select DVB_DIB3000MC
76 help
77 Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
78
79config DVB_USB_CXUSB
80 tristate "Medion MD95700 hybrid USB2.0 (Conexant) support"
81 depends on DVB_USB
82 select DVB_CX22702
83 help
84 Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently
85 only the DVB-T part is supported.
86
87config DVB_USB_DIGITV
88 tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
89 depends on DVB_USB
90 select DVB_NXT6000
91 select DVB_MT352
92 help
93 Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
94
95config DVB_USB_VP7045
96 tristate "TwinhanDTV Alpha/MagicBoxII and DNTV tinyUSB2 DVB-T USB2.0 support"
97 depends on DVB_USB
98 help
99 Say Y here to support the
100 TwinhanDTV Alpha (stick) (VP-7045),
101 TwinhanDTV MagicBox II (VP-7046) and
102 DigitalNow TinyUSB 2 DVB-t DVB-T USB2.0 receivers.
103
104config DVB_USB_NOVA_T_USB2
105 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
106 depends on DVB_USB
107 select DVB_DIB3000MC
108 help
109 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
110
111config DVB_USB_DTT200U
112 tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
113 depends on DVB_USB
114 help
115 Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
116
117 The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
118
119 The WT-220U and its clones are pen-sized.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
new file mode 100644
index 000000000000..746d87ed6f32
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -0,0 +1,33 @@
1dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o
2obj-$(CONFIG_DVB_USB) += dvb-usb.o
3
4dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
5obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
6
7dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
8obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
9
10dvb-usb-dibusb-common-objs = dibusb-common.o
11
12dvb-usb-a800-objs = a800.o
13obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o
14
15dvb-usb-dibusb-mb-objs = dibusb-mb.o
16obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o
17
18dvb-usb-dibusb-mc-objs = dibusb-mc.o
19obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o
20
21dvb-usb-nova-t-usb2-objs = nova-t-usb2.o
22obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o
23
24dvb-usb-umt-010-objs = umt-010.o
25obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
26
27dvb-usb-digitv-objs = digitv.o
28obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
29
30dvb-usb-cxusb-objs = cxusb.o
31obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
32
33EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
new file mode 100644
index 000000000000..f2fcc2f1f846
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -0,0 +1,182 @@
1/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T
2 * USB2.0 (A800) DVB-T receiver.
3 *
4 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to
7 * - AVerMedia who kindly provided information and
8 * - Glen Harris who suffered from my mistakes during development.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation, version 2.
13 *
14 * see Documentation/dvb/README.dvb-usb for more information
15 */
16#include "dibusb.h"
17
18static int debug;
19module_param(debug, int, 0644);
20MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);
21#define deb_rc(args...) dprintk(debug,0x01,args)
22
23static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
24{
25 /* do nothing for the AVerMedia */
26 return 0;
27}
28
29static struct dvb_usb_rc_key a800_rc_keys[] = {
30 { 0x02, 0x01, KEY_PROG1 }, /* SOURCE */
31 { 0x02, 0x00, KEY_POWER }, /* POWER */
32 { 0x02, 0x05, KEY_1 }, /* 1 */
33 { 0x02, 0x06, KEY_2 }, /* 2 */
34 { 0x02, 0x07, KEY_3 }, /* 3 */
35 { 0x02, 0x09, KEY_4 }, /* 4 */
36 { 0x02, 0x0a, KEY_5 }, /* 5 */
37 { 0x02, 0x0b, KEY_6 }, /* 6 */
38 { 0x02, 0x0d, KEY_7 }, /* 7 */
39 { 0x02, 0x0e, KEY_8 }, /* 8 */
40 { 0x02, 0x0f, KEY_9 }, /* 9 */
41 { 0x02, 0x12, KEY_LEFT }, /* L / DISPLAY */
42 { 0x02, 0x11, KEY_0 }, /* 0 */
43 { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */
44 { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */
45 { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */
46 { 0x02, 0x03, KEY_CHANNELUP }, /* CH UP */
47 { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */
48 { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */
49 { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */
50 { 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
51 { 0x02, 0x14, KEY_MUTE }, /* MUTE */
52 { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */
53 { 0x02, 0x19, KEY_RECORD }, /* RECORD */
54 { 0x02, 0x18, KEY_PLAY }, /* PLAY */
55 { 0x02, 0x1b, KEY_STOP }, /* STOP */
56 { 0x02, 0x1a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
57 { 0x02, 0x1d, KEY_BACK }, /* << / RED */
58 { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */
59 { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */
60 { 0x02, 0x01, KEY_FIRST }, /* |<< / GREEN */
61 { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */
62 { 0x02, 0x04, KEY_EPG }, /* EPG */
63 { 0x02, 0x15, KEY_MENU }, /* MENU */
64
65 { 0x03, 0x03, KEY_CHANNELUP }, /* CH UP */
66 { 0x03, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
67 { 0x03, 0x01, KEY_FIRST }, /* |<< / GREEN */
68 { 0x03, 0x00, KEY_LAST }, /* >>| / BLUE */
69
70};
71
72int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
73{
74 u8 key[5];
75 if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
76 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
77 2000) != 5)
78 return -ENODEV;
79
80 /* call the universal NEC remote processor, to find out the key's state and event */
81 dvb_usb_nec_rc_key_to_event(d,key,event,state);
82 if (key[0] != 0)
83 deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
84 return 0;
85}
86
87/* USB Driver stuff */
88static struct dvb_usb_properties a800_properties;
89
90static int a800_probe(struct usb_interface *intf,
91 const struct usb_device_id *id)
92{
93 return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE);
94}
95
96/* do not change the order of the ID table */
97static struct usb_device_id a800_table [] = {
98/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_COLD) },
99/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_WARM) },
100 { } /* Terminating entry */
101};
102MODULE_DEVICE_TABLE (usb, a800_table);
103
104static struct dvb_usb_properties a800_properties = {
105 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
106 .pid_filter_count = 32,
107
108 .usb_ctrl = CYPRESS_FX2,
109
110 .firmware = "dvb-usb-avertv-a800-02.fw",
111
112 .size_of_priv = sizeof(struct dibusb_state),
113
114 .streaming_ctrl = dibusb2_0_streaming_ctrl,
115 .pid_filter = dibusb_pid_filter,
116 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
117 .power_ctrl = a800_power_ctrl,
118 .frontend_attach = dibusb_dib3000mc_frontend_attach,
119 .tuner_attach = dibusb_dib3000mc_tuner_attach,
120
121 .rc_interval = DEFAULT_RC_INTERVAL,
122 .rc_key_map = a800_rc_keys,
123 .rc_key_map_size = ARRAY_SIZE(a800_rc_keys),
124 .rc_query = a800_rc_query,
125
126 .i2c_algo = &dibusb_i2c_algo,
127
128 .generic_bulk_ctrl_endpoint = 0x01,
129 /* parameter for the MPEG2-data transfer */
130 .urb = {
131 .type = DVB_USB_BULK,
132 .count = 7,
133 .endpoint = 0x06,
134 .u = {
135 .bulk = {
136 .buffersize = 4096,
137 }
138 }
139 },
140
141 .num_device_descs = 1,
142 .devices = {
143 { "AVerMedia AverTV DVB-T USB 2.0 (A800)",
144 { &a800_table[0], NULL },
145 { &a800_table[1], NULL },
146 },
147 }
148};
149
150static struct usb_driver a800_driver = {
151 .owner = THIS_MODULE,
152 .name = "dvb_usb_a800",
153 .probe = a800_probe,
154 .disconnect = dvb_usb_device_exit,
155 .id_table = a800_table,
156};
157
158/* module stuff */
159static int __init a800_module_init(void)
160{
161 int result;
162 if ((result = usb_register(&a800_driver))) {
163 err("usb_register failed. Error number %d",result);
164 return result;
165 }
166
167 return 0;
168}
169
170static void __exit a800_module_exit(void)
171{
172 /* deregister this driver from the USB subsystem */
173 usb_deregister(&a800_driver);
174}
175
176module_init (a800_module_init);
177module_exit (a800_module_exit);
178
179MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
180MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
181MODULE_VERSION("1.0");
182MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
new file mode 100644
index 000000000000..c3e1b661aae6
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -0,0 +1,295 @@
1/* DVB USB compliant linux driver for Conexant USB reference design.
2 *
3 * The Conexant reference design I saw on their website was only for analogue
4 * capturing (using the cx25842). The box I took to write this driver (reverse
5 * engineered) is the one labeled Medion MD95700. In addition to the cx25842
6 * for analogue capturing it also has a cx22702 DVB-T demodulator on the main
7 * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard.
8 *
9 * Maybe it is a little bit premature to call this driver cxusb, but I assume
10 * the USB protocol is identical or at least inherited from the reference
11 * design, so it can be reused for the "analogue-only" device (if it will
12 * appear at all).
13 *
14 * TODO: check if the cx25840-driver (from ivtv) can be used for the analogue
15 * part
16 *
17 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
18 *
19 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License as published by the Free
21 * Software Foundation, version 2.
22 *
23 * see Documentation/dvb/README.dvb-usb for more information
24 */
25#include "cxusb.h"
26
27#include "cx22702.h"
28
29/* debug */
30int dvb_usb_cxusb_debug;
31module_param_named(debug,dvb_usb_cxusb_debug, int, 0644);
32MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
33
34static int cxusb_ctrl_msg(struct dvb_usb_device *d,
35 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
36{
37 int wo = (rbuf == NULL || rlen == 0); /* write-only */
38 u8 sndbuf[1+wlen];
39 memset(sndbuf,0,1+wlen);
40
41 sndbuf[0] = cmd;
42 memcpy(&sndbuf[1],wbuf,wlen);
43 if (wo)
44 dvb_usb_generic_write(d,sndbuf,1+wlen);
45 else
46 dvb_usb_generic_rw(d,sndbuf,1+wlen,rbuf,rlen,0);
47
48 return 0;
49}
50
51/* I2C */
52static void cxusb_set_i2c_path(struct dvb_usb_device *d, enum cxusb_i2c_pathes path)
53{
54 struct cxusb_state *st = d->priv;
55 u8 o[2],i;
56
57 if (path == st->cur_i2c_path)
58 return;
59
60 o[0] = IOCTL_SET_I2C_PATH;
61 switch (path) {
62 case PATH_CX22702:
63 o[1] = 0;
64 break;
65 case PATH_TUNER_OTHER:
66 o[1] = 1;
67 break;
68 default:
69 err("unkown i2c path");
70 return;
71 }
72 cxusb_ctrl_msg(d,CMD_IOCTL,o,2,&i,1);
73
74 if (i != 0x01)
75 deb_info("i2c_path setting failed.\n");
76
77 st->cur_i2c_path = path;
78}
79
80static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
81{
82 struct dvb_usb_device *d = i2c_get_adapdata(adap);
83 int i;
84
85 if (down_interruptible(&d->i2c_sem) < 0)
86 return -EAGAIN;
87
88 if (num > 2)
89 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
90
91 for (i = 0; i < num; i++) {
92
93 switch (msg[i].addr) {
94 case 0x63:
95 cxusb_set_i2c_path(d,PATH_CX22702);
96 break;
97 default:
98 cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
99 break;
100 }
101
102 /* read request */
103 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
104 u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
105 obuf[0] = msg[i].len;
106 obuf[1] = msg[i+1].len;
107 obuf[2] = msg[i].addr;
108 memcpy(&obuf[3],msg[i].buf,msg[i].len);
109
110 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
111 obuf, 3+msg[i].len,
112 ibuf, 1+msg[i+1].len) < 0)
113 break;
114
115 if (ibuf[0] != 0x08)
116 deb_info("i2c read could have been failed\n");
117
118 memcpy(msg[i+1].buf,&ibuf[1],msg[i+1].len);
119
120 i++;
121 } else { /* write */
122 u8 obuf[2+msg[i].len], ibuf;
123 obuf[0] = msg[i].addr;
124 obuf[1] = msg[i].len;
125 memcpy(&obuf[2],msg[i].buf,msg[i].len);
126
127 if (cxusb_ctrl_msg(d,CMD_I2C_WRITE, obuf, 2+msg[i].len, &ibuf,1) < 0)
128 break;
129 if (ibuf != 0x08)
130 deb_info("i2c write could have been failed\n");
131 }
132 }
133
134 up(&d->i2c_sem);
135 return i;
136}
137
138static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
139{
140 return I2C_FUNC_I2C;
141}
142
143static struct i2c_algorithm cxusb_i2c_algo = {
144 .name = "Conexant USB I2C algorithm",
145 .id = I2C_ALGO_BIT,
146 .master_xfer = cxusb_i2c_xfer,
147 .functionality = cxusb_i2c_func,
148};
149
150static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
151{
152 return 0;
153}
154
155static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
156{
157 u8 buf[2] = { 0x03, 0x00 };
158 if (onoff)
159 cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
160 else
161 cxusb_ctrl_msg(d,0x37, NULL, 0, NULL, 0);
162
163 return 0;
164}
165
166struct cx22702_config cxusb_cx22702_config = {
167 .demod_address = 0x63,
168
169 .output_mode = CX22702_PARALLEL_OUTPUT,
170
171 .pll_init = dvb_usb_pll_init_i2c,
172 .pll_set = dvb_usb_pll_set_i2c,
173};
174
175/* Callbacks for DVB USB */
176static int cxusb_tuner_attach(struct dvb_usb_device *d)
177{
178 u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 };
179 d->pll_addr = 0x61;
180 memcpy(d->pll_init,bpll,4);
181 d->pll_desc = &dvb_pll_fmd1216me;
182 return 0;
183}
184
185static int cxusb_frontend_attach(struct dvb_usb_device *d)
186{
187 u8 buf[2] = { 0x03, 0x00 };
188 u8 b = 0;
189
190 if (usb_set_interface(d->udev,0,0) < 0)
191 err("set interface to alts=0 failed");
192
193 cxusb_ctrl_msg(d,0xde,&b,0,NULL,0);
194 cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
195 cxusb_ctrl_msg(d,CMD_POWER_OFF, NULL, 0, &b, 1);
196
197 if (usb_set_interface(d->udev,0,6) < 0)
198 err("set interface failed");
199
200 cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
201 cxusb_set_i2c_path(d,PATH_CX22702);
202 cxusb_ctrl_msg(d,CMD_POWER_ON, NULL, 0, &b, 1);
203
204 if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL)
205 return 0;
206
207 return -EIO;
208}
209
210/* DVB USB Driver stuff */
211static struct dvb_usb_properties cxusb_properties;
212
213static int cxusb_probe(struct usb_interface *intf,
214 const struct usb_device_id *id)
215{
216 return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE);
217}
218
219static struct usb_device_id cxusb_table [] = {
220 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
221 {} /* Terminating entry */
222};
223MODULE_DEVICE_TABLE (usb, cxusb_table);
224
225static struct dvb_usb_properties cxusb_properties = {
226 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
227
228 .usb_ctrl = CYPRESS_FX2,
229
230 .size_of_priv = sizeof(struct cxusb_state),
231
232 .streaming_ctrl = cxusb_streaming_ctrl,
233 .power_ctrl = cxusb_power_ctrl,
234 .frontend_attach = cxusb_frontend_attach,
235 .tuner_attach = cxusb_tuner_attach,
236
237 .i2c_algo = &cxusb_i2c_algo,
238
239 .generic_bulk_ctrl_endpoint = 0x01,
240 /* parameter for the MPEG2-data transfer */
241 .urb = {
242 .type = DVB_USB_ISOC,
243 .count = 5,
244 .endpoint = 0x02,
245 .u = {
246 .isoc = {
247 .framesperurb = 32,
248 .framesize = 940,
249 .interval = 5,
250 }
251 }
252 },
253
254 .num_device_descs = 1,
255 .devices = {
256 { "Medion MD95700 (MDUSBTV-HYBRID)",
257 { NULL },
258 { &cxusb_table[0], NULL },
259 },
260 }
261};
262
263static struct usb_driver cxusb_driver = {
264 .owner = THIS_MODULE,
265 .name = "dvb_usb_cxusb",
266 .probe = cxusb_probe,
267 .disconnect = dvb_usb_device_exit,
268 .id_table = cxusb_table,
269};
270
271/* module stuff */
272static int __init cxusb_module_init(void)
273{
274 int result;
275 if ((result = usb_register(&cxusb_driver))) {
276 err("usb_register failed. Error number %d",result);
277 return result;
278 }
279
280 return 0;
281}
282
283static void __exit cxusb_module_exit(void)
284{
285 /* deregister this driver from the USB subsystem */
286 usb_deregister(&cxusb_driver);
287}
288
289module_init (cxusb_module_init);
290module_exit (cxusb_module_exit);
291
292MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
293MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
294MODULE_VERSION("1.0-alpha");
295MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
new file mode 100644
index 000000000000..1d79016e3195
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -0,0 +1,30 @@
1#ifndef _DVB_USB_CXUSB_H_
2#define _DVB_USB_CXUSB_H_
3
4#define DVB_USB_LOG_PREFIX "digitv"
5#include "dvb-usb.h"
6
7extern int dvb_usb_cxusb_debug;
8#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
9
10/* usb commands - some of it are guesses, don't have a reference yet */
11#define CMD_I2C_WRITE 0x08
12#define CMD_I2C_READ 0x09
13
14#define CMD_IOCTL 0x0e
15#define IOCTL_SET_I2C_PATH 0x02
16
17#define CMD_POWER_OFF 0x50
18#define CMD_POWER_ON 0x51
19
20enum cxusb_i2c_pathes {
21 PATH_UNDEF = 0x00,
22 PATH_CX22702 = 0x01,
23 PATH_TUNER_OTHER = 0x02,
24};
25
26struct cxusb_state {
27 enum cxusb_i2c_pathes cur_i2c_path;
28};
29
30#endif
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
new file mode 100644
index 000000000000..63b626f70c81
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -0,0 +1,272 @@
1/* Common methods for dibusb-based-receivers.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation, version 2.
8 *
9 * see Documentation/dvb/README.dvb-usb for more information
10 */
11#include "dibusb.h"
12
13static int debug;
14module_param(debug, int, 0644);
15MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS);
16MODULE_LICENSE("GPL");
17
18#define deb_info(args...) dprintk(debug,0x01,args)
19
20/* common stuff used by the different dibusb modules */
21int dibusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
22{
23 if (d->priv != NULL) {
24 struct dib_fe_xfer_ops *ops = d->priv;
25 if (ops->fifo_ctrl != NULL)
26 if (ops->fifo_ctrl(d->fe,onoff)) {
27 err("error while controlling the fifo of the demod.");
28 return -ENODEV;
29 }
30 }
31 return 0;
32}
33EXPORT_SYMBOL(dibusb_streaming_ctrl);
34
35int dibusb_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
36{
37 if (d->priv != NULL) {
38 struct dib_fe_xfer_ops *ops = d->priv;
39 if (d->pid_filtering && ops->pid_ctrl != NULL)
40 ops->pid_ctrl(d->fe,index,pid,onoff);
41 }
42 return 0;
43}
44EXPORT_SYMBOL(dibusb_pid_filter);
45
46int dibusb_pid_filter_ctrl(struct dvb_usb_device *d, int onoff)
47{
48 if (d->priv != NULL) {
49 struct dib_fe_xfer_ops *ops = d->priv;
50 if (ops->pid_parse != NULL)
51 if (ops->pid_parse(d->fe,onoff) < 0)
52 err("could not handle pid_parser");
53 }
54 return 0;
55}
56EXPORT_SYMBOL(dibusb_pid_filter_ctrl);
57
58int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
59{
60 u8 b[3];
61 int ret;
62 b[0] = DIBUSB_REQ_SET_IOCTL;
63 b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
64 b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP;
65 ret = dvb_usb_generic_write(d,b,3);
66 msleep(10);
67 return ret;
68}
69EXPORT_SYMBOL(dibusb_power_ctrl);
70
71int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff)
72{
73 u8 b[2];
74 b[0] = DIBUSB_REQ_SET_IOCTL;
75 b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
76
77 dvb_usb_generic_write(d,b,3);
78
79 return dibusb_streaming_ctrl(d,onoff);
80}
81EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
82
83int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff)
84{
85 if (onoff) {
86 u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP };
87 return dvb_usb_generic_write(d,b,3);
88 } else
89 return 0;
90}
91EXPORT_SYMBOL(dibusb2_0_power_ctrl);
92
93static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr,
94 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
95{
96 u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
97 /* write only ? */
98 int wo = (rbuf == NULL || rlen == 0),
99 len = 2 + wlen + (wo ? 0 : 2);
100
101 sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
102 sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
103
104 memcpy(&sndbuf[2],wbuf,wlen);
105
106 if (!wo) {
107 sndbuf[wlen+2] = (rlen >> 8) & 0xff;
108 sndbuf[wlen+3] = rlen & 0xff;
109 }
110
111 return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0);
112}
113
114/*
115 * I2C master xfer function
116 */
117static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
118{
119 struct dvb_usb_device *d = i2c_get_adapdata(adap);
120 int i;
121
122 if (down_interruptible(&d->i2c_sem) < 0)
123 return -EAGAIN;
124
125 if (num > 2)
126 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
127
128 for (i = 0; i < num; i++) {
129 /* write/read request */
130 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
131 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
132 msg[i+1].buf,msg[i+1].len) < 0)
133 break;
134 i++;
135 } else
136 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
137 break;
138 }
139
140 up(&d->i2c_sem);
141 return i;
142}
143
144static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
145{
146 return I2C_FUNC_I2C;
147}
148
149struct i2c_algorithm dibusb_i2c_algo = {
150 .name = "DiBcom USB I2C algorithm",
151 .id = I2C_ALGO_BIT,
152 .master_xfer = dibusb_i2c_xfer,
153 .functionality = dibusb_i2c_func,
154};
155EXPORT_SYMBOL(dibusb_i2c_algo);
156
157int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
158{
159 u8 wbuf[1] = { offs };
160 return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
161}
162EXPORT_SYMBOL(dibusb_read_eeprom_byte);
163
164int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
165{
166 struct dib3000_config demod_cfg;
167 struct dibusb_state *st = d->priv;
168
169 demod_cfg.pll_set = dvb_usb_pll_set_i2c;
170 demod_cfg.pll_init = dvb_usb_pll_init_i2c;
171
172 for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++)
173 if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) {
174 d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
175 return 0;
176 }
177
178 return -ENODEV;
179}
180EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
181
182int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
183{
184 d->pll_addr = 0x60;
185 d->pll_desc = &dvb_pll_env57h1xd5;
186 return 0;
187}
188EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
189
190/*
191 * common remote control stuff
192 */
193struct dvb_usb_rc_key dibusb_rc_keys[] = {
194 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
195 { 0x00, 0x16, KEY_POWER },
196 { 0x00, 0x10, KEY_MUTE },
197 { 0x00, 0x03, KEY_1 },
198 { 0x00, 0x01, KEY_2 },
199 { 0x00, 0x06, KEY_3 },
200 { 0x00, 0x09, KEY_4 },
201 { 0x00, 0x1d, KEY_5 },
202 { 0x00, 0x1f, KEY_6 },
203 { 0x00, 0x0d, KEY_7 },
204 { 0x00, 0x19, KEY_8 },
205 { 0x00, 0x1b, KEY_9 },
206 { 0x00, 0x15, KEY_0 },
207 { 0x00, 0x05, KEY_CHANNELUP },
208 { 0x00, 0x02, KEY_CHANNELDOWN },
209 { 0x00, 0x1e, KEY_VOLUMEUP },
210 { 0x00, 0x0a, KEY_VOLUMEDOWN },
211 { 0x00, 0x11, KEY_RECORD },
212 { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
213 { 0x00, 0x14, KEY_PLAY },
214 { 0x00, 0x1a, KEY_STOP },
215 { 0x00, 0x40, KEY_REWIND },
216 { 0x00, 0x12, KEY_FASTFORWARD },
217 { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
218 { 0x00, 0x4c, KEY_PAUSE },
219 { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
220 { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
221 /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
222 { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
223 { 0x00, 0x1c, KEY_EPG }, /* EPG */
224 { 0x00, 0x00, KEY_TAB }, /* Tab */
225 { 0x00, 0x48, KEY_INFO }, /* Preview */
226 { 0x00, 0x04, KEY_LIST }, /* RecordList */
227 { 0x00, 0x0f, KEY_TEXT }, /* Teletext */
228 /* Key codes for the KWorld/ADSTech/JetWay remote. */
229 { 0x86, 0x12, KEY_POWER },
230 { 0x86, 0x0f, KEY_SELECT }, /* source */
231 { 0x86, 0x0c, KEY_UNKNOWN }, /* scan */
232 { 0x86, 0x0b, KEY_EPG },
233 { 0x86, 0x10, KEY_MUTE },
234 { 0x86, 0x01, KEY_1 },
235 { 0x86, 0x02, KEY_2 },
236 { 0x86, 0x03, KEY_3 },
237 { 0x86, 0x04, KEY_4 },
238 { 0x86, 0x05, KEY_5 },
239 { 0x86, 0x06, KEY_6 },
240 { 0x86, 0x07, KEY_7 },
241 { 0x86, 0x08, KEY_8 },
242 { 0x86, 0x09, KEY_9 },
243 { 0x86, 0x0a, KEY_0 },
244 { 0x86, 0x18, KEY_ZOOM },
245 { 0x86, 0x1c, KEY_UNKNOWN }, /* preview */
246 { 0x86, 0x13, KEY_UNKNOWN }, /* snap */
247 { 0x86, 0x00, KEY_UNDO },
248 { 0x86, 0x1d, KEY_RECORD },
249 { 0x86, 0x0d, KEY_STOP },
250 { 0x86, 0x0e, KEY_PAUSE },
251 { 0x86, 0x16, KEY_PLAY },
252 { 0x86, 0x11, KEY_BACK },
253 { 0x86, 0x19, KEY_FORWARD },
254 { 0x86, 0x14, KEY_UNKNOWN }, /* pip */
255 { 0x86, 0x15, KEY_ESC },
256 { 0x86, 0x1a, KEY_UP },
257 { 0x86, 0x1e, KEY_DOWN },
258 { 0x86, 0x1f, KEY_LEFT },
259 { 0x86, 0x1b, KEY_RIGHT },
260};
261EXPORT_SYMBOL(dibusb_rc_keys);
262
263int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
264{
265 u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE;
266 dvb_usb_generic_rw(d,&cmd,1,key,5,0);
267 dvb_usb_nec_rc_key_to_event(d,key,event,state);
268 if (key[0] != 0)
269 deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
270 return 0;
271}
272EXPORT_SYMBOL(dibusb_rc_query);
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
new file mode 100644
index 000000000000..828b5182e16c
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -0,0 +1,350 @@
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
17static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
18{
19 struct dib3000_config demod_cfg;
20 struct dibusb_state *st = d->priv;
21
22 demod_cfg.demod_address = 0x8;
23 demod_cfg.pll_set = dvb_usb_pll_set_i2c;
24 demod_cfg.pll_init = dvb_usb_pll_init_i2c;
25
26 if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL)
27 return -ENODEV;
28
29 d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
30
31 return 0;
32}
33
34static int dibusb_thomson_tuner_attach(struct dvb_usb_device *d)
35{
36 d->pll_addr = 0x61;
37 d->pll_desc = &dvb_pll_tua6010xs;
38 return 0;
39}
40
41/* Some of the Artec 1.1 device aren't equipped with the default tuner
42 * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures
43 * this out. */
44static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
45{
46 u8 b[2] = { 0,0 }, b2[1];
47 int ret = 0;
48 struct i2c_msg msg[2] = {
49 { .flags = 0, .buf = b, .len = 2 },
50 { .flags = I2C_M_RD, .buf = b2, .len = 1 },
51 };
52
53 /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
54 msg[0].addr = msg[1].addr = 0x60;
55
56 if (d->tuner_pass_ctrl)
57 d->tuner_pass_ctrl(d->fe,1,msg[0].addr);
58
59 if (i2c_transfer (&d->i2c_adap, msg, 2) != 2) {
60 err("tuner i2c write failed.");
61 ret = -EREMOTEIO;
62 }
63
64 if (d->tuner_pass_ctrl)
65 d->tuner_pass_ctrl(d->fe,0,msg[0].addr);
66
67 if (b2[0] == 0xfe) {
68 info("this device has the Thomson Cable onboard. Which is default.");
69 dibusb_thomson_tuner_attach(d);
70 } else {
71 u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab };
72 info("this device has the Panasonic ENV77H11D5 onboard.");
73 d->pll_addr = 0x60;
74 memcpy(d->pll_init,bpll,4);
75 d->pll_desc = &dvb_pll_tda665x;
76 }
77
78 return ret;
79}
80
81/* USB Driver stuff */
82static struct dvb_usb_properties dibusb1_1_properties;
83static struct dvb_usb_properties dibusb1_1_an2235_properties;
84static struct dvb_usb_properties dibusb2_0b_properties;
85
86static int dibusb_probe(struct usb_interface *intf,
87 const struct usb_device_id *id)
88{
89 if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 ||
90 dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) == 0 ||
91 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0)
92 return 0;
93
94 return -EINVAL;
95}
96
97/* do not change the order of the ID table */
98static struct usb_device_id dibusb_dib3000mb_table [] = {
99/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
100/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
101/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
102/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
103/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
104/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
105/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
106/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
107/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
108/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
109/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
110/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
111/* 12 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
112/* 13 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
113/* 14 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
114/* 15 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_COLD) },
115/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) },
116/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
117/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
118/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
119/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
120/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
121/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
122/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
123
124/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
125/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
126/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) },
127/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) },
128
129// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
130
131#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
132/* 27 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
133#endif
134 { } /* Terminating entry */
135};
136MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
137
138static struct dvb_usb_properties dibusb1_1_properties = {
139 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
140 .pid_filter_count = 16,
141
142 .usb_ctrl = CYPRESS_AN2135,
143
144 .firmware = "dvb-usb-dibusb-5.0.0.11.fw",
145
146 .size_of_priv = sizeof(struct dibusb_state),
147
148 .streaming_ctrl = dibusb_streaming_ctrl,
149 .pid_filter = dibusb_pid_filter,
150 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
151 .power_ctrl = dibusb_power_ctrl,
152 .frontend_attach = dibusb_dib3000mb_frontend_attach,
153 .tuner_attach = dibusb_tuner_probe_and_attach,
154
155 .rc_interval = DEFAULT_RC_INTERVAL,
156 .rc_key_map = dibusb_rc_keys,
157 .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
158 .rc_query = dibusb_rc_query,
159
160 .i2c_algo = &dibusb_i2c_algo,
161
162 .generic_bulk_ctrl_endpoint = 0x01,
163 /* parameter for the MPEG2-data transfer */
164 .urb = {
165 .type = DVB_USB_BULK,
166 .count = 7,
167 .endpoint = 0x02,
168 .u = {
169 .bulk = {
170 .buffersize = 4096,
171 }
172 }
173 },
174
175 .num_device_descs = 9,
176 .devices = {
177 { "AVerMedia AverTV DVBT USB1.1",
178 { &dibusb_dib3000mb_table[0], NULL },
179 { &dibusb_dib3000mb_table[1], NULL },
180 },
181 { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
182 { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL},
183 { &dibusb_dib3000mb_table[3], NULL },
184 },
185 { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
186 { &dibusb_dib3000mb_table[5], NULL },
187 { &dibusb_dib3000mb_table[6], NULL },
188 },
189 { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
190 { &dibusb_dib3000mb_table[7], NULL },
191 { &dibusb_dib3000mb_table[8], NULL },
192 },
193 { "Grandtec USB1.1 DVB-T",
194 { &dibusb_dib3000mb_table[9], &dibusb_dib3000mb_table[11], NULL },
195 { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
196 },
197 { "Unkown USB1.1 DVB-T device ???? please report the name to the author",
198 { &dibusb_dib3000mb_table[13], NULL },
199 { &dibusb_dib3000mb_table[14], NULL },
200 },
201 { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
202 { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL},
203 { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL},
204 },
205 { "Artec T1 USB1.1 TVBOX with AN2135",
206 { &dibusb_dib3000mb_table[19], NULL },
207 { &dibusb_dib3000mb_table[20], NULL },
208 },
209 { "VideoWalker DVB-T USB",
210 { &dibusb_dib3000mb_table[25], NULL },
211 { &dibusb_dib3000mb_table[26], NULL },
212 },
213 }
214};
215
216static struct dvb_usb_properties dibusb1_1_an2235_properties = {
217 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
218 .pid_filter_count = 16,
219
220 .usb_ctrl = CYPRESS_AN2235,
221
222 .firmware = "dvb-usb-dibusb-an2235-01.fw",
223
224 .size_of_priv = sizeof(struct dibusb_state),
225
226 .streaming_ctrl = dibusb_streaming_ctrl,
227 .pid_filter = dibusb_pid_filter,
228 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
229 .power_ctrl = dibusb_power_ctrl,
230 .frontend_attach = dibusb_dib3000mb_frontend_attach,
231 .tuner_attach = dibusb_tuner_probe_and_attach,
232
233 .rc_interval = DEFAULT_RC_INTERVAL,
234 .rc_key_map = dibusb_rc_keys,
235 .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
236 .rc_query = dibusb_rc_query,
237
238 .i2c_algo = &dibusb_i2c_algo,
239
240 .generic_bulk_ctrl_endpoint = 0x01,
241 /* parameter for the MPEG2-data transfer */
242 .urb = {
243 .type = DVB_USB_BULK,
244 .count = 7,
245 .endpoint = 0x02,
246 .u = {
247 .bulk = {
248 .buffersize = 4096,
249 }
250 }
251 },
252
253#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
254 .num_device_descs = 2,
255#else
256 .num_device_descs = 1,
257#endif
258 .devices = {
259 { "Artec T1 USB1.1 TVBOX with AN2235",
260 { &dibusb_dib3000mb_table[20], NULL },
261 { &dibusb_dib3000mb_table[21], NULL },
262 },
263#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
264 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
265 { &dibusb_dib3000mb_table[27], NULL },
266 { NULL },
267 },
268#endif
269 }
270};
271
272static struct dvb_usb_properties dibusb2_0b_properties = {
273 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
274 .pid_filter_count = 32,
275
276 .usb_ctrl = CYPRESS_FX2,
277
278 .firmware = "dvb-usb-adstech-usb2-02.fw",
279
280 .size_of_priv = sizeof(struct dibusb_state),
281
282 .streaming_ctrl = dibusb2_0_streaming_ctrl,
283 .pid_filter = dibusb_pid_filter,
284 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
285 .power_ctrl = dibusb2_0_power_ctrl,
286 .frontend_attach = dibusb_dib3000mb_frontend_attach,
287 .tuner_attach = dibusb_thomson_tuner_attach,
288
289 .rc_interval = DEFAULT_RC_INTERVAL,
290 .rc_key_map = dibusb_rc_keys,
291 .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
292 .rc_query = dibusb_rc_query,
293
294 .i2c_algo = &dibusb_i2c_algo,
295
296 .generic_bulk_ctrl_endpoint = 0x01,
297 /* parameter for the MPEG2-data transfer */
298 .urb = {
299 .type = DVB_USB_BULK,
300 .count = 7,
301 .endpoint = 0x06,
302 .u = {
303 .bulk = {
304 .buffersize = 4096,
305 }
306 }
307 },
308
309 .num_device_descs = 1,
310 .devices = {
311 { "KWorld/ADSTech Instant DVB-T USB 2.0",
312 { &dibusb_dib3000mb_table[23], NULL },
313 { &dibusb_dib3000mb_table[24], NULL },
314 },
315 }
316};
317
318static struct usb_driver dibusb_driver = {
319 .owner = THIS_MODULE,
320 .name = "dvb_usb_dibusb_mb",
321 .probe = dibusb_probe,
322 .disconnect = dvb_usb_device_exit,
323 .id_table = dibusb_dib3000mb_table,
324};
325
326/* module stuff */
327static int __init dibusb_module_init(void)
328{
329 int result;
330 if ((result = usb_register(&dibusb_driver))) {
331 err("usb_register failed. Error number %d",result);
332 return result;
333 }
334
335 return 0;
336}
337
338static void __exit dibusb_module_exit(void)
339{
340 /* deregister this driver from the USB subsystem */
341 usb_deregister(&dibusb_driver);
342}
343
344module_init (dibusb_module_init);
345module_exit (dibusb_module_exit);
346
347MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
348MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
349MODULE_VERSION("1.0");
350MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
new file mode 100644
index 000000000000..e9dac430f37d
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -0,0 +1,116 @@
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-C/P)
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
17/* USB Driver stuff */
18static struct dvb_usb_properties dibusb_mc_properties;
19
20static int dibusb_mc_probe(struct usb_interface *intf,
21 const struct usb_device_id *id)
22{
23 return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE);
24}
25
26/* do not change the order of the ID table */
27static struct usb_device_id dibusb_dib3000mc_table [] = {
28/* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
29/* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
30/* 02 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
31 { } /* Terminating entry */
32};
33MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
34
35static struct dvb_usb_properties dibusb_mc_properties = {
36 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
37 .pid_filter_count = 32,
38
39 .usb_ctrl = CYPRESS_FX2,
40 .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
41
42 .size_of_priv = sizeof(struct dibusb_state),
43
44 .streaming_ctrl = dibusb2_0_streaming_ctrl,
45 .pid_filter = dibusb_pid_filter,
46 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
47 .power_ctrl = dibusb2_0_power_ctrl,
48 .frontend_attach = dibusb_dib3000mc_frontend_attach,
49 .tuner_attach = dibusb_dib3000mc_tuner_attach,
50
51 .rc_interval = DEFAULT_RC_INTERVAL,
52 .rc_key_map = dibusb_rc_keys,
53 .rc_key_map_size = 63, /* FIXME */
54 .rc_query = dibusb_rc_query,
55
56 .i2c_algo = &dibusb_i2c_algo,
57
58 .generic_bulk_ctrl_endpoint = 0x01,
59 /* parameter for the MPEG2-data transfer */
60 .urb = {
61 .type = DVB_USB_BULK,
62 .count = 7,
63 .endpoint = 0x06,
64 .u = {
65 .bulk = {
66 .buffersize = 4096,
67 }
68 }
69 },
70
71 .num_device_descs = 2,
72 .devices = {
73 { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
74 { &dibusb_dib3000mc_table[0], NULL },
75 { &dibusb_dib3000mc_table[1], NULL },
76 },
77 { "Artec T1 USB2.0 TVBOX (please report the warm ID)",
78 { &dibusb_dib3000mc_table[2], NULL },
79 { NULL },
80 },
81 }
82};
83
84static struct usb_driver dibusb_mc_driver = {
85 .owner = THIS_MODULE,
86 .name = "dvb_usb_dibusb_mc",
87 .probe = dibusb_mc_probe,
88 .disconnect = dvb_usb_device_exit,
89 .id_table = dibusb_dib3000mc_table,
90};
91
92/* module stuff */
93static int __init dibusb_mc_module_init(void)
94{
95 int result;
96 if ((result = usb_register(&dibusb_mc_driver))) {
97 err("usb_register failed. Error number %d",result);
98 return result;
99 }
100
101 return 0;
102}
103
104static void __exit dibusb_mc_module_exit(void)
105{
106 /* deregister this driver from the USB subsystem */
107 usb_deregister(&dibusb_mc_driver);
108}
109
110module_init (dibusb_mc_module_init);
111module_exit (dibusb_mc_module_exit);
112
113MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
114MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices");
115MODULE_VERSION("1.0");
116MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
new file mode 100644
index 000000000000..6611f62977c0
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -0,0 +1,122 @@
1/* Header file for all dibusb-based-receivers.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation, version 2.
8 *
9 * see Documentation/dvb/README.dvb-usb for more information
10 */
11#ifndef _DVB_USB_DIBUSB_H_
12#define _DVB_USB_DIBUSB_H_
13
14#define DVB_USB_LOG_PREFIX "dibusb"
15#include "dvb-usb.h"
16
17#include "dib3000.h"
18
19/*
20 * protocol of all dibusb related devices
21 */
22
23/*
24 * bulk msg to/from endpoint 0x01
25 *
26 * general structure:
27 * request_byte parameter_bytes
28 */
29
30#define DIBUSB_REQ_START_READ 0x00
31#define DIBUSB_REQ_START_DEMOD 0x01
32
33/*
34 * i2c read
35 * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
36 * bulk read: byte_buffer (length_word bytes)
37 */
38#define DIBUSB_REQ_I2C_READ 0x02
39
40/*
41 * i2c write
42 * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
43 */
44#define DIBUSB_REQ_I2C_WRITE 0x03
45
46/*
47 * polling the value of the remote control
48 * bulk write: 0x04
49 * bulk read: byte_buffer (5 bytes)
50 */
51#define DIBUSB_REQ_POLL_REMOTE 0x04
52
53/* additional status values for Hauppauge Remote Control Protocol */
54#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01
55#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03
56
57/* streaming mode:
58 * bulk write: 0x05 mode_byte
59 *
60 * mode_byte is mostly 0x00
61 */
62#define DIBUSB_REQ_SET_STREAMING_MODE 0x05
63
64/* interrupt the internal read loop, when blocking */
65#define DIBUSB_REQ_INTR_READ 0x06
66
67/* io control
68 * 0x07 cmd_byte param_bytes
69 *
70 * param_bytes can be up to 32 bytes
71 *
72 * cmd_byte function parameter name
73 * 0x00 power mode
74 * 0x00 sleep
75 * 0x01 wakeup
76 *
77 * 0x01 enable streaming
78 * 0x02 disable streaming
79 *
80 *
81 */
82#define DIBUSB_REQ_SET_IOCTL 0x07
83
84/* IOCTL commands */
85
86/* change the power mode in firmware */
87#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00
88#define DIBUSB_IOCTL_POWER_SLEEP 0x00
89#define DIBUSB_IOCTL_POWER_WAKEUP 0x01
90
91/* modify streaming of the FX2 */
92#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01
93#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02
94
95struct dibusb_state {
96 struct dib_fe_xfer_ops ops;
97
98 /* for RC5 remote control */
99 int old_toggle;
100 int last_repeat_count;
101};
102
103extern struct i2c_algorithm dibusb_i2c_algo;
104
105extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *);
106extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *);
107
108extern int dibusb_streaming_ctrl(struct dvb_usb_device *, int);
109extern int dibusb_pid_filter(struct dvb_usb_device *, int, u16, int);
110extern int dibusb_pid_filter_ctrl(struct dvb_usb_device *, int);
111extern int dibusb_power_ctrl(struct dvb_usb_device *, int);
112extern int dibusb2_0_streaming_ctrl(struct dvb_usb_device *, int);
113extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
114
115#define DEFAULT_RC_INTERVAL 150
116//#define DEFAULT_RC_INTERVAL 100000
117
118extern struct dvb_usb_rc_key dibusb_rc_keys[];
119extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
120extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);
121
122#endif
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
new file mode 100644
index 000000000000..9a676afc1d6e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -0,0 +1,261 @@
1/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
2 * receiver
3 *
4 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * partly based on the SDK published by Nebula Electronics
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "digitv.h"
15
16#include "mt352.h"
17#include "nxt6000.h"
18
19/* debug */
20int dvb_usb_digitv_debug;
21module_param_named(debug,dvb_usb_digitv_debug, int, 0644);
22MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
23
24static int digitv_ctrl_msg(struct dvb_usb_device *d,
25 u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
26{
27 int wo = (rbuf == NULL || rlen == 0); /* write-only */
28 u8 sndbuf[7],rcvbuf[7];
29 memset(sndbuf,0,7); memset(rcvbuf,0,7);
30
31 sndbuf[0] = cmd;
32 sndbuf[1] = vv;
33 sndbuf[2] = wo ? wlen : rlen;
34
35 if (!wo) {
36 memcpy(&sndbuf[3],wbuf,wlen);
37 dvb_usb_generic_write(d,sndbuf,7);
38 } else {
39 dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
40 memcpy(rbuf,&rcvbuf[3],rlen);
41 }
42 return 0;
43}
44
45/* I2C */
46static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
47{
48 struct dvb_usb_device *d = i2c_get_adapdata(adap);
49 int i;
50
51 if (down_interruptible(&d->i2c_sem) < 0)
52 return -EAGAIN;
53
54 if (num > 2)
55 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
56
57 for (i = 0; i < num; i++) {
58 /* write/read request */
59 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
60 if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0,
61 msg[i+1].buf,msg[i+1].len) < 0)
62 break;
63 i++;
64 } else
65 if (digitv_ctrl_msg(d,USB_WRITE_COFDM, msg[i].buf[0],
66 &msg[i].buf[1],msg[i].len-1,NULL,0) < 0)
67 break;
68 }
69
70 up(&d->i2c_sem);
71 return i;
72}
73
74static u32 digitv_i2c_func(struct i2c_adapter *adapter)
75{
76 return I2C_FUNC_I2C;
77}
78
79static struct i2c_algorithm digitv_i2c_algo = {
80 .name = "Nebula DigiTV USB I2C algorithm",
81 .id = I2C_ALGO_BIT,
82 .master_xfer = digitv_i2c_xfer,
83 .functionality = digitv_i2c_func,
84};
85
86/* Callbacks for DVB USB */
87static int digitv_identify_state (struct usb_device *udev, struct
88 dvb_usb_properties *props, struct dvb_usb_device_description **desc,
89 int *cold)
90{
91 *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
92 return 0;
93}
94
95static int digitv_mt352_demod_init(struct dvb_frontend *fe)
96{
97 static u8 reset_buf[] = { 0x89, 0x38, 0x8a, 0x2d, 0x50, 0x80 };
98 static u8 init_buf[] = { 0x68, 0xa0, 0x8e, 0x40, 0x53, 0x50,
99 0x67, 0x20, 0x7d, 0x01, 0x7c, 0x00, 0x7a, 0x00,
100 0x79, 0x20, 0x57, 0x05, 0x56, 0x31, 0x88, 0x0f,
101 0x75, 0x32 };
102 int i;
103
104 for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2)
105 mt352_write(fe, &reset_buf[i], 2);
106
107 msleep(1);
108
109 for (i = 0; i < ARRAY_SIZE(init_buf); i += 2)
110 mt352_write(fe, &init_buf[i], 2);
111
112 return 0;
113}
114
115static struct mt352_config digitv_mt352_config = {
116 .demod_address = 0x0, /* ignored by the digitv anyway */
117 .demod_init = digitv_mt352_demod_init,
118 .pll_set = dvb_usb_pll_set,
119};
120
121static struct nxt6000_config digitv_nxt6000_config = {
122 .demod_address = 0x0, /* ignored by the digitv anyway */
123 .clock_inversion = 0x0,
124
125 .pll_init = NULL,
126 .pll_set = NULL,
127};
128
129static int digitv_frontend_attach(struct dvb_usb_device *d)
130{
131 if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL)
132 return 0;
133 if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
134
135 warn("nxt6000 support is not done yet, in fact you are one of the first "
136 "person who wants to use this device in Linux. Please report to "
137 "linux-dvb@linuxtv.org");
138
139 return 0;
140 }
141 return -EIO;
142}
143
144static int digitv_tuner_attach(struct dvb_usb_device *d)
145{
146 d->pll_addr = 0x60;
147 d->pll_desc = &dvb_pll_tded4;
148 return 0;
149}
150
151static struct dvb_usb_rc_key digitv_rc_keys[] = {
152 { 0x00, 0x16, KEY_POWER }, /* dummy key */
153};
154
155/* TODO is it really the NEC protocol ? */
156int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
157{
158 u8 key[5];
159
160 digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
161 /* TODO state, maybe it is VV ? */
162 if (key[1] != 0)
163 key[0] = 0x01; /* if something is inside the buffer, simulate key press */
164
165 /* call the universal NEC remote processor, to find out the key's state and event */
166 dvb_usb_nec_rc_key_to_event(d,key,event,state);
167 if (key[0] != 0)
168 deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
169 return 0;
170}
171
172/* DVB USB Driver stuff */
173static struct dvb_usb_properties digitv_properties;
174
175static int digitv_probe(struct usb_interface *intf,
176 const struct usb_device_id *id)
177{
178 return dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE);
179}
180
181static struct usb_device_id digitv_table [] = {
182 { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) },
183 { } /* Terminating entry */
184};
185MODULE_DEVICE_TABLE (usb, digitv_table);
186
187static struct dvb_usb_properties digitv_properties = {
188 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
189
190 .usb_ctrl = CYPRESS_FX2,
191 .firmware = "dvb-usb-digitv-01.fw",
192
193 .size_of_priv = 0,
194
195 .frontend_attach = digitv_frontend_attach,
196 .tuner_attach = digitv_tuner_attach,
197
198 .rc_interval = 1000,
199 .rc_key_map = digitv_rc_keys,
200 .rc_key_map_size = ARRAY_SIZE(digitv_rc_keys),
201 .rc_query = digitv_rc_query,
202
203 .identify_state = digitv_identify_state,
204
205 .i2c_algo = &digitv_i2c_algo,
206
207 .generic_bulk_ctrl_endpoint = 0x01,
208 /* parameter for the MPEG2-data transfer */
209 .urb = {
210 .type = DVB_USB_BULK,
211 .count = 7,
212 .endpoint = 0x02,
213 .u = {
214 .bulk = {
215 .buffersize = 4096,
216 }
217 }
218 },
219
220 .num_device_descs = 1,
221 .devices = {
222 { "Nebula Electronics uDigiTV DVB-T USB2.0)",
223 { &digitv_table[0], NULL },
224 { NULL },
225 },
226 }
227};
228
229static struct usb_driver digitv_driver = {
230 .owner = THIS_MODULE,
231 .name = "dvb_usb_digitv",
232 .probe = digitv_probe,
233 .disconnect = dvb_usb_device_exit,
234 .id_table = digitv_table,
235};
236
237/* module stuff */
238static int __init digitv_module_init(void)
239{
240 int result;
241 if ((result = usb_register(&digitv_driver))) {
242 err("usb_register failed. Error number %d",result);
243 return result;
244 }
245
246 return 0;
247}
248
249static void __exit digitv_module_exit(void)
250{
251 /* deregister this driver from the USB subsystem */
252 usb_deregister(&digitv_driver);
253}
254
255module_init (digitv_module_init);
256module_exit (digitv_module_exit);
257
258MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
259MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0");
260MODULE_VERSION("1.0-alpha");
261MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/digitv.h b/drivers/media/dvb/dvb-usb/digitv.h
new file mode 100644
index 000000000000..477ee428a70e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/digitv.h
@@ -0,0 +1,65 @@
1#ifndef _DVB_USB_DIGITV_H_
2#define _DVB_USB_DIGITV_H_
3
4#define DVB_USB_LOG_PREFIX "digitv"
5#include "dvb-usb.h"
6
7extern int dvb_usb_digitv_debug;
8#define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args)
9
10/* protocol (from usblogging and the SDK:
11 *
12 * Always 7 bytes bulk message(s) for controlling
13 *
14 * First byte describes the command. Reads are 2 consecutive transfer (as always).
15 *
16 * General structure:
17 *
18 * write or first message of a read:
19 * <cmdbyte> VV <len> B0 B1 B2 B3
20 *
21 * second message of a read
22 * <cmdbyte> VV <len> R0 R1 R2 R3
23 *
24 * whereas 0 < len <= 4
25 *
26 * I2C address is stored somewhere inside the device.
27 *
28 * 0x01 read from EEPROM
29 * VV = offset; B* = 0; R* = value(s)
30 *
31 * 0x02 read register of the COFDM
32 * VV = register; B* = 0; R* = value(s)
33 *
34 * 0x05 write register of the COFDM
35 * VV = register; B* = value(s);
36 *
37 * 0x06 write to the tuner (only for NXT6000)
38 * VV = 0; B* = PLL data; len = 4;
39 *
40 * 0x03 read remote control
41 * VV = 0; B* = 0; len = 4; R* = key
42 *
43 * 0x07 write to the remote (don't know why one should this, resetting ?)
44 * VV = 0; B* = key; len = 4;
45 *
46 * 0x08 write remote type
47 * VV = 0; B[0] = 0x01, len = 4
48 *
49 * 0x09 write device init
50 * TODO
51 */
52#define USB_READ_EEPROM 1
53
54#define USB_READ_COFDM 2
55#define USB_WRITE_COFDM 5
56
57#define USB_WRITE_TUNER 6
58
59#define USB_READ_REMOTE 3
60#define USB_WRITE_REMOTE 7
61#define USB_WRITE_REMOTE_TYPE 8
62
63#define USB_DEV_INIT 9
64
65#endif
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
new file mode 100644
index 000000000000..b032523b07bc
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -0,0 +1,208 @@
1/* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/
2 * Typhoon/ Yuan DVB-T USB2.0 receiver.
3 *
4 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dtt200u.h"
13
14struct dtt200u_fe_state {
15 struct dvb_usb_device *d;
16
17 fe_status_t stat;
18
19 struct dvb_frontend_parameters fep;
20 struct dvb_frontend frontend;
21};
22
23static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
24{
25 struct dtt200u_fe_state *state = fe->demodulator_priv;
26 u8 st = GET_TUNE_STATUS, b[3];
27
28 dvb_usb_generic_rw(state->d,&st,1,b,3,0);
29
30 switch (b[0]) {
31 case 0x01:
32 *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
33 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
34 break;
35 case 0x00: /* pending */
36 *stat = FE_TIMEDOUT; /* during set_frontend */
37 break;
38 default:
39 case 0x02: /* failed */
40 *stat = 0;
41 break;
42 }
43 return 0;
44}
45
46static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
47{
48 struct dtt200u_fe_state *state = fe->demodulator_priv;
49 u8 bw = GET_VIT_ERR_CNT,b[3];
50 dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
51 *ber = (b[0] << 16) | (b[1] << 8) | b[2];
52 return 0;
53}
54
55static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
56{
57 struct dtt200u_fe_state *state = fe->demodulator_priv;
58 u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];
59
60 dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
61 *unc = (b[0] << 8) | b[1];
62 return 0;
63}
64
65static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
66{
67 struct dtt200u_fe_state *state = fe->demodulator_priv;
68 u8 bw = GET_AGC, b;
69 dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
70 *strength = (b << 8) | b;
71 return 0;
72}
73
74static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
75{
76 struct dtt200u_fe_state *state = fe->demodulator_priv;
77 u8 bw = GET_SNR,br;
78 dvb_usb_generic_rw(state->d,&bw,1,&br,1,0);
79 *snr = ~((br << 8) | br);
80 return 0;
81}
82
83static int dtt200u_fe_init(struct dvb_frontend* fe)
84{
85 struct dtt200u_fe_state *state = fe->demodulator_priv;
86 u8 b = SET_INIT;
87 return dvb_usb_generic_write(state->d,&b,1);
88}
89
90static int dtt200u_fe_sleep(struct dvb_frontend* fe)
91{
92 return dtt200u_fe_init(fe);
93}
94
95static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
96{
97 tune->min_delay_ms = 1500;
98 tune->step_size = 0;
99 tune->max_drift = 0;
100 return 0;
101}
102
103static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
104 struct dvb_frontend_parameters *fep)
105{
106 struct dtt200u_fe_state *state = fe->demodulator_priv;
107 int i;
108 fe_status_t st;
109 u16 freq = fep->frequency / 250000;
110 u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
111
112 switch (fep->u.ofdm.bandwidth) {
113 case BANDWIDTH_8_MHZ: bwbuf[1] = 8; break;
114 case BANDWIDTH_7_MHZ: bwbuf[1] = 7; break;
115 case BANDWIDTH_6_MHZ: bwbuf[1] = 6; break;
116 case BANDWIDTH_AUTO: return -EOPNOTSUPP;
117 default:
118 return -EINVAL;
119 }
120
121 dvb_usb_generic_write(state->d,bwbuf,2);
122
123 freqbuf[1] = freq & 0xff;
124 freqbuf[2] = (freq >> 8) & 0xff;
125 dvb_usb_generic_write(state->d,freqbuf,3);
126
127 for (i = 0; i < 30; i++) {
128 msleep(20);
129 dtt200u_fe_read_status(fe, &st);
130 if (st & FE_TIMEDOUT)
131 continue;
132 }
133
134 return 0;
135}
136
137static int dtt200u_fe_get_frontend(struct dvb_frontend* fe,
138 struct dvb_frontend_parameters *fep)
139{
140 struct dtt200u_fe_state *state = fe->demodulator_priv;
141 memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters));
142 return 0;
143}
144
145static void dtt200u_fe_release(struct dvb_frontend* fe)
146{
147 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
148 kfree(state);
149}
150
151static struct dvb_frontend_ops dtt200u_fe_ops;
152
153struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
154{
155 struct dtt200u_fe_state* state = NULL;
156
157 /* allocate memory for the internal state */
158 state = (struct dtt200u_fe_state*) kmalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL);
159 if (state == NULL)
160 goto error;
161 memset(state,0,sizeof(struct dtt200u_fe_state));
162
163 deb_info("attaching frontend dtt200u\n");
164
165 state->d = d;
166
167 state->frontend.ops = &dtt200u_fe_ops;
168 state->frontend.demodulator_priv = state;
169
170 goto success;
171error:
172 return NULL;
173success:
174 return &state->frontend;
175}
176
177static struct dvb_frontend_ops dtt200u_fe_ops = {
178 .info = {
179 .name = "WideView USB DVB-T",
180 .type = FE_OFDM,
181 .frequency_min = 44250000,
182 .frequency_max = 867250000,
183 .frequency_stepsize = 250000,
184 .caps = FE_CAN_INVERSION_AUTO |
185 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
186 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
187 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
188 FE_CAN_TRANSMISSION_MODE_AUTO |
189 FE_CAN_GUARD_INTERVAL_AUTO |
190 FE_CAN_RECOVER |
191 FE_CAN_HIERARCHY_AUTO,
192 },
193
194 .release = dtt200u_fe_release,
195
196 .init = dtt200u_fe_init,
197 .sleep = dtt200u_fe_sleep,
198
199 .set_frontend = dtt200u_fe_set_frontend,
200 .get_frontend = dtt200u_fe_get_frontend,
201 .get_tune_settings = dtt200u_fe_get_tune_settings,
202
203 .read_status = dtt200u_fe_read_status,
204 .read_ber = dtt200u_fe_read_ber,
205 .read_signal_strength = dtt200u_fe_read_signal_strength,
206 .read_snr = dtt200u_fe_read_snr,
207 .read_ucblocks = dtt200u_fe_read_unc_blocks,
208};
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
new file mode 100644
index 000000000000..47dba6e45968
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -0,0 +1,233 @@
1/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
2 * Typhoon/ Yuan DVB-T USB2.0 receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to Steve Chang from WideView for providing support for the WT-220U.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "dtt200u.h"
15
16/* debug */
17int dvb_usb_dtt200u_debug;
18module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
19MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
20
21static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
22{
23 u8 b = SET_INIT;
24
25 if (onoff)
26 dvb_usb_generic_write(d,&b,2);
27
28 return 0;
29}
30
31static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff)
32{
33 u8 b_streaming[2] = { SET_STREAMING, onoff };
34 u8 b_rst_pid = RESET_PID_FILTER;
35
36 dvb_usb_generic_write(d,b_streaming,2);
37
38 if (onoff == 0)
39 dvb_usb_generic_write(d,&b_rst_pid,1);
40 return 0;
41}
42
43static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
44{
45 u8 b_pid[4];
46 pid = onoff ? pid : 0;
47
48 b_pid[0] = SET_PID_FILTER;
49 b_pid[1] = index;
50 b_pid[2] = pid & 0xff;
51 b_pid[3] = (pid >> 8) & 0x1f;
52
53 return dvb_usb_generic_write(d,b_pid,4);
54}
55
56/* remote control */
57/* key list for the tiny remote control (Yakumo, don't know about the others) */
58static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
59 { 0x80, 0x01, KEY_MUTE },
60 { 0x80, 0x02, KEY_CHANNELDOWN },
61 { 0x80, 0x03, KEY_VOLUMEDOWN },
62 { 0x80, 0x04, KEY_1 },
63 { 0x80, 0x05, KEY_2 },
64 { 0x80, 0x06, KEY_3 },
65 { 0x80, 0x07, KEY_4 },
66 { 0x80, 0x08, KEY_5 },
67 { 0x80, 0x09, KEY_6 },
68 { 0x80, 0x0a, KEY_7 },
69 { 0x80, 0x0c, KEY_ZOOM },
70 { 0x80, 0x0d, KEY_0 },
71 { 0x80, 0x0e, KEY_SELECT },
72 { 0x80, 0x12, KEY_POWER },
73 { 0x80, 0x1a, KEY_CHANNELUP },
74 { 0x80, 0x1b, KEY_8 },
75 { 0x80, 0x1e, KEY_VOLUMEUP },
76 { 0x80, 0x1f, KEY_9 },
77};
78
79static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
80{
81 u8 key[5],cmd = GET_RC_CODE;
82 dvb_usb_generic_rw(d,&cmd,1,key,5,0);
83 dvb_usb_nec_rc_key_to_event(d,key,event,state);
84 if (key[0] != 0)
85 deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
86 return 0;
87}
88
89static int dtt200u_frontend_attach(struct dvb_usb_device *d)
90{
91 d->fe = dtt200u_fe_attach(d);
92 return 0;
93}
94
95static struct dvb_usb_properties dtt200u_properties;
96static struct dvb_usb_properties wt220u_properties;
97
98static int dtt200u_usb_probe(struct usb_interface *intf,
99 const struct usb_device_id *id)
100{
101 if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE) == 0 ||
102 dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE) == 0)
103 return 0;
104
105 return -ENODEV;
106}
107
108static struct usb_device_id dtt200u_usb_table [] = {
109// { USB_DEVICE(0x04b4,0x8613) },
110 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
111 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
112 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
113 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
114 { 0 },
115};
116MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
117
118static struct dvb_usb_properties dtt200u_properties = {
119 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
120 .pid_filter_count = 15,
121
122 .usb_ctrl = CYPRESS_FX2,
123 .firmware = "dvb-usb-dtt200u-01.fw",
124
125 .power_ctrl = dtt200u_power_ctrl,
126 .streaming_ctrl = dtt200u_streaming_ctrl,
127 .pid_filter = dtt200u_pid_filter,
128 .frontend_attach = dtt200u_frontend_attach,
129
130 .rc_interval = 300,
131 .rc_key_map = dtt200u_rc_keys,
132 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
133 .rc_query = dtt200u_rc_query,
134
135 .generic_bulk_ctrl_endpoint = 0x01,
136
137 /* parameter for the MPEG2-data transfer */
138 .urb = {
139 .type = DVB_USB_BULK,
140 .count = 7,
141 .endpoint = 0x02,
142 .u = {
143 .bulk = {
144 .buffersize = 4096,
145 }
146 }
147 },
148
149 .num_device_descs = 1,
150 .devices = {
151 { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
152 .cold_ids = { &dtt200u_usb_table[0], NULL },
153 .warm_ids = { &dtt200u_usb_table[1], NULL },
154 },
155 { 0 },
156 }
157};
158
159static struct dvb_usb_properties wt220u_properties = {
160 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
161 .pid_filter_count = 15,
162
163 .usb_ctrl = CYPRESS_FX2,
164 .firmware = "dvb-usb-wt220u-01.fw",
165
166 .power_ctrl = dtt200u_power_ctrl,
167 .streaming_ctrl = dtt200u_streaming_ctrl,
168 .pid_filter = dtt200u_pid_filter,
169 .frontend_attach = dtt200u_frontend_attach,
170
171 .rc_interval = 300,
172 .rc_key_map = dtt200u_rc_keys,
173 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
174 .rc_query = dtt200u_rc_query,
175
176 .generic_bulk_ctrl_endpoint = 0x01,
177
178 /* parameter for the MPEG2-data transfer */
179 .urb = {
180 .type = DVB_USB_BULK,
181 .count = 7,
182 .endpoint = 0x02,
183 .u = {
184 .bulk = {
185 .buffersize = 4096,
186 }
187 }
188 },
189
190 .num_device_descs = 1,
191 .devices = {
192 { .name = "WideView WT-220U PenType Receiver (and clones)",
193 .cold_ids = { &dtt200u_usb_table[2], NULL },
194 .warm_ids = { &dtt200u_usb_table[3], NULL },
195 },
196 { 0 },
197 }
198};
199
200/* usb specific object needed to register this driver with the usb subsystem */
201static struct usb_driver dtt200u_usb_driver = {
202 .owner = THIS_MODULE,
203 .name = "dvb_usb_dtt200u",
204 .probe = dtt200u_usb_probe,
205 .disconnect = dvb_usb_device_exit,
206 .id_table = dtt200u_usb_table,
207};
208
209/* module stuff */
210static int __init dtt200u_usb_module_init(void)
211{
212 int result;
213 if ((result = usb_register(&dtt200u_usb_driver))) {
214 err("usb_register failed. (%d)",result);
215 return result;
216 }
217
218 return 0;
219}
220
221static void __exit dtt200u_usb_module_exit(void)
222{
223 /* deregister this driver from the USB subsystem */
224 usb_deregister(&dtt200u_usb_driver);
225}
226
227module_init(dtt200u_usb_module_init);
228module_exit(dtt200u_usb_module_exit);
229
230MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
231MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon DVB-T USB2.0 devices");
232MODULE_VERSION("1.0");
233MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h
new file mode 100644
index 000000000000..6f1f3042e21a
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u.h
@@ -0,0 +1,56 @@
1/* Common header file of Linux driver for the WideView/ Yakumo/ Hama/
2 * Typhoon/ Yuan DVB-T USB2.0 receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#ifndef _DVB_USB_DTT200U_H_
13#define _DVB_USB_DTT200U_H_
14
15#define DVB_USB_LOG_PREFIX "dtt200u"
16#include "dvb-usb.h"
17
18extern int dvb_usb_dtt200u_debug;
19#define deb_info(args...) dprintk(dvb_usb_dtt200u_debug,0x01,args)
20#define deb_xfer(args...) dprintk(dvb_usb_dtt200u_debug,0x02,args)
21
22/* guessed protocol description (reverse engineered):
23 * read
24 * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
25 * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
26 */
27
28#define GET_SPEED 0x00
29#define GET_TUNE_STATUS 0x81
30#define GET_RC_CODE 0x84
31#define GET_CONFIGURATION 0x88
32#define GET_AGC 0x89
33#define GET_SNR 0x8a
34#define GET_VIT_ERR_CNT 0x8c
35#define GET_RS_ERR_CNT 0x8d
36#define GET_RS_UNCOR_BLK_CNT 0x8e
37
38/* write
39 * 01 - init
40 * 02 - frequency (divided by 250000)
41 * 03 - bandwidth
42 * 04 - pid table (index pid(7:0) pid(12:8))
43 * 05 - reset the pid table
44 * 08 - transfer switch
45 */
46
47#define SET_INIT 0x01
48#define SET_RF_FREQ 0x02
49#define SET_BANDWIDTH 0x03
50#define SET_PID_FILTER 0x04
51#define RESET_PID_FILTER 0x05
52#define SET_STREAMING 0x08
53
54extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
55
56#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
new file mode 100644
index 000000000000..7300489d3e24
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
@@ -0,0 +1,46 @@
1/* dvb-usb-common.h is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * a header file containing prototypes and types for internal use of the dvb-usb-lib
7 */
8#ifndef _DVB_USB_COMMON_H_
9#define _DVB_USB_COMMON_H_
10
11#define DVB_USB_LOG_PREFIX "dvb-usb"
12#include "dvb-usb.h"
13
14extern int dvb_usb_debug;
15extern int dvb_usb_disable_rc_polling;
16
17#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args)
18#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args)
19#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args)
20#define deb_ts(args...) dprintk(dvb_usb_debug,0x08,args)
21#define deb_err(args...) dprintk(dvb_usb_debug,0x10,args)
22#define deb_rc(args...) dprintk(dvb_usb_debug,0x20,args)
23#define deb_fw(args...) dprintk(dvb_usb_debug,0x40,args)
24#define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args)
25
26/* commonly used methods */
27extern int usb_cypress_load_firmware(struct usb_device *, const char *, int);
28
29extern int dvb_usb_urb_submit(struct dvb_usb_device *);
30extern int dvb_usb_urb_kill(struct dvb_usb_device *);
31extern int dvb_usb_urb_init(struct dvb_usb_device *);
32extern int dvb_usb_urb_exit(struct dvb_usb_device *);
33
34extern int dvb_usb_i2c_init(struct dvb_usb_device *);
35extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
36
37extern int dvb_usb_dvb_init(struct dvb_usb_device *);
38extern int dvb_usb_dvb_exit(struct dvb_usb_device *);
39
40extern int dvb_usb_fe_init(struct dvb_usb_device *);
41extern int dvb_usb_fe_exit(struct dvb_usb_device *);
42
43extern int dvb_usb_remote_init(struct dvb_usb_device *);
44extern int dvb_usb_remote_exit(struct dvb_usb_device *);
45
46#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
new file mode 100644
index 000000000000..3491ff40885c
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -0,0 +1,210 @@
1/* dvb-usb-dvb.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing and handling the
7 * linux-dvb API.
8 */
9#include "dvb-usb-common.h"
10
11static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
12{
13 struct dvb_usb_device *d = dvbdmxfeed->demux->priv;
14 int newfeedcount,ret;
15
16 if (d == NULL)
17 return -ENODEV;
18
19 newfeedcount = d->feedcount + (onoff ? 1 : -1);
20
21 /*
22 * stop feed before setting a new pid if there will be no pid anymore
23 */
24 if (newfeedcount == 0) {
25 deb_ts("stop feeding\n");
26
27 if (d->props.streaming_ctrl != NULL)
28 if ((ret = d->props.streaming_ctrl(d,0)))
29 err("error while stopping stream.");
30
31 dvb_usb_urb_kill(d);
32 }
33
34 d->feedcount = newfeedcount;
35
36 /* activate the pid on the device specific pid_filter */
37 deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off");
38 if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
39 d->pid_filtering &&
40 d->props.pid_filter != NULL)
41 d->props.pid_filter(d,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
42
43 /* start the feed if this was the first feed and there is still a feed
44 * for reception.
45 */
46 if (d->feedcount == onoff && d->feedcount > 0) {
47
48 deb_ts("controlling pid parser\n");
49 if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
50 d->props.caps & DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF &&
51 d->props.pid_filter_ctrl != NULL)
52 if (d->props.pid_filter_ctrl(d,d->pid_filtering) < 0)
53 err("could not handle pid_parser");
54
55 deb_ts("start feeding\n");
56 if (d->props.streaming_ctrl != NULL)
57 if (d->props.streaming_ctrl(d,1)) {
58 err("error while enabling fifo.");
59 return -ENODEV;
60 }
61
62 dvb_usb_urb_submit(d);
63 }
64 return 0;
65}
66
67static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
68{
69 deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
70 return dvb_usb_ctrl_feed(dvbdmxfeed,1);
71}
72
73static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
74{
75 deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
76 return dvb_usb_ctrl_feed(dvbdmxfeed,0);
77}
78
79int dvb_usb_dvb_init(struct dvb_usb_device *d)
80{
81 int ret;
82
83 if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name,
84 d->owner)) < 0) {
85 deb_info("dvb_register_adapter failed: error %d", ret);
86 goto err;
87 }
88 d->dvb_adap.priv = d;
89
90 if (d->props.read_mac_address) {
91 if (d->props.read_mac_address(d,d->dvb_adap.proposed_mac) == 0)
92 info("MAC address: %02x:%02x:%02x:%02x:%02x:%02x",d->dvb_adap.proposed_mac[0],
93 d->dvb_adap.proposed_mac[1],d->dvb_adap.proposed_mac[2],
94 d->dvb_adap.proposed_mac[3],d->dvb_adap.proposed_mac[4],
95 d->dvb_adap.proposed_mac[5]);
96 else
97 err("MAC address reading failed.");
98 }
99
100
101 d->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
102 d->demux.priv = d;
103
104 d->demux.feednum = d->demux.filternum = d->max_feed_count;
105 d->demux.start_feed = dvb_usb_start_feed;
106 d->demux.stop_feed = dvb_usb_stop_feed;
107 d->demux.write_to_decoder = NULL;
108 if ((ret = dvb_dmx_init(&d->demux)) < 0) {
109 err("dvb_dmx_init failed: error %d",ret);
110 goto err_dmx;
111 }
112
113 d->dmxdev.filternum = d->demux.filternum;
114 d->dmxdev.demux = &d->demux.dmx;
115 d->dmxdev.capabilities = 0;
116 if ((ret = dvb_dmxdev_init(&d->dmxdev, &d->dvb_adap)) < 0) {
117 err("dvb_dmxdev_init failed: error %d",ret);
118 goto err_dmx_dev;
119 }
120
121 dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx);
122
123 goto success;
124err_dmx_dev:
125 dvb_dmx_release(&d->demux);
126err_dmx:
127 dvb_unregister_adapter(&d->dvb_adap);
128err:
129 return ret;
130success:
131 d->state |= DVB_USB_STATE_DVB;
132 return 0;
133}
134
135int dvb_usb_dvb_exit(struct dvb_usb_device *d)
136{
137 if (d->state & DVB_USB_STATE_DVB) {
138 deb_info("unregistering DVB part\n");
139 dvb_net_release(&d->dvb_net);
140 d->demux.dmx.close(&d->demux.dmx);
141 dvb_dmxdev_release(&d->dmxdev);
142 dvb_dmx_release(&d->demux);
143 dvb_unregister_adapter(&d->dvb_adap);
144 d->state &= ~DVB_USB_STATE_DVB;
145 }
146 return 0;
147}
148
149static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
150{
151 struct dvb_usb_device *d = fe->dvb->priv;
152
153 if (d->props.power_ctrl)
154 d->props.power_ctrl(d,1);
155
156 if (d->fe_init)
157 d->fe_init(fe);
158
159 return 0;
160}
161
162static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
163{
164 struct dvb_usb_device *d = fe->dvb->priv;
165
166 if (d->fe_sleep)
167 d->fe_sleep(fe);
168
169 if (d->props.power_ctrl)
170 d->props.power_ctrl(d,0);
171
172 return 0;
173}
174
175int dvb_usb_fe_init(struct dvb_usb_device* d)
176{
177 if (d->props.frontend_attach == NULL) {
178 err("strange '%s' doesn't want to attach a frontend.",d->desc->name);
179 return 0;
180 }
181
182 d->props.frontend_attach(d);
183
184 /* re-assign sleep and wakeup functions */
185 if (d->fe != NULL) {
186 d->fe_init = d->fe->ops->init; d->fe->ops->init = dvb_usb_fe_wakeup;
187 d->fe_sleep = d->fe->ops->sleep; d->fe->ops->sleep = dvb_usb_fe_sleep;
188
189 if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
190 err("Frontend registration failed.");
191 if (d->fe->ops->release)
192 d->fe->ops->release(d->fe);
193 d->fe = NULL;
194 return -ENODEV;
195 }
196 } else
197 err("no frontend was attached by '%s'",d->desc->name);
198
199 if (d->props.tuner_attach != NULL)
200 d->props.tuner_attach(d);
201
202 return 0;
203}
204
205int dvb_usb_fe_exit(struct dvb_usb_device *d)
206{
207 if (d->fe != NULL)
208 dvb_unregister_frontend(d->fe);
209 return 0;
210}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
new file mode 100644
index 000000000000..5244e39770a0
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
@@ -0,0 +1,100 @@
1/* dvb-usb-firmware.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices.
7 *
8 * FIXME: This part does actually not belong to dvb-usb, but to the usb-subsystem.
9 */
10#include "dvb-usb-common.h"
11
12#include <linux/firmware.h>
13#include <linux/usb.h>
14
15struct usb_cypress_controller {
16 int id;
17 const char *name; /* name of the usb controller */
18 u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */
19};
20
21static struct usb_cypress_controller cypress[] = {
22 { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
23 { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
24 { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 },
25};
26
27/*
28 * load a firmware packet to the device
29 */
30static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
31{
32 return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
33 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ);
34}
35
36int usb_cypress_load_firmware(struct usb_device *udev, const char *filename, int type)
37{
38 const struct firmware *fw = NULL;
39 u16 addr;
40 u8 *b,*p;
41 int ret = 0,i;
42
43 if ((ret = request_firmware(&fw, filename, &udev->dev)) != 0) {
44 err("did not find the firmware file. (%s) "
45 "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
46 filename);
47 return ret;
48 }
49
50 info("downloading firmware from file '%s' to the '%s'",filename,cypress[type].name);
51
52 p = kmalloc(fw->size,GFP_KERNEL);
53 if (p != NULL) {
54 u8 reset;
55 /*
56 * you cannot use the fw->data as buffer for
57 * usb_control_msg, a new buffer has to be
58 * created
59 */
60 memcpy(p,fw->data,fw->size);
61
62 /* stop the CPU */
63 reset = 1;
64 if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
65 err("could not stop the USB controller CPU.");
66 for(i = 0; p[i+3] == 0 && i < fw->size; ) {
67 b = (u8 *) &p[i];
68 addr = cpu_to_le16( *((u16 *) &b[1]) );
69
70 deb_fw("writing to address 0x%04x (buffer: 0x%02x%02x)\n",addr,b[1],b[2]);
71
72 ret = usb_cypress_writemem(udev,addr,&b[4],b[0]);
73
74 if (ret != b[0]) {
75 err("error while transferring firmware "
76 "(transferred size: %d, block size: %d)",
77 ret,b[0]);
78 ret = -EINVAL;
79 break;
80 }
81 i += 5 + b[0];
82 }
83 /* length in ret */
84 if (ret > 0)
85 ret = 0;
86 /* restart the CPU */
87 reset = 0;
88 if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
89 err("could not restart the USB controller CPU.");
90 ret = -EINVAL;
91 }
92
93 kfree(p);
94 } else {
95 ret = -ENOMEM;
96 }
97 release_firmware(fw);
98
99 return ret;
100}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
new file mode 100644
index 000000000000..9f0a8d90d146
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -0,0 +1,118 @@
1/* dvb-usb-i2c.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for (de-)initializing an I2C adapter.
7 */
8#include "dvb-usb-common.h"
9
10int dvb_usb_i2c_init(struct dvb_usb_device *d)
11{
12 int ret = 0;
13
14 if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER))
15 return 0;
16
17 if (d->props.i2c_algo == NULL) {
18 err("no i2c algorithm specified");
19 return -EINVAL;
20 }
21
22 strncpy(d->i2c_adap.name,d->desc->name,I2C_NAME_SIZE);
23#ifdef I2C_ADAP_CLASS_TV_DIGITAL
24 d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
25#else
26 d->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
27#endif
28 d->i2c_adap.algo = d->props.i2c_algo;
29 d->i2c_adap.algo_data = NULL;
30 d->i2c_adap.id = I2C_ALGO_BIT;
31
32 i2c_set_adapdata(&d->i2c_adap, d);
33
34 if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0)
35 err("could not add i2c adapter");
36
37 d->state |= DVB_USB_STATE_I2C;
38
39 return ret;
40}
41
42int dvb_usb_i2c_exit(struct dvb_usb_device *d)
43{
44 if (d->state & DVB_USB_STATE_I2C)
45 i2c_del_adapter(&d->i2c_adap);
46 d->state &= ~DVB_USB_STATE_I2C;
47 return 0;
48}
49
50int dvb_usb_pll_init_i2c(struct dvb_frontend *fe)
51{
52 struct dvb_usb_device *d = fe->dvb->priv;
53 struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 };
54 int ret = 0;
55
56 /* if there is nothing to initialize */
57 if (d->pll_init[0] == 0x00 && d->pll_init[1] == 0x00 &&
58 d->pll_init[2] == 0x00 && d->pll_init[3] == 0x00)
59 return 0;
60
61 if (d->tuner_pass_ctrl)
62 d->tuner_pass_ctrl(fe,1,d->pll_addr);
63
64 deb_pll("pll init: %x\n",d->pll_addr);
65 deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1],
66 d->pll_init[2],d->pll_init[3]);
67
68 if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
69 err("tuner i2c write failed for pll_init.");
70 ret = -EREMOTEIO;
71 }
72 msleep(1);
73
74 if (d->tuner_pass_ctrl)
75 d->tuner_pass_ctrl(fe,0,d->pll_addr);
76 return ret;
77}
78EXPORT_SYMBOL(dvb_usb_pll_init_i2c);
79
80int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5])
81{
82 struct dvb_usb_device *d = fe->dvb->priv;
83
84 deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc);
85
86 b[0] = d->pll_addr << 1;
87 dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth);
88
89 deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]);
90
91 return 0;
92}
93EXPORT_SYMBOL(dvb_usb_pll_set);
94
95int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
96{
97 struct dvb_usb_device *d = fe->dvb->priv;
98 int ret = 0;
99 u8 b[5];
100 struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 };
101
102 dvb_usb_pll_set(fe,fep,b);
103
104 if (d->tuner_pass_ctrl)
105 d->tuner_pass_ctrl(fe,1,d->pll_addr);
106
107 if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
108 err("tuner i2c write failed for pll_set.");
109 ret = -EREMOTEIO;
110 }
111 msleep(1);
112
113 if (d->tuner_pass_ctrl)
114 d->tuner_pass_ctrl(fe,0,d->pll_addr);
115
116 return ret;
117}
118EXPORT_SYMBOL(dvb_usb_pll_set_i2c);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
new file mode 100644
index 000000000000..794d513a8480
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -0,0 +1,89 @@
1/* dvb-usb-ids.h is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) see
4 * dvb-usb-init.c for copyright information.
5 *
6 * a header file containing define's for the USB device supported by the
7 * various drivers.
8 */
9#ifndef _DVB_USB_IDS_H_
10#define _DVB_USB_IDS_H_
11
12/* Vendor IDs */
13#define USB_VID_ADSTECH 0x06e1
14#define USB_VID_ANCHOR 0x0547
15#define USB_VID_WIDEVIEW 0x14aa
16#define USB_VID_AVERMEDIA 0x07ca
17#define USB_VID_COMPRO 0x185b
18#define USB_VID_COMPRO_UNK 0x145f
19#define USB_VID_CYPRESS 0x04b4
20#define USB_VID_DIBCOM 0x10b8
21#define USB_VID_DVICO 0x0fe9
22#define USB_VID_EMPIA 0xeb1a
23#define USB_VID_GRANDTEC 0x5032
24#define USB_VID_HANFTEK 0x15f4
25#define USB_VID_HAUPPAUGE 0x2040
26#define USB_VID_HYPER_PALTEK 0x1025
27#define USB_VID_KYE 0x0458
28#define USB_VID_MEDION 0x1660
29#define USB_VID_VISIONPLUS 0x13d3
30#define USB_VID_TWINHAN 0x1822
31#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
32
33/* Product IDs */
34#define USB_PID_ADSTECH_USB2_COLD 0xa333
35#define USB_PID_ADSTECH_USB2_WARM 0xa334
36#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
37#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
38#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
39#define USB_PID_AVERMEDIA_DVBT_USB2_WARM 0xa801
40#define USB_PID_COMPRO_DVBU2000_COLD 0xd000
41#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
42#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
43#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
44#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
45#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
46#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
47#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
48#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
49#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
50#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
51#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
52#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
53#define USB_PID_TWINHAN_VP7041_COLD 0x3201
54#define USB_PID_TWINHAN_VP7041_WARM 0x3202
55#define USB_PID_TWINHAN_VP7045_COLD 0x3205
56#define USB_PID_TWINHAN_VP7045_WARM 0x3206
57#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
58#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
59#define USB_PID_TWINHAN_VP7021_COLD 0x3207
60#define USB_PID_TWINHAN_VP7021_WARM 0x3208
61#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
62#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
63#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
64#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
65#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
66#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
67#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
68#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
69#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
70#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
71#define USB_PID_HANFTEK_UMT_010_COLD 0x0001
72#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
73#define USB_PID_DTT200U_COLD 0x0201
74#define USB_PID_DTT200U_WARM 0x0301
75#define USB_PID_WT220U_COLD 0x0222
76#define USB_PID_WT220U_WARM 0x0221
77#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
78#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
79#define USB_PID_NEBULA_DIGITV 0x0201
80#define USB_PID_DVICO_BLUEBIRD_LGZ201 0xdb00
81#define USB_PID_DVICO_BLUEBIRD_TH7579 0xdb10
82#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820
83#define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01
84#define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11
85#define USB_PID_MEDION_MD95700 0x0932
86#define USB_PID_KYE_DVB_T_COLD 0x701e
87#define USB_PID_KYE_DVB_T_WARM 0x701f
88
89#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
new file mode 100644
index 000000000000..65f0c095abc9
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -0,0 +1,215 @@
1/*
2 * DVB USB library - provides a generic interface for a DVB USB device driver.
3 *
4 * dvb-usb-init.c
5 *
6 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "dvb-usb-common.h"
15
16/* debug */
17int dvb_usb_debug;
18module_param_named(debug,dvb_usb_debug, int, 0644);
19MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." DVB_USB_DEBUG_STATUS);
20
21int dvb_usb_disable_rc_polling;
22module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
23MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
24
25/* general initialization functions */
26int dvb_usb_exit(struct dvb_usb_device *d)
27{
28 deb_info("state before exiting everything: %x\n",d->state);
29 dvb_usb_remote_exit(d);
30 dvb_usb_fe_exit(d);
31 dvb_usb_i2c_exit(d);
32 dvb_usb_dvb_exit(d);
33 dvb_usb_urb_exit(d);
34 deb_info("state should be zero now: %x\n",d->state);
35 d->state = DVB_USB_STATE_INIT;
36 kfree(d->priv);
37 kfree(d);
38 return 0;
39}
40
41static int dvb_usb_init(struct dvb_usb_device *d)
42{
43 int ret = 0;
44
45 sema_init(&d->usb_sem, 1);
46 sema_init(&d->i2c_sem, 1);
47
48 d->state = DVB_USB_STATE_INIT;
49
50/* check the capabilites and set appropriate variables */
51
52/* speed - when running at FULL speed we need a HW PID filter */
53 if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) {
54 err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
55 return -ENODEV;
56 }
57
58 if ((d->udev->speed == USB_SPEED_FULL && d->props.caps & DVB_USB_HAS_PID_FILTER) ||
59 (d->props.caps & DVB_USB_NEED_PID_FILTERING)) {
60 info("will use the device's hardware PID filter (table count: %d).",d->props.pid_filter_count);
61 d->pid_filtering = 1;
62 d->max_feed_count = d->props.pid_filter_count;
63 } else {
64 info("will pass the complete MPEG2 transport stream to the software demuxer.");
65 d->pid_filtering = 0;
66 d->max_feed_count = 255;
67 }
68
69 if (d->props.power_ctrl)
70 d->props.power_ctrl(d,1);
71
72 if ((ret = dvb_usb_urb_init(d)) ||
73 (ret = dvb_usb_dvb_init(d)) ||
74 (ret = dvb_usb_i2c_init(d)) ||
75 (ret = dvb_usb_fe_init(d))) {
76 dvb_usb_exit(d);
77 return ret;
78 }
79
80 if ((ret = dvb_usb_remote_init(d)))
81 err("could not initialize remote control.");
82
83 if (d->props.power_ctrl)
84 d->props.power_ctrl(d,0);
85
86 return 0;
87}
88
89/* determine the name and the state of the just found USB device */
90static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_properties *props, int *cold)
91{
92 int i,j;
93 struct dvb_usb_device_description *desc = NULL;
94 *cold = -1;
95
96 for (i = 0; i < props->num_device_descs; i++) {
97
98 for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) {
99 deb_info("check for cold %x %x\n",props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
100 if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
101 props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
102 *cold = 1;
103 desc = &props->devices[i];
104 break;
105 }
106 }
107
108 if (desc != NULL)
109 break;
110
111 for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) {
112 deb_info("check for warm %x %x\n",props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
113 if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
114 props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
115 *cold = 0;
116 desc = &props->devices[i];
117 break;
118 }
119 }
120 }
121
122 if (desc != NULL && props->identify_state != NULL)
123 props->identify_state(udev,props,&desc,cold);
124
125 return desc;
126}
127
128/*
129 * USB
130 */
131int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *props, struct module *owner)
132{
133 struct usb_device *udev = interface_to_usbdev(intf);
134 struct dvb_usb_device *d = NULL;
135 struct dvb_usb_device_description *desc = NULL;
136
137 int ret = -ENOMEM,cold=0;
138
139 if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) {
140 deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
141 return -ENODEV;
142 }
143
144 if (cold) {
145 info("found a '%s' in cold state, will try to load a firmware",desc->name);
146 ret = usb_cypress_load_firmware(udev,props->firmware,props->usb_ctrl);
147 } else {
148 info("found a '%s' in warm state.",desc->name);
149 d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
150 if (d == NULL) {
151 err("no memory for 'struct dvb_usb_device'");
152 return ret;
153 }
154 memset(d,0,sizeof(struct dvb_usb_device));
155
156 d->udev = udev;
157 memcpy(&d->props,props,sizeof(struct dvb_usb_properties));
158 d->desc = desc;
159 d->owner = owner;
160
161 if (d->props.size_of_priv > 0) {
162 d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL);
163 if (d->priv == NULL) {
164 err("no memory for priv in 'struct dvb_usb_device'");
165 kfree(d);
166 return -ENOMEM;
167 }
168 memset(d->priv,0,d->props.size_of_priv);
169 }
170
171 usb_set_intfdata(intf, d);
172
173 ret = dvb_usb_init(d);
174 }
175
176 if (ret == 0)
177 info("%s successfully initialized and connected.",desc->name);
178 else
179 info("%s error while loading driver (%d)",desc->name,ret);
180 return ret;
181}
182EXPORT_SYMBOL(dvb_usb_device_init);
183
184void dvb_usb_device_exit(struct usb_interface *intf)
185{
186 struct dvb_usb_device *d = usb_get_intfdata(intf);
187 const char *name = "generic DVB-USB module";
188
189 usb_set_intfdata(intf,NULL);
190 if (d != NULL && d->desc != NULL) {
191 name = d->desc->name;
192 dvb_usb_exit(d);
193 }
194 info("%s successfully deinitialized and disconnected.",name);
195
196}
197EXPORT_SYMBOL(dvb_usb_device_exit);
198
199/* module stuff */
200static int __init dvb_usb_module_init(void)
201{
202 return 0;
203}
204
205static void __exit dvb_usb_module_exit(void)
206{
207}
208
209module_init (dvb_usb_module_init);
210module_exit (dvb_usb_module_exit);
211
212MODULE_VERSION("0.3");
213MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
214MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
215MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
new file mode 100644
index 000000000000..fc7800f1743e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -0,0 +1,181 @@
1/* dvb-usb-remote.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing the the input-device and for handling remote-control-queries.
7 */
8#include "dvb-usb-common.h"
9
10/* Remote-control poll function - called every dib->rc_query_interval ms to see
11 * whether the remote control has received anything.
12 *
13 * TODO: Fix the repeat rate of the input device.
14 */
15static void dvb_usb_read_remote_control(void *data)
16{
17 struct dvb_usb_device *d = data;
18 u32 event;
19 int state;
20
21 /* TODO: need a lock here. We can simply skip checking for the remote control
22 if we're busy. */
23
24 /* when the parameter has been set to 1 via sysfs while the driver was running */
25 if (dvb_usb_disable_rc_polling)
26 return;
27
28 if (d->props.rc_query(d,&event,&state)) {
29 err("error while querying for an remote control event.");
30 goto schedule;
31 }
32
33
34 switch (state) {
35 case REMOTE_NO_KEY_PRESSED:
36 break;
37 case REMOTE_KEY_PRESSED:
38 deb_rc("key pressed\n");
39 d->last_event = event;
40 case REMOTE_KEY_REPEAT:
41 deb_rc("key repeated\n");
42 input_event(&d->rc_input_dev, EV_KEY, d->last_event, 1);
43 input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
44 input_sync(&d->rc_input_dev);
45 break;
46 default:
47 break;
48 }
49
50/* improved repeat handling ???
51 switch (state) {
52 case REMOTE_NO_KEY_PRESSED:
53 deb_rc("NO KEY PRESSED\n");
54 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
55 deb_rc("releasing event %d\n",d->last_event);
56 input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
57 input_sync(&d->rc_input_dev);
58 }
59 d->last_state = REMOTE_NO_KEY_PRESSED;
60 d->last_event = 0;
61 break;
62 case REMOTE_KEY_PRESSED:
63 deb_rc("KEY PRESSED\n");
64 deb_rc("pressing event %d\n",event);
65
66 input_event(&d->rc_input_dev, EV_KEY, event, 1);
67 input_sync(&d->rc_input_dev);
68
69 d->last_event = event;
70 d->last_state = REMOTE_KEY_PRESSED;
71 break;
72 case REMOTE_KEY_REPEAT:
73 deb_rc("KEY_REPEAT\n");
74 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
75 deb_rc("repeating event %d\n",d->last_event);
76 input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2);
77 input_sync(&d->rc_input_dev);
78 d->last_state = REMOTE_KEY_REPEAT;
79 }
80 default:
81 break;
82 }
83*/
84
85schedule:
86 schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
87}
88
89int dvb_usb_remote_init(struct dvb_usb_device *d)
90{
91 int i;
92 if (d->props.rc_key_map == NULL ||
93 d->props.rc_query == NULL ||
94 dvb_usb_disable_rc_polling)
95 return 0;
96
97 /* Initialise the remote-control structures.*/
98 init_input_dev(&d->rc_input_dev);
99
100 d->rc_input_dev.evbit[0] = BIT(EV_KEY);
101 d->rc_input_dev.keycodesize = sizeof(unsigned char);
102 d->rc_input_dev.keycodemax = KEY_MAX;
103 d->rc_input_dev.name = "IR-receiver inside an USB DVB receiver";
104
105 /* set the bits for the keys */
106 deb_rc("key map size: %d\n",d->props.rc_key_map_size);
107 for (i = 0; i < d->props.rc_key_map_size; i++) {
108 deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
109 set_bit(d->props.rc_key_map[i].event, d->rc_input_dev.keybit);
110 }
111
112 /* Start the remote-control polling. */
113 if (d->props.rc_interval < 40)
114 d->props.rc_interval = 100; /* default */
115
116 /* setting these two values to non-zero, we have to manage key repeats */
117 d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval;
118 d->rc_input_dev.rep[REP_DELAY] = d->props.rc_interval + 150;
119
120 input_register_device(&d->rc_input_dev);
121
122 INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
123
124 info("schedule remote query interval to %d msecs.",d->props.rc_interval);
125 schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
126
127 d->state |= DVB_USB_STATE_REMOTE;
128
129 return 0;
130}
131
132int dvb_usb_remote_exit(struct dvb_usb_device *d)
133{
134 if (d->state & DVB_USB_STATE_REMOTE) {
135 cancel_delayed_work(&d->rc_query_work);
136 flush_scheduled_work();
137 input_unregister_device(&d->rc_input_dev);
138 }
139 d->state &= ~DVB_USB_STATE_REMOTE;
140 return 0;
141}
142
143#define DVB_USB_RC_NEC_EMPTY 0x00
144#define DVB_USB_RC_NEC_KEY_PRESSED 0x01
145#define DVB_USB_RC_NEC_KEY_REPEATED 0x02
146int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
147 u8 keybuf[5], u32 *event, int *state)
148{
149 int i;
150 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
151 *event = 0;
152 *state = REMOTE_NO_KEY_PRESSED;
153 switch (keybuf[0]) {
154 case DVB_USB_RC_NEC_EMPTY:
155 break;
156 case DVB_USB_RC_NEC_KEY_PRESSED:
157 if ((u8) ~keybuf[1] != keybuf[2] ||
158 (u8) ~keybuf[3] != keybuf[4]) {
159 deb_err("remote control checksum failed.\n");
160 break;
161 }
162 /* See if we can match the raw key code. */
163 for (i = 0; i < d->props.rc_key_map_size; i++)
164 if (keymap[i].custom == keybuf[1] &&
165 keymap[i].data == keybuf[3]) {
166 *event = keymap[i].event;
167 *state = REMOTE_KEY_PRESSED;
168 return 0;
169 }
170 deb_err("key mapping failed - no appropriate key found in keymapping\n");
171 break;
172 case DVB_USB_RC_NEC_KEY_REPEATED:
173 *state = REMOTE_KEY_REPEAT;
174 break;
175 default:
176 deb_err("unkown type of remote status: %d\n",keybuf[0]);
177 break;
178 }
179 return 0;
180}
181EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
new file mode 100644
index 000000000000..f5799a4c228e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -0,0 +1,325 @@
1/* dvb-usb-urb.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing and handling the
7 * USB and URB stuff.
8 */
9#include "dvb-usb-common.h"
10
11int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
12 u16 rlen, int delay_ms)
13{
14 int actlen,ret = -ENOMEM;
15
16 if (d->props.generic_bulk_ctrl_endpoint == 0) {
17 err("endpoint for generic control not specified.");
18 return -EINVAL;
19 }
20
21 if (wbuf == NULL || wlen == 0)
22 return -EINVAL;
23
24 if ((ret = down_interruptible(&d->usb_sem)))
25 return ret;
26
27 deb_xfer(">>> ");
28 debug_dump(wbuf,wlen,deb_xfer);
29
30 ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
31 d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
32 2000);
33
34 if (ret)
35 err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
36 else
37 ret = actlen != wlen ? -1 : 0;
38
39 /* an answer is expected, and no error before */
40 if (!ret && rbuf && rlen) {
41 if (delay_ms)
42 msleep(delay_ms);
43
44 ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
45 d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
46 2000);
47
48 if (ret)
49 err("recv bulk message failed: %d",ret);
50 else {
51 deb_xfer("<<< ");
52 debug_dump(rbuf,actlen,deb_xfer);
53 }
54 }
55
56 up(&d->usb_sem);
57 return ret;
58}
59EXPORT_SYMBOL(dvb_usb_generic_rw);
60
61int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
62{
63 return dvb_usb_generic_rw(d,buf,len,NULL,0,0);
64}
65EXPORT_SYMBOL(dvb_usb_generic_write);
66
67
68/* URB stuff for streaming */
69static void dvb_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
70{
71 struct dvb_usb_device *d = urb->context;
72 int ptype = usb_pipetype(urb->pipe);
73 int i;
74 u8 *b;
75
76 deb_ts("'%s' urb completed. feedcount: %d, status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
77 ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", d->feedcount,
78 urb->status,urb->actual_length,urb->transfer_buffer_length,
79 urb->number_of_packets,urb->error_count);
80
81 switch (urb->status) {
82 case 0: /* success */
83 case -ETIMEDOUT: /* NAK */
84 break;
85 case -ECONNRESET: /* kill */
86 case -ENOENT:
87 case -ESHUTDOWN:
88 return;
89 default: /* error */
90 deb_ts("urb completition error %d.", urb->status);
91 break;
92 }
93
94 if (d->feedcount > 0) {
95 if (d->state & DVB_USB_STATE_DVB) {
96 switch (ptype) {
97 case PIPE_ISOCHRONOUS:
98 b = (u8 *) urb->transfer_buffer;
99 for (i = 0; i < urb->number_of_packets; i++) {
100 if (urb->iso_frame_desc[i].status != 0)
101 deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
102 else if (urb->iso_frame_desc[i].actual_length > 0) {
103 dvb_dmx_swfilter(&d->demux,b + urb->iso_frame_desc[i].offset,
104 urb->iso_frame_desc[i].actual_length);
105 }
106 urb->iso_frame_desc[i].status = 0;
107 urb->iso_frame_desc[i].actual_length = 0;
108 }
109 debug_dump(b,20,deb_ts);
110 break;
111 case PIPE_BULK:
112 if (urb->actual_length > 0)
113 dvb_dmx_swfilter(&d->demux, (u8 *) urb->transfer_buffer,urb->actual_length);
114 break;
115 default:
116 err("unkown endpoint type in completition handler.");
117 return;
118 }
119 }
120 }
121
122 usb_submit_urb(urb,GFP_ATOMIC);
123}
124
125int dvb_usb_urb_kill(struct dvb_usb_device *d)
126{
127 int i;
128 for (i = 0; i < d->urbs_submitted; i++) {
129 deb_ts("killing URB no. %d.\n",i);
130
131 /* stop the URB */
132 usb_kill_urb(d->urb_list[i]);
133 }
134 d->urbs_submitted = 0;
135 return 0;
136}
137
138int dvb_usb_urb_submit(struct dvb_usb_device *d)
139{
140 int i,ret;
141 for (i = 0; i < d->urbs_initialized; i++) {
142 deb_ts("submitting URB no. %d\n",i);
143 if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) {
144 err("could not submit URB no. %d - get them all back",i);
145 dvb_usb_urb_kill(d);
146 return ret;
147 }
148 d->urbs_submitted++;
149 }
150 return 0;
151}
152
153static int dvb_usb_free_stream_buffers(struct dvb_usb_device *d)
154{
155 if (d->state & DVB_USB_STATE_URB_BUF) {
156 while (d->buf_num) {
157 d->buf_num--;
158 deb_mem("freeing buffer %d\n",d->buf_num);
159 usb_buffer_free(d->udev, d->buf_size,
160 d->buf_list[d->buf_num], d->dma_addr[d->buf_num]);
161 }
162 kfree(d->buf_list);
163 kfree(d->dma_addr);
164 }
165
166 d->state &= ~DVB_USB_STATE_URB_BUF;
167
168 return 0;
169}
170
171static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, unsigned long size)
172{
173 d->buf_num = 0;
174 d->buf_size = size;
175
176 deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
177
178 if ((d->buf_list = kmalloc(num*sizeof(u8 *), GFP_ATOMIC)) == NULL)
179 return -ENOMEM;
180
181 if ((d->dma_addr = kmalloc(num*sizeof(dma_addr_t), GFP_ATOMIC)) == NULL) {
182 kfree(d->buf_list);
183 return -ENOMEM;
184 }
185 memset(d->buf_list,0,num*sizeof(u8 *));
186 memset(d->dma_addr,0,num*sizeof(dma_addr_t));
187
188 d->state |= DVB_USB_STATE_URB_BUF;
189
190 for (d->buf_num = 0; d->buf_num < num; d->buf_num++) {
191 deb_mem("allocating buffer %d\n",d->buf_num);
192 if (( d->buf_list[d->buf_num] =
193 usb_buffer_alloc(d->udev, size, SLAB_ATOMIC,
194 &d->dma_addr[d->buf_num]) ) == NULL) {
195 deb_mem("not enough memory for urb-buffer allocation.\n");
196 dvb_usb_free_stream_buffers(d);
197 return -ENOMEM;
198 }
199 deb_mem("buffer %d: %p (dma: %d)\n",d->buf_num,d->buf_list[d->buf_num],d->dma_addr[d->buf_num]);
200 memset(d->buf_list[d->buf_num],0,size);
201 }
202 deb_mem("allocation successful\n");
203
204 return 0;
205}
206
207static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
208{
209 int i;
210
211 if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
212 d->props.urb.u.bulk.buffersize)) < 0)
213 return i;
214
215 /* allocate the URBs */
216 for (i = 0; i < d->props.urb.count; i++) {
217 if ((d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
218 return -ENOMEM;
219
220 usb_fill_bulk_urb( d->urb_list[i], d->udev,
221 usb_rcvbulkpipe(d->udev,d->props.urb.endpoint),
222 d->buf_list[i],
223 d->props.urb.u.bulk.buffersize,
224 dvb_usb_urb_complete, d);
225
226 d->urb_list[i]->transfer_flags = 0;
227 d->urbs_initialized++;
228 }
229 return 0;
230}
231
232static int dvb_usb_isoc_urb_init(struct dvb_usb_device *d)
233{
234 int i,j;
235
236 if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
237 d->props.urb.u.isoc.framesize*d->props.urb.u.isoc.framesperurb)) < 0)
238 return i;
239
240 /* allocate the URBs */
241 for (i = 0; i < d->props.urb.count; i++) {
242 struct urb *urb;
243 int frame_offset = 0;
244 if ((d->urb_list[i] =
245 usb_alloc_urb(d->props.urb.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
246 return -ENOMEM;
247
248 urb = d->urb_list[i];
249
250 urb->dev = d->udev;
251 urb->context = d;
252 urb->complete = dvb_usb_urb_complete;
253 urb->pipe = usb_rcvisocpipe(d->udev,d->props.urb.endpoint);
254 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
255 urb->interval = d->props.urb.u.isoc.interval;
256 urb->number_of_packets = d->props.urb.u.isoc.framesperurb;
257 urb->transfer_buffer_length = d->buf_size;
258 urb->transfer_buffer = d->buf_list[i];
259 urb->transfer_dma = d->dma_addr[i];
260
261 for (j = 0; j < d->props.urb.u.isoc.framesperurb; j++) {
262 urb->iso_frame_desc[j].offset = frame_offset;
263 urb->iso_frame_desc[j].length = d->props.urb.u.isoc.framesize;
264 frame_offset += d->props.urb.u.isoc.framesize;
265 }
266
267 d->urbs_initialized++;
268 }
269 return 0;
270
271}
272
273int dvb_usb_urb_init(struct dvb_usb_device *d)
274{
275 /*
276 * when reloading the driver w/o replugging the device
277 * sometimes a timeout occures, this helps
278 */
279 if (d->props.generic_bulk_ctrl_endpoint != 0) {
280 usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
281 usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
282 }
283 usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.urb.endpoint));
284
285 /* allocate the array for the data transfer URBs */
286 d->urb_list = kmalloc(d->props.urb.count * sizeof(struct urb *),GFP_KERNEL);
287 if (d->urb_list == NULL)
288 return -ENOMEM;
289 memset(d->urb_list,0,d->props.urb.count * sizeof(struct urb *));
290 d->state |= DVB_USB_STATE_URB_LIST;
291
292 switch (d->props.urb.type) {
293 case DVB_USB_BULK:
294 return dvb_usb_bulk_urb_init(d);
295 case DVB_USB_ISOC:
296 return dvb_usb_isoc_urb_init(d);
297 default:
298 err("unkown URB-type for data transfer.");
299 return -EINVAL;
300 }
301}
302
303int dvb_usb_urb_exit(struct dvb_usb_device *d)
304{
305 int i;
306
307 dvb_usb_urb_kill(d);
308
309 if (d->state & DVB_USB_STATE_URB_LIST) {
310 for (i = 0; i < d->urbs_initialized; i++) {
311 if (d->urb_list[i] != NULL) {
312 deb_mem("freeing URB no. %d.\n",i);
313 /* free the URBs */
314 usb_free_urb(d->urb_list[i]);
315 }
316 }
317 d->urbs_initialized = 0;
318 /* free the urb array */
319 kfree(d->urb_list);
320 d->state &= ~DVB_USB_STATE_URB_LIST;
321 }
322
323 dvb_usb_free_stream_buffers(d);
324 return 0;
325}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
new file mode 100644
index 000000000000..a80567caf508
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -0,0 +1,329 @@
1/* dvb-usb.h is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * the headerfile, all dvb-usb-drivers have to include.
7 */
8#ifndef __DVB_USB_H__
9#define __DVB_USB_H__
10
11#include <linux/config.h>
12#include <linux/input.h>
13#include <linux/module.h>
14#include <linux/usb.h>
15
16#include "dvb_frontend.h"
17#include "dvb_demux.h"
18#include "dvb_net.h"
19#include "dmxdev.h"
20
21#include "dvb-pll.h"
22
23#include "dvb-usb-ids.h"
24
25/* debug */
26#ifdef CONFIG_DVB_USB_DEBUG
27#define dprintk(var,level,args...) \
28 do { if ((var & level)) { printk(args); } } while (0)
29
30#define debug_dump(b,l,func) {\
31 int loop_; \
32 for (loop_ = 0; loop_ < l; loop_++) func("%02x ", b[loop_]); \
33 func("\n");\
34}
35#define DVB_USB_DEBUG_STATUS
36#else
37#define dprintk(args...)
38#define debug_dump(b,l,func)
39
40#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
41
42#endif
43
44/* generic log methods - taken from usb.h */
45#ifndef DVB_USB_LOG_PREFIX
46 #define DVB_USB_LOG_PREFIX "dvb-usb (please define a log prefix)"
47#endif
48
49#undef err
50#define err(format, arg...) printk(KERN_ERR DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
51#undef info
52#define info(format, arg...) printk(KERN_INFO DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
53#undef warn
54#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
55
56/**
57 * struct dvb_usb_device_description - name and its according USB IDs
58 * @name: real name of the box, regardless which DVB USB device class is in use
59 * @cold_ids: array of struct usb_device_id which describe the device in
60 * pre-firmware state
61 * @warm_ids: array of struct usb_device_id which describe the device in
62 * post-firmware state
63 *
64 * Each DVB USB device class can have one or more actual devices, this struct
65 * assigns a name to it.
66 */
67struct dvb_usb_device_description {
68 const char *name;
69
70#define DVB_USB_ID_MAX_NUM 15
71 struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM];
72 struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
73};
74
75/**
76 * struct dvb_usb_rc_key - a remote control key and its input-event
77 * @custom: the vendor/custom part of the key
78 * @data: the actual key part
79 * @event: the input event assigned to key identified by custom and data
80 */
81struct dvb_usb_rc_key {
82 u8 custom,data;
83 u32 event;
84};
85
86struct dvb_usb_device;
87
88/**
89 * struct dvb_usb_properties - properties of a dvb-usb-device
90 * @caps: capabilites of the DVB USB device.
91 * @pid_filter_count: number of PID filter position in the optional hardware
92 * PID-filter.
93 *
94 * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
95 * download.
96 * @firmware: name of the firmware file.
97 *
98 * @size_of_priv: how many bytes shall be allocated for the private field
99 * of struct dvb_usb_device.
100 *
101 * @power_ctrl: called to enable/disable power of the device.
102 * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the
103 * device (not URB submitting/killing).
104 * @pid_filter_ctrl: called to en/disable the PID filter, if any.
105 * @pid_filter: called to set/unset a PID for filtering.
106 *
107 * @read_mac_address: called to read the MAC address of the device.
108 *
109 * @frontend_attach: called to attach the possible frontends (fill fe-field
110 * of struct dvb_usb_device).
111 * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
112 * pll_desc and pll_init_buf of struct dvb_usb_device).
113 * @identify_state: called to determine the state (cold or warm), when it
114 * is not distinguishable by the USB IDs.
115 *
116 * @rc_key_map: a hard-wired array of struct dvb_usb_rc_key (NULL to disable
117 * remote control handling).
118 * @rc_key_map_size: number of items in @rc_key_map.
119 * @rc_query: called to query an event event.
120 * @rc_interval: time in ms between two queries.
121 *
122 * @i2c_algo: i2c_algorithm if the device has I2CoverUSB.
123 *
124 * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic
125 * endpoint which received control messages with bulk transfers. When this
126 * is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
127 * helper functions.
128 *
129 * @urb: describes the kind of USB transfer used for MPEG2-TS-streaming.
130 * Currently only BULK is implemented
131 *
132 * @num_device_descs: number of struct dvb_usb_device_description in @devices
133 * @devices: array of struct dvb_usb_device_description compatibles with these
134 * properties.
135 */
136struct dvb_usb_properties {
137
138#define DVB_USB_HAS_PID_FILTER 0x01
139#define DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF 0x02
140#define DVB_USB_NEED_PID_FILTERING 0x04
141#define DVB_USB_IS_AN_I2C_ADAPTER 0x08
142 int caps;
143 int pid_filter_count;
144
145#define CYPRESS_AN2135 0
146#define CYPRESS_AN2235 1
147#define CYPRESS_FX2 2
148 int usb_ctrl;
149 const char *firmware;
150
151 int size_of_priv;
152
153 int (*power_ctrl) (struct dvb_usb_device *, int);
154 int (*streaming_ctrl) (struct dvb_usb_device *, int);
155 int (*pid_filter_ctrl) (struct dvb_usb_device *, int);
156 int (*pid_filter) (struct dvb_usb_device *, int, u16, int);
157
158 int (*read_mac_address) (struct dvb_usb_device *, u8 []);
159 int (*frontend_attach) (struct dvb_usb_device *);
160 int (*tuner_attach) (struct dvb_usb_device *);
161
162 int (*identify_state) (struct usb_device *, struct dvb_usb_properties *,
163 struct dvb_usb_device_description **, int *);
164
165/* remote control properties */
166#define REMOTE_NO_KEY_PRESSED 0x00
167#define REMOTE_KEY_PRESSED 0x01
168#define REMOTE_KEY_REPEAT 0x02
169 struct dvb_usb_rc_key *rc_key_map;
170 int rc_key_map_size;
171 int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
172 int rc_interval;
173
174 struct i2c_algorithm *i2c_algo;
175
176 int generic_bulk_ctrl_endpoint;
177
178 struct {
179#define DVB_USB_BULK 1
180#define DVB_USB_ISOC 2
181 int type;
182 int count;
183 int endpoint;
184
185 union {
186 struct {
187 int buffersize; /* per URB */
188 } bulk;
189 struct {
190 int framesperurb;
191 int framesize;
192 int interval;
193 } isoc;
194 } u;
195 } urb;
196
197 int num_device_descs;
198 struct dvb_usb_device_description devices[9];
199};
200
201
202/**
203 * struct dvb_usb_device - object of a DVB USB device
204 * @props: copy of the struct dvb_usb_properties this device belongs to.
205 * @desc: pointer to the device's struct dvb_usb_device_description.
206 * @state: initialization and runtime state of the device.
207 *
208 * @udev: pointer to the device's struct usb_device.
209 * @urb_list: array of dynamically allocated struct urb for the MPEG2-TS-
210 * streaming.
211 *
212 * @buf_num: number of buffer allocated.
213 * @buf_size: size of each buffer in buf_list.
214 * @buf_list: array containing all allocate buffers for streaming.
215 * @dma_addr: list of dma_addr_t for each buffer in buf_list.
216 *
217 * @urbs_initialized: number of URBs initialized.
218 * @urbs_submitted: number of URBs submitted.
219 *
220 * @feedcount: number of reqested feeds (used for streaming-activation)
221 * @pid_filtering: is hardware pid_filtering used or not.
222 *
223 * @usb_sem: semaphore of USB control messages (reading needs two messages)
224 * @i2c_sem: semaphore for i2c-transfers
225 *
226 * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
227 * @pll_addr: I2C address of the tuner for programming
228 * @pll_init: array containing the initialization buffer
229 * @pll_desc: pointer to the appropriate struct dvb_pll_desc
230 *
231 * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
232 *
233 * @dvb_adap: device's dvb_adapter.
234 * @dmxdev: device's dmxdev.
235 * @demux: device's software demuxer.
236 * @dvb_net: device's dvb_net interfaces.
237 * @dvb_frontend: device's frontend.
238 * @max_feed_count: how many feeds can be handled simultaneously by this
239 * device
240 * @fe_sleep: rerouted frontend-sleep function.
241 * @fe_init: rerouted frontend-init (wakeup) function.
242 * @rc_input_dev: input device for the remote control.
243 * @rc_query_work: struct work_struct frequent rc queries
244 * @last_event: last triggered event
245 * @last_state: last state (no, pressed, repeat)
246 * @owner: owner of the dvb_adapter
247 * @priv: private data of the actual driver (allocate by dvb-usb, size defined
248 * in size_of_priv of dvb_usb_properties).
249 */
250struct dvb_usb_device {
251 struct dvb_usb_properties props;
252 struct dvb_usb_device_description *desc;
253
254#define DVB_USB_STATE_INIT 0x000
255#define DVB_USB_STATE_URB_LIST 0x001
256#define DVB_USB_STATE_URB_BUF 0x002
257#define DVB_USB_STATE_DVB 0x004
258#define DVB_USB_STATE_I2C 0x008
259#define DVB_USB_STATE_REMOTE 0x010
260#define DVB_USB_STATE_URB_SUBMIT 0x020
261 int state;
262
263 /* usb */
264 struct usb_device *udev;
265 struct urb **urb_list;
266
267 int buf_num;
268 unsigned long buf_size;
269 u8 **buf_list;
270 dma_addr_t *dma_addr;
271
272 int urbs_initialized;
273 int urbs_submitted;
274
275 int feedcount;
276 int pid_filtering;
277
278 /* locking */
279 struct semaphore usb_sem;
280
281 /* i2c */
282 struct semaphore i2c_sem;
283 struct i2c_adapter i2c_adap;
284
285 /* tuner programming information */
286 u8 pll_addr;
287 u8 pll_init[4];
288 struct dvb_pll_desc *pll_desc;
289 int (*tuner_pass_ctrl)(struct dvb_frontend *, int, u8);
290
291 /* dvb */
292 struct dvb_adapter dvb_adap;
293 struct dmxdev dmxdev;
294 struct dvb_demux demux;
295 struct dvb_net dvb_net;
296 struct dvb_frontend* fe;
297 int max_feed_count;
298
299 int (*fe_sleep) (struct dvb_frontend *);
300 int (*fe_init) (struct dvb_frontend *);
301
302 /* remote control */
303 struct input_dev rc_input_dev;
304 struct work_struct rc_query_work;
305 u32 last_event;
306 int last_state;
307
308 struct module *owner;
309
310 void *priv;
311};
312
313extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *);
314extern void dvb_usb_device_exit(struct usb_interface *);
315
316/* the generic read/write method for device control */
317extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int);
318extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
319
320/* commonly used remote control parsing */
321extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
322
323/* commonly used pll init and set functions */
324extern int dvb_usb_pll_init_i2c(struct dvb_frontend *);
325extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]);
326extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *);
327
328
329#endif
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
new file mode 100644
index 000000000000..258a92bfbcc7
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -0,0 +1,236 @@
1/* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dibusb.h"
13
14static int debug;
15module_param(debug, int, 0644);
16MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS);
17
18#define deb_rc(args...) dprintk(debug,0x01,args)
19#define deb_ee(args...) dprintk(debug,0x02,args)
20
21/* Hauppauge NOVA-T USB2 keys */
22static struct dvb_usb_rc_key haupp_rc_keys [] = {
23 { 0x1e, 0x00, KEY_0 },
24 { 0x1e, 0x01, KEY_1 },
25 { 0x1e, 0x02, KEY_2 },
26 { 0x1e, 0x03, KEY_3 },
27 { 0x1e, 0x04, KEY_4 },
28 { 0x1e, 0x05, KEY_5 },
29 { 0x1e, 0x06, KEY_6 },
30 { 0x1e, 0x07, KEY_7 },
31 { 0x1e, 0x08, KEY_8 },
32 { 0x1e, 0x09, KEY_9 },
33 { 0x1e, 0x0a, KEY_KPASTERISK },
34 { 0x1e, 0x0b, KEY_RED },
35 { 0x1e, 0x0c, KEY_RADIO },
36 { 0x1e, 0x0d, KEY_MENU },
37 { 0x1e, 0x0e, KEY_GRAVE }, /* # */
38 { 0x1e, 0x0f, KEY_MUTE },
39 { 0x1e, 0x10, KEY_VOLUMEUP },
40 { 0x1e, 0x11, KEY_VOLUMEDOWN },
41 { 0x1e, 0x12, KEY_CHANNEL },
42 { 0x1e, 0x14, KEY_UP },
43 { 0x1e, 0x15, KEY_DOWN },
44 { 0x1e, 0x16, KEY_LEFT },
45 { 0x1e, 0x17, KEY_RIGHT },
46 { 0x1e, 0x18, KEY_VIDEO },
47 { 0x1e, 0x19, KEY_AUDIO },
48 { 0x1e, 0x1a, KEY_MEDIA },
49 { 0x1e, 0x1b, KEY_EPG },
50 { 0x1e, 0x1c, KEY_TV },
51 { 0x1e, 0x1e, KEY_NEXT },
52 { 0x1e, 0x1f, KEY_BACK },
53 { 0x1e, 0x20, KEY_CHANNELUP },
54 { 0x1e, 0x21, KEY_CHANNELDOWN },
55 { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
56 { 0x1e, 0x25, KEY_OK },
57 { 0x1e, 0x29, KEY_BLUE},
58 { 0x1e, 0x2e, KEY_GREEN },
59 { 0x1e, 0x30, KEY_PAUSE },
60 { 0x1e, 0x32, KEY_REWIND },
61 { 0x1e, 0x34, KEY_FASTFORWARD },
62 { 0x1e, 0x35, KEY_PLAY },
63 { 0x1e, 0x36, KEY_STOP },
64 { 0x1e, 0x37, KEY_RECORD },
65 { 0x1e, 0x38, KEY_YELLOW },
66 { 0x1e, 0x3b, KEY_GOTO },
67 { 0x1e, 0x3d, KEY_POWER },
68};
69
70/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key
71 * is delivered. No workaround yet, maybe a new firmware.
72 */
73static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
74{
75 u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom;
76 u16 raw;
77 int i;
78 struct dibusb_state *st = d->priv;
79
80 dvb_usb_generic_rw(d,cmd,2,key,5,0);
81
82 *state = REMOTE_NO_KEY_PRESSED;
83 switch (key[0]) {
84 case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
85 raw = ((key[1] << 8) | key[2]) >> 3;
86 toggle = !!(raw & 0x800);
87 data = raw & 0x3f;
88 custom = (raw >> 6) & 0x1f;
89
90 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
91
92 for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) {
93 deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom);
94 if (haupp_rc_keys[i].data == data &&
95 haupp_rc_keys[i].custom == custom) {
96 *event = haupp_rc_keys[i].event;
97 *state = REMOTE_KEY_PRESSED;
98 if (st->old_toggle == toggle) {
99 if (st->last_repeat_count++ < 2)
100 *state = REMOTE_NO_KEY_PRESSED;
101 } else {
102 st->last_repeat_count = 0;
103 st->old_toggle = toggle;
104 }
105 break;
106 }
107 }
108
109 break;
110 case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
111 default:
112 break;
113 }
114
115 return 0;
116}
117
118static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
119{
120 int i;
121 u8 b;
122
123 mac[0] = 0x00;
124 mac[1] = 0x0d;
125 mac[2] = 0xfe;
126
127 /* this is a complete guess, but works for my box */
128 for (i = 136; i < 139; i++) {
129 dibusb_read_eeprom_byte(d,i, &b);
130
131 mac[5 - (i - 136)] = b;
132
133/* deb_ee("%02x ",b);
134 if ((i+1) % 16 == 0)
135 deb_ee("\n");*/
136 }
137
138 return 0;
139}
140
141/* USB Driver stuff */
142static struct dvb_usb_properties nova_t_properties;
143
144static int nova_t_probe(struct usb_interface *intf,
145 const struct usb_device_id *id)
146{
147 return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE);
148}
149
150/* do not change the order of the ID table */
151static struct usb_device_id nova_t_table [] = {
152/* 00 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) },
153/* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) },
154 { } /* Terminating entry */
155};
156MODULE_DEVICE_TABLE (usb, nova_t_table);
157
158static struct dvb_usb_properties nova_t_properties = {
159 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
160 .pid_filter_count = 32,
161
162 .usb_ctrl = CYPRESS_FX2,
163 .firmware = "dvb-usb-nova-t-usb2-01.fw",
164
165 .size_of_priv = sizeof(struct dibusb_state),
166
167 .streaming_ctrl = dibusb2_0_streaming_ctrl,
168 .pid_filter = dibusb_pid_filter,
169 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
170 .power_ctrl = dibusb2_0_power_ctrl,
171 .frontend_attach = dibusb_dib3000mc_frontend_attach,
172 .tuner_attach = dibusb_dib3000mc_tuner_attach,
173 .read_mac_address = nova_t_read_mac_address,
174
175 .rc_interval = 100,
176 .rc_key_map = haupp_rc_keys,
177 .rc_key_map_size = ARRAY_SIZE(haupp_rc_keys),
178 .rc_query = nova_t_rc_query,
179
180 .i2c_algo = &dibusb_i2c_algo,
181
182 .generic_bulk_ctrl_endpoint = 0x01,
183 /* parameter for the MPEG2-data transfer */
184 .urb = {
185 .type = DVB_USB_BULK,
186 .count = 7,
187 .endpoint = 0x06,
188 .u = {
189 .bulk = {
190 .buffersize = 4096,
191 }
192 }
193 },
194
195 .num_device_descs = 1,
196 .devices = {
197 { "Hauppauge WinTV-NOVA-T usb2",
198 { &nova_t_table[0], NULL },
199 { &nova_t_table[1], NULL },
200 },
201 }
202};
203
204static struct usb_driver nova_t_driver = {
205 .owner = THIS_MODULE,
206 .name = "dvb_usb_nova_t_usb2",
207 .probe = nova_t_probe,
208 .disconnect = dvb_usb_device_exit,
209 .id_table = nova_t_table,
210};
211
212/* module stuff */
213static int __init nova_t_module_init(void)
214{
215 int result;
216 if ((result = usb_register(&nova_t_driver))) {
217 err("usb_register failed. Error number %d",result);
218 return result;
219 }
220
221 return 0;
222}
223
224static void __exit nova_t_module_exit(void)
225{
226 /* deregister this driver from the USB subsystem */
227 usb_deregister(&nova_t_driver);
228}
229
230module_init (nova_t_module_init);
231module_exit (nova_t_module_exit);
232
233MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
234MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2");
235MODULE_VERSION("1.0");
236MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
new file mode 100644
index 000000000000..2112ac3cf5e2
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -0,0 +1,162 @@
1/* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dibusb.h"
13
14#include "mt352.h"
15
16static int umt_mt352_demod_init(struct dvb_frontend *fe)
17{
18 static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
19 static u8 mt352_reset[] = { 0x50, 0x80 };
20 static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
21 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
22 static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
23
24 static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
25 static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
26 static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
27 static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
28 static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
29
30 static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
31 static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
32
33 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
34 udelay(2000);
35 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
36 mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
37
38 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
39 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
40
41 mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
42 mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
43 mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
44 mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
45 mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
46
47 mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
48 mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
49
50 return 0;
51}
52
53static int umt_mt352_frontend_attach(struct dvb_usb_device *d)
54{
55 struct mt352_config umt_config;
56
57 memset(&umt_config,0,sizeof(struct mt352_config));
58 umt_config.demod_init = umt_mt352_demod_init;
59 umt_config.demod_address = 0xf;
60 umt_config.pll_set = dvb_usb_pll_set;
61
62 d->fe = mt352_attach(&umt_config, &d->i2c_adap);
63
64 return 0;
65}
66
67static int umt_tuner_attach (struct dvb_usb_device *d)
68{
69 d->pll_addr = 0x61;
70 d->pll_desc = &dvb_pll_tua6034;
71 return 0;
72}
73
74/* USB Driver stuff */
75static struct dvb_usb_properties umt_properties;
76
77static int umt_probe(struct usb_interface *intf,
78 const struct usb_device_id *id)
79{
80 if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE) == 0)
81 return 0;
82 return -EINVAL;
83}
84
85/* do not change the order of the ID table */
86static struct usb_device_id umt_table [] = {
87/* 00 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
88/* 01 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
89 { } /* Terminating entry */
90};
91MODULE_DEVICE_TABLE (usb, umt_table);
92
93static struct dvb_usb_properties umt_properties = {
94 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
95
96 .usb_ctrl = CYPRESS_FX2,
97 .firmware = "dvb-usb-umt-010-02.fw",
98
99 .size_of_priv = sizeof(struct dibusb_state),
100
101 .streaming_ctrl = dibusb2_0_streaming_ctrl,
102 .power_ctrl = dibusb_power_ctrl,
103 .frontend_attach = umt_mt352_frontend_attach,
104 .tuner_attach = umt_tuner_attach,
105
106 .i2c_algo = &dibusb_i2c_algo,
107
108 .generic_bulk_ctrl_endpoint = 0x01,
109 /* parameter for the MPEG2-data transfer */
110 .urb = {
111 .type = DVB_USB_BULK,
112 .count = 20,
113 .endpoint = 0x06,
114 .u = {
115 .bulk = {
116 .buffersize = 512,
117 }
118 }
119 },
120
121 .num_device_descs = 1,
122 .devices = {
123 { "Hanftek UMT-010 DVB-T USB2.0",
124 { &umt_table[0], NULL },
125 { &umt_table[1], NULL },
126 },
127 }
128};
129
130static struct usb_driver umt_driver = {
131 .owner = THIS_MODULE,
132 .name = "dvb_usb_umt_010",
133 .probe = umt_probe,
134 .disconnect = dvb_usb_device_exit,
135 .id_table = umt_table,
136};
137
138/* module stuff */
139static int __init umt_module_init(void)
140{
141 int result;
142 if ((result = usb_register(&umt_driver))) {
143 err("usb_register failed. Error number %d",result);
144 return result;
145 }
146
147 return 0;
148}
149
150static void __exit umt_module_exit(void)
151{
152 /* deregister this driver from the USB subsystem */
153 usb_deregister(&umt_driver);
154}
155
156module_init (umt_module_init);
157module_exit (umt_module_exit);
158
159MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
160MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device");
161MODULE_VERSION("1.0");
162MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c
new file mode 100644
index 000000000000..2746edfeccba
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c
@@ -0,0 +1,196 @@
1/* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to Twinhan who kindly provided hardware and information.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 *
14 */
15#include "vp7045.h"
16
17/* It is a Zarlink MT352 within a Samsung Tuner (DNOS404ZH102A) - 040929 - AAT
18 *
19 * Programming is hidden inside the firmware, so set_frontend is very easy.
20 * Even though there is a Firmware command that one can use to access the demod
21 * via its registers. This is used for status information.
22 */
23
24struct vp7045_fe_state {
25 struct dvb_frontend fe;
26 struct dvb_usb_device *d;
27};
28
29
30static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
31{
32 struct vp7045_fe_state *state = fe->demodulator_priv;
33 u8 s0 = vp7045_read_reg(state->d,0x00),
34 s1 = vp7045_read_reg(state->d,0x01),
35 s3 = vp7045_read_reg(state->d,0x03);
36
37 *status = 0;
38 if (s0 & (1 << 4))
39 *status |= FE_HAS_CARRIER;
40 if (s0 & (1 << 1))
41 *status |= FE_HAS_VITERBI;
42 if (s0 & (1 << 5))
43 *status |= FE_HAS_LOCK;
44 if (s1 & (1 << 1))
45 *status |= FE_HAS_SYNC;
46 if (s3 & (1 << 6))
47 *status |= FE_HAS_SIGNAL;
48
49 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
50 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
51 *status &= ~FE_HAS_LOCK;
52
53 return 0;
54}
55
56static int vp7045_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
57{
58 struct vp7045_fe_state *state = fe->demodulator_priv;
59 *ber = (vp7045_read_reg(state->d, 0x0D) << 16) |
60 (vp7045_read_reg(state->d, 0x0E) << 8) |
61 vp7045_read_reg(state->d, 0x0F);
62 return 0;
63}
64
65static int vp7045_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
66{
67 struct vp7045_fe_state *state = fe->demodulator_priv;
68 *unc = (vp7045_read_reg(state->d, 0x10) << 8) |
69 vp7045_read_reg(state->d, 0x11);
70 return 0;
71}
72
73static int vp7045_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
74{
75 struct vp7045_fe_state *state = fe->demodulator_priv;
76 u16 signal = (vp7045_read_reg(state->d, 0x14) << 8) |
77 vp7045_read_reg(state->d, 0x15);
78
79 *strength = ~signal;
80 return 0;
81}
82
83static int vp7045_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
84{
85 struct vp7045_fe_state *state = fe->demodulator_priv;
86 u8 _snr = vp7045_read_reg(state->d, 0x09);
87 *snr = (_snr << 8) | _snr;
88 return 0;
89}
90
91static int vp7045_fe_init(struct dvb_frontend* fe)
92{
93 return 0;
94}
95
96static int vp7045_fe_sleep(struct dvb_frontend* fe)
97{
98 return 0;
99}
100
101static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
102{
103 tune->min_delay_ms = 800;
104 return 0;
105}
106
107static int vp7045_fe_set_frontend(struct dvb_frontend* fe,
108 struct dvb_frontend_parameters *fep)
109{
110 struct vp7045_fe_state *state = fe->demodulator_priv;
111 u8 buf[5];
112 u32 freq = fep->frequency / 1000;
113
114 buf[0] = (freq >> 16) & 0xff;
115 buf[1] = (freq >> 8) & 0xff;
116 buf[2] = freq & 0xff;
117 buf[3] = 0;
118
119 switch (fep->u.ofdm.bandwidth) {
120 case BANDWIDTH_8_MHZ: buf[4] = 8; break;
121 case BANDWIDTH_7_MHZ: buf[4] = 7; break;
122 case BANDWIDTH_6_MHZ: buf[4] = 6; break;
123 case BANDWIDTH_AUTO: return -EOPNOTSUPP;
124 default:
125 return -EINVAL;
126 }
127
128 vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200);
129 return 0;
130}
131
132static int vp7045_fe_get_frontend(struct dvb_frontend* fe,
133 struct dvb_frontend_parameters *fep)
134{
135 return 0;
136}
137
138static void vp7045_fe_release(struct dvb_frontend* fe)
139{
140 struct vp7045_fe_state *state = fe->demodulator_priv;
141 kfree(state);
142}
143
144static struct dvb_frontend_ops vp7045_fe_ops;
145
146struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
147{
148 struct vp7045_fe_state *s = kmalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL);
149 if (s == NULL)
150 goto error;
151 memset(s,0,sizeof(struct vp7045_fe_state));
152
153 s->d = d;
154 s->fe.ops = &vp7045_fe_ops;
155 s->fe.demodulator_priv = s;
156
157 goto success;
158error:
159 return NULL;
160success:
161 return &s->fe;
162}
163
164
165static struct dvb_frontend_ops vp7045_fe_ops = {
166 .info = {
167 .name = "Twinhan VP7045/46 USB DVB-T",
168 .type = FE_OFDM,
169 .frequency_min = 44250000,
170 .frequency_max = 867250000,
171 .frequency_stepsize = 1000,
172 .caps = FE_CAN_INVERSION_AUTO |
173 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
174 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
175 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
176 FE_CAN_TRANSMISSION_MODE_AUTO |
177 FE_CAN_GUARD_INTERVAL_AUTO |
178 FE_CAN_RECOVER |
179 FE_CAN_HIERARCHY_AUTO,
180 },
181
182 .release = vp7045_fe_release,
183
184 .init = vp7045_fe_init,
185 .sleep = vp7045_fe_sleep,
186
187 .set_frontend = vp7045_fe_set_frontend,
188 .get_frontend = vp7045_fe_get_frontend,
189 .get_tune_settings = vp7045_fe_get_tune_settings,
190
191 .read_status = vp7045_fe_read_status,
192 .read_ber = vp7045_fe_read_ber,
193 .read_signal_strength = vp7045_fe_read_signal_strength,
194 .read_snr = vp7045_fe_read_snr,
195 .read_ucblocks = vp7045_fe_read_unc_blocks,
196};
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
new file mode 100644
index 000000000000..9ac95f54f9fc
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -0,0 +1,288 @@
1/* DVB USB compliant Linux driver for the
2 * - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver
3 * - DigitalNow TinyUSB2 DVB-t receiver
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * Thanks to Twinhan who kindly provided hardware and information.
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 "vp7045.h"
16
17/* debug */
18int dvb_usb_vp7045_debug;
19module_param_named(debug,dvb_usb_vp7045_debug, int, 0644);
20MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
21
22int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
23{
24 int ret = 0;
25 u8 inbuf[12] = { 0 }, outbuf[20] = { 0 };
26
27 outbuf[0] = cmd;
28
29 if (outlen > 19)
30 outlen = 19;
31
32 if (inlen > 11)
33 inlen = 11;
34
35 if (out != NULL && outlen > 0)
36 memcpy(&outbuf[1], out, outlen);
37
38 deb_xfer("out buffer: ");
39 debug_dump(outbuf,outlen+1,deb_xfer);
40
41 if ((ret = down_interruptible(&d->usb_sem)))
42 return ret;
43
44 if (usb_control_msg(d->udev,
45 usb_sndctrlpipe(d->udev,0),
46 TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
47 outbuf, 20, 2000) != 20) {
48 err("USB control message 'out' went wrong.");
49 ret = -EIO;
50 goto unlock;
51 }
52
53 msleep(msec);
54
55 if (usb_control_msg(d->udev,
56 usb_rcvctrlpipe(d->udev,0),
57 TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
58 inbuf, 12, 2000) != 12) {
59 err("USB control message 'in' went wrong.");
60 ret = -EIO;
61 goto unlock;
62 }
63
64 deb_xfer("in buffer: ");
65 debug_dump(inbuf,12,deb_xfer);
66
67 if (in != NULL && inlen > 0)
68 memcpy(in,&inbuf[1],inlen);
69
70unlock:
71 up(&d->usb_sem);
72
73 return ret;
74}
75
76u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg)
77{
78 u8 obuf[2] = { 0 },v;
79 obuf[1] = reg;
80
81 vp7045_usb_op(d,TUNER_REG_READ,obuf,2,&v,1,30);
82
83 return v;
84}
85
86static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
87{
88 u8 v = onoff;
89 return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150);
90}
91
92/* remote control stuff */
93
94/* The keymapping struct. Somehow this should be loaded to the driver, but
95 * currently it is hardcoded. */
96static struct dvb_usb_rc_key vp7045_rc_keys[] = {
97 { 0x00, 0x16, KEY_POWER },
98 { 0x00, 0x10, KEY_MUTE },
99 { 0x00, 0x03, KEY_1 },
100 { 0x00, 0x01, KEY_2 },
101 { 0x00, 0x06, KEY_3 },
102 { 0x00, 0x09, KEY_4 },
103 { 0x00, 0x1d, KEY_5 },
104 { 0x00, 0x1f, KEY_6 },
105 { 0x00, 0x0d, KEY_7 },
106 { 0x00, 0x19, KEY_8 },
107 { 0x00, 0x1b, KEY_9 },
108 { 0x00, 0x15, KEY_0 },
109 { 0x00, 0x05, KEY_CHANNELUP },
110 { 0x00, 0x02, KEY_CHANNELDOWN },
111 { 0x00, 0x1e, KEY_VOLUMEUP },
112 { 0x00, 0x0a, KEY_VOLUMEDOWN },
113 { 0x00, 0x11, KEY_RECORD },
114 { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
115 { 0x00, 0x14, KEY_PLAY },
116 { 0x00, 0x1a, KEY_STOP },
117 { 0x00, 0x40, KEY_REWIND },
118 { 0x00, 0x12, KEY_FASTFORWARD },
119 { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
120 { 0x00, 0x4c, KEY_PAUSE },
121 { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
122 { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
123 { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
124 { 0x00, 0x1c, KEY_EPG }, /* EPG */
125 { 0x00, 0x00, KEY_TAB }, /* Tab */
126 { 0x00, 0x48, KEY_INFO }, /* Preview */
127 { 0x00, 0x04, KEY_LIST }, /* RecordList */
128 { 0x00, 0x0f, KEY_TEXT } /* Teletext */
129};
130
131static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
132{
133 u8 key;
134 int i;
135 vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20);
136
137 deb_rc("remote query key: %x %d\n",key,key);
138
139 if (key == 0x44) {
140 *state = REMOTE_NO_KEY_PRESSED;
141 return 0;
142 }
143
144 for (i = 0; i < sizeof(vp7045_rc_keys)/sizeof(struct dvb_usb_rc_key); i++)
145 if (vp7045_rc_keys[i].data == key) {
146 *state = REMOTE_KEY_PRESSED;
147 *event = vp7045_rc_keys[i].event;
148 break;
149 }
150 return 0;
151}
152
153static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset)
154{
155 int i = 0;
156 u8 v,br[2];
157 for (i=0; i < len; i++) {
158 v = offset + i;
159 vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5);
160 buf[i] = br[1];
161 }
162 deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i);
163 debug_dump(buf,i,deb_info);
164 return 0;
165}
166
167
168static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
169{
170 return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
171}
172
173static int vp7045_frontend_attach(struct dvb_usb_device *d)
174{
175 u8 buf[255] = { 0 };
176
177 vp7045_usb_op(d,VENDOR_STRING_READ,NULL,0,buf,20,0);
178 buf[10] = '\0';
179 deb_info("firmware says: %s ",buf);
180
181 vp7045_usb_op(d,PRODUCT_STRING_READ,NULL,0,buf,20,0);
182 buf[10] = '\0';
183 deb_info("%s ",buf);
184
185 vp7045_usb_op(d,FW_VERSION_READ,NULL,0,buf,20,0);
186 buf[10] = '\0';
187 deb_info("v%s\n",buf);
188
189/* Dump the EEPROM */
190/* vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
191
192 d->fe = vp7045_fe_attach(d);
193
194 return 0;
195}
196
197static struct dvb_usb_properties vp7045_properties;
198
199static int vp7045_usb_probe(struct usb_interface *intf,
200 const struct usb_device_id *id)
201{
202 return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE);
203}
204
205static struct usb_device_id vp7045_usb_table [] = {
206 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_COLD) },
207 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_WARM) },
208 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_COLD) },
209 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_WARM) },
210 { 0 },
211};
212MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
213
214static struct dvb_usb_properties vp7045_properties = {
215 .caps = 0,
216
217 .usb_ctrl = CYPRESS_FX2,
218 .firmware = "dvb-usb-vp7045-01.fw",
219
220 .power_ctrl = vp7045_power_ctrl,
221 .frontend_attach = vp7045_frontend_attach,
222 .read_mac_address = vp7045_read_mac_addr,
223
224 .rc_interval = 400,
225 .rc_key_map = vp7045_rc_keys,
226 .rc_key_map_size = ARRAY_SIZE(vp7045_rc_keys),
227 .rc_query = vp7045_rc_query,
228
229 /* parameter for the MPEG2-data transfer */
230 .urb = {
231 .type = DVB_USB_BULK,
232 .count = 7,
233 .endpoint = 0x02,
234 .u = {
235 .bulk = {
236 .buffersize = 4096,
237 }
238 }
239 },
240
241 .num_device_descs = 2,
242 .devices = {
243 { .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)",
244 .cold_ids = { &vp7045_usb_table[0], NULL },
245 .warm_ids = { &vp7045_usb_table[1], NULL },
246 },
247 { .name = "DigitalNow TinyUSB 2 DVB-t Receiver",
248 .cold_ids = { &vp7045_usb_table[2], NULL },
249 .warm_ids = { &vp7045_usb_table[3], NULL },
250 },
251 { 0 },
252 }
253};
254
255/* usb specific object needed to register this driver with the usb subsystem */
256static struct usb_driver vp7045_usb_driver = {
257 .owner = THIS_MODULE,
258 .name = "dvb_usb_vp7045",
259 .probe = vp7045_usb_probe,
260 .disconnect = dvb_usb_device_exit,
261 .id_table = vp7045_usb_table,
262};
263
264/* module stuff */
265static int __init vp7045_usb_module_init(void)
266{
267 int result;
268 if ((result = usb_register(&vp7045_usb_driver))) {
269 err("usb_register failed. (%d)",result);
270 return result;
271 }
272
273 return 0;
274}
275
276static void __exit vp7045_usb_module_exit(void)
277{
278 /* deregister this driver from the USB subsystem */
279 usb_deregister(&vp7045_usb_driver);
280}
281
282module_init(vp7045_usb_module_init);
283module_exit(vp7045_usb_module_exit);
284
285MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
286MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0");
287MODULE_VERSION("1.0");
288MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp7045.h b/drivers/media/dvb/dvb-usb/vp7045.h
new file mode 100644
index 000000000000..9ce21a20fa86
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045.h
@@ -0,0 +1,78 @@
1/* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII
2 * USB2.0 DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to Twinhan who kindly provided hardware and information.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#ifndef _DVB_USB_VP7045_H_
15#define _DVB_USB_VP7045_H_
16
17#define DVB_USB_LOG_PREFIX "vp7045"
18#include "dvb-usb.h"
19
20extern int dvb_usb_vp7045_debug;
21#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
22#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
23#define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args)
24
25/* vp7045 commands */
26
27/* Twinhan Vendor requests */
28#define TH_COMMAND_IN 0xC0
29#define TH_COMMAND_OUT 0xC1
30
31/* command bytes */
32#define TUNER_REG_READ 0x03
33#define TUNER_REG_WRITE 0x04
34
35#define RC_VAL_READ 0x05
36 #define RC_NO_KEY 0x44
37
38#define SET_TUNER_POWER 0x06
39#define CHECK_TUNER_POWER 0x12
40 #define Tuner_Power_ON 1
41 #define Tuner_Power_OFF 0
42
43#define GET_USB_SPEED 0x07
44 #define USB_SPEED_LOW 0
45 #define USB_SPEED_FULL 1
46 #define USB_SPEED_HIGH 2
47
48#define LOCK_TUNER_COMMAND 0x09
49
50#define TUNER_SIGNAL_READ 0x0A
51
52/* FX2 eeprom */
53#define SET_EE_VALUE 0x10
54#define GET_EE_VALUE 0x11
55 #define FX2_ID_ADDR 0x00
56 #define VID_MSB_ADDR 0x02
57 #define VID_LSB_ADDR 0x01
58 #define PID_MSB_ADDR 0x04
59 #define PID_LSB_ADDR 0x03
60 #define MAC_0_ADDR 0x07
61 #define MAC_1_ADDR 0x08
62 #define MAC_2_ADDR 0x09
63 #define MAC_3_ADDR 0x0a
64 #define MAC_4_ADDR 0x0b
65 #define MAC_5_ADDR 0x0c
66
67#define RESET_FX2 0x13
68
69#define FW_VERSION_READ 0x0B
70#define VENDOR_STRING_READ 0x0C
71#define PRODUCT_STRING_READ 0x0D
72#define FW_BCD_VERSION_READ 0x14
73
74extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d);
75extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec);
76extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg);
77
78#endif