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/Kconfig42
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile10
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-remote.c2
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-script.h2
-rw-r--r--drivers/media/dvb/dvb-usb/af9005.c23
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c1474
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h524
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c30
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-core.c268
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-fe.c351
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2.h95
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c504
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c115
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c195
-rw-r--r--drivers/media/dvb/dvb-usb/dtv5100.c240
-rw-r--r--drivers/media/dvb/dvb-usb/dtv5100.h51
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h29
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c572
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.h1
20 files changed, 4404 insertions, 128 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index e84152b7576d..3c13bcfa6385 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -72,9 +72,11 @@ config DVB_USB_DIB0700
72 select DVB_DIB7000P 72 select DVB_DIB7000P
73 select DVB_DIB7000M 73 select DVB_DIB7000M
74 select DVB_DIB3000MC 74 select DVB_DIB3000MC
75 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
75 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE 76 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
76 select MEDIA_TUNER_MT2266 if !DVB_FE_CUSTOMISE 77 select MEDIA_TUNER_MT2266 if !DVB_FE_CUSTOMISE
77 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE 78 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE
79 select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
78 select DVB_TUNER_DIB0070 80 select DVB_TUNER_DIB0070
79 help 81 help
80 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The 82 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
@@ -108,6 +110,8 @@ config DVB_USB_CXUSB
108 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE 110 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
109 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE 111 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE
110 select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE 112 select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE
113 select DVB_DIB7000P if !DVB_FE_CUSTOMISE
114 select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
111 help 115 help
112 Say Y here to support the Conexant USB2.0 hybrid reference design. 116 Say Y here to support the Conexant USB2.0 hybrid reference design.
113 Currently, only DVB and ATSC modes are supported, analog mode 117 Currently, only DVB and ATSC modes are supported, analog mode
@@ -245,12 +249,25 @@ config DVB_USB_AF9005_REMOTE
245 Afatech AF9005 based receiver. 249 Afatech AF9005 based receiver.
246 250
247config DVB_USB_DW2102 251config DVB_USB_DW2102
248 tristate "DvbWorld 2102 DVB-S USB2.0 receiver" 252 tristate "DvbWorld DVB-S/S2 USB2.0 support"
249 depends on DVB_USB 253 depends on DVB_USB
250 select DVB_STV0299 if !DVB_FE_CUSTOMISE
251 select DVB_PLL if !DVB_FE_CUSTOMISE 254 select DVB_PLL if !DVB_FE_CUSTOMISE
255 select DVB_STV0299 if !DVB_FE_CUSTOMISE
256 select DVB_STV0288 if !DVB_FE_CUSTOMISE
257 select DVB_STB6000 if !DVB_FE_CUSTOMISE
258 select DVB_CX24116 if !DVB_FE_CUSTOMISE
259 select DVB_SI21XX if !DVB_FE_CUSTOMISE
252 help 260 help
253 Say Y here to support the DvbWorld 2102 DVB-S USB2.0 receiver. 261 Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
262 and the TeVii S650.
263
264config DVB_USB_CINERGY_T2
265 tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
266 depends on DVB_USB
267 help
268 Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
269
270 Say Y if you own such a device and want to use it.
254 271
255config DVB_USB_ANYSEE 272config DVB_USB_ANYSEE
256 tristate "Anysee DVB-T/C USB2.0 support" 273 tristate "Anysee DVB-T/C USB2.0 support"
@@ -262,3 +279,22 @@ config DVB_USB_ANYSEE
262 help 279 help
263 Say Y here to support the Anysee E30, Anysee E30 Plus or 280 Say Y here to support the Anysee E30, Anysee E30 Plus or
264 Anysee E30 C Plus DVB USB2.0 receiver. 281 Anysee E30 C Plus DVB USB2.0 receiver.
282
283config DVB_USB_DTV5100
284 tristate "AME DTV-5100 USB2.0 DVB-T support"
285 depends on DVB_USB
286 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
287 help
288 Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
289
290config DVB_USB_AF9015
291 tristate "Afatech AF9015 DVB-T USB2.0 support"
292 depends on DVB_USB && EXPERIMENTAL
293 select DVB_AF9013
294 select DVB_PLL if !DVB_FE_CUSTOMISE
295 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
296 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
297 select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMISE
298 select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE
299 help
300 Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index e206f1ea0027..3122b7cc2c23 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -67,6 +67,16 @@ obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
67dvb-usb-dw2102-objs = dw2102.o 67dvb-usb-dw2102-objs = dw2102.o
68obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o 68obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
69 69
70dvb-usb-dtv5100-objs = dtv5100.o
71obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
72
73dvb-usb-af9015-objs = af9015.o
74obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
75
76dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
77obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
78
79
70EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 80EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
71# due to tuner-xc3028 81# due to tuner-xc3028
72EXTRA_CFLAGS += -Idrivers/media/common/tuners 82EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c
index ff00c0e8f4a1..7c596f926764 100644
--- a/drivers/media/dvb/dvb-usb/af9005-remote.c
+++ b/drivers/media/dvb/dvb-usb/af9005-remote.c
@@ -25,7 +25,7 @@
25 */ 25 */
26#include "af9005.h" 26#include "af9005.h"
27/* debug */ 27/* debug */
28int dvb_usb_af9005_remote_debug; 28static int dvb_usb_af9005_remote_debug;
29module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644); 29module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644);
30MODULE_PARM_DESC(debug, 30MODULE_PARM_DESC(debug,
31 "enable (1) or disable (0) debug messages." 31 "enable (1) or disable (0) debug messages."
diff --git a/drivers/media/dvb/dvb-usb/af9005-script.h b/drivers/media/dvb/dvb-usb/af9005-script.h
index 6eeaae51b1ca..4d69045426dd 100644
--- a/drivers/media/dvb/dvb-usb/af9005-script.h
+++ b/drivers/media/dvb/dvb-usb/af9005-script.h
@@ -14,7 +14,7 @@ typedef struct {
14 u8 val; 14 u8 val;
15} RegDesc; 15} RegDesc;
16 16
17RegDesc script[] = { 17static RegDesc script[] = {
18 {0xa180, 0x0, 0x8, 0xa}, 18 {0xa180, 0x0, 0x8, 0xa},
19 {0xa181, 0x0, 0x8, 0xd7}, 19 {0xa181, 0x0, 0x8, 0xd7},
20 {0xa182, 0x0, 0x8, 0xa3}, 20 {0xa182, 0x0, 0x8, 0xa3},
diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c
index cfe71feefcad..ca5a0a4d2a47 100644
--- a/drivers/media/dvb/dvb-usb/af9005.c
+++ b/drivers/media/dvb/dvb-usb/af9005.c
@@ -35,17 +35,17 @@ module_param_named(led, dvb_usb_af9005_led, bool, 0644);
35MODULE_PARM_DESC(led, "enable led (default: 1)."); 35MODULE_PARM_DESC(led, "enable led (default: 1).");
36 36
37/* eeprom dump */ 37/* eeprom dump */
38int dvb_usb_af9005_dump_eeprom = 0; 38static int dvb_usb_af9005_dump_eeprom;
39module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0); 39module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0);
40MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom."); 40MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom.");
41 41
42DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 42DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
43 43
44/* remote control decoder */ 44/* remote control decoder */
45int (*rc_decode) (struct dvb_usb_device * d, u8 * data, int len, u32 * event, 45static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len,
46 int *state); 46 u32 *event, int *state);
47void *rc_keys; 47static void *rc_keys;
48int *rc_keys_size; 48static int *rc_keys_size;
49 49
50u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; 50u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
51 51
@@ -54,8 +54,8 @@ struct af9005_device_state {
54 int led_state; 54 int led_state;
55}; 55};
56 56
57int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 * wbuf, u16 wlen, 57static int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen,
58 u8 * rbuf, u16 rlen, int delay_ms) 58 u8 *rbuf, u16 rlen, int delay_ms)
59{ 59{
60 int actlen, ret = -ENOMEM; 60 int actlen, ret = -ENOMEM;
61 61
@@ -98,12 +98,7 @@ int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 * wbuf, u16 wlen,
98 return ret; 98 return ret;
99} 99}
100 100
101int af9005_usb_generic_write(struct dvb_usb_device *d, u8 * buf, u16 len) 101static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
102{
103 return af9005_usb_generic_rw(d, buf, len, NULL, 0, 0);
104}
105
106int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
107 int readwrite, int type, u8 * values, int len) 102 int readwrite, int type, u8 * values, int len)
108{ 103{
109 struct af9005_device_state *st = d->priv; 104 struct af9005_device_state *st = d->priv;
@@ -765,7 +760,7 @@ static int af9005_boot_packet(struct usb_device *udev, int type, u8 * reply)
765 return 0; 760 return 0;
766} 761}
767 762
768int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw) 763static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw)
769{ 764{
770 int i, packets, ret, act_len; 765 int i, packets, ret, act_len;
771 766
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
new file mode 100644
index 000000000000..cb0829c038ce
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -0,0 +1,1474 @@
1/*
2 * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include "af9015.h"
25#include "af9013.h"
26#include "mt2060.h"
27#include "qt1010.h"
28#include "tda18271.h"
29#include "mxl5005s.h"
30#if 0
31#include "mc44s80x.h"
32#endif
33
34int dvb_usb_af9015_debug;
35module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
36MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
37int dvb_usb_af9015_remote;
38module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
39MODULE_PARM_DESC(remote, "select remote");
40int dvb_usb_af9015_dual_mode;
41module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644);
42MODULE_PARM_DESC(dual_mode, "enable dual mode");
43DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
44
45static DEFINE_MUTEX(af9015_usb_mutex);
46
47static struct af9015_config af9015_config;
48static struct dvb_usb_device_properties af9015_properties[2];
49int af9015_properties_count = ARRAY_SIZE(af9015_properties);
50
51static struct af9013_config af9015_af9013_config[] = {
52 {
53 .demod_address = AF9015_I2C_DEMOD,
54 .output_mode = AF9013_OUTPUT_MODE_USB,
55 .api_version = { 0, 1, 9, 0 },
56 .gpio[0] = AF9013_GPIO_HI,
57 .gpio[3] = AF9013_GPIO_TUNER_ON,
58
59 }, {
60 .output_mode = AF9013_OUTPUT_MODE_SERIAL,
61 .api_version = { 0, 1, 9, 0 },
62 .gpio[0] = AF9013_GPIO_TUNER_ON,
63 .gpio[1] = AF9013_GPIO_LO,
64 }
65};
66
67static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
68{
69 int act_len, ret;
70 u8 buf[64];
71 u8 write = 1;
72 u8 msg_len = 8;
73 static u8 seq; /* packet sequence number */
74
75 if (mutex_lock_interruptible(&af9015_usb_mutex) < 0)
76 return -EAGAIN;
77
78 buf[0] = req->cmd;
79 buf[1] = seq++;
80 buf[2] = req->i2c_addr;
81 buf[3] = req->addr >> 8;
82 buf[4] = req->addr & 0xff;
83 buf[5] = req->mbox;
84 buf[6] = req->addr_len;
85 buf[7] = req->data_len;
86
87 switch (req->cmd) {
88 case GET_CONFIG:
89 case BOOT:
90 case READ_MEMORY:
91 case RECONNECT_USB:
92 case GET_IR_CODE:
93 write = 0;
94 break;
95 case READ_I2C:
96 write = 0;
97 buf[2] |= 0x01; /* set I2C direction */
98 case WRITE_I2C:
99 buf[0] = READ_WRITE_I2C;
100 break;
101 case WRITE_MEMORY:
102 if (((req->addr & 0xff00) == 0xff00) ||
103 ((req->addr & 0xae00) == 0xae00))
104 buf[0] = WRITE_VIRTUAL_MEMORY;
105 case WRITE_VIRTUAL_MEMORY:
106 case COPY_FIRMWARE:
107 case DOWNLOAD_FIRMWARE:
108 break;
109 default:
110 err("unknown command:%d", req->cmd);
111 ret = -1;
112 goto error_unlock;
113 }
114
115 /* write requested */
116 if (write) {
117 memcpy(&buf[8], req->data, req->data_len);
118 msg_len += req->data_len;
119 }
120 deb_xfer(">>> ");
121 debug_dump(buf, msg_len, deb_xfer);
122
123 /* send req */
124 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
125 &act_len, AF9015_USB_TIMEOUT);
126 if (ret)
127 err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len);
128 else
129 if (act_len != msg_len)
130 ret = -1; /* all data is not send */
131 if (ret)
132 goto error_unlock;
133
134 /* no ack for those packets */
135 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
136 goto exit_unlock;
137
138 /* receive ack and data if read req */
139 msg_len = 1 + 1 + req->data_len; /* seq + status + data len */
140 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
141 &act_len, AF9015_USB_TIMEOUT);
142 if (ret) {
143 err("recv bulk message failed:%d", ret);
144 ret = -1;
145 goto error_unlock;
146 }
147
148 deb_xfer("<<< ");
149 debug_dump(buf, act_len, deb_xfer);
150
151 /* remote controller query status is 1 if remote code is not received */
152 if (req->cmd == GET_IR_CODE && buf[1] == 1) {
153 buf[1] = 0; /* clear command "error" status */
154 memset(&buf[2], 0, req->data_len);
155 buf[3] = 1; /* no remote code received mark */
156 }
157
158 /* check status */
159 if (buf[1]) {
160 err("command failed:%d", buf[1]);
161 ret = -1;
162 goto error_unlock;
163 }
164
165 /* read request, copy returned data to return buf */
166 if (!write)
167 memcpy(req->data, &buf[2], req->data_len);
168
169error_unlock:
170exit_unlock:
171 mutex_unlock(&af9015_usb_mutex);
172
173 return ret;
174}
175
176static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
177{
178 return af9015_rw_udev(d->udev, req);
179}
180
181static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
182 u8 len)
183{
184 struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
185 val};
186 return af9015_ctrl_msg(d, &req);
187}
188
189static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
190{
191 return af9015_write_regs(d, addr, &val, 1);
192}
193
194static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
195{
196 struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, 1, val};
197 return af9015_ctrl_msg(d, &req);
198}
199
200static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
201 u8 val)
202{
203 struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
204
205 if (addr == af9015_af9013_config[0].demod_address ||
206 addr == af9015_af9013_config[1].demod_address)
207 req.addr_len = 3;
208
209 return af9015_ctrl_msg(d, &req);
210}
211
212static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
213 u8 *val)
214{
215 struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
216
217 if (addr == af9015_af9013_config[0].demod_address ||
218 addr == af9015_af9013_config[1].demod_address)
219 req.addr_len = 3;
220
221 return af9015_ctrl_msg(d, &req);
222}
223
224static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
225 int num)
226{
227 struct dvb_usb_device *d = i2c_get_adapdata(adap);
228 int ret = 0, i = 0;
229 u16 addr;
230 u8 mbox, addr_len;
231 struct req_t req;
232
233/* TODO: implement bus lock
234
235The bus lock is needed because there is two tuners both using same I2C-address.
236Due to that the only way to select correct tuner is use demodulator I2C-gate.
237
238................................................
239. AF9015 includes integrated AF9013 demodulator.
240. ____________ ____________ . ____________
241.| uC | | demod | . | tuner |
242.|------------| |------------| . |------------|
243.| AF9015 | | AF9013/5 | . | MXL5003 |
244.| |--+----I2C-------|-----/ -----|-.-----I2C-------| |
245.| | | | addr 0x38 | . | addr 0xc6 |
246.|____________| | |____________| . |____________|
247.................|..............................
248 | ____________ ____________
249 | | demod | | tuner |
250 | |------------| |------------|
251 | | AF9013 | | MXL5003 |
252 +----I2C-------|-----/ -----|-------I2C-------| |
253 | addr 0x3a | | addr 0xc6 |
254 |____________| |____________|
255*/
256 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
257 return -EAGAIN;
258
259 while (i < num) {
260 if (msg[i].addr == af9015_af9013_config[0].demod_address ||
261 msg[i].addr == af9015_af9013_config[1].demod_address) {
262 addr = msg[i].buf[0] << 8;
263 addr += msg[i].buf[1];
264 mbox = msg[i].buf[2];
265 addr_len = 3;
266 } else {
267 addr = msg[i].buf[0];
268 addr_len = 1;
269 mbox = 0;
270 }
271
272 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
273 if (msg[i].addr ==
274 af9015_af9013_config[0].demod_address)
275 req.cmd = READ_MEMORY;
276 else
277 req.cmd = READ_I2C;
278 req.i2c_addr = msg[i].addr;
279 req.addr = addr;
280 req.mbox = mbox;
281 req.addr_len = addr_len;
282 req.data_len = msg[i+1].len;
283 req.data = &msg[i+1].buf[0];
284 ret = af9015_ctrl_msg(d, &req);
285 i += 2;
286 } else {
287 if (msg[i].addr ==
288 af9015_af9013_config[0].demod_address)
289 req.cmd = WRITE_MEMORY;
290 else
291 req.cmd = WRITE_I2C;
292 req.i2c_addr = msg[i].addr;
293 req.addr = addr;
294 req.mbox = mbox;
295 req.addr_len = addr_len;
296 req.data_len = msg[i].len-addr_len;
297 req.data = &msg[i].buf[addr_len];
298 ret = af9015_ctrl_msg(d, &req);
299 i += 1;
300 }
301 if (ret)
302 goto error;
303
304 }
305 ret = i;
306
307error:
308 mutex_unlock(&d->i2c_mutex);
309
310 return ret;
311}
312
313static u32 af9015_i2c_func(struct i2c_adapter *adapter)
314{
315 return I2C_FUNC_I2C;
316}
317
318static struct i2c_algorithm af9015_i2c_algo = {
319 .master_xfer = af9015_i2c_xfer,
320 .functionality = af9015_i2c_func,
321};
322
323static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
324{
325 int ret;
326 u8 val, mask = 0x01;
327
328 ret = af9015_read_reg(d, addr, &val);
329 if (ret)
330 return ret;
331
332 mask <<= bit;
333 if (op) {
334 /* set bit */
335 val |= mask;
336 } else {
337 /* clear bit */
338 mask ^= 0xff;
339 val &= mask;
340 }
341
342 return af9015_write_reg(d, addr, val);
343}
344
345static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
346{
347 return af9015_do_reg_bit(d, addr, bit, 1);
348}
349
350static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
351{
352 return af9015_do_reg_bit(d, addr, bit, 0);
353}
354
355static int af9015_init_endpoint(struct dvb_usb_device *d)
356{
357 int ret;
358 u16 frame_size;
359 u8 packet_size;
360 deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
361
362#define TS_PACKET_SIZE 188
363
364#define TS_USB20_PACKET_COUNT 348
365#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
366
367#define TS_USB11_PACKET_COUNT 21
368#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
369
370#define TS_USB20_MAX_PACKET_SIZE 512
371#define TS_USB11_MAX_PACKET_SIZE 64
372
373 if (d->udev->speed == USB_SPEED_FULL) {
374 frame_size = TS_USB11_FRAME_SIZE/4;
375 packet_size = TS_USB11_MAX_PACKET_SIZE/4;
376 } else {
377 frame_size = TS_USB20_FRAME_SIZE/4;
378 packet_size = TS_USB20_MAX_PACKET_SIZE/4;
379 }
380
381 ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
382 if (ret)
383 goto error;
384 ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
385 if (ret)
386 goto error;
387 ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
388 if (ret)
389 goto error;
390 ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
391 if (ret)
392 goto error;
393 ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
394 if (ret)
395 goto error;
396 if (af9015_config.dual_mode) {
397 ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
398 if (ret)
399 goto error;
400 }
401 ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
402 if (ret)
403 goto error;
404 if (af9015_config.dual_mode) {
405 ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
406 if (ret)
407 goto error;
408 }
409 /* EP4 xfer length */
410 ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
411 if (ret)
412 goto error;
413 ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
414 if (ret)
415 goto error;
416 /* EP5 xfer length */
417 ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
418 if (ret)
419 goto error;
420 ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
421 if (ret)
422 goto error;
423 ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
424 if (ret)
425 goto error;
426 ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
427 if (ret)
428 goto error;
429 ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
430 if (ret)
431 goto error;
432 if (af9015_config.dual_mode) {
433 ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
434 if (ret)
435 goto error;
436 }
437
438 /* enable / disable mp2if2 */
439 if (af9015_config.dual_mode)
440 ret = af9015_set_reg_bit(d, 0xd50b, 0);
441 else
442 ret = af9015_clear_reg_bit(d, 0xd50b, 0);
443error:
444 if (ret)
445 err("endpoint init failed:%d", ret);
446 return ret;
447}
448
449static int af9015_copy_firmware(struct dvb_usb_device *d)
450{
451 int ret;
452 u8 fw_params[4];
453 u8 val, i;
454 struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
455 fw_params };
456 deb_info("%s:\n", __func__);
457
458 fw_params[0] = af9015_config.firmware_size >> 8;
459 fw_params[1] = af9015_config.firmware_size & 0xff;
460 fw_params[2] = af9015_config.firmware_checksum >> 8;
461 fw_params[3] = af9015_config.firmware_checksum & 0xff;
462
463 /* wait 2nd demodulator ready */
464 msleep(100);
465
466 ret = af9015_read_reg_i2c(d, 0x3a, 0x98be, &val);
467 if (ret)
468 goto error;
469 else
470 deb_info("%s: firmware status:%02x\n", __func__, val);
471
472 if (val == 0x0c) /* fw is running, no need for download */
473 goto exit;
474
475 /* set I2C master clock to fast (to speed up firmware copy) */
476 ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
477 if (ret)
478 goto error;
479
480 msleep(50);
481
482 /* copy firmware */
483 ret = af9015_ctrl_msg(d, &req);
484 if (ret)
485 err("firmware copy cmd failed:%d", ret);
486 deb_info("%s: firmware copy done\n", __func__);
487
488 /* set I2C master clock back to normal */
489 ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
490 if (ret)
491 goto error;
492
493 /* request boot firmware */
494 ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].demod_address,
495 0xe205, 1);
496 deb_info("%s: firmware boot cmd status:%d\n", __func__, ret);
497 if (ret)
498 goto error;
499
500 for (i = 0; i < 15; i++) {
501 msleep(100);
502
503 /* check firmware status */
504 ret = af9015_read_reg_i2c(d,
505 af9015_af9013_config[1].demod_address, 0x98be, &val);
506 deb_info("%s: firmware status cmd status:%d fw status:%02x\n",
507 __func__, ret, val);
508 if (ret)
509 goto error;
510
511 if (val == 0x0c || val == 0x04) /* success or fail */
512 break;
513 }
514
515 if (val == 0x04) {
516 err("firmware did not run");
517 ret = -1;
518 } else if (val != 0x0c) {
519 err("firmware boot timeout");
520 ret = -1;
521 }
522
523error:
524exit:
525 return ret;
526}
527
528/* dump eeprom */
529static int af9015_eeprom_dump(struct dvb_usb_device *d)
530{
531 char buf[52], buf2[4];
532 u8 reg, val;
533
534 for (reg = 0; ; reg++) {
535 if (reg % 16 == 0) {
536 if (reg)
537 deb_info("%s\n", buf);
538 sprintf(buf, "%02x: ", reg);
539 }
540 if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0)
541 sprintf(buf2, "%02x ", val);
542 else
543 strcpy(buf2, "-- ");
544 strcat(buf, buf2);
545 if (reg == 0xff)
546 break;
547 }
548 deb_info("%s\n", buf);
549 return 0;
550}
551
552int af9015_download_ir_table(struct dvb_usb_device *d)
553{
554 int i, packets = 0, ret;
555 u16 addr = 0x9a56; /* ir-table start address */
556 struct req_t req = {WRITE_MEMORY, 0, 0, 0, 0, 1, NULL};
557 u8 *data = NULL;
558 deb_info("%s:\n", __func__);
559
560 data = af9015_config.ir_table;
561 packets = af9015_config.ir_table_size;
562
563 /* no remote */
564 if (!packets)
565 goto exit;
566
567 /* load remote ir-table */
568 for (i = 0; i < packets; i++) {
569 req.addr = addr + i;
570 req.data = &data[i];
571 ret = af9015_ctrl_msg(d, &req);
572 if (ret) {
573 err("ir-table download failed at packet %d with " \
574 "code %d", i, ret);
575 return ret;
576 }
577 }
578
579exit:
580 return 0;
581}
582
583static int af9015_init(struct dvb_usb_device *d)
584{
585 int ret;
586 deb_info("%s:\n", __func__);
587
588 ret = af9015_init_endpoint(d);
589 if (ret)
590 goto error;
591
592 ret = af9015_download_ir_table(d);
593 if (ret)
594 goto error;
595
596error:
597 return ret;
598}
599
600static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
601{
602 int ret;
603 deb_info("%s: onoff:%d\n", __func__, onoff);
604
605 if (onoff)
606 ret = af9015_set_reg_bit(adap->dev, 0xd503, 0);
607 else
608 ret = af9015_clear_reg_bit(adap->dev, 0xd503, 0);
609
610 return ret;
611}
612
613static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
614 int onoff)
615{
616 int ret;
617 u8 idx;
618
619 deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
620 __func__, index, pid, onoff);
621
622 ret = af9015_write_reg(adap->dev, 0xd505, (pid & 0xff));
623 if (ret)
624 goto error;
625
626 ret = af9015_write_reg(adap->dev, 0xd506, (pid >> 8));
627 if (ret)
628 goto error;
629
630 idx = ((index & 0x1f) | (1 << 5));
631 ret = af9015_write_reg(adap->dev, 0xd504, idx);
632
633error:
634 return ret;
635}
636
637static int af9015_download_firmware(struct usb_device *udev,
638 const struct firmware *fw)
639{
640 int i, len, packets, remainder, ret;
641 struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
642 u16 addr = 0x5100; /* firmware start address */
643 u16 checksum = 0;
644
645 deb_info("%s:\n", __func__);
646
647 /* calc checksum */
648 for (i = 0; i < fw->size; i++)
649 checksum += fw->data[i];
650
651 af9015_config.firmware_size = fw->size;
652 af9015_config.firmware_checksum = checksum;
653
654 #define FW_PACKET_MAX_DATA 55
655
656 packets = fw->size / FW_PACKET_MAX_DATA;
657 remainder = fw->size % FW_PACKET_MAX_DATA;
658 len = FW_PACKET_MAX_DATA;
659 for (i = 0; i <= packets; i++) {
660 if (i == packets) /* set size of the last packet */
661 len = remainder;
662
663 req.data_len = len;
664 req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
665 req.addr = addr;
666 addr += FW_PACKET_MAX_DATA;
667
668 ret = af9015_rw_udev(udev, &req);
669 if (ret) {
670 err("firmware download failed at packet %d with " \
671 "code %d", i, ret);
672 goto error;
673 }
674 }
675
676 /* firmware loaded, request boot */
677 req.cmd = BOOT;
678 ret = af9015_rw_udev(udev, &req);
679 if (ret) {
680 err("firmware boot failed:%d", ret);
681 goto error;
682 }
683
684 /* firmware is running, reconnect device in the usb bus */
685 req.cmd = RECONNECT_USB;
686 ret = af9015_rw_udev(udev, &req);
687 if (ret)
688 err("reconnect failed: %d", ret);
689
690error:
691 return ret;
692}
693
694static int af9015_read_config(struct usb_device *udev)
695{
696 int ret;
697 u8 val, i, offset = 0;
698 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
699 char manufacturer[10];
700
701 /* IR remote controller */
702 req.addr = AF9015_EEPROM_IR_MODE;
703 ret = af9015_rw_udev(udev, &req);
704 if (ret)
705 goto error;
706 deb_info("%s: IR mode:%d\n", __func__, val);
707 for (i = 0; i < af9015_properties_count; i++) {
708 if (val == AF9015_IR_MODE_DISABLED || val == 0x04) {
709 af9015_properties[i].rc_key_map = NULL;
710 af9015_properties[i].rc_key_map_size = 0;
711 } else if (dvb_usb_af9015_remote) {
712 /* load remote defined as module param */
713 switch (dvb_usb_af9015_remote) {
714 case AF9015_REMOTE_A_LINK_DTU_M:
715 af9015_properties[i].rc_key_map =
716 af9015_rc_keys_a_link;
717 af9015_properties[i].rc_key_map_size =
718 ARRAY_SIZE(af9015_rc_keys_a_link);
719 af9015_config.ir_table = af9015_ir_table_a_link;
720 af9015_config.ir_table_size =
721 ARRAY_SIZE(af9015_ir_table_a_link);
722 break;
723 case AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3:
724 af9015_properties[i].rc_key_map =
725 af9015_rc_keys_msi;
726 af9015_properties[i].rc_key_map_size =
727 ARRAY_SIZE(af9015_rc_keys_msi);
728 af9015_config.ir_table = af9015_ir_table_msi;
729 af9015_config.ir_table_size =
730 ARRAY_SIZE(af9015_ir_table_msi);
731 break;
732 case AF9015_REMOTE_MYGICTV_U718:
733 af9015_properties[i].rc_key_map =
734 af9015_rc_keys_mygictv;
735 af9015_properties[i].rc_key_map_size =
736 ARRAY_SIZE(af9015_rc_keys_mygictv);
737 af9015_config.ir_table =
738 af9015_ir_table_mygictv;
739 af9015_config.ir_table_size =
740 ARRAY_SIZE(af9015_ir_table_mygictv);
741 break;
742 }
743 } else {
744 switch (udev->descriptor.idVendor) {
745 case USB_VID_LEADTEK:
746 af9015_properties[i].rc_key_map =
747 af9015_rc_keys_leadtek;
748 af9015_properties[i].rc_key_map_size =
749 ARRAY_SIZE(af9015_rc_keys_leadtek);
750 af9015_config.ir_table =
751 af9015_ir_table_leadtek;
752 af9015_config.ir_table_size =
753 ARRAY_SIZE(af9015_ir_table_leadtek);
754 break;
755 case USB_VID_VISIONPLUS:
756 if (udev->descriptor.idProduct ==
757 USB_PID_AZUREWAVE_AD_TU700) {
758 af9015_properties[i].rc_key_map =
759 af9015_rc_keys_twinhan;
760 af9015_properties[i].rc_key_map_size =
761 ARRAY_SIZE(af9015_rc_keys_twinhan);
762 af9015_config.ir_table =
763 af9015_ir_table_twinhan;
764 af9015_config.ir_table_size =
765 ARRAY_SIZE(af9015_ir_table_twinhan);
766 }
767 break;
768 case USB_VID_KWORLD_2:
769 /* TODO: use correct rc keys */
770 af9015_properties[i].rc_key_map =
771 af9015_rc_keys_twinhan;
772 af9015_properties[i].rc_key_map_size =
773 ARRAY_SIZE(af9015_rc_keys_twinhan);
774 af9015_config.ir_table = af9015_ir_table_kworld;
775 af9015_config.ir_table_size =
776 ARRAY_SIZE(af9015_ir_table_kworld);
777 break;
778 /* Check USB manufacturer and product strings and try
779 to determine correct remote in case of chip vendor
780 reference IDs are used. */
781 case USB_VID_AFATECH:
782 memset(manufacturer, 0, sizeof(manufacturer));
783 usb_string(udev, udev->descriptor.iManufacturer,
784 manufacturer, sizeof(manufacturer));
785 if (!strcmp("Geniatech", manufacturer)) {
786 /* iManufacturer 1 Geniatech
787 iProduct 2 AF9015 */
788 af9015_properties[i].rc_key_map =
789 af9015_rc_keys_mygictv;
790 af9015_properties[i].rc_key_map_size =
791 ARRAY_SIZE(af9015_rc_keys_mygictv);
792 af9015_config.ir_table =
793 af9015_ir_table_mygictv;
794 af9015_config.ir_table_size =
795 ARRAY_SIZE(af9015_ir_table_mygictv);
796 } else if (!strcmp("MSI", manufacturer)) {
797 /* iManufacturer 1 MSI
798 iProduct 2 MSI K-VOX */
799 af9015_properties[i].rc_key_map =
800 af9015_rc_keys_msi;
801 af9015_properties[i].rc_key_map_size =
802 ARRAY_SIZE(af9015_rc_keys_msi);
803 af9015_config.ir_table =
804 af9015_ir_table_msi;
805 af9015_config.ir_table_size =
806 ARRAY_SIZE(af9015_ir_table_msi);
807 }
808 break;
809 }
810 }
811 }
812
813 /* TS mode - one or two receivers */
814 req.addr = AF9015_EEPROM_TS_MODE;
815 ret = af9015_rw_udev(udev, &req);
816 if (ret)
817 goto error;
818 af9015_config.dual_mode = val;
819 deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode);
820 /* disable dual mode by default because it is buggy */
821 if (!dvb_usb_af9015_dual_mode)
822 af9015_config.dual_mode = 0;
823
824 /* set buffer size according to USB port speed */
825 for (i = 0; i < af9015_properties_count; i++) {
826 /* USB1.1 set smaller buffersize and disable 2nd adapter */
827 if (udev->speed == USB_SPEED_FULL) {
828 af9015_properties[i].adapter->stream.u.bulk.buffersize =
829 TS_USB11_MAX_PACKET_SIZE;
830 /* disable 2nd adapter because we don't have
831 PID-filters */
832 af9015_config.dual_mode = 0;
833 } else {
834 af9015_properties[i].adapter->stream.u.bulk.buffersize =
835 TS_USB20_MAX_PACKET_SIZE;
836 }
837 }
838
839 if (af9015_config.dual_mode) {
840 /* read 2nd demodulator I2C address */
841 req.addr = AF9015_EEPROM_DEMOD2_I2C;
842 ret = af9015_rw_udev(udev, &req);
843 if (ret)
844 goto error;
845 af9015_af9013_config[1].demod_address = val;
846
847 /* enable 2nd adapter */
848 for (i = 0; i < af9015_properties_count; i++)
849 af9015_properties[i].num_adapters = 2;
850
851 } else {
852 /* disable 2nd adapter */
853 for (i = 0; i < af9015_properties_count; i++)
854 af9015_properties[i].num_adapters = 1;
855 }
856
857 for (i = 0; i < af9015_properties[0].num_adapters; i++) {
858 if (i == 1)
859 offset = AF9015_EEPROM_OFFSET;
860 /* xtal */
861 req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
862 ret = af9015_rw_udev(udev, &req);
863 if (ret)
864 goto error;
865 switch (val) {
866 case 0:
867 af9015_af9013_config[i].adc_clock = 28800;
868 break;
869 case 1:
870 af9015_af9013_config[i].adc_clock = 20480;
871 break;
872 case 2:
873 af9015_af9013_config[i].adc_clock = 28000;
874 break;
875 case 3:
876 af9015_af9013_config[i].adc_clock = 25000;
877 break;
878 };
879 deb_info("%s: [%d] xtal:%d set adc_clock:%d\n", __func__, i,
880 val, af9015_af9013_config[i].adc_clock);
881
882 /* tuner IF */
883 req.addr = AF9015_EEPROM_IF1H + offset;
884 ret = af9015_rw_udev(udev, &req);
885 if (ret)
886 goto error;
887 af9015_af9013_config[i].tuner_if = val << 8;
888 req.addr = AF9015_EEPROM_IF1L + offset;
889 ret = af9015_rw_udev(udev, &req);
890 if (ret)
891 goto error;
892 af9015_af9013_config[i].tuner_if += val;
893 deb_info("%s: [%d] IF1:%d\n", __func__, i,
894 af9015_af9013_config[0].tuner_if);
895
896 /* MT2060 IF1 */
897 req.addr = AF9015_EEPROM_MT2060_IF1H + offset;
898 ret = af9015_rw_udev(udev, &req);
899 if (ret)
900 goto error;
901 af9015_config.mt2060_if1[i] = val << 8;
902 req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
903 ret = af9015_rw_udev(udev, &req);
904 if (ret)
905 goto error;
906 af9015_config.mt2060_if1[i] += val;
907 deb_info("%s: [%d] MT2060 IF1:%d\n", __func__, i,
908 af9015_config.mt2060_if1[i]);
909
910 /* tuner */
911 req.addr = AF9015_EEPROM_TUNER_ID1 + offset;
912 ret = af9015_rw_udev(udev, &req);
913 if (ret)
914 goto error;
915 switch (val) {
916 case AF9013_TUNER_ENV77H11D5:
917 case AF9013_TUNER_MT2060:
918 case AF9013_TUNER_MC44S803:
919 case AF9013_TUNER_QT1010:
920 case AF9013_TUNER_UNKNOWN:
921 case AF9013_TUNER_MT2060_2:
922 case AF9013_TUNER_TDA18271:
923 case AF9013_TUNER_QT1010A:
924 af9015_af9013_config[i].rf_spec_inv = 1;
925 break;
926 case AF9013_TUNER_MXL5003D:
927 case AF9013_TUNER_MXL5005D:
928 case AF9013_TUNER_MXL5005R:
929 af9015_af9013_config[i].rf_spec_inv = 0;
930 break;
931 default:
932 warn("tuner id:%d not supported, please report!", val);
933 return -ENODEV;
934 };
935
936 af9015_af9013_config[i].tuner = val;
937 deb_info("%s: [%d] tuner id:%d\n", __func__, i, val);
938 }
939
940error:
941 if (ret)
942 err("eeprom read failed:%d", ret);
943
944 return ret;
945}
946
947static int af9015_identify_state(struct usb_device *udev,
948 struct dvb_usb_device_properties *props,
949 struct dvb_usb_device_description **desc,
950 int *cold)
951{
952 int ret;
953 u8 reply;
954 struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
955
956 ret = af9015_rw_udev(udev, &req);
957 if (ret)
958 return ret;
959
960 deb_info("%s: reply:%02x\n", __func__, reply);
961 if (reply == 0x02)
962 *cold = 0;
963 else
964 *cold = 1;
965
966 return ret;
967}
968
969static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
970{
971 u8 buf[8];
972 struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf};
973 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
974 int i, ret;
975
976 memset(buf, 0, sizeof(buf));
977
978 ret = af9015_ctrl_msg(d, &req);
979 if (ret)
980 return ret;
981
982 *event = 0;
983 *state = REMOTE_NO_KEY_PRESSED;
984
985 for (i = 0; i < d->props.rc_key_map_size; i++) {
986 if (!buf[1] && keymap[i].custom == buf[0] &&
987 keymap[i].data == buf[2]) {
988 *event = keymap[i].event;
989 *state = REMOTE_KEY_PRESSED;
990 break;
991 }
992 }
993 if (!buf[1])
994 deb_rc("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n",
995 __func__, buf[0], buf[1], buf[2], buf[3], buf[4],
996 buf[5], buf[6], buf[7]);
997
998 return 0;
999}
1000
1001/* init 2nd I2C adapter */
1002int af9015_i2c_init(struct dvb_usb_device *d)
1003{
1004 int ret;
1005 struct af9015_state *state = d->priv;
1006 deb_info("%s:\n", __func__);
1007
1008 strncpy(state->i2c_adap.name, d->desc->name,
1009 sizeof(state->i2c_adap.name));
1010#ifdef I2C_ADAP_CLASS_TV_DIGITAL
1011 state->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
1012#else
1013 state->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
1014#endif
1015 state->i2c_adap.algo = d->props.i2c_algo;
1016 state->i2c_adap.algo_data = NULL;
1017 state->i2c_adap.dev.parent = &d->udev->dev;
1018
1019 i2c_set_adapdata(&state->i2c_adap, d);
1020
1021 ret = i2c_add_adapter(&state->i2c_adap);
1022 if (ret < 0)
1023 err("could not add i2c adapter");
1024
1025 return ret;
1026}
1027
1028static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
1029{
1030 int ret;
1031 struct af9015_state *state = adap->dev->priv;
1032 struct i2c_adapter *i2c_adap;
1033
1034 if (adap->id == 0) {
1035 /* select I2C adapter */
1036 i2c_adap = &adap->dev->i2c_adap;
1037
1038 deb_info("%s: init I2C\n", __func__);
1039 ret = af9015_i2c_init(adap->dev);
1040
1041 /* dump eeprom (debug) */
1042 ret = af9015_eeprom_dump(adap->dev);
1043 if (ret)
1044 return ret;
1045 } else {
1046 /* select I2C adapter */
1047 i2c_adap = &state->i2c_adap;
1048
1049 /* copy firmware to 2nd demodulator */
1050 if (af9015_config.dual_mode) {
1051 ret = af9015_copy_firmware(adap->dev);
1052 if (ret) {
1053 err("firmware copy to 2nd frontend " \
1054 "failed, will disable it");
1055 af9015_config.dual_mode = 0;
1056 return -ENODEV;
1057 }
1058 } else {
1059 return -ENODEV;
1060 }
1061 }
1062
1063 /* attach demodulator */
1064 adap->fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id],
1065 i2c_adap);
1066
1067 return adap->fe == NULL ? -ENODEV : 0;
1068}
1069
1070static struct mt2060_config af9015_mt2060_config = {
1071 .i2c_address = 0xc0,
1072 .clock_out = 0,
1073};
1074
1075static struct qt1010_config af9015_qt1010_config = {
1076 .i2c_address = 0xc4,
1077};
1078
1079static struct tda18271_config af9015_tda18271_config = {
1080 .gate = TDA18271_GATE_DIGITAL,
1081 .small_i2c = 1,
1082};
1083
1084static struct mxl5005s_config af9015_mxl5003_config = {
1085 .i2c_address = 0xc6,
1086 .if_freq = IF_FREQ_4570000HZ,
1087 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1088 .agc_mode = MXL_SINGLE_AGC,
1089 .tracking_filter = MXL_TF_DEFAULT,
1090 .rssi_enable = MXL_RSSI_ENABLE,
1091 .cap_select = MXL_CAP_SEL_ENABLE,
1092 .div_out = MXL_DIV_OUT_4,
1093 .clock_out = MXL_CLOCK_OUT_DISABLE,
1094 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1095 .top = MXL5005S_TOP_25P2,
1096 .mod_mode = MXL_DIGITAL_MODE,
1097 .if_mode = MXL_ZERO_IF,
1098 .AgcMasterByte = 0x00,
1099};
1100
1101static struct mxl5005s_config af9015_mxl5005_config = {
1102 .i2c_address = 0xc6,
1103 .if_freq = IF_FREQ_4570000HZ,
1104 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1105 .agc_mode = MXL_SINGLE_AGC,
1106 .tracking_filter = MXL_TF_OFF,
1107 .rssi_enable = MXL_RSSI_ENABLE,
1108 .cap_select = MXL_CAP_SEL_ENABLE,
1109 .div_out = MXL_DIV_OUT_4,
1110 .clock_out = MXL_CLOCK_OUT_DISABLE,
1111 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1112 .top = MXL5005S_TOP_25P2,
1113 .mod_mode = MXL_DIGITAL_MODE,
1114 .if_mode = MXL_ZERO_IF,
1115 .AgcMasterByte = 0x00,
1116};
1117
1118static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
1119{
1120 struct af9015_state *state = adap->dev->priv;
1121 struct i2c_adapter *i2c_adap;
1122 int ret;
1123 deb_info("%s: \n", __func__);
1124
1125 /* select I2C adapter */
1126 if (adap->id == 0)
1127 i2c_adap = &adap->dev->i2c_adap;
1128 else
1129 i2c_adap = &state->i2c_adap;
1130
1131 switch (af9015_af9013_config[adap->id].tuner) {
1132 case AF9013_TUNER_MT2060:
1133 case AF9013_TUNER_MT2060_2:
1134 ret = dvb_attach(mt2060_attach, adap->fe, i2c_adap,
1135 &af9015_mt2060_config,
1136 af9015_config.mt2060_if1[adap->id])
1137 == NULL ? -ENODEV : 0;
1138 break;
1139 case AF9013_TUNER_QT1010:
1140 case AF9013_TUNER_QT1010A:
1141 ret = dvb_attach(qt1010_attach, adap->fe, i2c_adap,
1142 &af9015_qt1010_config) == NULL ? -ENODEV : 0;
1143 break;
1144 case AF9013_TUNER_TDA18271:
1145 ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap,
1146 &af9015_tda18271_config) == NULL ? -ENODEV : 0;
1147 break;
1148 case AF9013_TUNER_MXL5003D:
1149 ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap,
1150 &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
1151 break;
1152 case AF9013_TUNER_MXL5005D:
1153 case AF9013_TUNER_MXL5005R:
1154 ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap,
1155 &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
1156 break;
1157 case AF9013_TUNER_ENV77H11D5:
1158 ret = dvb_attach(dvb_pll_attach, adap->fe, 0xc0, i2c_adap,
1159 DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
1160 break;
1161 case AF9013_TUNER_MC44S803:
1162#if 0
1163 ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap)
1164 == NULL ? -ENODEV : 0;
1165#else
1166 ret = -ENODEV;
1167 info("Freescale MC44S803 tuner found but no driver for that" \
1168 "tuner. Look at the Linuxtv.org for tuner driver" \
1169 "status.");
1170#endif
1171 break;
1172 case AF9013_TUNER_UNKNOWN:
1173 default:
1174 ret = -ENODEV;
1175 err("Unknown tuner id:%d",
1176 af9015_af9013_config[adap->id].tuner);
1177 }
1178 return ret;
1179}
1180
1181static struct usb_device_id af9015_usb_table[] = {
1182/* 0 */{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)},
1183 {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)},
1184 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)},
1185 {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)},
1186 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)},
1187/* 5 */{USB_DEVICE(USB_VID_VISIONPLUS,
1188 USB_PID_TINYTWIN)},
1189 {USB_DEVICE(USB_VID_VISIONPLUS,
1190 USB_PID_AZUREWAVE_AD_TU700)},
1191 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)},
1192 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)},
1193 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)},
1194/* 10 */{USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)},
1195 {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)},
1196 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)},
1197 {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
1198 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
1199/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
1200 {0},
1201};
1202MODULE_DEVICE_TABLE(usb, af9015_usb_table);
1203
1204static struct dvb_usb_device_properties af9015_properties[] = {
1205 {
1206 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1207
1208 .usb_ctrl = DEVICE_SPECIFIC,
1209 .download_firmware = af9015_download_firmware,
1210 .firmware = "dvb-usb-af9015.fw",
1211
1212 .size_of_priv = sizeof(struct af9015_state), \
1213
1214 .num_adapters = 2,
1215 .adapter = {
1216 {
1217 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1218 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1219
1220 .pid_filter_count = 32,
1221 .pid_filter = af9015_pid_filter,
1222 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1223
1224 .frontend_attach =
1225 af9015_af9013_frontend_attach,
1226 .tuner_attach = af9015_tuner_attach,
1227 .stream = {
1228 .type = USB_BULK,
1229 .count = 6,
1230 .endpoint = 0x84,
1231 },
1232 },
1233 {
1234 .frontend_attach =
1235 af9015_af9013_frontend_attach,
1236 .tuner_attach = af9015_tuner_attach,
1237 .stream = {
1238 .type = USB_BULK,
1239 .count = 6,
1240 .endpoint = 0x85,
1241 },
1242 }
1243 },
1244
1245 .identify_state = af9015_identify_state,
1246
1247 .rc_query = af9015_rc_query,
1248 .rc_interval = 150,
1249
1250 .i2c_algo = &af9015_i2c_algo,
1251
1252 .num_device_descs = 9,
1253 .devices = {
1254 {
1255 .name = "Afatech AF9015 DVB-T USB2.0 stick",
1256 .cold_ids = {&af9015_usb_table[0],
1257 &af9015_usb_table[1], NULL},
1258 .warm_ids = {NULL},
1259 },
1260 {
1261 .name = "Leadtek WinFast DTV Dongle Gold",
1262 .cold_ids = {&af9015_usb_table[2], NULL},
1263 .warm_ids = {NULL},
1264 },
1265 {
1266 .name = "Pinnacle PCTV 71e",
1267 .cold_ids = {&af9015_usb_table[3], NULL},
1268 .warm_ids = {NULL},
1269 },
1270 {
1271 .name = "KWorld PlusTV Dual DVB-T Stick " \
1272 "(DVB-T 399U)",
1273 .cold_ids = {&af9015_usb_table[4], NULL},
1274 .warm_ids = {NULL},
1275 },
1276 {
1277 .name = "DigitalNow TinyTwin DVB-T Receiver",
1278 .cold_ids = {&af9015_usb_table[5], NULL},
1279 .warm_ids = {NULL},
1280 },
1281 {
1282 .name = "TwinHan AzureWave AD-TU700(704J)",
1283 .cold_ids = {&af9015_usb_table[6], NULL},
1284 .warm_ids = {NULL},
1285 },
1286 {
1287 .name = "TerraTec Cinergy T USB XE",
1288 .cold_ids = {&af9015_usb_table[7], NULL},
1289 .warm_ids = {NULL},
1290 },
1291 {
1292 .name = "KWorld PlusTV Dual DVB-T PCI " \
1293 "(DVB-T PC160-2T)",
1294 .cold_ids = {&af9015_usb_table[8], NULL},
1295 .warm_ids = {NULL},
1296 },
1297 {
1298 .name = "AVerMedia AVerTV DVB-T Volar X",
1299 .cold_ids = {&af9015_usb_table[9], NULL},
1300 .warm_ids = {NULL},
1301 },
1302 }
1303 }, {
1304 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1305
1306 .usb_ctrl = DEVICE_SPECIFIC,
1307 .download_firmware = af9015_download_firmware,
1308 .firmware = "dvb-usb-af9015.fw",
1309
1310 .size_of_priv = sizeof(struct af9015_state), \
1311
1312 .num_adapters = 2,
1313 .adapter = {
1314 {
1315 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1316 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1317
1318 .pid_filter_count = 32,
1319 .pid_filter = af9015_pid_filter,
1320 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1321
1322 .frontend_attach =
1323 af9015_af9013_frontend_attach,
1324 .tuner_attach = af9015_tuner_attach,
1325 .stream = {
1326 .type = USB_BULK,
1327 .count = 6,
1328 .endpoint = 0x84,
1329 },
1330 },
1331 {
1332 .frontend_attach =
1333 af9015_af9013_frontend_attach,
1334 .tuner_attach = af9015_tuner_attach,
1335 .stream = {
1336 .type = USB_BULK,
1337 .count = 6,
1338 .endpoint = 0x85,
1339 },
1340 }
1341 },
1342
1343 .identify_state = af9015_identify_state,
1344
1345 .rc_query = af9015_rc_query,
1346 .rc_interval = 150,
1347
1348 .i2c_algo = &af9015_i2c_algo,
1349
1350 .num_device_descs = 6,
1351 .devices = {
1352 {
1353 .name = "Xtensions XD-380",
1354 .cold_ids = {&af9015_usb_table[10], NULL},
1355 .warm_ids = {NULL},
1356 },
1357 {
1358 .name = "MSI DIGIVOX Duo",
1359 .cold_ids = {&af9015_usb_table[11], NULL},
1360 .warm_ids = {NULL},
1361 },
1362 {
1363 .name = "Fujitsu-Siemens Slim Mobile USB DVB-T",
1364 .cold_ids = {&af9015_usb_table[12], NULL},
1365 .warm_ids = {NULL},
1366 },
1367 {
1368 .name = "Telestar Starstick 2",
1369 .cold_ids = {&af9015_usb_table[13], NULL},
1370 .warm_ids = {NULL},
1371 },
1372 {
1373 .name = "AVerMedia A309",
1374 .cold_ids = {&af9015_usb_table[14], NULL},
1375 .warm_ids = {NULL},
1376 },
1377 {
1378 .name = "MSI Digi VOX mini III",
1379 .cold_ids = {&af9015_usb_table[15], NULL},
1380 .warm_ids = {NULL},
1381 },
1382 }
1383 }
1384};
1385
1386static int af9015_usb_probe(struct usb_interface *intf,
1387 const struct usb_device_id *id)
1388{
1389 int ret = 0;
1390 struct dvb_usb_device *d = NULL;
1391 struct usb_device *udev = interface_to_usbdev(intf);
1392 u8 i;
1393
1394 deb_info("%s: interface:%d\n", __func__,
1395 intf->cur_altsetting->desc.bInterfaceNumber);
1396
1397 /* interface 0 is used by DVB-T receiver and
1398 interface 1 is for remote controller (HID) */
1399 if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
1400 ret = af9015_read_config(udev);
1401 if (ret)
1402 return ret;
1403
1404 for (i = 0; i < af9015_properties_count; i++) {
1405 ret = dvb_usb_device_init(intf, &af9015_properties[i],
1406 THIS_MODULE, &d, adapter_nr);
1407 if (!ret)
1408 break;
1409 if (ret != -ENODEV)
1410 return ret;
1411 }
1412 if (ret)
1413 return ret;
1414
1415 if (d)
1416 ret = af9015_init(d);
1417 }
1418
1419 return ret;
1420}
1421
1422void af9015_i2c_exit(struct dvb_usb_device *d)
1423{
1424 struct af9015_state *state = d->priv;
1425 deb_info("%s: \n", __func__);
1426
1427 /* remove 2nd I2C adapter */
1428 if (d->state & DVB_USB_STATE_I2C)
1429 i2c_del_adapter(&state->i2c_adap);
1430}
1431
1432static void af9015_usb_device_exit(struct usb_interface *intf)
1433{
1434 struct dvb_usb_device *d = usb_get_intfdata(intf);
1435 deb_info("%s: \n", __func__);
1436
1437 /* remove 2nd I2C adapter */
1438 if (d != NULL && d->desc != NULL)
1439 af9015_i2c_exit(d);
1440
1441 dvb_usb_device_exit(intf);
1442}
1443
1444/* usb specific object needed to register this driver with the usb subsystem */
1445static struct usb_driver af9015_usb_driver = {
1446 .name = "dvb_usb_af9015",
1447 .probe = af9015_usb_probe,
1448 .disconnect = af9015_usb_device_exit,
1449 .id_table = af9015_usb_table,
1450};
1451
1452/* module stuff */
1453static int __init af9015_usb_module_init(void)
1454{
1455 int ret;
1456 ret = usb_register(&af9015_usb_driver);
1457 if (ret)
1458 err("module init failed:%d", ret);
1459
1460 return ret;
1461}
1462
1463static void __exit af9015_usb_module_exit(void)
1464{
1465 /* deregister this driver from the USB subsystem */
1466 usb_deregister(&af9015_usb_driver);
1467}
1468
1469module_init(af9015_usb_module_init);
1470module_exit(af9015_usb_module_exit);
1471
1472MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1473MODULE_DESCRIPTION("Driver for Afatech AF9015 DVB-T");
1474MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
new file mode 100644
index 000000000000..882e8a4b3681
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -0,0 +1,524 @@
1/*
2 * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#ifndef _DVB_USB_AF9015_H_
25#define _DVB_USB_AF9015_H_
26
27#define DVB_USB_LOG_PREFIX "af9015"
28#include "dvb-usb.h"
29
30extern int dvb_usb_af9015_debug;
31#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args)
32#define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args)
33#define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args)
34#define deb_reg(args...) dprintk(dvb_usb_af9015_debug, 0x08, args)
35#define deb_i2c(args...) dprintk(dvb_usb_af9015_debug, 0x10, args)
36#define deb_fw(args...) dprintk(dvb_usb_af9015_debug, 0x20, args)
37
38#define AF9015_I2C_EEPROM 0xa0
39#define AF9015_I2C_DEMOD 0x38
40#define AF9015_USB_TIMEOUT 2000
41
42/* EEPROM locations */
43#define AF9015_EEPROM_IR_MODE 0x18
44#define AF9015_EEPROM_IR_REMOTE_TYPE 0x34
45#define AF9015_EEPROM_TS_MODE 0x31
46#define AF9015_EEPROM_DEMOD2_I2C 0x32
47
48#define AF9015_EEPROM_SAW_BW1 0x35
49#define AF9015_EEPROM_XTAL_TYPE1 0x36
50#define AF9015_EEPROM_SPEC_INV1 0x37
51#define AF9015_EEPROM_IF1L 0x38
52#define AF9015_EEPROM_IF1H 0x39
53#define AF9015_EEPROM_MT2060_IF1L 0x3a
54#define AF9015_EEPROM_MT2060_IF1H 0x3b
55#define AF9015_EEPROM_TUNER_ID1 0x3c
56
57#define AF9015_EEPROM_SAW_BW2 0x45
58#define AF9015_EEPROM_XTAL_TYPE2 0x46
59#define AF9015_EEPROM_SPEC_INV2 0x47
60#define AF9015_EEPROM_IF2L 0x48
61#define AF9015_EEPROM_IF2H 0x49
62#define AF9015_EEPROM_MT2060_IF2L 0x4a
63#define AF9015_EEPROM_MT2060_IF2H 0x4b
64#define AF9015_EEPROM_TUNER_ID2 0x4c
65
66#define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1)
67
68#define AF9015_GPIO_ON (1 << 0)
69#define AF9015_GPIO_EN (1 << 1)
70#define AF9015_GPIO_O (1 << 2)
71#define AF9015_GPIO_I (1 << 3)
72
73#define AF9015_GPIO_TUNER_ON (AF9015_GPIO_ON|AF9015_GPIO_EN)
74#define AF9015_GPIO_TUNER_OFF (AF9015_GPIO_ON|AF9015_GPIO_EN|AF9015_GPIO_O)
75
76struct req_t {
77 u8 cmd; /* [0] */
78 /* seq */ /* [1] */
79 u8 i2c_addr; /* [2] */
80 u16 addr; /* [3|4] */
81 u8 mbox; /* [5] */
82 u8 addr_len; /* [6] */
83 u8 data_len; /* [7] */
84 u8 *data;
85};
86
87enum af9015_cmd {
88 GET_CONFIG = 0x10,
89 DOWNLOAD_FIRMWARE = 0x11,
90 BOOT = 0x13,
91 READ_MEMORY = 0x20,
92 WRITE_MEMORY = 0x21,
93 READ_WRITE_I2C = 0x22,
94 COPY_FIRMWARE = 0x23,
95 RECONNECT_USB = 0x5a,
96 WRITE_VIRTUAL_MEMORY = 0x26,
97 GET_IR_CODE = 0x27,
98 READ_I2C,
99 WRITE_I2C,
100};
101
102enum af9015_ir_mode {
103 AF9015_IR_MODE_DISABLED = 0,
104 AF9015_IR_MODE_HID,
105 AF9015_IR_MODE_RLC,
106 AF9015_IR_MODE_RC6,
107};
108
109struct af9015_state {
110 struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */
111};
112
113struct af9015_config {
114 u8 dual_mode:1;
115 u16 mt2060_if1[2];
116 u16 firmware_size;
117 u16 firmware_checksum;
118 u8 *ir_table;
119 u16 ir_table_size;
120};
121
122enum af9015_remote {
123 AF9015_REMOTE_NONE = 0,
124 AF9015_REMOTE_A_LINK_DTU_M,
125 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
126 AF9015_REMOTE_MYGICTV_U718,
127};
128
129/* Leadtek WinFast DTV Dongle Gold */
130static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = {
131 { 0x00, 0x1e, KEY_1 },
132 { 0x00, 0x1f, KEY_2 },
133 { 0x00, 0x20, KEY_3 },
134 { 0x00, 0x21, KEY_4 },
135 { 0x00, 0x22, KEY_5 },
136 { 0x00, 0x23, KEY_6 },
137 { 0x00, 0x24, KEY_7 },
138 { 0x00, 0x25, KEY_8 },
139 { 0x00, 0x26, KEY_9 },
140 { 0x00, 0x27, KEY_0 },
141 { 0x00, 0x28, KEY_ENTER },
142 { 0x00, 0x4f, KEY_VOLUMEUP },
143 { 0x00, 0x50, KEY_VOLUMEDOWN },
144 { 0x00, 0x51, KEY_CHANNELDOWN },
145 { 0x00, 0x52, KEY_CHANNELUP },
146};
147
148static u8 af9015_ir_table_leadtek[] = {
149 0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00,
150 0x03, 0xfc, 0x56, 0xa9, 0x00, 0x00, 0x00,
151 0x03, 0xfc, 0x4b, 0xb4, 0x00, 0x00, 0x00,
152 0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00,
153 0x03, 0xfc, 0x4d, 0xb2, 0x00, 0x00, 0x00,
154 0x03, 0xfc, 0x4e, 0xb1, 0x00, 0x00, 0x00,
155 0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00,
156 0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00,
157 0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00,
158 0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00,
159 0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00,
160 0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00,
161 0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00,
162 0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00,
163 0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00,
164 0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00,
165 0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00,
166 0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00,
167 0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00,
168 0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00,
169 0x03, 0xfc, 0x43, 0xbc, 0x00, 0x00, 0x00,
170 0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00,
171 0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00,
172 0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00,
173 0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00,
174 0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00,
175 0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00,
176 0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00,
177 0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00,
178 0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00,
179 0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00,
180 0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00,
181 0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00,
182 0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00,
183 0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00,
184 0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00,
185 0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00,
186 0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00,
187 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00,
188 0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00,
189 0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00,
190 0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00,
191 0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00,
192 0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00,
193 0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00,
194 0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00,
195 0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00,
196 0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00,
197 0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00,
198 0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00,
199};
200
201/* TwinHan AzureWave AD-TU700(704J) */
202static struct dvb_usb_rc_key af9015_rc_keys_twinhan[] = {
203 { 0x05, 0x3f, KEY_POWER },
204 { 0x00, 0x19, KEY_FAVORITES }, /* Favorite List */
205 { 0x00, 0x04, KEY_TEXT }, /* Teletext */
206 { 0x00, 0x0e, KEY_POWER },
207 { 0x00, 0x0e, KEY_INFO }, /* Preview */
208 { 0x00, 0x08, KEY_EPG }, /* Info/EPG */
209 { 0x00, 0x0f, KEY_LIST }, /* Record List */
210 { 0x00, 0x1e, KEY_1 },
211 { 0x00, 0x1f, KEY_2 },
212 { 0x00, 0x20, KEY_3 },
213 { 0x00, 0x21, KEY_4 },
214 { 0x00, 0x22, KEY_5 },
215 { 0x00, 0x23, KEY_6 },
216 { 0x00, 0x24, KEY_7 },
217 { 0x00, 0x25, KEY_8 },
218 { 0x00, 0x26, KEY_9 },
219 { 0x00, 0x27, KEY_0 },
220 { 0x00, 0x29, KEY_CANCEL }, /* Cancel */
221 { 0x00, 0x4c, KEY_CLEAR }, /* Clear */
222 { 0x00, 0x2a, KEY_BACK }, /* Back */
223 { 0x00, 0x2b, KEY_TAB }, /* Tab */
224 { 0x00, 0x52, KEY_UP }, /* up arrow */
225 { 0x00, 0x51, KEY_DOWN }, /* down arrow */
226 { 0x00, 0x4f, KEY_RIGHT }, /* right arrow */
227 { 0x00, 0x50, KEY_LEFT }, /* left arrow */
228 { 0x00, 0x28, KEY_ENTER }, /* Enter / ok */
229 { 0x02, 0x52, KEY_VOLUMEUP },
230 { 0x02, 0x51, KEY_VOLUMEDOWN },
231 { 0x00, 0x4e, KEY_CHANNELDOWN },
232 { 0x00, 0x4b, KEY_CHANNELUP },
233 { 0x00, 0x4a, KEY_RECORD },
234 { 0x01, 0x11, KEY_PLAY },
235 { 0x00, 0x17, KEY_PAUSE },
236 { 0x00, 0x0c, KEY_REWIND }, /* FR << */
237 { 0x00, 0x11, KEY_FASTFORWARD }, /* FF >> */
238 { 0x01, 0x15, KEY_PREVIOUS }, /* Replay */
239 { 0x01, 0x0e, KEY_NEXT }, /* Skip */
240 { 0x00, 0x13, KEY_CAMERA }, /* Capture */
241 { 0x01, 0x0f, KEY_LANGUAGE }, /* SAP */
242 { 0x01, 0x13, KEY_TV2 }, /* PIP */
243 { 0x00, 0x1d, KEY_ZOOM }, /* Full Screen */
244 { 0x01, 0x17, KEY_SUBTITLE }, /* Subtitle / CC */
245 { 0x00, 0x10, KEY_MUTE },
246 { 0x01, 0x19, KEY_AUDIO }, /* L/R */ /* TODO better event */
247 { 0x01, 0x16, KEY_SLEEP }, /* Hibernate */
248 { 0x01, 0x16, KEY_SWITCHVIDEOMODE },
249 /* A/V */ /* TODO does not work */
250 { 0x00, 0x06, KEY_AGAIN }, /* Recall */
251 { 0x01, 0x16, KEY_KPPLUS }, /* Zoom+ */ /* TODO does not work */
252 { 0x01, 0x16, KEY_KPMINUS }, /* Zoom- */ /* TODO does not work */
253 { 0x02, 0x15, KEY_RED },
254 { 0x02, 0x0a, KEY_GREEN },
255 { 0x02, 0x1c, KEY_YELLOW },
256 { 0x02, 0x05, KEY_BLUE },
257};
258
259static u8 af9015_ir_table_twinhan[] = {
260 0x00, 0xff, 0x16, 0xe9, 0x3f, 0x05, 0x00,
261 0x00, 0xff, 0x07, 0xf8, 0x16, 0x01, 0x00,
262 0x00, 0xff, 0x14, 0xeb, 0x11, 0x01, 0x00,
263 0x00, 0xff, 0x1a, 0xe5, 0x4d, 0x00, 0x00,
264 0x00, 0xff, 0x4c, 0xb3, 0x17, 0x00, 0x00,
265 0x00, 0xff, 0x12, 0xed, 0x11, 0x00, 0x00,
266 0x00, 0xff, 0x40, 0xbf, 0x0c, 0x00, 0x00,
267 0x00, 0xff, 0x11, 0xee, 0x4a, 0x00, 0x00,
268 0x00, 0xff, 0x54, 0xab, 0x13, 0x00, 0x00,
269 0x00, 0xff, 0x41, 0xbe, 0x15, 0x01, 0x00,
270 0x00, 0xff, 0x42, 0xbd, 0x0e, 0x01, 0x00,
271 0x00, 0xff, 0x43, 0xbc, 0x17, 0x01, 0x00,
272 0x00, 0xff, 0x50, 0xaf, 0x0f, 0x01, 0x00,
273 0x00, 0xff, 0x4d, 0xb2, 0x1d, 0x00, 0x00,
274 0x00, 0xff, 0x47, 0xb8, 0x13, 0x01, 0x00,
275 0x00, 0xff, 0x05, 0xfa, 0x4b, 0x00, 0x00,
276 0x00, 0xff, 0x02, 0xfd, 0x4e, 0x00, 0x00,
277 0x00, 0xff, 0x0e, 0xf1, 0x06, 0x00, 0x00,
278 0x00, 0xff, 0x1e, 0xe1, 0x52, 0x02, 0x00,
279 0x00, 0xff, 0x0a, 0xf5, 0x51, 0x02, 0x00,
280 0x00, 0xff, 0x10, 0xef, 0x10, 0x00, 0x00,
281 0x00, 0xff, 0x49, 0xb6, 0x19, 0x01, 0x00,
282 0x00, 0xff, 0x15, 0xea, 0x27, 0x00, 0x00,
283 0x00, 0xff, 0x03, 0xfc, 0x1e, 0x00, 0x00,
284 0x00, 0xff, 0x01, 0xfe, 0x1f, 0x00, 0x00,
285 0x00, 0xff, 0x06, 0xf9, 0x20, 0x00, 0x00,
286 0x00, 0xff, 0x09, 0xf6, 0x21, 0x00, 0x00,
287 0x00, 0xff, 0x1d, 0xe2, 0x22, 0x00, 0x00,
288 0x00, 0xff, 0x1f, 0xe0, 0x23, 0x00, 0x00,
289 0x00, 0xff, 0x0d, 0xf2, 0x24, 0x00, 0x00,
290 0x00, 0xff, 0x19, 0xe6, 0x25, 0x00, 0x00,
291 0x00, 0xff, 0x1b, 0xe4, 0x26, 0x00, 0x00,
292 0x00, 0xff, 0x00, 0xff, 0x2b, 0x00, 0x00,
293 0x00, 0xff, 0x4a, 0xb5, 0x4c, 0x00, 0x00,
294 0x00, 0xff, 0x4b, 0xb4, 0x52, 0x00, 0x00,
295 0x00, 0xff, 0x51, 0xae, 0x51, 0x00, 0x00,
296 0x00, 0xff, 0x52, 0xad, 0x4f, 0x00, 0x00,
297 0x00, 0xff, 0x4e, 0xb1, 0x50, 0x00, 0x00,
298 0x00, 0xff, 0x0c, 0xf3, 0x29, 0x00, 0x00,
299 0x00, 0xff, 0x4f, 0xb0, 0x28, 0x00, 0x00,
300 0x00, 0xff, 0x13, 0xec, 0x2a, 0x00, 0x00,
301 0x00, 0xff, 0x17, 0xe8, 0x19, 0x00, 0x00,
302 0x00, 0xff, 0x04, 0xfb, 0x0f, 0x00, 0x00,
303 0x00, 0xff, 0x48, 0xb7, 0x0e, 0x00, 0x00,
304 0x00, 0xff, 0x0f, 0xf0, 0x04, 0x00, 0x00,
305 0x00, 0xff, 0x1c, 0xe3, 0x08, 0x00, 0x00,
306 0x00, 0xff, 0x18, 0xe7, 0x15, 0x02, 0x00,
307 0x00, 0xff, 0x53, 0xac, 0x0a, 0x02, 0x00,
308 0x00, 0xff, 0x5e, 0xa1, 0x1c, 0x02, 0x00,
309 0x00, 0xff, 0x5f, 0xa0, 0x05, 0x02, 0x00,
310};
311
312/* A-Link DTU(m) */
313static struct dvb_usb_rc_key af9015_rc_keys_a_link[] = {
314 { 0x00, 0x1e, KEY_1 },
315 { 0x00, 0x1f, KEY_2 },
316 { 0x00, 0x20, KEY_3 },
317 { 0x00, 0x21, KEY_4 },
318 { 0x00, 0x22, KEY_5 },
319 { 0x00, 0x23, KEY_6 },
320 { 0x00, 0x24, KEY_7 },
321 { 0x00, 0x25, KEY_8 },
322 { 0x00, 0x26, KEY_9 },
323 { 0x00, 0x27, KEY_0 },
324 { 0x00, 0x2e, KEY_CHANNELUP },
325 { 0x00, 0x2d, KEY_CHANNELDOWN },
326 { 0x04, 0x28, KEY_ZOOM },
327 { 0x00, 0x41, KEY_MUTE },
328 { 0x00, 0x42, KEY_VOLUMEDOWN },
329 { 0x00, 0x43, KEY_VOLUMEUP },
330 { 0x00, 0x44, KEY_GOTO }, /* jump */
331 { 0x05, 0x45, KEY_POWER },
332};
333
334static u8 af9015_ir_table_a_link[] = {
335 0x08, 0xf7, 0x12, 0xed, 0x45, 0x05, 0x00, /* power */
336 0x08, 0xf7, 0x1a, 0xe5, 0x41, 0x00, 0x00, /* mute */
337 0x08, 0xf7, 0x01, 0xfe, 0x1e, 0x00, 0x00, /* 1 */
338 0x08, 0xf7, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */
339 0x08, 0xf7, 0x03, 0xfc, 0x24, 0x00, 0x00, /* 7 */
340 0x08, 0xf7, 0x05, 0xfa, 0x28, 0x04, 0x00, /* zoom */
341 0x08, 0xf7, 0x00, 0xff, 0x43, 0x00, 0x00, /* volume up */
342 0x08, 0xf7, 0x16, 0xe9, 0x42, 0x00, 0x00, /* volume down */
343 0x08, 0xf7, 0x0f, 0xf0, 0x1f, 0x00, 0x00, /* 2 */
344 0x08, 0xf7, 0x0d, 0xf2, 0x22, 0x00, 0x00, /* 5 */
345 0x08, 0xf7, 0x1b, 0xe4, 0x25, 0x00, 0x00, /* 8 */
346 0x08, 0xf7, 0x06, 0xf9, 0x27, 0x00, 0x00, /* 0 */
347 0x08, 0xf7, 0x14, 0xeb, 0x2e, 0x00, 0x00, /* channel up */
348 0x08, 0xf7, 0x1d, 0xe2, 0x2d, 0x00, 0x00, /* channel down */
349 0x08, 0xf7, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */
350 0x08, 0xf7, 0x18, 0xe7, 0x23, 0x00, 0x00, /* 6 */
351 0x08, 0xf7, 0x04, 0xfb, 0x26, 0x00, 0x00, /* 9 */
352 0x08, 0xf7, 0x07, 0xf8, 0x44, 0x00, 0x00, /* jump */
353};
354
355/* MSI DIGIVOX mini II V3.0 */
356static struct dvb_usb_rc_key af9015_rc_keys_msi[] = {
357 { 0x00, 0x1e, KEY_1 },
358 { 0x00, 0x1f, KEY_2 },
359 { 0x00, 0x20, KEY_3 },
360 { 0x00, 0x21, KEY_4 },
361 { 0x00, 0x22, KEY_5 },
362 { 0x00, 0x23, KEY_6 },
363 { 0x00, 0x24, KEY_7 },
364 { 0x00, 0x25, KEY_8 },
365 { 0x00, 0x26, KEY_9 },
366 { 0x00, 0x27, KEY_0 },
367 { 0x03, 0x0f, KEY_CHANNELUP },
368 { 0x03, 0x0e, KEY_CHANNELDOWN },
369 { 0x00, 0x42, KEY_VOLUMEDOWN },
370 { 0x00, 0x43, KEY_VOLUMEUP },
371 { 0x05, 0x45, KEY_POWER },
372 { 0x00, 0x52, KEY_UP }, /* up */
373 { 0x00, 0x51, KEY_DOWN }, /* down */
374 { 0x00, 0x28, KEY_ENTER },
375};
376
377static u8 af9015_ir_table_msi[] = {
378 0x03, 0xfc, 0x17, 0xe8, 0x45, 0x05, 0x00, /* power */
379 0x03, 0xfc, 0x0d, 0xf2, 0x51, 0x00, 0x00, /* down */
380 0x03, 0xfc, 0x03, 0xfc, 0x52, 0x00, 0x00, /* up */
381 0x03, 0xfc, 0x1a, 0xe5, 0x1e, 0x00, 0x00, /* 1 */
382 0x03, 0xfc, 0x02, 0xfd, 0x1f, 0x00, 0x00, /* 2 */
383 0x03, 0xfc, 0x04, 0xfb, 0x20, 0x00, 0x00, /* 3 */
384 0x03, 0xfc, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */
385 0x03, 0xfc, 0x08, 0xf7, 0x22, 0x00, 0x00, /* 5 */
386 0x03, 0xfc, 0x1d, 0xe2, 0x23, 0x00, 0x00, /* 6 */
387 0x03, 0xfc, 0x11, 0xee, 0x24, 0x00, 0x00, /* 7 */
388 0x03, 0xfc, 0x0b, 0xf4, 0x25, 0x00, 0x00, /* 8 */
389 0x03, 0xfc, 0x10, 0xef, 0x26, 0x00, 0x00, /* 9 */
390 0x03, 0xfc, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */
391 0x03, 0xfc, 0x14, 0xeb, 0x43, 0x00, 0x00, /* volume up */
392 0x03, 0xfc, 0x1f, 0xe0, 0x42, 0x00, 0x00, /* volume down */
393 0x03, 0xfc, 0x15, 0xea, 0x0f, 0x03, 0x00, /* channel up */
394 0x03, 0xfc, 0x05, 0xfa, 0x0e, 0x03, 0x00, /* channel down */
395 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* enter */
396};
397
398/* MYGICTV U718 */
399static struct dvb_usb_rc_key af9015_rc_keys_mygictv[] = {
400 { 0x00, 0x3d, KEY_SWITCHVIDEOMODE },
401 /* TV / AV */
402 { 0x05, 0x45, KEY_POWER },
403 { 0x00, 0x1e, KEY_1 },
404 { 0x00, 0x1f, KEY_2 },
405 { 0x00, 0x20, KEY_3 },
406 { 0x00, 0x21, KEY_4 },
407 { 0x00, 0x22, KEY_5 },
408 { 0x00, 0x23, KEY_6 },
409 { 0x00, 0x24, KEY_7 },
410 { 0x00, 0x25, KEY_8 },
411 { 0x00, 0x26, KEY_9 },
412 { 0x00, 0x27, KEY_0 },
413 { 0x00, 0x41, KEY_MUTE },
414 { 0x00, 0x2a, KEY_ESC }, /* Esc */
415 { 0x00, 0x2e, KEY_CHANNELUP },
416 { 0x00, 0x2d, KEY_CHANNELDOWN },
417 { 0x00, 0x42, KEY_VOLUMEDOWN },
418 { 0x00, 0x43, KEY_VOLUMEUP },
419 { 0x00, 0x52, KEY_UP }, /* up arrow */
420 { 0x00, 0x51, KEY_DOWN }, /* down arrow */
421 { 0x00, 0x4f, KEY_RIGHT }, /* right arrow */
422 { 0x00, 0x50, KEY_LEFT }, /* left arrow */
423 { 0x00, 0x28, KEY_ENTER }, /* ok */
424 { 0x01, 0x15, KEY_RECORD },
425 { 0x03, 0x13, KEY_PLAY },
426 { 0x01, 0x13, KEY_PAUSE },
427 { 0x01, 0x16, KEY_STOP },
428 { 0x03, 0x07, KEY_REWIND }, /* FR << */
429 { 0x03, 0x09, KEY_FASTFORWARD }, /* FF >> */
430 { 0x00, 0x3b, KEY_TIME }, /* TimeShift */
431 { 0x00, 0x3e, KEY_CAMERA }, /* Snapshot */
432 { 0x03, 0x16, KEY_CYCLEWINDOWS }, /* yellow, min / max */
433 { 0x00, 0x00, KEY_ZOOM }, /* 'select' (?) */
434 { 0x03, 0x16, KEY_SHUFFLE }, /* Shuffle */
435 { 0x03, 0x45, KEY_POWER },
436};
437
438static u8 af9015_ir_table_mygictv[] = {
439 0x02, 0xbd, 0x0c, 0xf3, 0x3d, 0x00, 0x00, /* TV / AV */
440 0x02, 0xbd, 0x14, 0xeb, 0x45, 0x05, 0x00, /* power */
441 0x02, 0xbd, 0x00, 0xff, 0x1e, 0x00, 0x00, /* 1 */
442 0x02, 0xbd, 0x01, 0xfe, 0x1f, 0x00, 0x00, /* 2 */
443 0x02, 0xbd, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */
444 0x02, 0xbd, 0x03, 0xfc, 0x21, 0x00, 0x00, /* 4 */
445 0x02, 0xbd, 0x04, 0xfb, 0x22, 0x00, 0x00, /* 5 */
446 0x02, 0xbd, 0x05, 0xfa, 0x23, 0x00, 0x00, /* 6 */
447 0x02, 0xbd, 0x06, 0xf9, 0x24, 0x00, 0x00, /* 7 */
448 0x02, 0xbd, 0x07, 0xf8, 0x25, 0x00, 0x00, /* 8 */
449 0x02, 0xbd, 0x08, 0xf7, 0x26, 0x00, 0x00, /* 9 */
450 0x02, 0xbd, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */
451 0x02, 0xbd, 0x0a, 0xf5, 0x41, 0x00, 0x00, /* mute */
452 0x02, 0xbd, 0x1c, 0xe3, 0x2a, 0x00, 0x00, /* esc */
453 0x02, 0xbd, 0x1f, 0xe0, 0x43, 0x00, 0x00, /* volume up */
454 0x02, 0xbd, 0x12, 0xed, 0x52, 0x00, 0x00, /* up arrow */
455 0x02, 0xbd, 0x11, 0xee, 0x50, 0x00, 0x00, /* left arrow */
456 0x02, 0xbd, 0x15, 0xea, 0x28, 0x00, 0x00, /* ok */
457 0x02, 0xbd, 0x10, 0xef, 0x4f, 0x00, 0x00, /* right arrow */
458 0x02, 0xbd, 0x13, 0xec, 0x51, 0x00, 0x00, /* down arrow */
459 0x02, 0xbd, 0x0e, 0xf1, 0x42, 0x00, 0x00, /* volume down */
460 0x02, 0xbd, 0x19, 0xe6, 0x15, 0x01, 0x00, /* record */
461 0x02, 0xbd, 0x1e, 0xe1, 0x13, 0x03, 0x00, /* play */
462 0x02, 0xbd, 0x16, 0xe9, 0x16, 0x01, 0x00, /* stop */
463 0x02, 0xbd, 0x0b, 0xf4, 0x28, 0x04, 0x00, /* yellow, min / max */
464 0x02, 0xbd, 0x0f, 0xf0, 0x3b, 0x00, 0x00, /* time shift */
465 0x02, 0xbd, 0x18, 0xe7, 0x2e, 0x00, 0x00, /* channel up */
466 0x02, 0xbd, 0x1a, 0xe5, 0x2d, 0x00, 0x00, /* channel down */
467 0x02, 0xbd, 0x17, 0xe8, 0x3e, 0x00, 0x00, /* snapshot */
468 0x02, 0xbd, 0x40, 0xbf, 0x13, 0x01, 0x00, /* pause */
469 0x02, 0xbd, 0x41, 0xbe, 0x09, 0x03, 0x00, /* FF >> */
470 0x02, 0xbd, 0x42, 0xbd, 0x07, 0x03, 0x00, /* FR << */
471 0x02, 0xbd, 0x43, 0xbc, 0x00, 0x00, 0x00, /* 'select' (?) */
472 0x02, 0xbd, 0x44, 0xbb, 0x16, 0x03, 0x00, /* shuffle */
473 0x02, 0xbd, 0x45, 0xba, 0x45, 0x03, 0x00, /* power */
474};
475
476/* KWorld PlusTV Dual DVB-T Stick (DVB-T 399U) */
477static u8 af9015_ir_table_kworld[] = {
478 0x86, 0x6b, 0x0c, 0xf3, 0x2e, 0x07, 0x00,
479 0x86, 0x6b, 0x16, 0xe9, 0x2d, 0x07, 0x00,
480 0x86, 0x6b, 0x1d, 0xe2, 0x37, 0x07, 0x00,
481 0x86, 0x6b, 0x00, 0xff, 0x1e, 0x07, 0x00,
482 0x86, 0x6b, 0x01, 0xfe, 0x1f, 0x07, 0x00,
483 0x86, 0x6b, 0x02, 0xfd, 0x20, 0x07, 0x00,
484 0x86, 0x6b, 0x03, 0xfc, 0x21, 0x07, 0x00,
485 0x86, 0x6b, 0x04, 0xfb, 0x22, 0x07, 0x00,
486 0x86, 0x6b, 0x05, 0xfa, 0x23, 0x07, 0x00,
487 0x86, 0x6b, 0x06, 0xf9, 0x24, 0x07, 0x00,
488 0x86, 0x6b, 0x07, 0xf8, 0x25, 0x07, 0x00,
489 0x86, 0x6b, 0x08, 0xf7, 0x26, 0x07, 0x00,
490 0x86, 0x6b, 0x09, 0xf6, 0x4d, 0x07, 0x00,
491 0x86, 0x6b, 0x0a, 0xf5, 0x4e, 0x07, 0x00,
492 0x86, 0x6b, 0x14, 0xeb, 0x4f, 0x07, 0x00,
493 0x86, 0x6b, 0x1e, 0xe1, 0x50, 0x07, 0x00,
494 0x86, 0x6b, 0x17, 0xe8, 0x52, 0x07, 0x00,
495 0x86, 0x6b, 0x1f, 0xe0, 0x51, 0x07, 0x00,
496 0x86, 0x6b, 0x0e, 0xf1, 0x0b, 0x07, 0x00,
497 0x86, 0x6b, 0x20, 0xdf, 0x0c, 0x07, 0x00,
498 0x86, 0x6b, 0x42, 0xbd, 0x0d, 0x07, 0x00,
499 0x86, 0x6b, 0x0b, 0xf4, 0x0e, 0x07, 0x00,
500 0x86, 0x6b, 0x43, 0xbc, 0x0f, 0x07, 0x00,
501 0x86, 0x6b, 0x10, 0xef, 0x10, 0x07, 0x00,
502 0x86, 0x6b, 0x21, 0xde, 0x11, 0x07, 0x00,
503 0x86, 0x6b, 0x13, 0xec, 0x12, 0x07, 0x00,
504 0x86, 0x6b, 0x11, 0xee, 0x13, 0x07, 0x00,
505 0x86, 0x6b, 0x12, 0xed, 0x14, 0x07, 0x00,
506 0x86, 0x6b, 0x19, 0xe6, 0x15, 0x07, 0x00,
507 0x86, 0x6b, 0x1a, 0xe5, 0x16, 0x07, 0x00,
508 0x86, 0x6b, 0x1b, 0xe4, 0x17, 0x07, 0x00,
509 0x86, 0x6b, 0x4b, 0xb4, 0x18, 0x07, 0x00,
510 0x86, 0x6b, 0x40, 0xbf, 0x19, 0x07, 0x00,
511 0x86, 0x6b, 0x44, 0xbb, 0x1a, 0x07, 0x00,
512 0x86, 0x6b, 0x41, 0xbe, 0x1b, 0x07, 0x00,
513 0x86, 0x6b, 0x22, 0xdd, 0x1c, 0x07, 0x00,
514 0x86, 0x6b, 0x15, 0xea, 0x1d, 0x07, 0x00,
515 0x86, 0x6b, 0x0f, 0xf0, 0x3f, 0x07, 0x00,
516 0x86, 0x6b, 0x1c, 0xe3, 0x40, 0x07, 0x00,
517 0x86, 0x6b, 0x4a, 0xb5, 0x41, 0x07, 0x00,
518 0x86, 0x6b, 0x48, 0xb7, 0x42, 0x07, 0x00,
519 0x86, 0x6b, 0x49, 0xb6, 0x43, 0x07, 0x00,
520 0x86, 0x6b, 0x18, 0xe7, 0x44, 0x07, 0x00,
521 0x86, 0x6b, 0x23, 0xdc, 0x45, 0x07, 0x00,
522};
523
524#endif
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index 2f408d2e1ef3..c786359fba03 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -41,6 +41,9 @@
41static int dvb_usb_anysee_debug; 41static int dvb_usb_anysee_debug;
42module_param_named(debug, dvb_usb_anysee_debug, int, 0644); 42module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); 43MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
44int dvb_usb_anysee_delsys;
45module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644);
46MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)");
44DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 47DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
45 48
46static struct mutex anysee_usb_mutex; 49static struct mutex anysee_usb_mutex;
@@ -178,14 +181,14 @@ static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
178 inc = 1; 181 inc = 1;
179 } 182 }
180 if (ret) 183 if (ret)
181 return ret; 184 break;
182 185
183 i += inc; 186 i += inc;
184 } 187 }
185 188
186 mutex_unlock(&d->i2c_mutex); 189 mutex_unlock(&d->i2c_mutex);
187 190
188 return i; 191 return ret ? ret : i;
189} 192}
190 193
191static u32 anysee_i2c_func(struct i2c_adapter *adapter) 194static u32 anysee_i2c_func(struct i2c_adapter *adapter)
@@ -272,9 +275,11 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
272 model demod hw firmware 275 model demod hw firmware
273 1. E30 MT352 02 0.2.1 276 1. E30 MT352 02 0.2.1
274 2. E30 ZL10353 02 0.2.1 277 2. E30 ZL10353 02 0.2.1
275 3. E30 Plus ZL10353 06 0.1.0 278 3. E30 Combo ZL10353 0f 0.1.2 DVB-T/C combo
276 4. E30C Plus TDA10023 0a 0.1.0 rev 0.2 279 4. E30 Plus ZL10353 06 0.1.0
277 4. E30C Plus TDA10023 0f 0.1.2 rev 0.4 280 5. E30C Plus TDA10023 0a 0.1.0 rev 0.2
281 E30C Plus TDA10023 0f 0.1.2 rev 0.4
282 E30 Combo TDA10023 0f 0.1.2 DVB-T/C combo
278 */ 283 */
279 284
280 /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */ 285 /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */
@@ -293,6 +298,21 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
293 return 0; 298 return 0;
294 } 299 }
295 300
301 /* for E30 Combo Plus DVB-T demodulator */
302 if (dvb_usb_anysee_delsys) {
303 ret = anysee_write_reg(adap->dev, 0xb0, 0x01);
304 if (ret)
305 return ret;
306
307 /* Zarlink ZL10353 DVB-T demod */
308 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
309 &adap->dev->i2c_adap);
310 if (adap->fe != NULL) {
311 state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A;
312 return 0;
313 }
314 }
315
296 /* connect demod on IO port D for TDA10023 & ZL10353 */ 316 /* connect demod on IO port D for TDA10023 & ZL10353 */
297 ret = anysee_write_reg(adap->dev, 0xb0, 0x25); 317 ret = anysee_write_reg(adap->dev, 0xb0, 0x25);
298 if (ret) 318 if (ret)
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
new file mode 100644
index 000000000000..3ac9f74e9fbf
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
@@ -0,0 +1,268 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#include "cinergyT2.h"
31
32
33/* debug */
34int dvb_usb_cinergyt2_debug;
35int disable_remote;
36
37module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644);
38MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 "
39 "(or-able)).");
40
41DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
42
43struct cinergyt2_state {
44 u8 rc_counter;
45};
46
47/* We are missing a release hook with usb_device data */
48struct dvb_usb_device *cinergyt2_usb_device;
49
50static struct dvb_usb_device_properties cinergyt2_properties;
51
52static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable)
53{
54 char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
55 char result[64];
56 return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result,
57 sizeof(result), 0);
58}
59
60static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable)
61{
62 char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 };
63 char state[3];
64 return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0);
65}
66
67static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
68{
69 char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION };
70 char state[3];
71 int ret;
72
73 adap->fe = cinergyt2_fe_attach(adap->dev);
74
75 ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state,
76 sizeof(state), 0);
77 if (ret < 0) {
78 deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep "
79 "state info\n");
80 }
81
82 /* Copy this pointer as we are gonna need it in the release phase */
83 cinergyt2_usb_device = adap->dev;
84
85 return 0;
86}
87
88static struct dvb_usb_rc_key cinergyt2_rc_keys[] = {
89 { 0x04, 0x01, KEY_POWER },
90 { 0x04, 0x02, KEY_1 },
91 { 0x04, 0x03, KEY_2 },
92 { 0x04, 0x04, KEY_3 },
93 { 0x04, 0x05, KEY_4 },
94 { 0x04, 0x06, KEY_5 },
95 { 0x04, 0x07, KEY_6 },
96 { 0x04, 0x08, KEY_7 },
97 { 0x04, 0x09, KEY_8 },
98 { 0x04, 0x0a, KEY_9 },
99 { 0x04, 0x0c, KEY_0 },
100 { 0x04, 0x0b, KEY_VIDEO },
101 { 0x04, 0x0d, KEY_REFRESH },
102 { 0x04, 0x0e, KEY_SELECT },
103 { 0x04, 0x0f, KEY_EPG },
104 { 0x04, 0x10, KEY_UP },
105 { 0x04, 0x14, KEY_DOWN },
106 { 0x04, 0x11, KEY_LEFT },
107 { 0x04, 0x13, KEY_RIGHT },
108 { 0x04, 0x12, KEY_OK },
109 { 0x04, 0x15, KEY_TEXT },
110 { 0x04, 0x16, KEY_INFO },
111 { 0x04, 0x17, KEY_RED },
112 { 0x04, 0x18, KEY_GREEN },
113 { 0x04, 0x19, KEY_YELLOW },
114 { 0x04, 0x1a, KEY_BLUE },
115 { 0x04, 0x1c, KEY_VOLUMEUP },
116 { 0x04, 0x1e, KEY_VOLUMEDOWN },
117 { 0x04, 0x1d, KEY_MUTE },
118 { 0x04, 0x1b, KEY_CHANNELUP },
119 { 0x04, 0x1f, KEY_CHANNELDOWN },
120 { 0x04, 0x40, KEY_PAUSE },
121 { 0x04, 0x4c, KEY_PLAY },
122 { 0x04, 0x58, KEY_RECORD },
123 { 0x04, 0x54, KEY_PREVIOUS },
124 { 0x04, 0x48, KEY_STOP },
125 { 0x04, 0x5c, KEY_NEXT }
126};
127
128/* Number of keypresses to ignore before detect repeating */
129#define RC_REPEAT_DELAY 3
130
131static int repeatable_keys[] = {
132 KEY_UP,
133 KEY_DOWN,
134 KEY_LEFT,
135 KEY_RIGHT,
136 KEY_VOLUMEUP,
137 KEY_VOLUMEDOWN,
138 KEY_CHANNELUP,
139 KEY_CHANNELDOWN
140};
141
142static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
143{
144 struct cinergyt2_state *st = d->priv;
145 u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS;
146 int i;
147
148 *state = REMOTE_NO_KEY_PRESSED;
149
150 dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0);
151 if (key[4] == 0xff) {
152 /* key repeat */
153 st->rc_counter++;
154 if (st->rc_counter > RC_REPEAT_DELAY) {
155 for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) {
156 if (d->last_event == repeatable_keys[i]) {
157 *state = REMOTE_KEY_REPEAT;
158 *event = d->last_event;
159 deb_rc("repeat key, event %x\n",
160 *event);
161 return 0;
162 }
163 }
164 deb_rc("repeated key (non repeatable)\n");
165 }
166 return 0;
167 }
168
169 /* hack to pass checksum on the custom field */
170 key[2] = ~key[1];
171 dvb_usb_nec_rc_key_to_event(d, key, event, state);
172 if (key[0] != 0) {
173 if (*event != d->last_event)
174 st->rc_counter = 0;
175
176 deb_rc("key: %x %x %x %x %x\n",
177 key[0], key[1], key[2], key[3], key[4]);
178 }
179 return 0;
180}
181
182static int cinergyt2_usb_probe(struct usb_interface *intf,
183 const struct usb_device_id *id)
184{
185 return dvb_usb_device_init(intf, &cinergyt2_properties,
186 THIS_MODULE, NULL, adapter_nr);
187}
188
189
190static struct usb_device_id cinergyt2_usb_table[] = {
191 { USB_DEVICE(USB_VID_TERRATEC, 0x0038) },
192 { 0 }
193};
194
195MODULE_DEVICE_TABLE(usb, cinergyt2_usb_table);
196
197static struct dvb_usb_device_properties cinergyt2_properties = {
198 .size_of_priv = sizeof(struct cinergyt2_state),
199 .num_adapters = 1,
200 .adapter = {
201 {
202 .streaming_ctrl = cinergyt2_streaming_ctrl,
203 .frontend_attach = cinergyt2_frontend_attach,
204
205 /* parameter for the MPEG2-data transfer */
206 .stream = {
207 .type = USB_BULK,
208 .count = 5,
209 .endpoint = 0x02,
210 .u = {
211 .bulk = {
212 .buffersize = 512,
213 }
214 }
215 },
216 }
217 },
218
219 .power_ctrl = cinergyt2_power_ctrl,
220
221 .rc_interval = 50,
222 .rc_key_map = cinergyt2_rc_keys,
223 .rc_key_map_size = ARRAY_SIZE(cinergyt2_rc_keys),
224 .rc_query = cinergyt2_rc_query,
225
226 .generic_bulk_ctrl_endpoint = 1,
227
228 .num_device_descs = 1,
229 .devices = {
230 { .name = "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver",
231 .cold_ids = {NULL},
232 .warm_ids = { &cinergyt2_usb_table[0], NULL },
233 },
234 { NULL },
235 }
236};
237
238
239static struct usb_driver cinergyt2_driver = {
240 .name = "cinergyT2",
241 .probe = cinergyt2_usb_probe,
242 .disconnect = dvb_usb_device_exit,
243 .id_table = cinergyt2_usb_table
244};
245
246static int __init cinergyt2_usb_init(void)
247{
248 int err;
249
250 err = usb_register(&cinergyt2_driver);
251 if (err) {
252 err("usb_register() failed! (err %i)\n", err);
253 return err;
254 }
255 return 0;
256}
257
258static void __exit cinergyt2_usb_exit(void)
259{
260 usb_deregister(&cinergyt2_driver);
261}
262
263module_init(cinergyt2_usb_init);
264module_exit(cinergyt2_usb_exit);
265
266MODULE_DESCRIPTION("Terratec Cinergy T2 DVB-T driver");
267MODULE_LICENSE("GPL");
268MODULE_AUTHOR("Tomi Orava");
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
new file mode 100644
index 000000000000..649f25cca49e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
@@ -0,0 +1,351 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#include "cinergyT2.h"
31
32
33/**
34 * convert linux-dvb frontend parameter set into TPS.
35 * See ETSI ETS-300744, section 4.6.2, table 9 for details.
36 *
37 * This function is probably reusable and may better get placed in a support
38 * library.
39 *
40 * We replace errornous fields by default TPS fields (the ones with value 0).
41 */
42
43static uint16_t compute_tps(struct dvb_frontend_parameters *p)
44{
45 struct dvb_ofdm_parameters *op = &p->u.ofdm;
46 uint16_t tps = 0;
47
48 switch (op->code_rate_HP) {
49 case FEC_2_3:
50 tps |= (1 << 7);
51 break;
52 case FEC_3_4:
53 tps |= (2 << 7);
54 break;
55 case FEC_5_6:
56 tps |= (3 << 7);
57 break;
58 case FEC_7_8:
59 tps |= (4 << 7);
60 break;
61 case FEC_1_2:
62 case FEC_AUTO:
63 default:
64 /* tps |= (0 << 7) */;
65 }
66
67 switch (op->code_rate_LP) {
68 case FEC_2_3:
69 tps |= (1 << 4);
70 break;
71 case FEC_3_4:
72 tps |= (2 << 4);
73 break;
74 case FEC_5_6:
75 tps |= (3 << 4);
76 break;
77 case FEC_7_8:
78 tps |= (4 << 4);
79 break;
80 case FEC_1_2:
81 case FEC_AUTO:
82 default:
83 /* tps |= (0 << 4) */;
84 }
85
86 switch (op->constellation) {
87 case QAM_16:
88 tps |= (1 << 13);
89 break;
90 case QAM_64:
91 tps |= (2 << 13);
92 break;
93 case QPSK:
94 default:
95 /* tps |= (0 << 13) */;
96 }
97
98 switch (op->transmission_mode) {
99 case TRANSMISSION_MODE_8K:
100 tps |= (1 << 0);
101 break;
102 case TRANSMISSION_MODE_2K:
103 default:
104 /* tps |= (0 << 0) */;
105 }
106
107 switch (op->guard_interval) {
108 case GUARD_INTERVAL_1_16:
109 tps |= (1 << 2);
110 break;
111 case GUARD_INTERVAL_1_8:
112 tps |= (2 << 2);
113 break;
114 case GUARD_INTERVAL_1_4:
115 tps |= (3 << 2);
116 break;
117 case GUARD_INTERVAL_1_32:
118 default:
119 /* tps |= (0 << 2) */;
120 }
121
122 switch (op->hierarchy_information) {
123 case HIERARCHY_1:
124 tps |= (1 << 10);
125 break;
126 case HIERARCHY_2:
127 tps |= (2 << 10);
128 break;
129 case HIERARCHY_4:
130 tps |= (3 << 10);
131 break;
132 case HIERARCHY_NONE:
133 default:
134 /* tps |= (0 << 10) */;
135 }
136
137 return tps;
138}
139
140struct cinergyt2_fe_state {
141 struct dvb_frontend fe;
142 struct dvb_usb_device *d;
143};
144
145static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
146 fe_status_t *status)
147{
148 struct cinergyt2_fe_state *state = fe->demodulator_priv;
149 struct dvbt_get_status_msg result;
150 u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
151 int ret;
152
153 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result,
154 sizeof(result), 0);
155 if (ret < 0)
156 return ret;
157
158 *status = 0;
159
160 if (0xffff - le16_to_cpu(result.gain) > 30)
161 *status |= FE_HAS_SIGNAL;
162 if (result.lock_bits & (1 << 6))
163 *status |= FE_HAS_LOCK;
164 if (result.lock_bits & (1 << 5))
165 *status |= FE_HAS_SYNC;
166 if (result.lock_bits & (1 << 4))
167 *status |= FE_HAS_CARRIER;
168 if (result.lock_bits & (1 << 1))
169 *status |= FE_HAS_VITERBI;
170
171 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
172 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
173 *status &= ~FE_HAS_LOCK;
174
175 return 0;
176}
177
178static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
179{
180 struct cinergyt2_fe_state *state = fe->demodulator_priv;
181 struct dvbt_get_status_msg status;
182 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
183 int ret;
184
185 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
186 sizeof(status), 0);
187 if (ret < 0)
188 return ret;
189
190 *ber = le32_to_cpu(status.viterbi_error_rate);
191 return 0;
192}
193
194static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
195{
196 struct cinergyt2_fe_state *state = fe->demodulator_priv;
197 struct dvbt_get_status_msg status;
198 u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
199 int ret;
200
201 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status,
202 sizeof(status), 0);
203 if (ret < 0) {
204 err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n",
205 ret);
206 return ret;
207 }
208 *unc = le32_to_cpu(status.uncorrected_block_count);
209 return 0;
210}
211
212static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe,
213 u16 *strength)
214{
215 struct cinergyt2_fe_state *state = fe->demodulator_priv;
216 struct dvbt_get_status_msg status;
217 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
218 int ret;
219
220 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
221 sizeof(status), 0);
222 if (ret < 0) {
223 err("cinergyt2_fe_read_signal_strength() Failed!"
224 " (Error=%d)\n", ret);
225 return ret;
226 }
227 *strength = (0xffff - le16_to_cpu(status.gain));
228 return 0;
229}
230
231static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
232{
233 struct cinergyt2_fe_state *state = fe->demodulator_priv;
234 struct dvbt_get_status_msg status;
235 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
236 int ret;
237
238 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
239 sizeof(status), 0);
240 if (ret < 0) {
241 err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret);
242 return ret;
243 }
244 *snr = (status.snr << 8) | status.snr;
245 return 0;
246}
247
248static int cinergyt2_fe_init(struct dvb_frontend *fe)
249{
250 return 0;
251}
252
253static int cinergyt2_fe_sleep(struct dvb_frontend *fe)
254{
255 deb_info("cinergyt2_fe_sleep() Called\n");
256 return 0;
257}
258
259static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe,
260 struct dvb_frontend_tune_settings *tune)
261{
262 tune->min_delay_ms = 800;
263 return 0;
264}
265
266static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe,
267 struct dvb_frontend_parameters *fep)
268{
269 struct cinergyt2_fe_state *state = fe->demodulator_priv;
270 struct dvbt_set_parameters_msg param;
271 char result[2];
272 int err;
273
274 param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
275 param.tps = cpu_to_le16(compute_tps(fep));
276 param.freq = cpu_to_le32(fep->frequency / 1000);
277 param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
278
279 err = dvb_usb_generic_rw(state->d,
280 (char *)&param, sizeof(param),
281 result, sizeof(result), 0);
282 if (err < 0)
283 err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err);
284
285 return (err < 0) ? err : 0;
286}
287
288static int cinergyt2_fe_get_frontend(struct dvb_frontend *fe,
289 struct dvb_frontend_parameters *fep)
290{
291 return 0;
292}
293
294static void cinergyt2_fe_release(struct dvb_frontend *fe)
295{
296 struct cinergyt2_fe_state *state = fe->demodulator_priv;
297 if (state != NULL)
298 kfree(state);
299}
300
301static struct dvb_frontend_ops cinergyt2_fe_ops;
302
303struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d)
304{
305 struct cinergyt2_fe_state *s = kzalloc(sizeof(
306 struct cinergyt2_fe_state), GFP_KERNEL);
307 if (s == NULL)
308 return NULL;
309
310 s->d = d;
311 memcpy(&s->fe.ops, &cinergyt2_fe_ops, sizeof(struct dvb_frontend_ops));
312 s->fe.demodulator_priv = s;
313 return &s->fe;
314}
315
316
317static struct dvb_frontend_ops cinergyt2_fe_ops = {
318 .info = {
319 .name = DRIVER_NAME,
320 .type = FE_OFDM,
321 .frequency_min = 174000000,
322 .frequency_max = 862000000,
323 .frequency_stepsize = 166667,
324 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2
325 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
326 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8
327 | FE_CAN_FEC_AUTO | FE_CAN_QPSK
328 | FE_CAN_QAM_16 | FE_CAN_QAM_64
329 | FE_CAN_QAM_AUTO
330 | FE_CAN_TRANSMISSION_MODE_AUTO
331 | FE_CAN_GUARD_INTERVAL_AUTO
332 | FE_CAN_HIERARCHY_AUTO
333 | FE_CAN_RECOVER
334 | FE_CAN_MUTE_TS
335 },
336
337 .release = cinergyt2_fe_release,
338
339 .init = cinergyt2_fe_init,
340 .sleep = cinergyt2_fe_sleep,
341
342 .set_frontend = cinergyt2_fe_set_frontend,
343 .get_frontend = cinergyt2_fe_get_frontend,
344 .get_tune_settings = cinergyt2_fe_get_tune_settings,
345
346 .read_status = cinergyt2_fe_read_status,
347 .read_ber = cinergyt2_fe_read_ber,
348 .read_signal_strength = cinergyt2_fe_read_signal_strength,
349 .read_snr = cinergyt2_fe_read_snr,
350 .read_ucblocks = cinergyt2_fe_read_unc_blocks,
351};
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2.h b/drivers/media/dvb/dvb-usb/cinergyT2.h
new file mode 100644
index 000000000000..11d79eb384c8
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cinergyT2.h
@@ -0,0 +1,95 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#ifndef _DVB_USB_CINERGYT2_H_
31#define _DVB_USB_CINERGYT2_H_
32
33#include <linux/usb/input.h>
34
35#define DVB_USB_LOG_PREFIX "cinergyT2"
36#include "dvb-usb.h"
37
38#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
39
40extern int dvb_usb_cinergyt2_debug;
41
42#define deb_info(args...) dprintk(dvb_usb_cinergyt2_debug, 0x001, args)
43#define deb_xfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x002, args)
44#define deb_pll(args...) dprintk(dvb_usb_cinergyt2_debug, 0x004, args)
45#define deb_ts(args...) dprintk(dvb_usb_cinergyt2_debug, 0x008, args)
46#define deb_err(args...) dprintk(dvb_usb_cinergyt2_debug, 0x010, args)
47#define deb_rc(args...) dprintk(dvb_usb_cinergyt2_debug, 0x020, args)
48#define deb_fw(args...) dprintk(dvb_usb_cinergyt2_debug, 0x040, args)
49#define deb_mem(args...) dprintk(dvb_usb_cinergyt2_debug, 0x080, args)
50#define deb_uxfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x100, args)
51
52
53
54enum cinergyt2_ep1_cmd {
55 CINERGYT2_EP1_PID_TABLE_RESET = 0x01,
56 CINERGYT2_EP1_PID_SETUP = 0x02,
57 CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03,
58 CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04,
59 CINERGYT2_EP1_GET_TUNER_STATUS = 0x05,
60 CINERGYT2_EP1_START_SCAN = 0x06,
61 CINERGYT2_EP1_CONTINUE_SCAN = 0x07,
62 CINERGYT2_EP1_GET_RC_EVENTS = 0x08,
63 CINERGYT2_EP1_SLEEP_MODE = 0x09,
64 CINERGYT2_EP1_GET_FIRMWARE_VERSION = 0x0A
65};
66
67
68struct dvbt_get_status_msg {
69 uint32_t freq;
70 uint8_t bandwidth;
71 uint16_t tps;
72 uint8_t flags;
73 uint16_t gain;
74 uint8_t snr;
75 uint32_t viterbi_error_rate;
76 uint32_t rs_error_rate;
77 uint32_t uncorrected_block_count;
78 uint8_t lock_bits;
79 uint8_t prev_lock_bits;
80} __attribute__((packed));
81
82
83struct dvbt_set_parameters_msg {
84 uint8_t cmd;
85 uint32_t freq;
86 uint8_t bandwidth;
87 uint16_t tps;
88 uint8_t flags;
89} __attribute__((packed));
90
91
92extern struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d);
93
94#endif /* _DVB_USB_CINERGYT2_H_ */
95
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 563400277a42..406d7fba369d 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -36,6 +36,9 @@
36#include "tuner-xc2028.h" 36#include "tuner-xc2028.h"
37#include "tuner-simple.h" 37#include "tuner-simple.h"
38#include "mxl5005s.h" 38#include "mxl5005s.h"
39#include "dib7000p.h"
40#include "dib0070.h"
41#include "lgs8gl5.h"
39 42
40/* debug */ 43/* debug */
41static int dvb_usb_cxusb_debug; 44static int dvb_usb_cxusb_debug;
@@ -109,6 +112,25 @@ static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
109 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40); 112 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
110} 113}
111 114
115static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
116 u8 addr, int onoff)
117{
118 u8 o[2] = {addr, onoff};
119 u8 i;
120 int rc;
121
122 rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
123
124 if (rc < 0)
125 return rc;
126 if (i == 0x01)
127 return 0;
128 else {
129 deb_info("gpio_write failed.\n");
130 return -EIO;
131 }
132}
133
112/* I2C */ 134/* I2C */
113static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], 135static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
114 int num) 136 int num)
@@ -262,6 +284,20 @@ static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
262 return rc; 284 return rc;
263} 285}
264 286
287static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff)
288{
289 int ret;
290 u8 b;
291 ret = cxusb_power_ctrl(d, onoff);
292 if (!onoff)
293 return ret;
294
295 msleep(128);
296 cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1);
297 msleep(100);
298 return ret;
299}
300
265static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 301static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
266{ 302{
267 u8 buf[2] = { 0x03, 0x00 }; 303 u8 buf[2] = { 0x03, 0x00 };
@@ -283,6 +319,67 @@ static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
283 return 0; 319 return 0;
284} 320}
285 321
322static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d)
323{
324 int ep = d->props.generic_bulk_ctrl_endpoint;
325 const int timeout = 100;
326 const int junk_len = 32;
327 u8 *junk;
328 int rd_count;
329
330 /* Discard remaining data in video pipe */
331 junk = kmalloc(junk_len, GFP_KERNEL);
332 if (!junk)
333 return;
334 while (1) {
335 if (usb_bulk_msg(d->udev,
336 usb_rcvbulkpipe(d->udev, ep),
337 junk, junk_len, &rd_count, timeout) < 0)
338 break;
339 if (!rd_count)
340 break;
341 }
342 kfree(junk);
343}
344
345static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d)
346{
347 struct usb_data_stream_properties *p = &d->props.adapter[0].stream;
348 const int timeout = 100;
349 const int junk_len = p->u.bulk.buffersize;
350 u8 *junk;
351 int rd_count;
352
353 /* Discard remaining data in video pipe */
354 junk = kmalloc(junk_len, GFP_KERNEL);
355 if (!junk)
356 return;
357 while (1) {
358 if (usb_bulk_msg(d->udev,
359 usb_rcvbulkpipe(d->udev, p->endpoint),
360 junk, junk_len, &rd_count, timeout) < 0)
361 break;
362 if (!rd_count)
363 break;
364 }
365 kfree(junk);
366}
367
368static int cxusb_d680_dmb_streaming_ctrl(
369 struct dvb_usb_adapter *adap, int onoff)
370{
371 if (onoff) {
372 u8 buf[2] = { 0x03, 0x00 };
373 cxusb_d680_dmb_drain_video(adap->dev);
374 return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON,
375 buf, sizeof(buf), NULL, 0);
376 } else {
377 int ret = cxusb_ctrl_msg(adap->dev,
378 CMD_STREAMING_OFF, NULL, 0, NULL, 0);
379 return ret;
380 }
381}
382
286static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 383static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
287{ 384{
288 struct dvb_usb_rc_key *keymap = d->props.rc_key_map; 385 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
@@ -335,6 +432,32 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
335 return 0; 432 return 0;
336} 433}
337 434
435static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
436 int *state)
437{
438 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
439 u8 ircode[2];
440 int i;
441
442 *event = 0;
443 *state = REMOTE_NO_KEY_PRESSED;
444
445 if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
446 return 0;
447
448 for (i = 0; i < d->props.rc_key_map_size; i++) {
449 if (keymap[i].custom == ircode[0] &&
450 keymap[i].data == ircode[1]) {
451 *event = keymap[i].event;
452 *state = REMOTE_KEY_PRESSED;
453
454 return 0;
455 }
456 }
457
458 return 0;
459}
460
338static struct dvb_usb_rc_key dvico_mce_rc_keys[] = { 461static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
339 { 0xfe, 0x02, KEY_TV }, 462 { 0xfe, 0x02, KEY_TV },
340 { 0xfe, 0x0e, KEY_MP3 }, 463 { 0xfe, 0x0e, KEY_MP3 },
@@ -422,6 +545,44 @@ static struct dvb_usb_rc_key dvico_portable_rc_keys[] = {
422 { 0xfc, 0x00, KEY_UNKNOWN }, /* HD */ 545 { 0xfc, 0x00, KEY_UNKNOWN }, /* HD */
423}; 546};
424 547
548static struct dvb_usb_rc_key d680_dmb_rc_keys[] = {
549 { 0x00, 0x38, KEY_UNKNOWN }, /* TV/AV */
550 { 0x08, 0x0c, KEY_ZOOM },
551 { 0x08, 0x00, KEY_0 },
552 { 0x00, 0x01, KEY_1 },
553 { 0x08, 0x02, KEY_2 },
554 { 0x00, 0x03, KEY_3 },
555 { 0x08, 0x04, KEY_4 },
556 { 0x00, 0x05, KEY_5 },
557 { 0x08, 0x06, KEY_6 },
558 { 0x00, 0x07, KEY_7 },
559 { 0x08, 0x08, KEY_8 },
560 { 0x00, 0x09, KEY_9 },
561 { 0x00, 0x0a, KEY_MUTE },
562 { 0x08, 0x29, KEY_BACK },
563 { 0x00, 0x12, KEY_CHANNELUP },
564 { 0x08, 0x13, KEY_CHANNELDOWN },
565 { 0x00, 0x2b, KEY_VOLUMEUP },
566 { 0x08, 0x2c, KEY_VOLUMEDOWN },
567 { 0x00, 0x20, KEY_UP },
568 { 0x08, 0x21, KEY_DOWN },
569 { 0x00, 0x11, KEY_LEFT },
570 { 0x08, 0x10, KEY_RIGHT },
571 { 0x00, 0x0d, KEY_OK },
572 { 0x08, 0x1f, KEY_RECORD },
573 { 0x00, 0x17, KEY_PLAYPAUSE },
574 { 0x08, 0x16, KEY_PLAYPAUSE },
575 { 0x00, 0x0b, KEY_STOP },
576 { 0x08, 0x27, KEY_FASTFORWARD },
577 { 0x00, 0x26, KEY_REWIND },
578 { 0x08, 0x1e, KEY_UNKNOWN }, /* Time Shift */
579 { 0x00, 0x0e, KEY_UNKNOWN }, /* Snapshot */
580 { 0x08, 0x2d, KEY_UNKNOWN }, /* Mouse Cursor */
581 { 0x00, 0x0f, KEY_UNKNOWN }, /* Minimize/Maximize */
582 { 0x08, 0x14, KEY_UNKNOWN }, /* Shuffle */
583 { 0x00, 0x25, KEY_POWER },
584};
585
425static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) 586static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
426{ 587{
427 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; 588 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
@@ -527,6 +688,24 @@ static struct mxl5005s_config aver_a868r_tuner = {
527 .AgcMasterByte = 0x00, 688 .AgcMasterByte = 0x00,
528}; 689};
529 690
691/* FIXME: needs tweaking */
692static struct mxl5005s_config d680_dmb_tuner = {
693 .i2c_address = 0x63,
694 .if_freq = 36125000UL,
695 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
696 .agc_mode = MXL_SINGLE_AGC,
697 .tracking_filter = MXL_TF_C,
698 .rssi_enable = MXL_RSSI_ENABLE,
699 .cap_select = MXL_CAP_SEL_ENABLE,
700 .div_out = MXL_DIV_OUT_4,
701 .clock_out = MXL_CLOCK_OUT_DISABLE,
702 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
703 .top = MXL5005S_TOP_25P2,
704 .mod_mode = MXL_DIGITAL_MODE,
705 .if_mode = MXL_ZERO_IF,
706 .AgcMasterByte = 0x00,
707};
708
530/* Callbacks for DVB USB */ 709/* Callbacks for DVB USB */
531static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) 710static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
532{ 711{
@@ -563,7 +742,8 @@ static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
563 return 0; 742 return 0;
564} 743}
565 744
566static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg) 745static int dvico_bluebird_xc2028_callback(void *ptr, int component,
746 int command, int arg)
567{ 747{
568 struct dvb_usb_adapter *adap = ptr; 748 struct dvb_usb_adapter *adap = ptr;
569 struct dvb_usb_device *d = adap->dev; 749 struct dvb_usb_device *d = adap->dev;
@@ -591,14 +771,16 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
591 struct xc2028_config cfg = { 771 struct xc2028_config cfg = {
592 .i2c_adap = &adap->dev->i2c_adap, 772 .i2c_adap = &adap->dev->i2c_adap,
593 .i2c_addr = 0x61, 773 .i2c_addr = 0x61,
594 .callback = dvico_bluebird_xc2028_callback,
595 }; 774 };
596 static struct xc2028_ctrl ctl = { 775 static struct xc2028_ctrl ctl = {
597 .fname = "xc3028-v27.fw", 776 .fname = XC2028_DEFAULT_FIRMWARE,
598 .max_len = 64, 777 .max_len = 64,
599 .demod = XC3028_FE_ZARLINK456, 778 .demod = XC3028_FE_ZARLINK456,
600 }; 779 };
601 780
781 /* FIXME: generalize & move to common area */
782 adap->fe->callback = dvico_bluebird_xc2028_callback;
783
602 fe = dvb_attach(xc2028_attach, adap->fe, &cfg); 784 fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
603 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL) 785 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
604 return -EIO; 786 return -EIO;
@@ -615,6 +797,14 @@ static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
615 return 0; 797 return 0;
616} 798}
617 799
800static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap)
801{
802 struct dvb_frontend *fe;
803 fe = dvb_attach(mxl5005s_attach, adap->fe,
804 &adap->dev->i2c_adap, &d680_dmb_tuner);
805 return (fe == NULL) ? -EIO : 0;
806}
807
618static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) 808static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
619{ 809{
620 u8 b; 810 u8 b;
@@ -726,6 +916,159 @@ no_IR:
726 return 0; 916 return 0;
727} 917}
728 918
919static struct dibx000_agc_config dib7070_agc_config = {
920 .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
921
922 /*
923 * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
924 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
925 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
926 */
927 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
928 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
929 .inv_gain = 600,
930 .time_stabiliz = 10,
931 .alpha_level = 0,
932 .thlock = 118,
933 .wbd_inv = 0,
934 .wbd_ref = 3530,
935 .wbd_sel = 1,
936 .wbd_alpha = 5,
937 .agc1_max = 65535,
938 .agc1_min = 0,
939 .agc2_max = 65535,
940 .agc2_min = 0,
941 .agc1_pt1 = 0,
942 .agc1_pt2 = 40,
943 .agc1_pt3 = 183,
944 .agc1_slope1 = 206,
945 .agc1_slope2 = 255,
946 .agc2_pt1 = 72,
947 .agc2_pt2 = 152,
948 .agc2_slope1 = 88,
949 .agc2_slope2 = 90,
950 .alpha_mant = 17,
951 .alpha_exp = 27,
952 .beta_mant = 23,
953 .beta_exp = 51,
954 .perform_agc_softsplit = 0,
955};
956
957static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
958 .internal = 60000,
959 .sampling = 15000,
960 .pll_prediv = 1,
961 .pll_ratio = 20,
962 .pll_range = 3,
963 .pll_reset = 1,
964 .pll_bypass = 0,
965 .enable_refdiv = 0,
966 .bypclk_div = 0,
967 .IO_CLK_en_core = 1,
968 .ADClkSrc = 1,
969 .modulo = 2,
970 /* refsel, sel, freq_15k */
971 .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
972 .ifreq = (0 << 25) | 0,
973 .timf = 20452225,
974 .xtal_hz = 12000000,
975};
976
977static struct dib7000p_config cxusb_dualdig4_rev2_config = {
978 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
979 .output_mpeg2_in_188_bytes = 1,
980
981 .agc_config_count = 1,
982 .agc = &dib7070_agc_config,
983 .bw = &dib7070_bw_config_12_mhz,
984 .tuner_is_baseband = 1,
985 .spur_protect = 1,
986
987 .gpio_dir = 0xfcef,
988 .gpio_val = 0x0110,
989
990 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
991
992 .hostbus_diversity = 1,
993};
994
995static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
996{
997 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
998 err("set interface failed");
999
1000 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1001
1002 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1003
1004 dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1005 &cxusb_dualdig4_rev2_config);
1006
1007 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1008 &cxusb_dualdig4_rev2_config);
1009 if (adap->fe == NULL)
1010 return -EIO;
1011
1012 return 0;
1013}
1014
1015static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1016{
1017 return dib7000p_set_gpio(fe, 8, 0, !onoff);
1018}
1019
1020static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1021{
1022 return 0;
1023}
1024
1025static struct dib0070_config dib7070p_dib0070_config = {
1026 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1027 .reset = dib7070_tuner_reset,
1028 .sleep = dib7070_tuner_sleep,
1029 .clock_khz = 12000,
1030};
1031
1032struct dib0700_adapter_state {
1033 int (*set_param_save) (struct dvb_frontend *,
1034 struct dvb_frontend_parameters *);
1035};
1036
1037static int dib7070_set_param_override(struct dvb_frontend *fe,
1038 struct dvb_frontend_parameters *fep)
1039{
1040 struct dvb_usb_adapter *adap = fe->dvb->priv;
1041 struct dib0700_adapter_state *state = adap->priv;
1042
1043 u16 offset;
1044 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1045 switch (band) {
1046 case BAND_VHF: offset = 950; break;
1047 default:
1048 case BAND_UHF: offset = 550; break;
1049 }
1050
1051 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1052
1053 return state->set_param_save(fe, fep);
1054}
1055
1056static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
1057{
1058 struct dib0700_adapter_state *st = adap->priv;
1059 struct i2c_adapter *tun_i2c =
1060 dib7000p_get_i2c_master(adap->fe,
1061 DIBX000_I2C_INTERFACE_TUNER, 1);
1062
1063 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1064 &dib7070p_dib0070_config) == NULL)
1065 return -ENODEV;
1066
1067 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1068 adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
1069 return 0;
1070}
1071
729static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap) 1072static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
730{ 1073{
731 if (usb_set_interface(adap->dev->udev, 0, 1) < 0) 1074 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
@@ -751,6 +1094,54 @@ static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
751 return -EIO; 1094 return -EIO;
752} 1095}
753 1096
1097static struct lgs8gl5_config lgs8gl5_cfg = {
1098 .demod_address = 0x19,
1099};
1100
1101static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
1102{
1103 struct dvb_usb_device *d = adap->dev;
1104 int n;
1105
1106 /* Select required USB configuration */
1107 if (usb_set_interface(d->udev, 0, 0) < 0)
1108 err("set interface failed");
1109
1110 /* Unblock all USB pipes */
1111 usb_clear_halt(d->udev,
1112 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1113 usb_clear_halt(d->udev,
1114 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1115 usb_clear_halt(d->udev,
1116 usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint));
1117
1118 /* Drain USB pipes to avoid hang after reboot */
1119 for (n = 0; n < 5; n++) {
1120 cxusb_d680_dmb_drain_message(d);
1121 cxusb_d680_dmb_drain_video(d);
1122 msleep(200);
1123 }
1124
1125 /* Reset the tuner */
1126 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1127 err("clear tuner gpio failed");
1128 return -EIO;
1129 }
1130 msleep(100);
1131 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1132 err("set tuner gpio failed");
1133 return -EIO;
1134 }
1135 msleep(100);
1136
1137 /* Attach frontend */
1138 adap->fe = dvb_attach(lgs8gl5_attach, &lgs8gl5_cfg, &d->i2c_adap);
1139 if (adap->fe == NULL)
1140 return -EIO;
1141
1142 return 0;
1143}
1144
754/* 1145/*
755 * DViCO has shipped two devices with the same USB ID, but only one of them 1146 * DViCO has shipped two devices with the same USB ID, but only one of them
756 * needs a firmware download. Check the device class details to see if they 1147 * needs a firmware download. Check the device class details to see if they
@@ -826,9 +1217,11 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
826static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties; 1217static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
827static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties; 1218static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
828static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; 1219static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
1220static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
829static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; 1221static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
830static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; 1222static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
831static struct dvb_usb_device_properties cxusb_aver_a868r_properties; 1223static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
1224static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
832 1225
833static int cxusb_probe(struct usb_interface *intf, 1226static int cxusb_probe(struct usb_interface *intf,
834 const struct usb_device_id *id) 1227 const struct usb_device_id *id)
@@ -852,6 +1245,11 @@ static int cxusb_probe(struct usb_interface *intf,
852 THIS_MODULE, NULL, adapter_nr) || 1245 THIS_MODULE, NULL, adapter_nr) ||
853 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, 1246 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
854 THIS_MODULE, NULL, adapter_nr) || 1247 THIS_MODULE, NULL, adapter_nr) ||
1248 0 == dvb_usb_device_init(intf,
1249 &cxusb_bluebird_dualdig4_rev2_properties,
1250 THIS_MODULE, NULL, adapter_nr) ||
1251 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
1252 THIS_MODULE, NULL, adapter_nr) ||
855 0) 1253 0)
856 return 0; 1254 return 0;
857 1255
@@ -876,6 +1274,8 @@ static struct usb_device_id cxusb_table [] = {
876 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) }, 1274 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
877 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) }, 1275 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
878 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) }, 1276 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
1277 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
1278 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
879 {} /* Terminating entry */ 1279 {} /* Terminating entry */
880}; 1280};
881MODULE_DEVICE_TABLE (usb, cxusb_table); 1281MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -1321,6 +1721,104 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1321 } 1721 }
1322}; 1722};
1323 1723
1724static
1725struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
1726 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1727
1728 .usb_ctrl = CYPRESS_FX2,
1729
1730 .size_of_priv = sizeof(struct cxusb_state),
1731
1732 .num_adapters = 1,
1733 .adapter = {
1734 {
1735 .streaming_ctrl = cxusb_streaming_ctrl,
1736 .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
1737 .tuner_attach = cxusb_dualdig4_rev2_tuner_attach,
1738 .size_of_priv = sizeof(struct dib0700_adapter_state),
1739 /* parameter for the MPEG2-data transfer */
1740 .stream = {
1741 .type = USB_BULK,
1742 .count = 7,
1743 .endpoint = 0x02,
1744 .u = {
1745 .bulk = {
1746 .buffersize = 4096,
1747 }
1748 }
1749 },
1750 },
1751 },
1752
1753 .power_ctrl = cxusb_bluebird_power_ctrl,
1754
1755 .i2c_algo = &cxusb_i2c_algo,
1756
1757 .generic_bulk_ctrl_endpoint = 0x01,
1758
1759 .rc_interval = 100,
1760 .rc_key_map = dvico_mce_rc_keys,
1761 .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys),
1762 .rc_query = cxusb_rc_query,
1763
1764 .num_device_descs = 1,
1765 .devices = {
1766 { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
1767 { NULL },
1768 { &cxusb_table[17], NULL },
1769 },
1770 }
1771};
1772
1773static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
1774 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1775
1776 .usb_ctrl = CYPRESS_FX2,
1777
1778 .size_of_priv = sizeof(struct cxusb_state),
1779
1780 .num_adapters = 1,
1781 .adapter = {
1782 {
1783 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
1784 .frontend_attach = cxusb_d680_dmb_frontend_attach,
1785 .tuner_attach = cxusb_d680_dmb_tuner_attach,
1786
1787 /* parameter for the MPEG2-data transfer */
1788 .stream = {
1789 .type = USB_BULK,
1790 .count = 5,
1791 .endpoint = 0x02,
1792 .u = {
1793 .bulk = {
1794 .buffersize = 8192,
1795 }
1796 }
1797 },
1798 },
1799 },
1800
1801 .power_ctrl = cxusb_d680_dmb_power_ctrl,
1802
1803 .i2c_algo = &cxusb_i2c_algo,
1804
1805 .generic_bulk_ctrl_endpoint = 0x01,
1806
1807 .rc_interval = 100,
1808 .rc_key_map = d680_dmb_rc_keys,
1809 .rc_key_map_size = ARRAY_SIZE(d680_dmb_rc_keys),
1810 .rc_query = cxusb_d680_dmb_rc_query,
1811
1812 .num_device_descs = 1,
1813 .devices = {
1814 {
1815 "Conexant DMB-TH Stick",
1816 { NULL },
1817 { &cxusb_table[18], NULL },
1818 },
1819 }
1820};
1821
1324static struct usb_driver cxusb_driver = { 1822static struct usb_driver cxusb_driver = {
1325 .name = "dvb_usb_cxusb", 1823 .name = "dvb_usb_cxusb",
1326 .probe = cxusb_probe, 1824 .probe = cxusb_probe,
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
index 66d4dc6ba46f..739193943c17 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -31,6 +31,8 @@ extern int dvb_usb_dib0700_debug;
31 // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) 31 // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
32 // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) 32 // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
33#define REQUEST_SET_RC 0x11 33#define REQUEST_SET_RC 0x11
34#define REQUEST_NEW_I2C_READ 0x12
35#define REQUEST_NEW_I2C_WRITE 0x13
34#define REQUEST_GET_VERSION 0x15 36#define REQUEST_GET_VERSION 0x15
35 37
36struct dib0700_state { 38struct dib0700_state {
@@ -39,6 +41,8 @@ struct dib0700_state {
39 u8 rc_toggle; 41 u8 rc_toggle;
40 u8 rc_counter; 42 u8 rc_counter;
41 u8 is_dib7000pc; 43 u8 is_dib7000pc;
44 u8 fw_use_new_i2c_api;
45 u8 disable_streaming_master_mode;
42}; 46};
43 47
44extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); 48extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 595a04696c87..dd53cee3896d 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -82,9 +82,98 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
82} 82}
83 83
84/* 84/*
85 * I2C master xfer function 85 * I2C master xfer function (supported in 1.20 firmware)
86 */ 86 */
87static int dib0700_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num) 87static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
88 int num)
89{
90 /* The new i2c firmware messages are more reliable and in particular
91 properly support i2c read calls not preceded by a write */
92
93 struct dvb_usb_device *d = i2c_get_adapdata(adap);
94 uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */
95 uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */
96 uint8_t en_start = 0;
97 uint8_t en_stop = 0;
98 uint8_t buf[255]; /* TBV: malloc ? */
99 int result, i;
100
101 /* Ensure nobody else hits the i2c bus while we're sending our
102 sequence of messages, (such as the remote control thread) */
103 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
104 return -EAGAIN;
105
106 for (i = 0; i < num; i++) {
107 if (i == 0) {
108 /* First message in the transaction */
109 en_start = 1;
110 } else if (!(msg[i].flags & I2C_M_NOSTART)) {
111 /* Device supports repeated-start */
112 en_start = 1;
113 } else {
114 /* Not the first packet and device doesn't support
115 repeated start */
116 en_start = 0;
117 }
118 if (i == (num - 1)) {
119 /* Last message in the transaction */
120 en_stop = 1;
121 }
122
123 if (msg[i].flags & I2C_M_RD) {
124 /* Read request */
125 u16 index, value;
126 uint8_t i2c_dest;
127
128 i2c_dest = (msg[i].addr << 1);
129 value = ((en_start << 7) | (en_stop << 6) |
130 (msg[i].len & 0x3F)) << 8 | i2c_dest;
131 /* I2C ctrl + FE bus; */
132 index = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30);
133
134 result = usb_control_msg(d->udev,
135 usb_rcvctrlpipe(d->udev, 0),
136 REQUEST_NEW_I2C_READ,
137 USB_TYPE_VENDOR | USB_DIR_IN,
138 value, index, msg[i].buf,
139 msg[i].len,
140 USB_CTRL_GET_TIMEOUT);
141 if (result < 0) {
142 err("i2c read error (status = %d)\n", result);
143 break;
144 }
145 } else {
146 /* Write request */
147 buf[0] = REQUEST_NEW_I2C_WRITE;
148 buf[1] = (msg[i].addr << 1);
149 buf[2] = (en_start << 7) | (en_stop << 6) |
150 (msg[i].len & 0x3F);
151 /* I2C ctrl + FE bus; */
152 buf[3] = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30);
153 /* The Actual i2c payload */
154 memcpy(&buf[4], msg[i].buf, msg[i].len);
155
156 result = usb_control_msg(d->udev,
157 usb_sndctrlpipe(d->udev, 0),
158 REQUEST_NEW_I2C_WRITE,
159 USB_TYPE_VENDOR | USB_DIR_OUT,
160 0, 0, buf, msg[i].len + 4,
161 USB_CTRL_GET_TIMEOUT);
162 if (result < 0) {
163 err("i2c write error (status = %d)\n", result);
164 break;
165 }
166 }
167 }
168 mutex_unlock(&d->i2c_mutex);
169 return i;
170}
171
172/*
173 * I2C master xfer function (pre-1.20 firmware)
174 */
175static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
176 struct i2c_msg *msg, int num)
88{ 177{
89 struct dvb_usb_device *d = i2c_get_adapdata(adap); 178 struct dvb_usb_device *d = i2c_get_adapdata(adap);
90 int i,len; 179 int i,len;
@@ -124,6 +213,21 @@ static int dib0700_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num
124 return i; 213 return i;
125} 214}
126 215
216static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
217 int num)
218{
219 struct dvb_usb_device *d = i2c_get_adapdata(adap);
220 struct dib0700_state *st = d->priv;
221
222 if (st->fw_use_new_i2c_api == 1) {
223 /* User running at least fw 1.20 */
224 return dib0700_i2c_xfer_new(adap, msg, num);
225 } else {
226 /* Use legacy calls */
227 return dib0700_i2c_xfer_legacy(adap, msg, num);
228 }
229}
230
127static u32 dib0700_i2c_func(struct i2c_adapter *adapter) 231static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
128{ 232{
129 return I2C_FUNC_I2C; 233 return I2C_FUNC_I2C;
@@ -246,7 +350,12 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
246 350
247 b[0] = REQUEST_ENABLE_VIDEO; 351 b[0] = REQUEST_ENABLE_VIDEO;
248 b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */ 352 b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */
249 b[2] = (0x01 << 4); /* Master mode */ 353
354 if (st->disable_streaming_master_mode == 1)
355 b[2] = 0x00;
356 else
357 b[2] = (0x01 << 4); /* Master mode */
358
250 b[3] = 0x00; 359 b[3] = 0x00;
251 360
252 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); 361 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 6c0e5c5f4362..0cfccc24b190 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -14,6 +14,8 @@
14#include "mt2060.h" 14#include "mt2060.h"
15#include "mt2266.h" 15#include "mt2266.h"
16#include "tuner-xc2028.h" 16#include "tuner-xc2028.h"
17#include "xc5000.h"
18#include "s5h1411.h"
17#include "dib0070.h" 19#include "dib0070.h"
18 20
19static int force_lna_activation; 21static int force_lna_activation;
@@ -366,7 +368,8 @@ static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
366 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, 368 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
367}; 369};
368 370
369static int stk7700ph_xc3028_callback(void *ptr, int command, int arg) 371static int stk7700ph_xc3028_callback(void *ptr, int component,
372 int command, int arg)
370{ 373{
371 struct dvb_usb_adapter *adap = ptr; 374 struct dvb_usb_adapter *adap = ptr;
372 375
@@ -394,7 +397,6 @@ static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
394 397
395static struct xc2028_config stk7700ph_xc3028_config = { 398static struct xc2028_config stk7700ph_xc3028_config = {
396 .i2c_addr = 0x61, 399 .i2c_addr = 0x61,
397 .callback = stk7700ph_xc3028_callback,
398 .ctrl = &stk7700ph_xc3028_ctrl, 400 .ctrl = &stk7700ph_xc3028_ctrl,
399}; 401};
400 402
@@ -435,7 +437,9 @@ static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
435 DIBX000_I2C_INTERFACE_TUNER, 1); 437 DIBX000_I2C_INTERFACE_TUNER, 1);
436 438
437 stk7700ph_xc3028_config.i2c_adap = tun_i2c; 439 stk7700ph_xc3028_config.i2c_adap = tun_i2c;
438 stk7700ph_xc3028_config.video_dev = adap; 440
441 /* FIXME: generalize & move to common area */
442 adap->fe->callback = stk7700ph_xc3028_callback;
439 443
440 return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config) 444 return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config)
441 == NULL ? -ENODEV : 0; 445 == NULL ? -ENODEV : 0;
@@ -677,6 +681,43 @@ static struct dvb_usb_rc_key dib0700_rc_keys[] = {
677 { 0x01, 0x7d, KEY_VOLUMEDOWN }, 681 { 0x01, 0x7d, KEY_VOLUMEDOWN },
678 { 0x02, 0x42, KEY_CHANNELUP }, 682 { 0x02, 0x42, KEY_CHANNELUP },
679 { 0x00, 0x7d, KEY_CHANNELDOWN }, 683 { 0x00, 0x7d, KEY_CHANNELDOWN },
684
685 /* Key codes for Nova-TD "credit card" remote control. */
686 { 0x1d, 0x00, KEY_0 },
687 { 0x1d, 0x01, KEY_1 },
688 { 0x1d, 0x02, KEY_2 },
689 { 0x1d, 0x03, KEY_3 },
690 { 0x1d, 0x04, KEY_4 },
691 { 0x1d, 0x05, KEY_5 },
692 { 0x1d, 0x06, KEY_6 },
693 { 0x1d, 0x07, KEY_7 },
694 { 0x1d, 0x08, KEY_8 },
695 { 0x1d, 0x09, KEY_9 },
696 { 0x1d, 0x0a, KEY_TEXT },
697 { 0x1d, 0x0d, KEY_MENU },
698 { 0x1d, 0x0f, KEY_MUTE },
699 { 0x1d, 0x10, KEY_VOLUMEUP },
700 { 0x1d, 0x11, KEY_VOLUMEDOWN },
701 { 0x1d, 0x12, KEY_CHANNEL },
702 { 0x1d, 0x14, KEY_UP },
703 { 0x1d, 0x15, KEY_DOWN },
704 { 0x1d, 0x16, KEY_LEFT },
705 { 0x1d, 0x17, KEY_RIGHT },
706 { 0x1d, 0x1c, KEY_TV },
707 { 0x1d, 0x1e, KEY_NEXT },
708 { 0x1d, 0x1f, KEY_BACK },
709 { 0x1d, 0x20, KEY_CHANNELUP },
710 { 0x1d, 0x21, KEY_CHANNELDOWN },
711 { 0x1d, 0x24, KEY_LAST },
712 { 0x1d, 0x25, KEY_OK },
713 { 0x1d, 0x30, KEY_PAUSE },
714 { 0x1d, 0x32, KEY_REWIND },
715 { 0x1d, 0x34, KEY_FASTFORWARD },
716 { 0x1d, 0x35, KEY_PLAY },
717 { 0x1d, 0x36, KEY_STOP },
718 { 0x1d, 0x37, KEY_RECORD },
719 { 0x1d, 0x3b, KEY_GOTO },
720 { 0x1d, 0x3d, KEY_POWER },
680}; 721};
681 722
682/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ 723/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
@@ -1078,6 +1119,97 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
1078 return adap->fe == NULL ? -ENODEV : 0; 1119 return adap->fe == NULL ? -ENODEV : 0;
1079} 1120}
1080 1121
1122/* S5H1411 */
1123static struct s5h1411_config pinnacle_801e_config = {
1124 .output_mode = S5H1411_PARALLEL_OUTPUT,
1125 .gpio = S5H1411_GPIO_OFF,
1126 .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
1127 .qam_if = S5H1411_IF_44000,
1128 .vsb_if = S5H1411_IF_44000,
1129 .inversion = S5H1411_INVERSION_OFF,
1130 .status_mode = S5H1411_DEMODLOCKING
1131};
1132
1133/* Pinnacle PCTV HD Pro 801e GPIOs map:
1134 GPIO0 - currently unknown
1135 GPIO1 - xc5000 tuner reset
1136 GPIO2 - CX25843 sleep
1137 GPIO3 - currently unknown
1138 GPIO4 - currently unknown
1139 GPIO6 - currently unknown
1140 GPIO7 - currently unknown
1141 GPIO9 - currently unknown
1142 GPIO10 - CX25843 reset
1143 */
1144static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
1145{
1146 struct dib0700_state *st = adap->dev->priv;
1147
1148 /* Make use of the new i2c functions from FW 1.20 */
1149 st->fw_use_new_i2c_api = 1;
1150
1151 /* The s5h1411 requires the dib0700 to not be in master mode */
1152 st->disable_streaming_master_mode = 1;
1153
1154 /* All msleep values taken from Windows USB trace */
1155 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
1156 dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
1157 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1158 msleep(400);
1159 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1160 msleep(60);
1161 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1162 msleep(30);
1163 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1164 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1165 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1166 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1167 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
1168 msleep(30);
1169
1170 /* Put the CX25843 to sleep for now since we're in digital mode */
1171 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
1172
1173 /* GPIOs are initialized, do the attach */
1174 adap->fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
1175 &adap->dev->i2c_adap);
1176 return adap->fe == NULL ? -ENODEV : 0;
1177}
1178
1179static int dib0700_xc5000_tuner_callback(void *priv, int component,
1180 int command, int arg)
1181{
1182 struct dvb_usb_adapter *adap = priv;
1183
1184 if (command == XC5000_TUNER_RESET) {
1185 /* Reset the tuner */
1186 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
1187 msleep(330); /* from Windows USB trace */
1188 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
1189 msleep(330); /* from Windows USB trace */
1190 } else {
1191 err("xc5000: unknown tuner callback command: %d\n", command);
1192 return -EINVAL;
1193 }
1194
1195 return 0;
1196}
1197
1198static struct xc5000_config s5h1411_xc5000_tunerconfig = {
1199 .i2c_address = 0x64,
1200 .if_khz = 5380,
1201};
1202
1203static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
1204{
1205 /* FIXME: generalize & move to common area */
1206 adap->fe->callback = dib0700_xc5000_tuner_callback;
1207
1208 return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap,
1209 &s5h1411_xc5000_tunerconfig)
1210 == NULL ? -ENODEV : 0;
1211}
1212
1081/* DVB-USB and USB stuff follows */ 1213/* DVB-USB and USB stuff follows */
1082struct usb_device_id dib0700_usb_id_table[] = { 1214struct usb_device_id dib0700_usb_id_table[] = {
1083/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) }, 1215/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
@@ -1119,6 +1251,11 @@ struct usb_device_id dib0700_usb_id_table[] = {
1119 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) }, 1251 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
1120/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) }, 1252/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
1121 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) }, 1253 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
1254 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) },
1255 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) },
1256 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
1257/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
1258 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
1122 { 0 } /* Terminating entry */ 1259 { 0 } /* Terminating entry */
1123}; 1260};
1124MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 1261MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1126,7 +1263,7 @@ MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
1126#define DIB0700_DEFAULT_DEVICE_PROPERTIES \ 1263#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
1127 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \ 1264 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
1128 .usb_ctrl = DEVICE_SPECIFIC, \ 1265 .usb_ctrl = DEVICE_SPECIFIC, \
1129 .firmware = "dvb-usb-dib0700-1.10.fw", \ 1266 .firmware = "dvb-usb-dib0700-1.20.fw", \
1130 .download_firmware = dib0700_download_firmware, \ 1267 .download_firmware = dib0700_download_firmware, \
1131 .no_reconnect = 1, \ 1268 .no_reconnect = 1, \
1132 .size_of_priv = sizeof(struct dib0700_state), \ 1269 .size_of_priv = sizeof(struct dib0700_state), \
@@ -1293,7 +1430,12 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1293 { &dib0700_usb_id_table[31], NULL }, 1430 { &dib0700_usb_id_table[31], NULL },
1294 { NULL }, 1431 { NULL },
1295 } 1432 }
1296 } 1433 },
1434
1435 .rc_interval = DEFAULT_RC_INTERVAL,
1436 .rc_key_map = dib0700_rc_keys,
1437 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1438 .rc_query = dib0700_rc_query
1297 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 1439 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1298 1440
1299 .num_adapters = 1, 1441 .num_adapters = 1,
@@ -1408,7 +1550,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1408 }, 1550 },
1409 }, 1551 },
1410 1552
1411 .num_device_descs = 3, 1553 .num_device_descs = 5,
1412 .devices = { 1554 .devices = {
1413 { "Terratec Cinergy HT USB XE", 1555 { "Terratec Cinergy HT USB XE",
1414 { &dib0700_usb_id_table[27], NULL }, 1556 { &dib0700_usb_id_table[27], NULL },
@@ -1422,6 +1564,47 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1422 { &dib0700_usb_id_table[32], NULL }, 1564 { &dib0700_usb_id_table[32], NULL },
1423 { NULL }, 1565 { NULL },
1424 }, 1566 },
1567 { "Gigabyte U8000-RH",
1568 { &dib0700_usb_id_table[37], NULL },
1569 { NULL },
1570 },
1571 { "YUAN High-Tech STK7700PH",
1572 { &dib0700_usb_id_table[38], NULL },
1573 { NULL },
1574 },
1575 { "Asus My Cinema-U3000Hybrid",
1576 { &dib0700_usb_id_table[39], NULL },
1577 { NULL },
1578 },
1579 },
1580 .rc_interval = DEFAULT_RC_INTERVAL,
1581 .rc_key_map = dib0700_rc_keys,
1582 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
1583 .rc_query = dib0700_rc_query
1584 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1585 .num_adapters = 1,
1586 .adapter = {
1587 {
1588 .frontend_attach = s5h1411_frontend_attach,
1589 .tuner_attach = xc5000_tuner_attach,
1590
1591 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
1592
1593 .size_of_priv = sizeof(struct
1594 dib0700_adapter_state),
1595 },
1596 },
1597
1598 .num_device_descs = 2,
1599 .devices = {
1600 { "Pinnacle PCTV HD Pro USB Stick",
1601 { &dib0700_usb_id_table[40], NULL },
1602 { NULL },
1603 },
1604 { "Pinnacle PCTV HD USB Stick",
1605 { &dib0700_usb_id_table[41], NULL },
1606 { NULL },
1607 },
1425 }, 1608 },
1426 .rc_interval = DEFAULT_RC_INTERVAL, 1609 .rc_interval = DEFAULT_RC_INTERVAL,
1427 .rc_key_map = dib0700_rc_keys, 1610 .rc_key_map = dib0700_rc_keys,
diff --git a/drivers/media/dvb/dvb-usb/dtv5100.c b/drivers/media/dvb/dvb-usb/dtv5100.c
new file mode 100644
index 000000000000..078ce92ca436
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtv5100.c
@@ -0,0 +1,240 @@
1/*
2 * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
3 *
4 * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com>
5 * http://royale.zerezo.com/dtv5100/
6 *
7 * Inspired by gl861.c and au6610.c drivers
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "dtv5100.h"
25#include "zl10353.h"
26#include "qt1010.h"
27
28/* debug */
29static int dvb_usb_dtv5100_debug;
30module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644);
31MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
32DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
33
34static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
35 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
36{
37 u8 request;
38 u8 type;
39 u16 value;
40 u16 index;
41
42 switch (wlen) {
43 case 1:
44 /* write { reg }, read { value } */
45 request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ :
46 DTV5100_TUNER_READ);
47 type = USB_TYPE_VENDOR | USB_DIR_IN;
48 value = 0;
49 break;
50 case 2:
51 /* write { reg, value } */
52 request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE :
53 DTV5100_TUNER_WRITE);
54 type = USB_TYPE_VENDOR | USB_DIR_OUT;
55 value = wbuf[1];
56 break;
57 default:
58 warn("wlen = %x, aborting.", wlen);
59 return -EINVAL;
60 }
61 index = (addr << 8) + wbuf[0];
62
63 msleep(1); /* avoid I2C errors */
64 return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request,
65 type, value, index, rbuf, rlen,
66 DTV5100_USB_TIMEOUT);
67}
68
69/* I2C */
70static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
71 int num)
72{
73 struct dvb_usb_device *d = i2c_get_adapdata(adap);
74 int i;
75
76 if (num > 2)
77 return -EINVAL;
78
79 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
80 return -EAGAIN;
81
82 for (i = 0; i < num; i++) {
83 /* write/read request */
84 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
85 if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
86 msg[i].len, msg[i+1].buf,
87 msg[i+1].len) < 0)
88 break;
89 i++;
90 } else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
91 msg[i].len, NULL, 0) < 0)
92 break;
93 }
94
95 mutex_unlock(&d->i2c_mutex);
96 return i;
97}
98
99static u32 dtv5100_i2c_func(struct i2c_adapter *adapter)
100{
101 return I2C_FUNC_I2C;
102}
103
104static struct i2c_algorithm dtv5100_i2c_algo = {
105 .master_xfer = dtv5100_i2c_xfer,
106 .functionality = dtv5100_i2c_func,
107};
108
109/* Callbacks for DVB USB */
110static struct zl10353_config dtv5100_zl10353_config = {
111 .demod_address = DTV5100_DEMOD_ADDR,
112 .no_tuner = 1,
113 .parallel_ts = 1,
114};
115
116static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap)
117{
118 adap->fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config,
119 &adap->dev->i2c_adap);
120 if (adap->fe == NULL)
121 return -EIO;
122
123 /* disable i2c gate, or it won't work... is this safe? */
124 adap->fe->ops.i2c_gate_ctrl = NULL;
125
126 return 0;
127}
128
129static struct qt1010_config dtv5100_qt1010_config = {
130 .i2c_address = DTV5100_TUNER_ADDR
131};
132
133static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap)
134{
135 return dvb_attach(qt1010_attach,
136 adap->fe, &adap->dev->i2c_adap,
137 &dtv5100_qt1010_config) == NULL ? -ENODEV : 0;
138}
139
140/* DVB USB Driver stuff */
141static struct dvb_usb_device_properties dtv5100_properties;
142
143static int dtv5100_probe(struct usb_interface *intf,
144 const struct usb_device_id *id)
145{
146 int i, ret;
147 struct usb_device *udev = interface_to_usbdev(intf);
148
149 /* initialize non qt1010/zl10353 part? */
150 for (i = 0; dtv5100_init[i].request; i++) {
151 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
152 dtv5100_init[i].request,
153 USB_TYPE_VENDOR | USB_DIR_OUT,
154 dtv5100_init[i].value,
155 dtv5100_init[i].index, NULL, 0,
156 DTV5100_USB_TIMEOUT);
157 if (ret)
158 return ret;
159 }
160
161 ret = dvb_usb_device_init(intf, &dtv5100_properties,
162 THIS_MODULE, NULL, adapter_nr);
163 if (ret)
164 return ret;
165
166 return 0;
167}
168
169static struct usb_device_id dtv5100_table[] = {
170 { USB_DEVICE(0x06be, 0xa232) },
171 { } /* Terminating entry */
172};
173MODULE_DEVICE_TABLE(usb, dtv5100_table);
174
175static struct dvb_usb_device_properties dtv5100_properties = {
176 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
177 .usb_ctrl = DEVICE_SPECIFIC,
178
179 .size_of_priv = 0,
180
181 .num_adapters = 1,
182 .adapter = {{
183 .frontend_attach = dtv5100_frontend_attach,
184 .tuner_attach = dtv5100_tuner_attach,
185
186 .stream = {
187 .type = USB_BULK,
188 .count = 8,
189 .endpoint = 0x82,
190 .u = {
191 .bulk = {
192 .buffersize = 4096,
193 }
194 }
195 },
196 } },
197
198 .i2c_algo = &dtv5100_i2c_algo,
199
200 .num_device_descs = 1,
201 .devices = {
202 {
203 .name = "AME DTV-5100 USB2.0 DVB-T",
204 .cold_ids = { NULL },
205 .warm_ids = { &dtv5100_table[0], NULL },
206 },
207 }
208};
209
210static struct usb_driver dtv5100_driver = {
211 .name = "dvb_usb_dtv5100",
212 .probe = dtv5100_probe,
213 .disconnect = dvb_usb_device_exit,
214 .id_table = dtv5100_table,
215};
216
217/* module stuff */
218static int __init dtv5100_module_init(void)
219{
220 int ret;
221
222 ret = usb_register(&dtv5100_driver);
223 if (ret)
224 err("usb_register failed. Error number %d", ret);
225
226 return ret;
227}
228
229static void __exit dtv5100_module_exit(void)
230{
231 /* deregister this driver from the USB subsystem */
232 usb_deregister(&dtv5100_driver);
233}
234
235module_init(dtv5100_module_init);
236module_exit(dtv5100_module_exit);
237
238MODULE_AUTHOR(DRIVER_AUTHOR);
239MODULE_DESCRIPTION(DRIVER_DESC);
240MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtv5100.h b/drivers/media/dvb/dvb-usb/dtv5100.h
new file mode 100644
index 000000000000..93e96e04a82a
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtv5100.h
@@ -0,0 +1,51 @@
1/*
2 * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
3 *
4 * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com>
5 * http://royale.zerezo.com/dtv5100/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef _DVB_USB_DTV5100_H_
23#define _DVB_USB_DTV5100_H_
24
25#define DVB_USB_LOG_PREFIX "dtv5100"
26#include "dvb-usb.h"
27
28#define DTV5100_USB_TIMEOUT 500
29
30#define DTV5100_DEMOD_ADDR 0x00
31#define DTV5100_DEMOD_WRITE 0xc0
32#define DTV5100_DEMOD_READ 0xc1
33
34#define DTV5100_TUNER_ADDR 0xc4
35#define DTV5100_TUNER_WRITE 0xc7
36#define DTV5100_TUNER_READ 0xc8
37
38#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
39#define DRIVER_DESC "AME DTV-5100 USB2.0 DVB-T"
40
41static struct {
42 u8 request;
43 u8 value;
44 u16 index;
45} dtv5100_init[] = {
46 { 0x000000c5, 0x00000000, 0x00000001 },
47 { 0x000000c5, 0x00000001, 0x00000001 },
48 { } /* Terminating entry */
49};
50
51#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 03dfb9f2fe30..7380b94b3b36 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -22,6 +22,7 @@
22#define USB_VID_AVERMEDIA 0x07ca 22#define USB_VID_AVERMEDIA 0x07ca
23#define USB_VID_COMPRO 0x185b 23#define USB_VID_COMPRO 0x185b
24#define USB_VID_COMPRO_UNK 0x145f 24#define USB_VID_COMPRO_UNK 0x145f
25#define USB_VID_CONEXANT 0x0572
25#define USB_VID_CYPRESS 0x04b4 26#define USB_VID_CYPRESS 0x04b4
26#define USB_VID_DIBCOM 0x10b8 27#define USB_VID_DIBCOM 0x10b8
27#define USB_VID_DPOSH 0x1498 28#define USB_VID_DPOSH 0x1498
@@ -33,16 +34,19 @@
33#define USB_VID_HAUPPAUGE 0x2040 34#define USB_VID_HAUPPAUGE 0x2040
34#define USB_VID_HYPER_PALTEK 0x1025 35#define USB_VID_HYPER_PALTEK 0x1025
35#define USB_VID_KWORLD 0xeb2a 36#define USB_VID_KWORLD 0xeb2a
37#define USB_VID_KWORLD_2 0x1b80
36#define USB_VID_KYE 0x0458 38#define USB_VID_KYE 0x0458
37#define USB_VID_LEADTEK 0x0413 39#define USB_VID_LEADTEK 0x0413
38#define USB_VID_LITEON 0x04ca 40#define USB_VID_LITEON 0x04ca
39#define USB_VID_MEDION 0x1660 41#define USB_VID_MEDION 0x1660
40#define USB_VID_MIGLIA 0x18f3 42#define USB_VID_MIGLIA 0x18f3
41#define USB_VID_MSI 0x0db0 43#define USB_VID_MSI 0x0db0
44#define USB_VID_MSI_2 0x1462
42#define USB_VID_OPERA1 0x695c 45#define USB_VID_OPERA1 0x695c
43#define USB_VID_PINNACLE 0x2304 46#define USB_VID_PINNACLE 0x2304
44#define USB_VID_TECHNOTREND 0x0b48 47#define USB_VID_TECHNOTREND 0x0b48
45#define USB_VID_TERRATEC 0x0ccd 48#define USB_VID_TERRATEC 0x0ccd
49#define USB_VID_TELESTAR 0x10b9
46#define USB_VID_VISIONPLUS 0x13d3 50#define USB_VID_VISIONPLUS 0x13d3
47#define USB_VID_TWINHAN 0x1822 51#define USB_VID_TWINHAN 0x1822
48#define USB_VID_ULTIMA_ELECTRONIC 0x05d8 52#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
@@ -50,15 +54,18 @@
50#define USB_VID_WIDEVIEW 0x14aa 54#define USB_VID_WIDEVIEW 0x14aa
51#define USB_VID_GIGABYTE 0x1044 55#define USB_VID_GIGABYTE 0x1044
52#define USB_VID_YUAN 0x1164 56#define USB_VID_YUAN 0x1164
53 57#define USB_VID_XTENSIONS 0x1ae7
54 58
55/* Product IDs */ 59/* Product IDs */
56#define USB_PID_ADSTECH_USB2_COLD 0xa333 60#define USB_PID_ADSTECH_USB2_COLD 0xa333
57#define USB_PID_ADSTECH_USB2_WARM 0xa334 61#define USB_PID_ADSTECH_USB2_WARM 0xa334
58#define USB_PID_AFATECH_AF9005 0x9020 62#define USB_PID_AFATECH_AF9005 0x9020
63#define USB_PID_AFATECH_AF9015_9015 0x9015
64#define USB_PID_AFATECH_AF9015_9016 0x9016
59#define USB_VID_ALINK_DTU 0xf170 65#define USB_VID_ALINK_DTU 0xf170
60#define USB_PID_ANSONIC_DVBT_USB 0x6000 66#define USB_PID_ANSONIC_DVBT_USB 0x6000
61#define USB_PID_ANYSEE 0x861f 67#define USB_PID_ANYSEE 0x861f
68#define USB_PID_AZUREWAVE_AD_TU700 0x3237
62#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 69#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
63#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 70#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
64#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 71#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
@@ -69,6 +76,7 @@
69#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d 76#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
70#define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78 77#define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78
71#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80 78#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80
79#define USB_PID_CONEXANT_D680_DMB 0x86d6
72#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 80#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
73#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 81#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
74#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 82#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
@@ -87,9 +95,12 @@
87#define USB_PID_UNIWILL_STK7700P 0x6003 95#define USB_PID_UNIWILL_STK7700P 0x6003
88#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 96#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
89#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 97#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
98#define USB_PID_KWORLD_399U 0xe399
99#define USB_PID_KWORLD_PC160_2T 0xc160
90#define USB_PID_KWORLD_VSTREAM_COLD 0x17de 100#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
91#define USB_PID_KWORLD_VSTREAM_WARM 0x17df 101#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
92#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 102#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055
103#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069
93#define USB_PID_TWINHAN_VP7041_COLD 0x3201 104#define USB_PID_TWINHAN_VP7041_COLD 0x3201
94#define USB_PID_TWINHAN_VP7041_WARM 0x3202 105#define USB_PID_TWINHAN_VP7041_WARM 0x3202
95#define USB_PID_TWINHAN_VP7020_COLD 0x3203 106#define USB_PID_TWINHAN_VP7020_COLD 0x3203
@@ -98,6 +109,7 @@
98#define USB_PID_TWINHAN_VP7045_WARM 0x3206 109#define USB_PID_TWINHAN_VP7045_WARM 0x3206
99#define USB_PID_TWINHAN_VP7021_COLD 0x3207 110#define USB_PID_TWINHAN_VP7021_COLD 0x3207
100#define USB_PID_TWINHAN_VP7021_WARM 0x3208 111#define USB_PID_TWINHAN_VP7021_WARM 0x3208
112#define USB_PID_TINYTWIN 0x3226
101#define USB_PID_DNTV_TINYUSB2_COLD 0x3223 113#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
102#define USB_PID_DNTV_TINYUSB2_WARM 0x3224 114#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
103#define USB_PID_ULTIMA_TVBOX_COLD 0x8105 115#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
@@ -144,6 +156,9 @@
144#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R 0x0039 156#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R 0x0039
145#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC 0x1039 157#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC 0x1039
146#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT 0x2039 158#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT 0x2039
159#define USB_PID_AVERMEDIA_VOLAR_X 0xa815
160#define USB_PID_AVERMEDIA_VOLAR_X_2 0x8150
161#define USB_PID_AVERMEDIA_A309 0xa309
147#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 162#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
148#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a 163#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
149#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 164#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
@@ -153,8 +168,11 @@
153#define USB_PID_PINNACLE_PCTV2000E 0x022c 168#define USB_PID_PINNACLE_PCTV2000E 0x022c
154#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 169#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228
155#define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T 0x0229 170#define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T 0x0229
171#define USB_PID_PINNACLE_PCTV71E 0x022b
156#define USB_PID_PINNACLE_PCTV72E 0x0236 172#define USB_PID_PINNACLE_PCTV72E 0x0236
157#define USB_PID_PINNACLE_PCTV73E 0x0237 173#define USB_PID_PINNACLE_PCTV73E 0x0237
174#define USB_PID_PINNACLE_PCTV801E 0x023a
175#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
158#define USB_PID_PCTV_200E 0x020e 176#define USB_PID_PCTV_200E 0x020e
159#define USB_PID_PCTV_400E 0x020f 177#define USB_PID_PCTV_400E 0x020f
160#define USB_PID_PCTV_450E 0x0222 178#define USB_PID_PCTV_450E 0x0222
@@ -171,6 +189,7 @@
171#define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD 0xdb58 189#define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD 0xdb58
172#define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM 0xdb59 190#define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM 0xdb59
173#define USB_PID_DVICO_BLUEBIRD_DUAL_4 0xdb78 191#define USB_PID_DVICO_BLUEBIRD_DUAL_4 0xdb78
192#define USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2 0xdb98
174#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2 0xdb70 193#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2 0xdb70
175#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM 0xdb71 194#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM 0xdb71
176#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54 195#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54
@@ -190,6 +209,7 @@
190#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 209#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026
191#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 210#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00
192#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01 211#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01
212#define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029
193#define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200 213#define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200
194#define USB_PID_GENPIX_8PSK_REV_1_WARM 0x0201 214#define USB_PID_GENPIX_8PSK_REV_1_WARM 0x0201
195#define USB_PID_GENPIX_8PSK_REV_2 0x0202 215#define USB_PID_GENPIX_8PSK_REV_2 0x0202
@@ -197,14 +217,21 @@
197#define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204 217#define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204
198#define USB_PID_SIGMATEK_DVB_110 0x6610 218#define USB_PID_SIGMATEK_DVB_110 0x6610
199#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513 219#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513
220#define USB_PID_MSI_DIGIVOX_DUO 0x8801
200#define USB_PID_OPERA1_COLD 0x2830 221#define USB_PID_OPERA1_COLD 0x2830
201#define USB_PID_OPERA1_WARM 0x3829 222#define USB_PID_OPERA1_WARM 0x3829
202#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514 223#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514
203#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513 224#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513
204#define USB_PID_GIGABYTE_U7000 0x7001 225#define USB_PID_GIGABYTE_U7000 0x7001
226#define USB_PID_GIGABYTE_U8000 0x7002
205#define USB_PID_ASUS_U3000 0x171f 227#define USB_PID_ASUS_U3000 0x171f
228#define USB_PID_ASUS_U3000H 0x1736
206#define USB_PID_ASUS_U3100 0x173f 229#define USB_PID_ASUS_U3100 0x173f
207#define USB_PID_YUAN_EC372S 0x1edc 230#define USB_PID_YUAN_EC372S 0x1edc
231#define USB_PID_YUAN_STK7700PH 0x1f08
208#define USB_PID_DW2102 0x2102 232#define USB_PID_DW2102 0x2102
233#define USB_PID_XTENSIONS_XD_380 0x0381
234#define USB_PID_TELESTAR_STARSTICK_2 0x8000
235#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807
209 236
210#endif 237#endif
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index a4d898b44e55..ca53df61caa8 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -1,4 +1,5 @@
1/* DVB USB framework compliant Linux driver for the DVBWorld DVB-S 2102 Card 1/* DVB USB framework compliant Linux driver for the
2* DVBWorld DVB-S 2101, 2102, DVB-S2 2104 Card
2* 3*
3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) 4* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
4* 5*
@@ -10,62 +11,74 @@
10*/ 11*/
11#include <linux/version.h> 12#include <linux/version.h>
12#include "dw2102.h" 13#include "dw2102.h"
14#include "si21xx.h"
13#include "stv0299.h" 15#include "stv0299.h"
14#include "z0194a.h" 16#include "z0194a.h"
17#include "stv0288.h"
18#include "stb6000.h"
19#include "eds1547.h"
20#include "cx24116.h"
15 21
16#ifndef USB_PID_DW2102 22#ifndef USB_PID_DW2102
17#define USB_PID_DW2102 0x2102 23#define USB_PID_DW2102 0x2102
18#endif 24#endif
19 25
20#define DW2102_READ_MSG 0 26#ifndef USB_PID_DW2104
21#define DW2102_WRITE_MSG 1 27#define USB_PID_DW2104 0x2104
28#endif
29
30#define DW210X_READ_MSG 0
31#define DW210X_WRITE_MSG 1
22 32
23#define REG_1F_SYMBOLRATE_BYTE0 0x1f 33#define REG_1F_SYMBOLRATE_BYTE0 0x1f
24#define REG_20_SYMBOLRATE_BYTE1 0x20 34#define REG_20_SYMBOLRATE_BYTE1 0x20
25#define REG_21_SYMBOLRATE_BYTE2 0x21 35#define REG_21_SYMBOLRATE_BYTE2 0x21
26 36/* on my own*/
27#define DW2102_VOLTAGE_CTRL (0x1800) 37#define DW2102_VOLTAGE_CTRL (0x1800)
28#define DW2102_RC_QUERY (0x1a00) 38#define DW2102_RC_QUERY (0x1a00)
29 39
30struct dw2102_state { 40struct dw210x_state {
31 u32 last_key_pressed; 41 u32 last_key_pressed;
32}; 42};
33struct dw2102_rc_keys { 43struct dw210x_rc_keys {
34 u32 keycode; 44 u32 keycode;
35 u32 event; 45 u32 event;
36}; 46};
37 47
48/* debug */
49static int dvb_usb_dw2102_debug;
50module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
51MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS);
52
38DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 53DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
39 54
40static int dw2102_op_rw(struct usb_device *dev, u8 request, u16 value, 55static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
41 u8 *data, u16 len, int flags) 56 u16 index, u8 * data, u16 len, int flags)
42{ 57{
43 int ret; 58 int ret;
44 u8 u8buf[len]; 59 u8 u8buf[len];
45 60
46 unsigned int pipe = (flags == DW2102_READ_MSG) ? 61 unsigned int pipe = (flags == DW210X_READ_MSG) ?
47 usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); 62 usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
48 u8 request_type = (flags == DW2102_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; 63 u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
49 64
50 if (flags == DW2102_WRITE_MSG) 65 if (flags == DW210X_WRITE_MSG)
51 memcpy(u8buf, data, len); 66 memcpy(u8buf, data, len);
52 ret = usb_control_msg(dev, pipe, request, 67 ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
53 request_type | USB_TYPE_VENDOR, value, 0 , u8buf, len, 2000); 68 value, index , u8buf, len, 2000);
54 69
55 if (flags == DW2102_READ_MSG) 70 if (flags == DW210X_READ_MSG)
56 memcpy(data, u8buf, len); 71 memcpy(data, u8buf, len);
57 return ret; 72 return ret;
58} 73}
59 74
60/* I2C */ 75/* I2C */
61
62static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], 76static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
63 int num) 77 int num)
64{ 78{
65struct dvb_usb_device *d = i2c_get_adapdata(adap); 79struct dvb_usb_device *d = i2c_get_adapdata(adap);
66 int i = 0, ret = 0; 80 int i = 0, ret = 0;
67 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; 81 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
68 u8 request;
69 u16 value; 82 u16 value;
70 83
71 if (!d) 84 if (!d)
@@ -76,14 +89,12 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap);
76 switch (num) { 89 switch (num) {
77 case 2: 90 case 2:
78 /* read stv0299 register */ 91 /* read stv0299 register */
79 request = 0xb5;
80 value = msg[0].buf[0];/* register */ 92 value = msg[0].buf[0];/* register */
81 for (i = 0; i < msg[1].len; i++) { 93 for (i = 0; i < msg[1].len; i++) {
82 value = value + i; 94 value = value + i;
83 ret = dw2102_op_rw(d->udev, 0xb5, 95 ret = dw210x_op_rw(d->udev, 0xb5, value, 0,
84 value, buf6, 2, DW2102_READ_MSG); 96 buf6, 2, DW210X_READ_MSG);
85 msg[1].buf[i] = buf6[0]; 97 msg[1].buf[i] = buf6[0];
86
87 } 98 }
88 break; 99 break;
89 case 1: 100 case 1:
@@ -93,8 +104,8 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap);
93 buf6[0] = 0x2a; 104 buf6[0] = 0x2a;
94 buf6[1] = msg[0].buf[0]; 105 buf6[1] = msg[0].buf[0];
95 buf6[2] = msg[0].buf[1]; 106 buf6[2] = msg[0].buf[1];
96 ret = dw2102_op_rw(d->udev, 0xb2, 107 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
97 0, buf6, 3, DW2102_WRITE_MSG); 108 buf6, 3, DW210X_WRITE_MSG);
98 break; 109 break;
99 case 0x60: 110 case 0x60:
100 if (msg[0].flags == 0) { 111 if (msg[0].flags == 0) {
@@ -106,26 +117,26 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap);
106 buf6[4] = msg[0].buf[1]; 117 buf6[4] = msg[0].buf[1];
107 buf6[5] = msg[0].buf[2]; 118 buf6[5] = msg[0].buf[2];
108 buf6[6] = msg[0].buf[3]; 119 buf6[6] = msg[0].buf[3];
109 ret = dw2102_op_rw(d->udev, 0xb2, 120 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
110 0, buf6, 7, DW2102_WRITE_MSG); 121 buf6, 7, DW210X_WRITE_MSG);
111 } else { 122 } else {
112 /* write to tuner pll */ 123 /* read from tuner */
113 ret = dw2102_op_rw(d->udev, 0xb5, 124 ret = dw210x_op_rw(d->udev, 0xb5, 0, 0,
114 0, buf6, 1, DW2102_READ_MSG); 125 buf6, 1, DW210X_READ_MSG);
115 msg[0].buf[0] = buf6[0]; 126 msg[0].buf[0] = buf6[0];
116 } 127 }
117 break; 128 break;
118 case (DW2102_RC_QUERY): 129 case (DW2102_RC_QUERY):
119 ret = dw2102_op_rw(d->udev, 0xb8, 130 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
120 0, buf6, 2, DW2102_READ_MSG); 131 buf6, 2, DW210X_READ_MSG);
121 msg[0].buf[0] = buf6[0]; 132 msg[0].buf[0] = buf6[0];
122 msg[0].buf[1] = buf6[1]; 133 msg[0].buf[1] = buf6[1];
123 break; 134 break;
124 case (DW2102_VOLTAGE_CTRL): 135 case (DW2102_VOLTAGE_CTRL):
125 buf6[0] = 0x30; 136 buf6[0] = 0x30;
126 buf6[1] = msg[0].buf[0]; 137 buf6[1] = msg[0].buf[0];
127 ret = dw2102_op_rw(d->udev, 0xb2, 138 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
128 0, buf6, 2, DW2102_WRITE_MSG); 139 buf6, 2, DW210X_WRITE_MSG);
129 break; 140 break;
130 } 141 }
131 142
@@ -136,17 +147,265 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap);
136 return num; 147 return num;
137} 148}
138 149
139static u32 dw2102_i2c_func(struct i2c_adapter *adapter) 150static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
151 struct i2c_msg msg[], int num)
152{
153 struct dvb_usb_device *d = i2c_get_adapdata(adap);
154 int ret = 0;
155 u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
156
157 if (!d)
158 return -ENODEV;
159 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
160 return -EAGAIN;
161
162 switch (num) {
163 case 2:
164 /* read si2109 register by number */
165 buf6[0] = 0xd0;
166 buf6[1] = msg[0].len;
167 buf6[2] = msg[0].buf[0];
168 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
169 buf6, msg[0].len + 2, DW210X_WRITE_MSG);
170 /* read si2109 register */
171 ret = dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
172 buf6, msg[1].len + 2, DW210X_READ_MSG);
173 memcpy(msg[1].buf, buf6 + 2, msg[1].len);
174
175 break;
176 case 1:
177 switch (msg[0].addr) {
178 case 0x68:
179 /* write to si2109 register */
180 buf6[0] = 0xd0;
181 buf6[1] = msg[0].len;
182 memcpy(buf6 + 2, msg[0].buf, msg[0].len);
183 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
184 msg[0].len + 2, DW210X_WRITE_MSG);
185 break;
186 case(DW2102_RC_QUERY):
187 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
188 buf6, 2, DW210X_READ_MSG);
189 msg[0].buf[0] = buf6[0];
190 msg[0].buf[1] = buf6[1];
191 break;
192 case(DW2102_VOLTAGE_CTRL):
193 buf6[0] = 0x30;
194 buf6[1] = msg[0].buf[0];
195 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
196 buf6, 2, DW210X_WRITE_MSG);
197 break;
198 }
199 break;
200 }
201
202 mutex_unlock(&d->i2c_mutex);
203 return num;
204}
205static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
206{
207 struct dvb_usb_device *d = i2c_get_adapdata(adap);
208 int ret = 0;
209
210 if (!d)
211 return -ENODEV;
212 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
213 return -EAGAIN;
214
215 switch (num) {
216 case 2: {
217 /* read */
218 /* first write first register number */
219 u8 ibuf [msg[1].len + 2], obuf[3];
220 obuf[0] = 0xd0;
221 obuf[1] = msg[0].len;
222 obuf[2] = msg[0].buf[0];
223 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
224 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
225 /* second read registers */
226 ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
227 ibuf, msg[1].len + 2, DW210X_READ_MSG);
228 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
229
230 break;
231 }
232 case 1:
233 switch (msg[0].addr) {
234 case 0x68: {
235 /* write to register */
236 u8 obuf[msg[0].len + 2];
237 obuf[0] = 0xd0;
238 obuf[1] = msg[0].len;
239 memcpy(obuf + 2, msg[0].buf, msg[0].len);
240 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
241 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
242 break;
243 }
244 case 0x61: {
245 /* write to tuner */
246 u8 obuf[msg[0].len + 2];
247 obuf[0] = 0xc2;
248 obuf[1] = msg[0].len;
249 memcpy(obuf + 2, msg[0].buf, msg[0].len);
250 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
251 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
252 break;
253 }
254 case(DW2102_RC_QUERY): {
255 u8 ibuf[2];
256 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
257 ibuf, 2, DW210X_READ_MSG);
258 memcpy(msg[0].buf, ibuf , 2);
259 break;
260 }
261 case(DW2102_VOLTAGE_CTRL): {
262 u8 obuf[2];
263 obuf[0] = 0x30;
264 obuf[1] = msg[0].buf[0];
265 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
266 obuf, 2, DW210X_WRITE_MSG);
267 break;
268 }
269 }
270
271 break;
272 }
273
274 mutex_unlock(&d->i2c_mutex);
275 return num;
276}
277
278static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
279{
280 struct dvb_usb_device *d = i2c_get_adapdata(adap);
281 int ret = 0;
282 int len, i;
283
284 if (!d)
285 return -ENODEV;
286 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
287 return -EAGAIN;
288
289 switch (num) {
290 case 2: {
291 /* read */
292 /* first write first register number */
293 u8 ibuf [msg[1].len + 2], obuf[3];
294 obuf[0] = 0xaa;
295 obuf[1] = msg[0].len;
296 obuf[2] = msg[0].buf[0];
297 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
298 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
299 /* second read registers */
300 ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0,
301 ibuf, msg[1].len + 2, DW210X_READ_MSG);
302 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
303
304 break;
305 }
306 case 1:
307 switch (msg[0].addr) {
308 case 0x55: {
309 if (msg[0].buf[0] == 0xf7) {
310 /* firmware */
311 /* Write in small blocks */
312 u8 obuf[19];
313 obuf[0] = 0xaa;
314 obuf[1] = 0x11;
315 obuf[2] = 0xf7;
316 len = msg[0].len - 1;
317 i = 1;
318 do {
319 memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len));
320 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
321 obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG);
322 i += 16;
323 len -= 16;
324 } while (len > 0);
325 } else {
326 /* write to register */
327 u8 obuf[msg[0].len + 2];
328 obuf[0] = 0xaa;
329 obuf[1] = msg[0].len;
330 memcpy(obuf + 2, msg[0].buf, msg[0].len);
331 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
332 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
333 }
334 break;
335 }
336 case(DW2102_RC_QUERY): {
337 u8 ibuf[2];
338 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
339 ibuf, 2, DW210X_READ_MSG);
340 memcpy(msg[0].buf, ibuf , 2);
341 break;
342 }
343 case(DW2102_VOLTAGE_CTRL): {
344 u8 obuf[2];
345 obuf[0] = 0x30;
346 obuf[1] = msg[0].buf[0];
347 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
348 obuf, 2, DW210X_WRITE_MSG);
349 break;
350 }
351 }
352
353 break;
354 }
355
356 mutex_unlock(&d->i2c_mutex);
357 return num;
358}
359
360static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
140{ 361{
141 return I2C_FUNC_I2C; 362 return I2C_FUNC_I2C;
142} 363}
143 364
144static struct i2c_algorithm dw2102_i2c_algo = { 365static struct i2c_algorithm dw2102_i2c_algo = {
145 .master_xfer = dw2102_i2c_transfer, 366 .master_xfer = dw2102_i2c_transfer,
146 .functionality = dw2102_i2c_func, 367 .functionality = dw210x_i2c_func,
368};
369
370static struct i2c_algorithm dw2102_serit_i2c_algo = {
371 .master_xfer = dw2102_serit_i2c_transfer,
372 .functionality = dw210x_i2c_func,
373};
374
375static struct i2c_algorithm dw2102_earda_i2c_algo = {
376 .master_xfer = dw2102_earda_i2c_transfer,
377 .functionality = dw210x_i2c_func,
378};
379
380static struct i2c_algorithm dw2104_i2c_algo = {
381 .master_xfer = dw2104_i2c_transfer,
382 .functionality = dw210x_i2c_func,
147}; 383};
148 384
149static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 385static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
386{
387 int i;
388 u8 ibuf[] = {0, 0};
389 u8 eeprom[256], eepromline[16];
390
391 for (i = 0; i < 256; i++) {
392 if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
393 err("read eeprom failed.");
394 return -1;
395 } else {
396 eepromline[i%16] = ibuf[0];
397 eeprom[i] = ibuf[0];
398 }
399 if ((i % 16) == 15) {
400 deb_xfer("%02x: ", i - 15);
401 debug_dump(eepromline, 16, deb_xfer);
402 }
403 }
404 memcpy(mac, eeprom + 8, 6);
405 return 0;
406};
407
408static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
150{ 409{
151 static u8 command_13v[1] = {0x00}; 410 static u8 command_13v[1] = {0x00};
152 static u8 command_18v[1] = {0x01}; 411 static u8 command_18v[1] = {0x01};
@@ -163,18 +422,66 @@ static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
163 return 0; 422 return 0;
164} 423}
165 424
166static int dw2102_frontend_attach(struct dvb_usb_adapter *d) 425static struct cx24116_config dw2104_config = {
426 .demod_address = 0x55,
427 .mpg_clk_pos_pol = 0x01,
428};
429
430static struct si21xx_config serit_sp1511lhb_config = {
431 .demod_address = 0x68,
432 .min_delay_ms = 100,
433
434};
435
436static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
167{ 437{
168 d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, 438 if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
169 &d->dev->i2c_adap); 439 &d->dev->i2c_adap)) != NULL) {
170 if (d->fe != NULL) { 440 d->fe->ops.set_voltage = dw210x_set_voltage;
171 d->fe->ops.set_voltage = dw2102_set_voltage; 441 info("Attached cx24116!\n");
172 info("Attached stv0299!\n");
173 return 0; 442 return 0;
174 } 443 }
175 return -EIO; 444 return -EIO;
176} 445}
177 446
447static struct dvb_usb_device_properties dw2102_properties;
448
449static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
450{
451 if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
452 /*dw2102_properties.adapter->tuner_attach = NULL;*/
453 d->fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
454 &d->dev->i2c_adap);
455 if (d->fe != NULL) {
456 d->fe->ops.set_voltage = dw210x_set_voltage;
457 info("Attached si21xx!\n");
458 return 0;
459 }
460 }
461 if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
462 /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
463 d->fe = dvb_attach(stv0288_attach, &earda_config,
464 &d->dev->i2c_adap);
465 if (d->fe != NULL) {
466 d->fe->ops.set_voltage = dw210x_set_voltage;
467 info("Attached stv0288!\n");
468 return 0;
469 }
470 }
471
472 if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
473 /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
474 d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
475 &d->dev->i2c_adap);
476 if (d->fe != NULL) {
477 d->fe->ops.set_voltage = dw210x_set_voltage;
478 info("Attached stv0299!\n");
479 return 0;
480 }
481 }
482 return -EIO;
483}
484
178static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) 485static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
179{ 486{
180 dvb_attach(dvb_pll_attach, adap->fe, 0x60, 487 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -182,7 +489,15 @@ static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
182 return 0; 489 return 0;
183} 490}
184 491
185static struct dvb_usb_rc_key dw2102_rc_keys[] = { 492static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap)
493{
494 dvb_attach(stb6000_attach, adap->fe, 0x61,
495 &adap->dev->i2c_adap);
496
497 return 0;
498}
499
500static struct dvb_usb_rc_key dw210x_rc_keys[] = {
186 { 0xf8, 0x0a, KEY_Q }, /*power*/ 501 { 0xf8, 0x0a, KEY_Q }, /*power*/
187 { 0xf8, 0x0c, KEY_M }, /*mute*/ 502 { 0xf8, 0x0c, KEY_M }, /*mute*/
188 { 0xf8, 0x11, KEY_1 }, 503 { 0xf8, 0x11, KEY_1 },
@@ -221,7 +536,7 @@ static struct dvb_usb_rc_key dw2102_rc_keys[] = {
221 536
222static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 537static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
223{ 538{
224 struct dw2102_state *st = d->priv; 539 struct dw210x_state *st = d->priv;
225 u8 key[2]; 540 u8 key[2];
226 struct i2c_msg msg[] = { 541 struct i2c_msg msg[] = {
227 {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key, 542 {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key,
@@ -231,12 +546,12 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
231 546
232 *state = REMOTE_NO_KEY_PRESSED; 547 *state = REMOTE_NO_KEY_PRESSED;
233 if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { 548 if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) {
234 for (i = 0; i < ARRAY_SIZE(dw2102_rc_keys); i++) { 549 for (i = 0; i < ARRAY_SIZE(dw210x_rc_keys); i++) {
235 if (dw2102_rc_keys[i].data == msg[0].buf[0]) { 550 if (dw210x_rc_keys[i].data == msg[0].buf[0]) {
236 *state = REMOTE_KEY_PRESSED; 551 *state = REMOTE_KEY_PRESSED;
237 *event = dw2102_rc_keys[i].event; 552 *event = dw210x_rc_keys[i].event;
238 st->last_key_pressed = 553 st->last_key_pressed =
239 dw2102_rc_keys[i].event; 554 dw210x_rc_keys[i].event;
240 break; 555 break;
241 } 556 }
242 st->last_key_pressed = 0; 557 st->last_key_pressed = 0;
@@ -249,6 +564,8 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
249static struct usb_device_id dw2102_table[] = { 564static struct usb_device_id dw2102_table[] = {
250 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, 565 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
251 {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, 566 {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
567 {USB_DEVICE(USB_VID_CYPRESS, 0x2104)},
568 {USB_DEVICE(0x9022, 0xd650)},
252 { } 569 { }
253}; 570};
254 571
@@ -260,7 +577,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
260 u8 *b, *p; 577 u8 *b, *p;
261 int ret = 0, i; 578 int ret = 0, i;
262 u8 reset; 579 u8 reset;
263 u8 reset16 [] = {0, 0, 0, 0, 0, 0, 0}; 580 u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
264 const struct firmware *fw; 581 const struct firmware *fw;
265 const char *filename = "dvb-usb-dw2101.fw"; 582 const char *filename = "dvb-usb-dw2101.fw";
266 switch (dev->descriptor.idProduct) { 583 switch (dev->descriptor.idProduct) {
@@ -273,25 +590,23 @@ static int dw2102_load_firmware(struct usb_device *dev,
273 return ret; 590 return ret;
274 } 591 }
275 break; 592 break;
276 case USB_PID_DW2102: 593 default:
277 fw = frmwr; 594 fw = frmwr;
278 break; 595 break;
279 } 596 }
280 info("start downloading DW2102 firmware"); 597 info("start downloading DW210X firmware");
281 p = kmalloc(fw->size, GFP_KERNEL); 598 p = kmalloc(fw->size, GFP_KERNEL);
282 reset = 1; 599 reset = 1;
283 /*stop the CPU*/ 600 /*stop the CPU*/
284 dw2102_op_rw(dev, 0xa0, 0x7f92, &reset, 1, DW2102_WRITE_MSG); 601 dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
285 dw2102_op_rw(dev, 0xa0, 0xe600, &reset, 1, DW2102_WRITE_MSG); 602 dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
286 603
287 if (p != NULL) { 604 if (p != NULL) {
288 memcpy(p, fw->data, fw->size); 605 memcpy(p, fw->data, fw->size);
289 for (i = 0; i < fw->size; i += 0x40) { 606 for (i = 0; i < fw->size; i += 0x40) {
290 b = (u8 *) p + i; 607 b = (u8 *) p + i;
291 if (dw2102_op_rw 608 if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
292 (dev, 0xa0, i, b , 0x40, 609 DW210X_WRITE_MSG) != 0x40) {
293 DW2102_WRITE_MSG) != 0x40
294 ) {
295 err("error while transferring firmware"); 610 err("error while transferring firmware");
296 ret = -EINVAL; 611 ret = -EINVAL;
297 break; 612 break;
@@ -299,43 +614,66 @@ static int dw2102_load_firmware(struct usb_device *dev,
299 } 614 }
300 /* restart the CPU */ 615 /* restart the CPU */
301 reset = 0; 616 reset = 0;
302 if (ret || dw2102_op_rw 617 if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
303 (dev, 0xa0, 0x7f92, &reset, 1, 618 DW210X_WRITE_MSG) != 1) {
304 DW2102_WRITE_MSG) != 1) {
305 err("could not restart the USB controller CPU."); 619 err("could not restart the USB controller CPU.");
306 ret = -EINVAL; 620 ret = -EINVAL;
307 } 621 }
308 if (ret || dw2102_op_rw 622 if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
309 (dev, 0xa0, 0xe600, &reset, 1, 623 DW210X_WRITE_MSG) != 1) {
310 DW2102_WRITE_MSG) != 1) {
311 err("could not restart the USB controller CPU."); 624 err("could not restart the USB controller CPU.");
312 ret = -EINVAL; 625 ret = -EINVAL;
313 } 626 }
314 /* init registers */ 627 /* init registers */
315 switch (dev->descriptor.idProduct) { 628 switch (dev->descriptor.idProduct) {
316 case USB_PID_DW2102: 629 case USB_PID_DW2104:
317 dw2102_op_rw 630 case 0xd650:
318 (dev, 0xbf, 0x0040, &reset, 0, 631 reset = 1;
319 DW2102_WRITE_MSG); 632 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
320 dw2102_op_rw 633 DW210X_WRITE_MSG);
321 (dev, 0xb9, 0x0000, &reset16[0], 2, 634 reset = 0;
322 DW2102_READ_MSG); 635 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
636 DW210X_WRITE_MSG);
323 break; 637 break;
638 case USB_PID_DW2102:
639 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
640 DW210X_WRITE_MSG);
641 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
642 DW210X_READ_MSG);
643 /* check STV0299 frontend */
644 dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
645 DW210X_READ_MSG);
646 if (reset16[0] == 0xa1) {
647 dw2102_properties.i2c_algo = &dw2102_i2c_algo;
648 dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach;
649 break;
650 } else {
651 /* check STV0288 frontend */
652 reset16[0] = 0xd0;
653 reset16[1] = 1;
654 reset16[2] = 0;
655 dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
656 DW210X_WRITE_MSG);
657 dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
658 DW210X_READ_MSG);
659 if (reset16[2] == 0x11) {
660 dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
661 dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach;
662 break;
663 }
664 }
324 case 0x2101: 665 case 0x2101:
325 dw2102_op_rw 666 dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
326 (dev, 0xbc, 0x0030, &reset16[0], 2, 667 DW210X_READ_MSG);
327 DW2102_READ_MSG); 668 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
328 dw2102_op_rw 669 DW210X_READ_MSG);
329 (dev, 0xba, 0x0000, &reset16[0], 7, 670 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
330 DW2102_READ_MSG); 671 DW210X_READ_MSG);
331 dw2102_op_rw 672 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
332 (dev, 0xba, 0x0000, &reset16[0], 7, 673 DW210X_READ_MSG);
333 DW2102_READ_MSG);
334 dw2102_op_rw
335 (dev, 0xb9, 0x0000, &reset16[0], 2,
336 DW2102_READ_MSG);
337 break; 674 break;
338 } 675 }
676 msleep(100);
339 kfree(p); 677 kfree(p);
340 } 678 }
341 return ret; 679 return ret;
@@ -345,12 +683,12 @@ static struct dvb_usb_device_properties dw2102_properties = {
345 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 683 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
346 .usb_ctrl = DEVICE_SPECIFIC, 684 .usb_ctrl = DEVICE_SPECIFIC,
347 .firmware = "dvb-usb-dw2102.fw", 685 .firmware = "dvb-usb-dw2102.fw",
348 .size_of_priv = sizeof(struct dw2102_state), 686 .size_of_priv = sizeof(struct dw210x_state),
349 .no_reconnect = 1, 687 .no_reconnect = 1,
350 688
351 .i2c_algo = &dw2102_i2c_algo, 689 .i2c_algo = &dw2102_serit_i2c_algo,
352 .rc_key_map = dw2102_rc_keys, 690 .rc_key_map = dw210x_rc_keys,
353 .rc_key_map_size = ARRAY_SIZE(dw2102_rc_keys), 691 .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys),
354 .rc_interval = 150, 692 .rc_interval = 150,
355 .rc_query = dw2102_rc_query, 693 .rc_query = dw2102_rc_query,
356 694
@@ -358,11 +696,12 @@ static struct dvb_usb_device_properties dw2102_properties = {
358 /* parameter for the MPEG2-data transfer */ 696 /* parameter for the MPEG2-data transfer */
359 .num_adapters = 1, 697 .num_adapters = 1,
360 .download_firmware = dw2102_load_firmware, 698 .download_firmware = dw2102_load_firmware,
361 .adapter = { 699 .read_mac_address = dw210x_read_mac_address,
700 .adapter = {
362 { 701 {
363 .frontend_attach = dw2102_frontend_attach, 702 .frontend_attach = dw2102_frontend_attach,
364 .streaming_ctrl = NULL, 703 .streaming_ctrl = NULL,
365 .tuner_attach = dw2102_tuner_attach, 704 .tuner_attach = NULL,
366 .stream = { 705 .stream = {
367 .type = USB_BULK, 706 .type = USB_BULK,
368 .count = 8, 707 .count = 8,
@@ -388,11 +727,64 @@ static struct dvb_usb_device_properties dw2102_properties = {
388 } 727 }
389}; 728};
390 729
730static struct dvb_usb_device_properties dw2104_properties = {
731 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
732 .usb_ctrl = DEVICE_SPECIFIC,
733 .firmware = "dvb-usb-dw2104.fw",
734 .size_of_priv = sizeof(struct dw210x_state),
735 .no_reconnect = 1,
736
737 .i2c_algo = &dw2104_i2c_algo,
738 .rc_key_map = dw210x_rc_keys,
739 .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys),
740 .rc_interval = 150,
741 .rc_query = dw2102_rc_query,
742
743 .generic_bulk_ctrl_endpoint = 0x81,
744 /* parameter for the MPEG2-data transfer */
745 .num_adapters = 1,
746 .download_firmware = dw2102_load_firmware,
747 .read_mac_address = dw210x_read_mac_address,
748 .adapter = {
749 {
750 .frontend_attach = dw2104_frontend_attach,
751 .streaming_ctrl = NULL,
752 /*.tuner_attach = dw2104_tuner_attach,*/
753 .stream = {
754 .type = USB_BULK,
755 .count = 8,
756 .endpoint = 0x82,
757 .u = {
758 .bulk = {
759 .buffersize = 4096,
760 }
761 }
762 },
763 }
764 },
765 .num_device_descs = 2,
766 .devices = {
767 { "DVBWorld DW2104 USB2.0",
768 {&dw2102_table[2], NULL},
769 {NULL},
770 },
771 { "TeVii S650 USB2.0",
772 {&dw2102_table[3], NULL},
773 {NULL},
774 },
775 }
776};
777
391static int dw2102_probe(struct usb_interface *intf, 778static int dw2102_probe(struct usb_interface *intf,
392 const struct usb_device_id *id) 779 const struct usb_device_id *id)
393{ 780{
394 return dvb_usb_device_init(intf, &dw2102_properties, 781 if (0 == dvb_usb_device_init(intf, &dw2102_properties,
395 THIS_MODULE, NULL, adapter_nr); 782 THIS_MODULE, NULL, adapter_nr) ||
783 0 == dvb_usb_device_init(intf, &dw2104_properties,
784 THIS_MODULE, NULL, adapter_nr)) {
785 return 0;
786 }
787 return -ENODEV;
396} 788}
397 789
398static struct usb_driver dw2102_driver = { 790static struct usb_driver dw2102_driver = {
@@ -420,6 +812,6 @@ module_init(dw2102_module_init);
420module_exit(dw2102_module_exit); 812module_exit(dw2102_module_exit);
421 813
422MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); 814MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
423MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101 2102 USB2.0 device"); 815MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104 USB2.0 device");
424MODULE_VERSION("0.1"); 816MODULE_VERSION("0.1");
425MODULE_LICENSE("GPL"); 817MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h
index 7a310f906837..e3370734e95a 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.h
+++ b/drivers/media/dvb/dvb-usb/dw2102.h
@@ -4,6 +4,5 @@
4#define DVB_USB_LOG_PREFIX "dw2102" 4#define DVB_USB_LOG_PREFIX "dw2102"
5#include "dvb-usb.h" 5#include "dvb-usb.h"
6 6
7extern int dvb_usb_dw2102_debug;
8#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) 7#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args)
9#endif 8#endif