blob: 56cbd3636c318aa327e96bf8b1397131ac70d370 [file] [log] [blame]
Antti Palosaari80619de2008-09-15 17:18:09 -03001/*
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
Jiri Slaby6c614042010-01-22 12:10:52 -030024#include <linux/hash.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090025#include <linux/slab.h>
Jiri Slaby6c614042010-01-22 12:10:52 -030026
Antti Palosaari80619de2008-09-15 17:18:09 -030027#include "af9015.h"
28#include "af9013.h"
29#include "mt2060.h"
30#include "qt1010.h"
31#include "tda18271.h"
32#include "mxl5005s.h"
Jochen Friedrichd5633992009-02-02 14:59:50 -030033#include "mc44s803.h"
Antti Palosaariee3d4402010-08-13 03:51:26 -030034#include "tda18218.h"
Antti Palosaariab07fdd2010-09-09 14:59:10 -030035#include "mxl5007t.h"
Antti Palosaari80619de2008-09-15 17:18:09 -030036
Antti Palosaari349d0422008-11-05 16:31:24 -030037static int dvb_usb_af9015_debug;
Antti Palosaari80619de2008-09-15 17:18:09 -030038module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
39MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
Antti Palosaari349d0422008-11-05 16:31:24 -030040static int dvb_usb_af9015_remote;
Antti Palosaari80619de2008-09-15 17:18:09 -030041module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
42MODULE_PARM_DESC(remote, "select remote");
Antti Palosaari80619de2008-09-15 17:18:09 -030043DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
44
45static DEFINE_MUTEX(af9015_usb_mutex);
46
47static struct af9015_config af9015_config;
Antti Palosaari85d7d7c2009-04-09 09:16:12 -030048static struct dvb_usb_device_properties af9015_properties[3];
Antti Palosaari349d0422008-11-05 16:31:24 -030049static int af9015_properties_count = ARRAY_SIZE(af9015_properties);
Antti Palosaari80619de2008-09-15 17:18:09 -030050
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,
Antti Palosaari80619de2008-09-15 17:18:09 -030057 .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{
Antti Palosaari06565d72009-09-12 20:46:30 -030069#define BUF_LEN 63
70#define REQ_HDR_LEN 8 /* send header size */
71#define ACK_HDR_LEN 2 /* rece header size */
Antti Palosaari80619de2008-09-15 17:18:09 -030072 int act_len, ret;
Antti Palosaari06565d72009-09-12 20:46:30 -030073 u8 buf[BUF_LEN];
Antti Palosaari80619de2008-09-15 17:18:09 -030074 u8 write = 1;
Antti Palosaari06565d72009-09-12 20:46:30 -030075 u8 msg_len = REQ_HDR_LEN;
Antti Palosaari80619de2008-09-15 17:18:09 -030076 static u8 seq; /* packet sequence number */
77
78 if (mutex_lock_interruptible(&af9015_usb_mutex) < 0)
79 return -EAGAIN;
80
81 buf[0] = req->cmd;
82 buf[1] = seq++;
83 buf[2] = req->i2c_addr;
84 buf[3] = req->addr >> 8;
85 buf[4] = req->addr & 0xff;
86 buf[5] = req->mbox;
87 buf[6] = req->addr_len;
88 buf[7] = req->data_len;
89
90 switch (req->cmd) {
91 case GET_CONFIG:
Antti Palosaari80619de2008-09-15 17:18:09 -030092 case READ_MEMORY:
93 case RECONNECT_USB:
Antti Palosaari80619de2008-09-15 17:18:09 -030094 write = 0;
95 break;
96 case READ_I2C:
97 write = 0;
98 buf[2] |= 0x01; /* set I2C direction */
99 case WRITE_I2C:
100 buf[0] = READ_WRITE_I2C;
101 break;
102 case WRITE_MEMORY:
103 if (((req->addr & 0xff00) == 0xff00) ||
Antti Palosaarif4e96de2009-09-12 21:25:59 -0300104 ((req->addr & 0xff00) == 0xae00))
Antti Palosaari80619de2008-09-15 17:18:09 -0300105 buf[0] = WRITE_VIRTUAL_MEMORY;
106 case WRITE_VIRTUAL_MEMORY:
107 case COPY_FIRMWARE:
108 case DOWNLOAD_FIRMWARE:
Nils Kassubeba1bc642009-07-28 11:54:52 -0300109 case BOOT:
Antti Palosaari80619de2008-09-15 17:18:09 -0300110 break;
111 default:
112 err("unknown command:%d", req->cmd);
113 ret = -1;
114 goto error_unlock;
115 }
116
Antti Palosaari06565d72009-09-12 20:46:30 -0300117 /* buffer overflow check */
118 if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
119 (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
120 err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
121 ret = -EINVAL;
122 goto error_unlock;
123 }
124
Antti Palosaari80619de2008-09-15 17:18:09 -0300125 /* write requested */
126 if (write) {
Antti Palosaari06565d72009-09-12 20:46:30 -0300127 memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
Antti Palosaari80619de2008-09-15 17:18:09 -0300128 msg_len += req->data_len;
129 }
Antti Palosaari06565d72009-09-12 20:46:30 -0300130
Antti Palosaari80619de2008-09-15 17:18:09 -0300131 deb_xfer(">>> ");
132 debug_dump(buf, msg_len, deb_xfer);
133
134 /* send req */
135 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
Antti Palosaari06565d72009-09-12 20:46:30 -0300136 &act_len, AF9015_USB_TIMEOUT);
Antti Palosaari80619de2008-09-15 17:18:09 -0300137 if (ret)
138 err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len);
139 else
140 if (act_len != msg_len)
141 ret = -1; /* all data is not send */
142 if (ret)
143 goto error_unlock;
144
145 /* no ack for those packets */
146 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
147 goto exit_unlock;
148
Antti Palosaari06565d72009-09-12 20:46:30 -0300149 /* write receives seq + status = 2 bytes
150 read receives seq + status + data = 2 + N bytes */
151 msg_len = ACK_HDR_LEN;
152 if (!write)
153 msg_len += req->data_len;
154
Antti Palosaari80619de2008-09-15 17:18:09 -0300155 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
Antti Palosaari06565d72009-09-12 20:46:30 -0300156 &act_len, AF9015_USB_TIMEOUT);
Antti Palosaari80619de2008-09-15 17:18:09 -0300157 if (ret) {
158 err("recv bulk message failed:%d", ret);
159 ret = -1;
160 goto error_unlock;
161 }
162
163 deb_xfer("<<< ");
164 debug_dump(buf, act_len, deb_xfer);
165
Antti Palosaari80619de2008-09-15 17:18:09 -0300166 /* check status */
167 if (buf[1]) {
168 err("command failed:%d", buf[1]);
169 ret = -1;
170 goto error_unlock;
171 }
172
173 /* read request, copy returned data to return buf */
174 if (!write)
Antti Palosaari06565d72009-09-12 20:46:30 -0300175 memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
Antti Palosaari80619de2008-09-15 17:18:09 -0300176
177error_unlock:
178exit_unlock:
179 mutex_unlock(&af9015_usb_mutex);
180
181 return ret;
182}
183
184static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
185{
186 return af9015_rw_udev(d->udev, req);
187}
188
189static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
190 u8 len)
191{
192 struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
193 val};
194 return af9015_ctrl_msg(d, &req);
195}
196
197static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
198{
199 return af9015_write_regs(d, addr, &val, 1);
200}
201
Antti Palosaari74c8e3a2010-10-22 18:45:18 -0300202static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
203{
204 struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
205 val};
206 return af9015_ctrl_msg(d, &req);
207}
208
Antti Palosaari80619de2008-09-15 17:18:09 -0300209static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
210{
Antti Palosaari74c8e3a2010-10-22 18:45:18 -0300211 return af9015_read_regs(d, addr, val, 1);
Antti Palosaari80619de2008-09-15 17:18:09 -0300212}
213
214static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
215 u8 val)
216{
217 struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
218
219 if (addr == af9015_af9013_config[0].demod_address ||
220 addr == af9015_af9013_config[1].demod_address)
221 req.addr_len = 3;
222
223 return af9015_ctrl_msg(d, &req);
224}
225
226static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
227 u8 *val)
228{
229 struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
230
231 if (addr == af9015_af9013_config[0].demod_address ||
232 addr == af9015_af9013_config[1].demod_address)
233 req.addr_len = 3;
234
235 return af9015_ctrl_msg(d, &req);
236}
237
238static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
239 int num)
240{
241 struct dvb_usb_device *d = i2c_get_adapdata(adap);
242 int ret = 0, i = 0;
243 u16 addr;
Antti Palosaari675375d2010-10-07 21:46:41 -0300244 u8 uninitialized_var(mbox), addr_len;
Antti Palosaari80619de2008-09-15 17:18:09 -0300245 struct req_t req;
246
247/* TODO: implement bus lock
248
249The bus lock is needed because there is two tuners both using same I2C-address.
250Due to that the only way to select correct tuner is use demodulator I2C-gate.
251
252................................................
253. AF9015 includes integrated AF9013 demodulator.
254. ____________ ____________ . ____________
255.| uC | | demod | . | tuner |
256.|------------| |------------| . |------------|
257.| AF9015 | | AF9013/5 | . | MXL5003 |
258.| |--+----I2C-------|-----/ -----|-.-----I2C-------| |
259.| | | | addr 0x38 | . | addr 0xc6 |
260.|____________| | |____________| . |____________|
261.................|..............................
262 | ____________ ____________
263 | | demod | | tuner |
264 | |------------| |------------|
265 | | AF9013 | | MXL5003 |
266 +----I2C-------|-----/ -----|-------I2C-------| |
267 | addr 0x3a | | addr 0xc6 |
268 |____________| |____________|
269*/
270 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
271 return -EAGAIN;
272
273 while (i < num) {
274 if (msg[i].addr == af9015_af9013_config[0].demod_address ||
275 msg[i].addr == af9015_af9013_config[1].demod_address) {
276 addr = msg[i].buf[0] << 8;
277 addr += msg[i].buf[1];
278 mbox = msg[i].buf[2];
279 addr_len = 3;
280 } else {
281 addr = msg[i].buf[0];
282 addr_len = 1;
Antti Palosaari675375d2010-10-07 21:46:41 -0300283 /* mbox is don't care in that case */
Antti Palosaari80619de2008-09-15 17:18:09 -0300284 }
285
286 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
Antti Palosaari709d9202011-06-17 21:16:38 -0300287 if (msg[i].len > 3 || msg[i+1].len > 61) {
288 ret = -EOPNOTSUPP;
289 goto error;
290 }
Antti Palosaari80619de2008-09-15 17:18:09 -0300291 if (msg[i].addr ==
292 af9015_af9013_config[0].demod_address)
293 req.cmd = READ_MEMORY;
294 else
295 req.cmd = READ_I2C;
296 req.i2c_addr = msg[i].addr;
297 req.addr = addr;
298 req.mbox = mbox;
299 req.addr_len = addr_len;
300 req.data_len = msg[i+1].len;
301 req.data = &msg[i+1].buf[0];
302 ret = af9015_ctrl_msg(d, &req);
303 i += 2;
Jochen Friedrichd5633992009-02-02 14:59:50 -0300304 } else if (msg[i].flags & I2C_M_RD) {
Antti Palosaari709d9202011-06-17 21:16:38 -0300305 if (msg[i].len > 61) {
306 ret = -EOPNOTSUPP;
307 goto error;
308 }
Jochen Friedrichd5633992009-02-02 14:59:50 -0300309 if (msg[i].addr ==
Antti Palosaari16b2dc22011-06-16 20:02:41 -0300310 af9015_af9013_config[0].demod_address) {
311 ret = -EINVAL;
Jochen Friedrichd5633992009-02-02 14:59:50 -0300312 goto error;
Antti Palosaari16b2dc22011-06-16 20:02:41 -0300313 }
314 req.cmd = READ_I2C;
Jochen Friedrichd5633992009-02-02 14:59:50 -0300315 req.i2c_addr = msg[i].addr;
316 req.addr = addr;
317 req.mbox = mbox;
318 req.addr_len = addr_len;
319 req.data_len = msg[i].len;
320 req.data = &msg[i].buf[0];
321 ret = af9015_ctrl_msg(d, &req);
322 i += 1;
Antti Palosaari80619de2008-09-15 17:18:09 -0300323 } else {
Antti Palosaari709d9202011-06-17 21:16:38 -0300324 if (msg[i].len > 21) {
325 ret = -EOPNOTSUPP;
326 goto error;
327 }
Antti Palosaari80619de2008-09-15 17:18:09 -0300328 if (msg[i].addr ==
329 af9015_af9013_config[0].demod_address)
330 req.cmd = WRITE_MEMORY;
331 else
332 req.cmd = WRITE_I2C;
333 req.i2c_addr = msg[i].addr;
334 req.addr = addr;
335 req.mbox = mbox;
336 req.addr_len = addr_len;
337 req.data_len = msg[i].len-addr_len;
338 req.data = &msg[i].buf[addr_len];
339 ret = af9015_ctrl_msg(d, &req);
340 i += 1;
341 }
342 if (ret)
343 goto error;
344
345 }
346 ret = i;
347
348error:
349 mutex_unlock(&d->i2c_mutex);
350
351 return ret;
352}
353
354static u32 af9015_i2c_func(struct i2c_adapter *adapter)
355{
356 return I2C_FUNC_I2C;
357}
358
359static struct i2c_algorithm af9015_i2c_algo = {
360 .master_xfer = af9015_i2c_xfer,
361 .functionality = af9015_i2c_func,
362};
363
364static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
365{
366 int ret;
367 u8 val, mask = 0x01;
368
369 ret = af9015_read_reg(d, addr, &val);
370 if (ret)
371 return ret;
372
373 mask <<= bit;
374 if (op) {
375 /* set bit */
376 val |= mask;
377 } else {
378 /* clear bit */
379 mask ^= 0xff;
380 val &= mask;
381 }
382
383 return af9015_write_reg(d, addr, val);
384}
385
386static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
387{
388 return af9015_do_reg_bit(d, addr, bit, 1);
389}
390
391static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
392{
393 return af9015_do_reg_bit(d, addr, bit, 0);
394}
395
396static int af9015_init_endpoint(struct dvb_usb_device *d)
397{
398 int ret;
399 u16 frame_size;
400 u8 packet_size;
401 deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
402
Antti Palosaari9c863272009-09-12 13:35:29 -0300403 /* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
404 We use smaller - about 1/4 from the original, 5 and 87. */
Antti Palosaari80619de2008-09-15 17:18:09 -0300405#define TS_PACKET_SIZE 188
406
Antti Palosaari9c863272009-09-12 13:35:29 -0300407#define TS_USB20_PACKET_COUNT 87
Antti Palosaari80619de2008-09-15 17:18:09 -0300408#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
409
Antti Palosaari9c863272009-09-12 13:35:29 -0300410#define TS_USB11_PACKET_COUNT 5
Antti Palosaari80619de2008-09-15 17:18:09 -0300411#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
412
413#define TS_USB20_MAX_PACKET_SIZE 512
414#define TS_USB11_MAX_PACKET_SIZE 64
415
416 if (d->udev->speed == USB_SPEED_FULL) {
417 frame_size = TS_USB11_FRAME_SIZE/4;
418 packet_size = TS_USB11_MAX_PACKET_SIZE/4;
419 } else {
420 frame_size = TS_USB20_FRAME_SIZE/4;
421 packet_size = TS_USB20_MAX_PACKET_SIZE/4;
422 }
423
424 ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
425 if (ret)
426 goto error;
427 ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
428 if (ret)
429 goto error;
430 ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
431 if (ret)
432 goto error;
433 ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
434 if (ret)
435 goto error;
436 ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
437 if (ret)
438 goto error;
439 if (af9015_config.dual_mode) {
440 ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
441 if (ret)
442 goto error;
443 }
444 ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
445 if (ret)
446 goto error;
447 if (af9015_config.dual_mode) {
448 ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
449 if (ret)
450 goto error;
451 }
452 /* EP4 xfer length */
453 ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
454 if (ret)
455 goto error;
456 ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
457 if (ret)
458 goto error;
459 /* EP5 xfer length */
460 ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
461 if (ret)
462 goto error;
463 ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
464 if (ret)
465 goto error;
466 ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
467 if (ret)
468 goto error;
469 ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
470 if (ret)
471 goto error;
472 ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
473 if (ret)
474 goto error;
475 if (af9015_config.dual_mode) {
476 ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
477 if (ret)
478 goto error;
479 }
480
481 /* enable / disable mp2if2 */
482 if (af9015_config.dual_mode)
483 ret = af9015_set_reg_bit(d, 0xd50b, 0);
484 else
485 ret = af9015_clear_reg_bit(d, 0xd50b, 0);
Antti Palosaari1e8750c2011-03-18 19:36:42 -0300486
Antti Palosaari80619de2008-09-15 17:18:09 -0300487error:
488 if (ret)
489 err("endpoint init failed:%d", ret);
490 return ret;
491}
492
493static int af9015_copy_firmware(struct dvb_usb_device *d)
494{
495 int ret;
496 u8 fw_params[4];
497 u8 val, i;
498 struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
499 fw_params };
500 deb_info("%s:\n", __func__);
501
502 fw_params[0] = af9015_config.firmware_size >> 8;
503 fw_params[1] = af9015_config.firmware_size & 0xff;
504 fw_params[2] = af9015_config.firmware_checksum >> 8;
505 fw_params[3] = af9015_config.firmware_checksum & 0xff;
506
507 /* wait 2nd demodulator ready */
508 msleep(100);
509
Antti Palosaaried19a5d2010-09-12 21:02:55 -0300510 ret = af9015_read_reg_i2c(d,
511 af9015_af9013_config[1].demod_address, 0x98be, &val);
Antti Palosaari80619de2008-09-15 17:18:09 -0300512 if (ret)
513 goto error;
514 else
515 deb_info("%s: firmware status:%02x\n", __func__, val);
516
517 if (val == 0x0c) /* fw is running, no need for download */
518 goto exit;
519
520 /* set I2C master clock to fast (to speed up firmware copy) */
521 ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
522 if (ret)
523 goto error;
524
525 msleep(50);
526
527 /* copy firmware */
528 ret = af9015_ctrl_msg(d, &req);
529 if (ret)
530 err("firmware copy cmd failed:%d", ret);
531 deb_info("%s: firmware copy done\n", __func__);
532
533 /* set I2C master clock back to normal */
534 ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
535 if (ret)
536 goto error;
537
538 /* request boot firmware */
539 ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].demod_address,
540 0xe205, 1);
541 deb_info("%s: firmware boot cmd status:%d\n", __func__, ret);
542 if (ret)
543 goto error;
544
545 for (i = 0; i < 15; i++) {
546 msleep(100);
547
548 /* check firmware status */
549 ret = af9015_read_reg_i2c(d,
550 af9015_af9013_config[1].demod_address, 0x98be, &val);
551 deb_info("%s: firmware status cmd status:%d fw status:%02x\n",
552 __func__, ret, val);
553 if (ret)
554 goto error;
555
556 if (val == 0x0c || val == 0x04) /* success or fail */
557 break;
558 }
559
560 if (val == 0x04) {
561 err("firmware did not run");
562 ret = -1;
563 } else if (val != 0x0c) {
564 err("firmware boot timeout");
565 ret = -1;
566 }
567
568error:
569exit:
570 return ret;
571}
572
Jiri Slaby6c614042010-01-22 12:10:52 -0300573/* hash (and dump) eeprom */
574static int af9015_eeprom_hash(struct usb_device *udev)
Antti Palosaari80619de2008-09-15 17:18:09 -0300575{
Jiri Slaby6c614042010-01-22 12:10:52 -0300576 static const unsigned int eeprom_size = 256;
577 unsigned int reg;
578 int ret;
579 u8 val, *eeprom;
580 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
Antti Palosaari80619de2008-09-15 17:18:09 -0300581
Jiri Slaby6c614042010-01-22 12:10:52 -0300582 eeprom = kmalloc(eeprom_size, GFP_KERNEL);
583 if (eeprom == NULL)
584 return -ENOMEM;
585
586 for (reg = 0; reg < eeprom_size; reg++) {
587 req.addr = reg;
588 ret = af9015_rw_udev(udev, &req);
589 if (ret)
590 goto free;
591 eeprom[reg] = val;
Antti Palosaari80619de2008-09-15 17:18:09 -0300592 }
Jiri Slaby6c614042010-01-22 12:10:52 -0300593
594 if (dvb_usb_af9015_debug & 0x01)
595 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
596 eeprom_size);
597
598 BUG_ON(eeprom_size % 4);
599
600 af9015_config.eeprom_sum = 0;
601 for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
602 af9015_config.eeprom_sum *= GOLDEN_RATIO_PRIME_32;
603 af9015_config.eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
604 }
605
606 deb_info("%s: eeprom sum=%.8x\n", __func__, af9015_config.eeprom_sum);
607
608 ret = 0;
609free:
610 kfree(eeprom);
611 return ret;
Antti Palosaari80619de2008-09-15 17:18:09 -0300612}
613
Antti Palosaari80619de2008-09-15 17:18:09 -0300614static int af9015_init(struct dvb_usb_device *d)
615{
616 int ret;
617 deb_info("%s:\n", __func__);
618
Antti Palosaari1e8750c2011-03-18 19:36:42 -0300619 /* init RC canary */
620 ret = af9015_write_reg(d, 0x98e9, 0xff);
621 if (ret)
622 goto error;
623
Antti Palosaari80619de2008-09-15 17:18:09 -0300624 ret = af9015_init_endpoint(d);
625 if (ret)
626 goto error;
627
Antti Palosaari80619de2008-09-15 17:18:09 -0300628error:
629 return ret;
630}
631
632static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
633{
634 int ret;
635 deb_info("%s: onoff:%d\n", __func__, onoff);
636
637 if (onoff)
638 ret = af9015_set_reg_bit(adap->dev, 0xd503, 0);
639 else
640 ret = af9015_clear_reg_bit(adap->dev, 0xd503, 0);
641
642 return ret;
643}
644
645static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
646 int onoff)
647{
648 int ret;
649 u8 idx;
650
651 deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
652 __func__, index, pid, onoff);
653
654 ret = af9015_write_reg(adap->dev, 0xd505, (pid & 0xff));
655 if (ret)
656 goto error;
657
658 ret = af9015_write_reg(adap->dev, 0xd506, (pid >> 8));
659 if (ret)
660 goto error;
661
662 idx = ((index & 0x1f) | (1 << 5));
663 ret = af9015_write_reg(adap->dev, 0xd504, idx);
664
665error:
666 return ret;
667}
668
669static int af9015_download_firmware(struct usb_device *udev,
670 const struct firmware *fw)
671{
Antti Palosaari582e5652011-03-19 16:51:43 -0300672 int i, len, remaining, ret;
Antti Palosaari80619de2008-09-15 17:18:09 -0300673 struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
Antti Palosaari80619de2008-09-15 17:18:09 -0300674 u16 checksum = 0;
675
676 deb_info("%s:\n", __func__);
677
678 /* calc checksum */
679 for (i = 0; i < fw->size; i++)
680 checksum += fw->data[i];
681
682 af9015_config.firmware_size = fw->size;
683 af9015_config.firmware_checksum = checksum;
684
Antti Palosaari582e5652011-03-19 16:51:43 -0300685 #define FW_ADDR 0x5100 /* firmware start address */
686 #define LEN_MAX 55 /* max packet size */
687 for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
688 len = remaining;
689 if (len > LEN_MAX)
690 len = LEN_MAX;
Antti Palosaari80619de2008-09-15 17:18:09 -0300691
692 req.data_len = len;
Antti Palosaari582e5652011-03-19 16:51:43 -0300693 req.data = (u8 *) &fw->data[fw->size - remaining];
694 req.addr = FW_ADDR + fw->size - remaining;
Antti Palosaari80619de2008-09-15 17:18:09 -0300695
696 ret = af9015_rw_udev(udev, &req);
697 if (ret) {
Antti Palosaari582e5652011-03-19 16:51:43 -0300698 err("firmware download failed:%d", ret);
Antti Palosaari80619de2008-09-15 17:18:09 -0300699 goto error;
700 }
701 }
Antti Palosaari80619de2008-09-15 17:18:09 -0300702
703 /* firmware loaded, request boot */
704 req.cmd = BOOT;
705 ret = af9015_rw_udev(udev, &req);
706 if (ret) {
707 err("firmware boot failed:%d", ret);
708 goto error;
709 }
710
Antti Palosaari80619de2008-09-15 17:18:09 -0300711error:
712 return ret;
713}
714
Antti Palosaari1cd72782010-10-12 17:22:32 -0300715struct af9015_rc_setup {
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300716 unsigned int id;
Antti Palosaari1cd72782010-10-12 17:22:32 -0300717 char *rc_codes;
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300718};
719
Antti Palosaari1cd72782010-10-12 17:22:32 -0300720static char *af9015_rc_setup_match(unsigned int id,
721 const struct af9015_rc_setup *table)
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300722{
Antti Palosaari1cd72782010-10-12 17:22:32 -0300723 for (; table->rc_codes; table++)
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300724 if (table->id == id)
Antti Palosaari1cd72782010-10-12 17:22:32 -0300725 return table->rc_codes;
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300726 return NULL;
727}
728
Antti Palosaari1cd72782010-10-12 17:22:32 -0300729static const struct af9015_rc_setup af9015_rc_setup_modparam[] = {
730 { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M },
731 { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II },
732 { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND },
733 { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE },
734 { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS },
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300735 { }
736};
737
Antti Palosaari1cd72782010-10-12 17:22:32 -0300738static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
739 { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II },
740 { 0xa3703d00, RC_MAP_ALINK_DTU_M },
741 { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */
Juergen Lock879b0d72011-06-12 17:25:12 -0300742 { 0x5d49e3db, RC_MAP_DIGITTRADE }, /* LC-Power LC-USB-DVBT */
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300743 { }
744};
745
Antti Palosaari1cd72782010-10-12 17:22:32 -0300746static const struct af9015_rc_setup af9015_rc_setup_usbids[] = {
Antti Palosaarif68baef2011-07-28 19:17:59 -0300747 { (USB_VID_TERRATEC << 16) | USB_PID_TERRATEC_CINERGY_T_STICK_RC,
Antti Palosaari04599c22011-03-19 14:25:36 -0300748 RC_MAP_TERRATEC_SLIM_2 },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300749 { (USB_VID_TERRATEC << 16) | USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
Antti Palosaari1cd72782010-10-12 17:22:32 -0300750 RC_MAP_TERRATEC_SLIM },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300751 { (USB_VID_VISIONPLUS << 16) | USB_PID_AZUREWAVE_AD_TU700,
Antti Palosaari1cd72782010-10-12 17:22:32 -0300752 RC_MAP_AZUREWAVE_AD_TU700 },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300753 { (USB_VID_VISIONPLUS << 16) | USB_PID_TINYTWIN,
Antti Palosaari1cd72782010-10-12 17:22:32 -0300754 RC_MAP_AZUREWAVE_AD_TU700 },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300755 { (USB_VID_MSI_2 << 16) | USB_PID_MSI_DIGI_VOX_MINI_III,
Antti Palosaari1cd72782010-10-12 17:22:32 -0300756 RC_MAP_MSI_DIGIVOX_III },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300757 { (USB_VID_MSI_2 << 16) | USB_PID_MSI_DIGIVOX_DUO,
Antti Palosaariae81aab2011-06-15 11:29:47 -0300758 RC_MAP_MSI_DIGIVOX_III },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300759 { (USB_VID_LEADTEK << 16) | USB_PID_WINFAST_DTV_DONGLE_GOLD,
Antti Palosaari1cd72782010-10-12 17:22:32 -0300760 RC_MAP_LEADTEK_Y04G0051 },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300761 { (USB_VID_LEADTEK << 16) | USB_PID_WINFAST_DTV2000DS,
Antti Palosaari4c0cfa22011-07-28 19:15:38 -0300762 RC_MAP_LEADTEK_Y04G0051 },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300763 { (USB_VID_AVERMEDIA << 16) | USB_PID_AVERMEDIA_VOLAR_X,
Antti Palosaari1cd72782010-10-12 17:22:32 -0300764 RC_MAP_AVERMEDIA_M135A },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300765 { (USB_VID_AFATECH << 16) | USB_PID_TREKSTOR_DVBT,
Antti Palosaari1cd72782010-10-12 17:22:32 -0300766 RC_MAP_TREKSTOR },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300767 { (USB_VID_KWORLD_2 << 16) | USB_PID_TINYTWIN_2,
Antti Palosaaribd864ce2010-10-22 20:37:11 -0300768 RC_MAP_DIGITALNOW_TINYTWIN },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300769 { (USB_VID_GTEK << 16) | USB_PID_TINYTWIN_3,
Antti Palosaarif8c61272010-10-23 07:35:31 -0300770 RC_MAP_DIGITALNOW_TINYTWIN },
Antti Palosaarif68baef2011-07-28 19:17:59 -0300771 { (USB_VID_KWORLD_2 << 16) | USB_PID_SVEON_STV22,
Emilio David Diaus Lopeza062d042011-07-12 19:53:39 -0300772 RC_MAP_MSI_DIGIVOX_III },
Jiri Slabye3a0cc62010-01-22 12:10:55 -0300773 { }
774};
775
Jiri Slaby634d2d72010-01-22 12:10:53 -0300776static void af9015_set_remote_config(struct usb_device *udev,
777 struct dvb_usb_device_properties *props)
778{
Antti Palosaari1cd72782010-10-12 17:22:32 -0300779 u16 vid = le16_to_cpu(udev->descriptor.idVendor);
780 u16 pid = le16_to_cpu(udev->descriptor.idProduct);
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300781
Antti Palosaari1cd72782010-10-12 17:22:32 -0300782 /* try to load remote based module param */
783 props->rc.core.rc_codes = af9015_rc_setup_match(
784 dvb_usb_af9015_remote, af9015_rc_setup_modparam);
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300785
Antti Palosaari1cd72782010-10-12 17:22:32 -0300786 /* try to load remote based eeprom hash */
787 if (!props->rc.core.rc_codes)
788 props->rc.core.rc_codes = af9015_rc_setup_match(
789 af9015_config.eeprom_sum, af9015_rc_setup_hashes);
Jiri Slabye3a0cc62010-01-22 12:10:55 -0300790
Antti Palosaari1cd72782010-10-12 17:22:32 -0300791 /* try to load remote based USB ID */
792 if (!props->rc.core.rc_codes)
793 props->rc.core.rc_codes = af9015_rc_setup_match(
794 (vid << 16) + pid, af9015_rc_setup_usbids);
795
796 /* try to load remote based USB iManufacturer string */
797 if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) {
798 /* Check USB manufacturer and product strings and try
799 to determine correct remote in case of chip vendor
800 reference IDs are used.
801 DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
802 char manufacturer[10];
803 memset(manufacturer, 0, sizeof(manufacturer));
804 usb_string(udev, udev->descriptor.iManufacturer,
805 manufacturer, sizeof(manufacturer));
806 if (!strcmp("MSI", manufacturer)) {
807 /* iManufacturer 1 MSI
808 iProduct 2 MSI K-VOX */
809 props->rc.core.rc_codes = af9015_rc_setup_match(
810 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
811 af9015_rc_setup_modparam);
812 }
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300813 }
Antti Palosaari74c8e3a2010-10-22 18:45:18 -0300814
815 /* finally load "empty" just for leaving IR receiver enabled */
816 if (!props->rc.core.rc_codes)
817 props->rc.core.rc_codes = RC_MAP_EMPTY;
818
Antti Palosaari1cd72782010-10-12 17:22:32 -0300819 return;
Jiri Slaby634d2d72010-01-22 12:10:53 -0300820}
821
Antti Palosaari80619de2008-09-15 17:18:09 -0300822static int af9015_read_config(struct usb_device *udev)
823{
824 int ret;
825 u8 val, i, offset = 0;
826 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
Antti Palosaari80619de2008-09-15 17:18:09 -0300827
828 /* IR remote controller */
829 req.addr = AF9015_EEPROM_IR_MODE;
Antti Palosaarid1a470f2009-01-20 14:56:20 -0300830 /* first message will timeout often due to possible hw bug */
831 for (i = 0; i < 4; i++) {
832 ret = af9015_rw_udev(udev, &req);
833 if (!ret)
834 break;
835 }
Antti Palosaari80619de2008-09-15 17:18:09 -0300836 if (ret)
837 goto error;
Jiri Slaby6c614042010-01-22 12:10:52 -0300838
839 ret = af9015_eeprom_hash(udev);
840 if (ret)
841 goto error;
842
Antti Palosaari80619de2008-09-15 17:18:09 -0300843 deb_info("%s: IR mode:%d\n", __func__, val);
844 for (i = 0; i < af9015_properties_count; i++) {
Antti Palosaari74c8e3a2010-10-22 18:45:18 -0300845 if (val == AF9015_IR_MODE_DISABLED)
846 af9015_properties[i].rc.core.rc_codes = NULL;
847 else
Jiri Slaby634d2d72010-01-22 12:10:53 -0300848 af9015_set_remote_config(udev, &af9015_properties[i]);
Antti Palosaari80619de2008-09-15 17:18:09 -0300849 }
850
851 /* TS mode - one or two receivers */
852 req.addr = AF9015_EEPROM_TS_MODE;
853 ret = af9015_rw_udev(udev, &req);
854 if (ret)
855 goto error;
856 af9015_config.dual_mode = val;
857 deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode);
Antti Palosaari80619de2008-09-15 17:18:09 -0300858
Antti Palosaarif0830eb2009-01-13 13:08:29 -0300859 /* Set adapter0 buffer size according to USB port speed, adapter1 buffer
860 size can be static because it is enabled only USB2.0 */
Antti Palosaari80619de2008-09-15 17:18:09 -0300861 for (i = 0; i < af9015_properties_count; i++) {
862 /* USB1.1 set smaller buffersize and disable 2nd adapter */
863 if (udev->speed == USB_SPEED_FULL) {
Michael Krufky77eed212011-09-06 09:31:57 -0300864 af9015_properties[i].adapter[0].fe[0].stream.u.bulk.buffersize
Antti Palosaari9c863272009-09-12 13:35:29 -0300865 = TS_USB11_FRAME_SIZE;
Antti Palosaari80619de2008-09-15 17:18:09 -0300866 /* disable 2nd adapter because we don't have
867 PID-filters */
868 af9015_config.dual_mode = 0;
869 } else {
Michael Krufky77eed212011-09-06 09:31:57 -0300870 af9015_properties[i].adapter[0].fe[0].stream.u.bulk.buffersize
Jose Alberto Reguero353330c2009-09-12 09:51:36 -0300871 = TS_USB20_FRAME_SIZE;
Antti Palosaari80619de2008-09-15 17:18:09 -0300872 }
873 }
874
875 if (af9015_config.dual_mode) {
876 /* read 2nd demodulator I2C address */
877 req.addr = AF9015_EEPROM_DEMOD2_I2C;
878 ret = af9015_rw_udev(udev, &req);
879 if (ret)
880 goto error;
881 af9015_af9013_config[1].demod_address = val;
882
883 /* enable 2nd adapter */
884 for (i = 0; i < af9015_properties_count; i++)
885 af9015_properties[i].num_adapters = 2;
886
887 } else {
888 /* disable 2nd adapter */
889 for (i = 0; i < af9015_properties_count; i++)
890 af9015_properties[i].num_adapters = 1;
891 }
892
893 for (i = 0; i < af9015_properties[0].num_adapters; i++) {
894 if (i == 1)
895 offset = AF9015_EEPROM_OFFSET;
896 /* xtal */
897 req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
898 ret = af9015_rw_udev(udev, &req);
899 if (ret)
900 goto error;
901 switch (val) {
902 case 0:
903 af9015_af9013_config[i].adc_clock = 28800;
904 break;
905 case 1:
906 af9015_af9013_config[i].adc_clock = 20480;
907 break;
908 case 2:
909 af9015_af9013_config[i].adc_clock = 28000;
910 break;
911 case 3:
912 af9015_af9013_config[i].adc_clock = 25000;
913 break;
914 };
915 deb_info("%s: [%d] xtal:%d set adc_clock:%d\n", __func__, i,
916 val, af9015_af9013_config[i].adc_clock);
917
918 /* tuner IF */
919 req.addr = AF9015_EEPROM_IF1H + offset;
920 ret = af9015_rw_udev(udev, &req);
921 if (ret)
922 goto error;
923 af9015_af9013_config[i].tuner_if = val << 8;
924 req.addr = AF9015_EEPROM_IF1L + offset;
925 ret = af9015_rw_udev(udev, &req);
926 if (ret)
927 goto error;
928 af9015_af9013_config[i].tuner_if += val;
929 deb_info("%s: [%d] IF1:%d\n", __func__, i,
930 af9015_af9013_config[0].tuner_if);
931
932 /* MT2060 IF1 */
933 req.addr = AF9015_EEPROM_MT2060_IF1H + offset;
934 ret = af9015_rw_udev(udev, &req);
935 if (ret)
936 goto error;
937 af9015_config.mt2060_if1[i] = val << 8;
938 req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
939 ret = af9015_rw_udev(udev, &req);
940 if (ret)
941 goto error;
942 af9015_config.mt2060_if1[i] += val;
943 deb_info("%s: [%d] MT2060 IF1:%d\n", __func__, i,
944 af9015_config.mt2060_if1[i]);
945
946 /* tuner */
947 req.addr = AF9015_EEPROM_TUNER_ID1 + offset;
948 ret = af9015_rw_udev(udev, &req);
949 if (ret)
950 goto error;
951 switch (val) {
952 case AF9013_TUNER_ENV77H11D5:
953 case AF9013_TUNER_MT2060:
Antti Palosaari80619de2008-09-15 17:18:09 -0300954 case AF9013_TUNER_QT1010:
955 case AF9013_TUNER_UNKNOWN:
956 case AF9013_TUNER_MT2060_2:
957 case AF9013_TUNER_TDA18271:
958 case AF9013_TUNER_QT1010A:
Antti Palosaariee3d4402010-08-13 03:51:26 -0300959 case AF9013_TUNER_TDA18218:
Antti Palosaari80619de2008-09-15 17:18:09 -0300960 af9015_af9013_config[i].rf_spec_inv = 1;
961 break;
962 case AF9013_TUNER_MXL5003D:
963 case AF9013_TUNER_MXL5005D:
964 case AF9013_TUNER_MXL5005R:
Antti Palosaariab07fdd2010-09-09 14:59:10 -0300965 case AF9013_TUNER_MXL5007T:
Antti Palosaari80619de2008-09-15 17:18:09 -0300966 af9015_af9013_config[i].rf_spec_inv = 0;
967 break;
Jochen Friedrichd5633992009-02-02 14:59:50 -0300968 case AF9013_TUNER_MC44S803:
969 af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
970 af9015_af9013_config[i].rf_spec_inv = 1;
971 break;
Antti Palosaari80619de2008-09-15 17:18:09 -0300972 default:
973 warn("tuner id:%d not supported, please report!", val);
974 return -ENODEV;
975 };
976
977 af9015_af9013_config[i].tuner = val;
978 deb_info("%s: [%d] tuner id:%d\n", __func__, i, val);
979 }
980
981error:
982 if (ret)
983 err("eeprom read failed:%d", ret);
984
Antti Palosaari3956fef2009-03-31 17:01:02 -0300985 /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
Yann E. MORIN8ccdf1a2010-10-01 16:55:43 -0300986 content :-( Override some wrong values here. Ditto for the
987 AVerTV Red HD+ (A850T) device. */
Antti Palosaari3956fef2009-03-31 17:01:02 -0300988 if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
Antti Palosaari9a3ecc72010-10-07 21:37:06 -0300989 ((le16_to_cpu(udev->descriptor.idProduct) ==
990 USB_PID_AVERMEDIA_A850) ||
991 (le16_to_cpu(udev->descriptor.idProduct) ==
992 USB_PID_AVERMEDIA_A850T))) {
Antti Palosaari3956fef2009-03-31 17:01:02 -0300993 deb_info("%s: AverMedia A850: overriding config\n", __func__);
994 /* disable dual mode */
995 af9015_config.dual_mode = 0;
996 /* disable 2nd adapter */
997 for (i = 0; i < af9015_properties_count; i++)
998 af9015_properties[i].num_adapters = 1;
999
1000 /* set correct IF */
1001 af9015_af9013_config[0].tuner_if = 4570;
1002 }
1003
Antti Palosaari80619de2008-09-15 17:18:09 -03001004 return ret;
1005}
1006
1007static int af9015_identify_state(struct usb_device *udev,
1008 struct dvb_usb_device_properties *props,
1009 struct dvb_usb_device_description **desc,
1010 int *cold)
1011{
1012 int ret;
1013 u8 reply;
1014 struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
1015
1016 ret = af9015_rw_udev(udev, &req);
1017 if (ret)
1018 return ret;
1019
1020 deb_info("%s: reply:%02x\n", __func__, reply);
1021 if (reply == 0x02)
1022 *cold = 0;
1023 else
1024 *cold = 1;
1025
1026 return ret;
1027}
1028
Antti Palosaari1cd72782010-10-12 17:22:32 -03001029static int af9015_rc_query(struct dvb_usb_device *d)
Antti Palosaari80619de2008-09-15 17:18:09 -03001030{
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001031 struct af9015_state *priv = d->priv;
1032 int ret;
Ian Armstrongc1e13972011-03-18 19:23:05 -03001033 u8 buf[17];
Antti Palosaari80619de2008-09-15 17:18:09 -03001034
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001035 /* read registers needed to detect remote controller code */
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001036 ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
Antti Palosaari80619de2008-09-15 17:18:09 -03001037 if (ret)
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001038 goto error;
Antti Palosaari80619de2008-09-15 17:18:09 -03001039
Ian Armstrongc1e13972011-03-18 19:23:05 -03001040 /* If any of these are non-zero, assume invalid data */
1041 if (buf[1] || buf[2] || buf[3])
1042 return ret;
1043
1044 /* Check for repeat of previous code */
1045 if ((priv->rc_repeat != buf[6] || buf[0]) &&
1046 !memcmp(&buf[12], priv->rc_last, 4)) {
1047 deb_rc("%s: key repeated\n", __func__);
1048 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
1049 priv->rc_repeat = buf[6];
1050 return ret;
1051 }
1052
1053 /* Only process key if canary killed */
1054 if (buf[16] != 0xff && buf[0] != 0x01) {
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001055 deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
1056 buf[12], buf[13], buf[14], buf[15]);
Antti Palosaari80619de2008-09-15 17:18:09 -03001057
Antti Palosaari1e8750c2011-03-18 19:36:42 -03001058 /* Reset the canary */
1059 ret = af9015_write_reg(d, 0x98e9, 0xff);
1060 if (ret)
1061 goto error;
1062
Ian Armstrongc1e13972011-03-18 19:23:05 -03001063 /* Remember this key */
1064 memcpy(priv->rc_last, &buf[12], 4);
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001065 if (buf[14] == (u8) ~buf[15]) {
1066 if (buf[12] == (u8) ~buf[13]) {
Antti Palosaari1cd72782010-10-12 17:22:32 -03001067 /* NEC */
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001068 priv->rc_keycode = buf[12] << 8 | buf[14];
Antti Palosaari1cd72782010-10-12 17:22:32 -03001069 } else {
1070 /* NEC extended*/
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001071 priv->rc_keycode = buf[12] << 16 |
1072 buf[13] << 8 | buf[14];
Antti Palosaari1cd72782010-10-12 17:22:32 -03001073 }
Antti Palosaari1cd72782010-10-12 17:22:32 -03001074 } else {
Antti Palosaari1e8750c2011-03-18 19:36:42 -03001075 /* 32 bit NEC */
Ian Armstrongc1e13972011-03-18 19:23:05 -03001076 priv->rc_keycode = buf[12] << 24 | buf[13] << 16 |
1077 buf[14] << 8 | buf[15];
Antti Palosaari1cd72782010-10-12 17:22:32 -03001078 }
Mauro Carvalho Chehabca866742010-11-17 13:53:11 -03001079 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001080 } else {
1081 deb_rc("%s: no key press\n", __func__);
Ian Armstrongc1e13972011-03-18 19:23:05 -03001082 /* Invalidate last keypress */
1083 /* Not really needed, but helps with debug */
1084 priv->rc_last[2] = priv->rc_last[3];
Antti Palosaari80619de2008-09-15 17:18:09 -03001085 }
Antti Palosaari80619de2008-09-15 17:18:09 -03001086
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001087 priv->rc_repeat = buf[6];
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001088
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001089error:
1090 if (ret)
1091 err("%s: failed:%d", __func__, ret);
1092
1093 return ret;
Antti Palosaari80619de2008-09-15 17:18:09 -03001094}
1095
Antti Palosaari80619de2008-09-15 17:18:09 -03001096static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
1097{
1098 int ret;
Antti Palosaari80619de2008-09-15 17:18:09 -03001099
Antti Palosaari713d9b52011-06-18 10:24:53 -03001100 if (adap->id == 1) {
Antti Palosaari80619de2008-09-15 17:18:09 -03001101 /* copy firmware to 2nd demodulator */
1102 if (af9015_config.dual_mode) {
1103 ret = af9015_copy_firmware(adap->dev);
1104 if (ret) {
1105 err("firmware copy to 2nd frontend " \
1106 "failed, will disable it");
1107 af9015_config.dual_mode = 0;
1108 return -ENODEV;
1109 }
1110 } else {
1111 return -ENODEV;
1112 }
1113 }
1114
1115 /* attach demodulator */
Michael Krufky77eed212011-09-06 09:31:57 -03001116 adap->fe_adap[0].fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id],
Antti Palosaari713d9b52011-06-18 10:24:53 -03001117 &adap->dev->i2c_adap);
Antti Palosaari80619de2008-09-15 17:18:09 -03001118
Michael Krufky77eed212011-09-06 09:31:57 -03001119 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
Antti Palosaari80619de2008-09-15 17:18:09 -03001120}
1121
1122static struct mt2060_config af9015_mt2060_config = {
1123 .i2c_address = 0xc0,
1124 .clock_out = 0,
1125};
1126
1127static struct qt1010_config af9015_qt1010_config = {
1128 .i2c_address = 0xc4,
1129};
1130
1131static struct tda18271_config af9015_tda18271_config = {
1132 .gate = TDA18271_GATE_DIGITAL,
Mauro Carvalho Chehab7655e592010-10-27 14:55:34 -02001133 .small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
Antti Palosaari80619de2008-09-15 17:18:09 -03001134};
1135
1136static struct mxl5005s_config af9015_mxl5003_config = {
1137 .i2c_address = 0xc6,
1138 .if_freq = IF_FREQ_4570000HZ,
1139 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1140 .agc_mode = MXL_SINGLE_AGC,
1141 .tracking_filter = MXL_TF_DEFAULT,
Antti Palosaaria1310772008-09-22 13:59:25 -03001142 .rssi_enable = MXL_RSSI_ENABLE,
Antti Palosaari80619de2008-09-15 17:18:09 -03001143 .cap_select = MXL_CAP_SEL_ENABLE,
1144 .div_out = MXL_DIV_OUT_4,
1145 .clock_out = MXL_CLOCK_OUT_DISABLE,
1146 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1147 .top = MXL5005S_TOP_25P2,
1148 .mod_mode = MXL_DIGITAL_MODE,
1149 .if_mode = MXL_ZERO_IF,
1150 .AgcMasterByte = 0x00,
1151};
1152
1153static struct mxl5005s_config af9015_mxl5005_config = {
1154 .i2c_address = 0xc6,
1155 .if_freq = IF_FREQ_4570000HZ,
1156 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1157 .agc_mode = MXL_SINGLE_AGC,
1158 .tracking_filter = MXL_TF_OFF,
Antti Palosaaria1310772008-09-22 13:59:25 -03001159 .rssi_enable = MXL_RSSI_ENABLE,
Antti Palosaari80619de2008-09-15 17:18:09 -03001160 .cap_select = MXL_CAP_SEL_ENABLE,
1161 .div_out = MXL_DIV_OUT_4,
1162 .clock_out = MXL_CLOCK_OUT_DISABLE,
1163 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1164 .top = MXL5005S_TOP_25P2,
1165 .mod_mode = MXL_DIGITAL_MODE,
1166 .if_mode = MXL_ZERO_IF,
1167 .AgcMasterByte = 0x00,
1168};
1169
Jochen Friedrichd5633992009-02-02 14:59:50 -03001170static struct mc44s803_config af9015_mc44s803_config = {
1171 .i2c_address = 0xc0,
1172 .dig_out = 1,
1173};
1174
Antti Palosaariee3d4402010-08-13 03:51:26 -03001175static struct tda18218_config af9015_tda18218_config = {
1176 .i2c_address = 0xc0,
1177 .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
1178};
1179
Antti Palosaariab07fdd2010-09-09 14:59:10 -03001180static struct mxl5007t_config af9015_mxl5007t_config = {
1181 .xtal_freq_hz = MxL_XTAL_24_MHZ,
1182 .if_freq_hz = MxL_IF_4_57_MHZ,
1183};
1184
Antti Palosaari80619de2008-09-15 17:18:09 -03001185static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
1186{
Antti Palosaari80619de2008-09-15 17:18:09 -03001187 int ret;
Antti Palosaari9a3ecc72010-10-07 21:37:06 -03001188 deb_info("%s:\n", __func__);
Antti Palosaari80619de2008-09-15 17:18:09 -03001189
Antti Palosaari80619de2008-09-15 17:18:09 -03001190 switch (af9015_af9013_config[adap->id].tuner) {
1191 case AF9013_TUNER_MT2060:
1192 case AF9013_TUNER_MT2060_2:
Michael Krufky77eed212011-09-06 09:31:57 -03001193 ret = dvb_attach(mt2060_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001194 &af9015_mt2060_config,
1195 af9015_config.mt2060_if1[adap->id])
1196 == NULL ? -ENODEV : 0;
1197 break;
1198 case AF9013_TUNER_QT1010:
1199 case AF9013_TUNER_QT1010A:
Michael Krufky77eed212011-09-06 09:31:57 -03001200 ret = dvb_attach(qt1010_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001201 &af9015_qt1010_config) == NULL ? -ENODEV : 0;
1202 break;
1203 case AF9013_TUNER_TDA18271:
Michael Krufky77eed212011-09-06 09:31:57 -03001204 ret = dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0xc0,
Antti Palosaari713d9b52011-06-18 10:24:53 -03001205 &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001206 &af9015_tda18271_config) == NULL ? -ENODEV : 0;
1207 break;
Antti Palosaariee3d4402010-08-13 03:51:26 -03001208 case AF9013_TUNER_TDA18218:
Michael Krufky77eed212011-09-06 09:31:57 -03001209 ret = dvb_attach(tda18218_attach, adap->fe_adap[0].fe,
Antti Palosaari713d9b52011-06-18 10:24:53 -03001210 &adap->dev->i2c_adap,
Antti Palosaariee3d4402010-08-13 03:51:26 -03001211 &af9015_tda18218_config) == NULL ? -ENODEV : 0;
1212 break;
Antti Palosaari80619de2008-09-15 17:18:09 -03001213 case AF9013_TUNER_MXL5003D:
Michael Krufky77eed212011-09-06 09:31:57 -03001214 ret = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
Antti Palosaari713d9b52011-06-18 10:24:53 -03001215 &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001216 &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
1217 break;
1218 case AF9013_TUNER_MXL5005D:
1219 case AF9013_TUNER_MXL5005R:
Michael Krufky77eed212011-09-06 09:31:57 -03001220 ret = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
Antti Palosaari713d9b52011-06-18 10:24:53 -03001221 &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001222 &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
1223 break;
1224 case AF9013_TUNER_ENV77H11D5:
Michael Krufky77eed212011-09-06 09:31:57 -03001225 ret = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0xc0,
Antti Palosaari713d9b52011-06-18 10:24:53 -03001226 &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001227 DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
1228 break;
1229 case AF9013_TUNER_MC44S803:
Michael Krufky77eed212011-09-06 09:31:57 -03001230 ret = dvb_attach(mc44s803_attach, adap->fe_adap[0].fe,
Antti Palosaari713d9b52011-06-18 10:24:53 -03001231 &adap->dev->i2c_adap,
Jochen Friedrichd5633992009-02-02 14:59:50 -03001232 &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
Antti Palosaari80619de2008-09-15 17:18:09 -03001233 break;
Antti Palosaariab07fdd2010-09-09 14:59:10 -03001234 case AF9013_TUNER_MXL5007T:
Michael Krufky77eed212011-09-06 09:31:57 -03001235 ret = dvb_attach(mxl5007t_attach, adap->fe_adap[0].fe,
Antti Palosaari713d9b52011-06-18 10:24:53 -03001236 &adap->dev->i2c_adap,
Antti Palosaariab07fdd2010-09-09 14:59:10 -03001237 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
1238 break;
Antti Palosaari80619de2008-09-15 17:18:09 -03001239 case AF9013_TUNER_UNKNOWN:
1240 default:
1241 ret = -ENODEV;
1242 err("Unknown tuner id:%d",
1243 af9015_af9013_config[adap->id].tuner);
1244 }
1245 return ret;
1246}
1247
1248static struct usb_device_id af9015_usb_table[] = {
1249/* 0 */{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)},
1250 {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)},
1251 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)},
1252 {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)},
1253 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)},
1254/* 5 */{USB_DEVICE(USB_VID_VISIONPLUS,
1255 USB_PID_TINYTWIN)},
1256 {USB_DEVICE(USB_VID_VISIONPLUS,
1257 USB_PID_AZUREWAVE_AD_TU700)},
1258 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)},
1259 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)},
1260 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)},
1261/* 10 */{USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)},
1262 {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)},
1263 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)},
Antti Palosaaria3765882008-09-19 18:34:06 -03001264 {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
Antti Palosaari05c1cab2008-09-22 12:32:37 -03001265 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
Herbert Graeber641015a2008-10-07 10:06:36 -03001266/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
Antti Palosaari163e9cd2008-11-04 12:57:47 -03001267 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
Antti Palosaari71bf2e02009-01-13 12:47:28 -03001268 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
Antti Palosaari58fe1592009-03-26 20:41:05 -03001269 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)},
Marc Schneider26144842009-03-26 21:07:18 -03001270 {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)},
Antti Palosaari1ed5fad2009-04-09 15:14:18 -03001271/* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
1272 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)},
Marcel Jueling734dd232009-04-09 17:16:41 -03001273 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
Wen-chien Jesse Sung6e9c1a22009-04-28 01:11:22 -03001274 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
Antti Palosaari22d46452009-05-31 17:07:01 -03001275 {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
Mart Raudseppc92f0562009-07-24 13:45:41 -03001276/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
Antti Palosaari486ba122009-09-18 13:37:57 -03001277 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)},
Ignacio de Miguel Diaz52322632009-11-13 23:13:34 -03001278 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)},
Antti Palosaarifa1df552010-02-10 20:05:48 -03001279 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)},
Antti Palosaari809c1e82010-02-10 20:07:30 -03001280 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)},
Antti Palosaariab9b4f22010-03-01 13:50:40 -03001281/* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
Antti Palosaari7fc87092010-03-01 14:06:52 -03001282 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
Antti Palosaari2606cfa2010-05-23 18:26:37 -03001283 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)},
Stefan Lippers-Hollmannd7ef4852010-08-25 10:08:48 -03001284 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)},
Antti Palosaariab07fdd2010-09-09 14:59:10 -03001285 {USB_DEVICE(USB_VID_TERRATEC,
1286 USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)},
Yann E. MORIN8ccdf1a2010-10-01 16:55:43 -03001287/* 35 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)},
Antti Palosaarif8c61272010-10-23 07:35:31 -03001288 {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)},
Emilio David Diaus Lopeza062d042011-07-12 19:53:39 -03001289 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)},
Antti Palosaari80619de2008-09-15 17:18:09 -03001290 {0},
1291};
1292MODULE_DEVICE_TABLE(usb, af9015_usb_table);
1293
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001294#define AF9015_RC_INTERVAL 500
Antti Palosaari80619de2008-09-15 17:18:09 -03001295static struct dvb_usb_device_properties af9015_properties[] = {
1296 {
1297 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1298
1299 .usb_ctrl = DEVICE_SPECIFIC,
1300 .download_firmware = af9015_download_firmware,
1301 .firmware = "dvb-usb-af9015.fw",
Jose Alberto Reguerocce25712008-11-13 14:14:18 -03001302 .no_reconnect = 1,
Antti Palosaari80619de2008-09-15 17:18:09 -03001303
Antti Palosaari02542942009-09-16 20:33:03 -03001304 .size_of_priv = sizeof(struct af9015_state),
Antti Palosaari80619de2008-09-15 17:18:09 -03001305
1306 .num_adapters = 2,
1307 .adapter = {
1308 {
Michael Krufky77eed212011-09-06 09:31:57 -03001309 .num_frontends = 1,
1310 .fe = {{
Antti Palosaari80619de2008-09-15 17:18:09 -03001311 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1312 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1313
1314 .pid_filter_count = 32,
1315 .pid_filter = af9015_pid_filter,
1316 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1317
1318 .frontend_attach =
1319 af9015_af9013_frontend_attach,
1320 .tuner_attach = af9015_tuner_attach,
1321 .stream = {
1322 .type = USB_BULK,
1323 .count = 6,
1324 .endpoint = 0x84,
1325 },
Michael Krufky77eed212011-09-06 09:31:57 -03001326 }},
Antti Palosaari80619de2008-09-15 17:18:09 -03001327 },
1328 {
Michael Krufky77eed212011-09-06 09:31:57 -03001329 .num_frontends = 1,
1330 .fe = {{
Antti Palosaari80619de2008-09-15 17:18:09 -03001331 .frontend_attach =
1332 af9015_af9013_frontend_attach,
1333 .tuner_attach = af9015_tuner_attach,
1334 .stream = {
1335 .type = USB_BULK,
1336 .count = 6,
1337 .endpoint = 0x85,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001338 .u = {
1339 .bulk = {
1340 .buffersize =
Jose Alberto Reguero353330c2009-09-12 09:51:36 -03001341 TS_USB20_FRAME_SIZE,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001342 }
1343 }
Antti Palosaari80619de2008-09-15 17:18:09 -03001344 },
Michael Krufky77eed212011-09-06 09:31:57 -03001345 }},
Antti Palosaari80619de2008-09-15 17:18:09 -03001346 }
1347 },
1348
1349 .identify_state = af9015_identify_state,
1350
Antti Palosaari1cd72782010-10-12 17:22:32 -03001351 .rc.core = {
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001352 .protocol = RC_TYPE_NEC,
Antti Palosaari1cd72782010-10-12 17:22:32 -03001353 .module_name = "af9015",
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001354 .rc_query = af9015_rc_query,
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001355 .rc_interval = AF9015_RC_INTERVAL,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001356 .allowed_protos = RC_TYPE_NEC,
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001357 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001358
1359 .i2c_algo = &af9015_i2c_algo,
1360
Yann E. MORIN8ccdf1a2010-10-01 16:55:43 -03001361 .num_device_descs = 12, /* check max from dvb-usb.h */
Antti Palosaari80619de2008-09-15 17:18:09 -03001362 .devices = {
1363 {
1364 .name = "Afatech AF9015 DVB-T USB2.0 stick",
1365 .cold_ids = {&af9015_usb_table[0],
1366 &af9015_usb_table[1], NULL},
1367 .warm_ids = {NULL},
1368 },
1369 {
1370 .name = "Leadtek WinFast DTV Dongle Gold",
1371 .cold_ids = {&af9015_usb_table[2], NULL},
1372 .warm_ids = {NULL},
1373 },
1374 {
1375 .name = "Pinnacle PCTV 71e",
1376 .cold_ids = {&af9015_usb_table[3], NULL},
1377 .warm_ids = {NULL},
1378 },
1379 {
1380 .name = "KWorld PlusTV Dual DVB-T Stick " \
1381 "(DVB-T 399U)",
Mart Raudseppc92f0562009-07-24 13:45:41 -03001382 .cold_ids = {&af9015_usb_table[4],
1383 &af9015_usb_table[25], NULL},
Antti Palosaari80619de2008-09-15 17:18:09 -03001384 .warm_ids = {NULL},
1385 },
1386 {
1387 .name = "DigitalNow TinyTwin DVB-T Receiver",
Antti Palosaarifa1df552010-02-10 20:05:48 -03001388 .cold_ids = {&af9015_usb_table[5],
Antti Palosaarif8c61272010-10-23 07:35:31 -03001389 &af9015_usb_table[28],
1390 &af9015_usb_table[36], NULL},
Antti Palosaari80619de2008-09-15 17:18:09 -03001391 .warm_ids = {NULL},
1392 },
1393 {
1394 .name = "TwinHan AzureWave AD-TU700(704J)",
1395 .cold_ids = {&af9015_usb_table[6], NULL},
1396 .warm_ids = {NULL},
1397 },
1398 {
1399 .name = "TerraTec Cinergy T USB XE",
1400 .cold_ids = {&af9015_usb_table[7], NULL},
1401 .warm_ids = {NULL},
1402 },
1403 {
1404 .name = "KWorld PlusTV Dual DVB-T PCI " \
1405 "(DVB-T PC160-2T)",
1406 .cold_ids = {&af9015_usb_table[8], NULL},
1407 .warm_ids = {NULL},
1408 },
1409 {
1410 .name = "AVerMedia AVerTV DVB-T Volar X",
1411 .cold_ids = {&af9015_usb_table[9], NULL},
1412 .warm_ids = {NULL},
1413 },
Antti Palosaari76391a72010-09-09 12:10:50 -03001414 {
1415 .name = "TerraTec Cinergy T Stick RC",
1416 .cold_ids = {&af9015_usb_table[33], NULL},
1417 .warm_ids = {NULL},
1418 },
Antti Palosaariab07fdd2010-09-09 14:59:10 -03001419 {
1420 .name = "TerraTec Cinergy T Stick Dual RC",
1421 .cold_ids = {&af9015_usb_table[34], NULL},
1422 .warm_ids = {NULL},
1423 },
Yann E. MORIN8ccdf1a2010-10-01 16:55:43 -03001424 {
1425 .name = "AverMedia AVerTV Red HD+ (A850T)",
1426 .cold_ids = {&af9015_usb_table[35], NULL},
1427 .warm_ids = {NULL},
1428 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001429 }
1430 }, {
1431 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1432
1433 .usb_ctrl = DEVICE_SPECIFIC,
1434 .download_firmware = af9015_download_firmware,
1435 .firmware = "dvb-usb-af9015.fw",
Jose Alberto Reguerocce25712008-11-13 14:14:18 -03001436 .no_reconnect = 1,
Antti Palosaari80619de2008-09-15 17:18:09 -03001437
Antti Palosaari02542942009-09-16 20:33:03 -03001438 .size_of_priv = sizeof(struct af9015_state),
Antti Palosaari80619de2008-09-15 17:18:09 -03001439
1440 .num_adapters = 2,
1441 .adapter = {
1442 {
Michael Krufky77eed212011-09-06 09:31:57 -03001443 .num_frontends = 1,
1444 .fe = {{
Antti Palosaari80619de2008-09-15 17:18:09 -03001445 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1446 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1447
1448 .pid_filter_count = 32,
1449 .pid_filter = af9015_pid_filter,
1450 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1451
1452 .frontend_attach =
1453 af9015_af9013_frontend_attach,
1454 .tuner_attach = af9015_tuner_attach,
1455 .stream = {
1456 .type = USB_BULK,
1457 .count = 6,
1458 .endpoint = 0x84,
1459 },
Michael Krufky77eed212011-09-06 09:31:57 -03001460 }},
Antti Palosaari80619de2008-09-15 17:18:09 -03001461 },
1462 {
Michael Krufky77eed212011-09-06 09:31:57 -03001463 .num_frontends = 1,
1464 .fe = {{
Antti Palosaari80619de2008-09-15 17:18:09 -03001465 .frontend_attach =
1466 af9015_af9013_frontend_attach,
1467 .tuner_attach = af9015_tuner_attach,
1468 .stream = {
1469 .type = USB_BULK,
1470 .count = 6,
1471 .endpoint = 0x85,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001472 .u = {
1473 .bulk = {
1474 .buffersize =
Jose Alberto Reguero353330c2009-09-12 09:51:36 -03001475 TS_USB20_FRAME_SIZE,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001476 }
1477 }
Antti Palosaari80619de2008-09-15 17:18:09 -03001478 },
Michael Krufky77eed212011-09-06 09:31:57 -03001479 }},
Antti Palosaari80619de2008-09-15 17:18:09 -03001480 }
1481 },
1482
1483 .identify_state = af9015_identify_state,
1484
Antti Palosaari1cd72782010-10-12 17:22:32 -03001485 .rc.core = {
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001486 .protocol = RC_TYPE_NEC,
Antti Palosaari1cd72782010-10-12 17:22:32 -03001487 .module_name = "af9015",
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001488 .rc_query = af9015_rc_query,
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001489 .rc_interval = AF9015_RC_INTERVAL,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001490 .allowed_protos = RC_TYPE_NEC,
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001491 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001492
1493 .i2c_algo = &af9015_i2c_algo,
1494
Emilio David Diaus Lopeza062d042011-07-12 19:53:39 -03001495 .num_device_descs = 10, /* check max from dvb-usb.h */
Antti Palosaari80619de2008-09-15 17:18:09 -03001496 .devices = {
1497 {
1498 .name = "Xtensions XD-380",
1499 .cold_ids = {&af9015_usb_table[10], NULL},
1500 .warm_ids = {NULL},
1501 },
1502 {
1503 .name = "MSI DIGIVOX Duo",
1504 .cold_ids = {&af9015_usb_table[11], NULL},
1505 .warm_ids = {NULL},
1506 },
1507 {
1508 .name = "Fujitsu-Siemens Slim Mobile USB DVB-T",
1509 .cold_ids = {&af9015_usb_table[12], NULL},
1510 .warm_ids = {NULL},
1511 },
Mikko Ohtamaa111f9ec2008-09-19 18:26:05 -03001512 {
Antti Palosaaria3765882008-09-19 18:34:06 -03001513 .name = "Telestar Starstick 2",
Mikko Ohtamaa111f9ec2008-09-19 18:26:05 -03001514 .cold_ids = {&af9015_usb_table[13], NULL},
1515 .warm_ids = {NULL},
1516 },
Antti Palosaari05c1cab2008-09-22 12:32:37 -03001517 {
1518 .name = "AVerMedia A309",
1519 .cold_ids = {&af9015_usb_table[14], NULL},
1520 .warm_ids = {NULL},
1521 },
Herbert Graeber641015a2008-10-07 10:06:36 -03001522 {
1523 .name = "MSI Digi VOX mini III",
1524 .cold_ids = {&af9015_usb_table[15], NULL},
1525 .warm_ids = {NULL},
1526 },
Antti Palosaari163e9cd2008-11-04 12:57:47 -03001527 {
1528 .name = "KWorld USB DVB-T TV Stick II " \
1529 "(VS-DVB-T 395U)",
Antti Palosaari71bf2e02009-01-13 12:47:28 -03001530 .cold_ids = {&af9015_usb_table[16],
Antti Palosaari58fe1592009-03-26 20:41:05 -03001531 &af9015_usb_table[17],
Antti Palosaari7fc87092010-03-01 14:06:52 -03001532 &af9015_usb_table[18],
1533 &af9015_usb_table[31], NULL},
Antti Palosaari163e9cd2008-11-04 12:57:47 -03001534 .warm_ids = {NULL},
1535 },
Marc Schneider26144842009-03-26 21:07:18 -03001536 {
1537 .name = "TrekStor DVB-T USB Stick",
1538 .cold_ids = {&af9015_usb_table[19], NULL},
1539 .warm_ids = {NULL},
1540 },
Antti Palosaari3956fef2009-03-31 17:01:02 -03001541 {
1542 .name = "AverMedia AVerTV Volar Black HD " \
1543 "(A850)",
1544 .cold_ids = {&af9015_usb_table[20], NULL},
1545 .warm_ids = {NULL},
1546 },
Emilio David Diaus Lopeza062d042011-07-12 19:53:39 -03001547 {
1548 .name = "Sveon STV22 Dual USB DVB-T Tuner HDTV",
1549 .cold_ids = {&af9015_usb_table[37], NULL},
1550 .warm_ids = {NULL},
1551 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001552 }
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001553 }, {
1554 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1555
1556 .usb_ctrl = DEVICE_SPECIFIC,
1557 .download_firmware = af9015_download_firmware,
1558 .firmware = "dvb-usb-af9015.fw",
1559 .no_reconnect = 1,
1560
Antti Palosaari02542942009-09-16 20:33:03 -03001561 .size_of_priv = sizeof(struct af9015_state),
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001562
1563 .num_adapters = 2,
1564 .adapter = {
1565 {
Michael Krufky77eed212011-09-06 09:31:57 -03001566 .num_frontends = 1,
1567 .fe = {{
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001568 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1569 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1570
1571 .pid_filter_count = 32,
1572 .pid_filter = af9015_pid_filter,
1573 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1574
1575 .frontend_attach =
1576 af9015_af9013_frontend_attach,
1577 .tuner_attach = af9015_tuner_attach,
1578 .stream = {
1579 .type = USB_BULK,
1580 .count = 6,
1581 .endpoint = 0x84,
1582 },
Michael Krufky77eed212011-09-06 09:31:57 -03001583 }},
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001584 },
1585 {
Michael Krufky77eed212011-09-06 09:31:57 -03001586 .num_frontends = 1,
1587 .fe = {{
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001588 .frontend_attach =
1589 af9015_af9013_frontend_attach,
1590 .tuner_attach = af9015_tuner_attach,
1591 .stream = {
1592 .type = USB_BULK,
1593 .count = 6,
1594 .endpoint = 0x85,
1595 .u = {
1596 .bulk = {
1597 .buffersize =
Jose Alberto Reguero353330c2009-09-12 09:51:36 -03001598 TS_USB20_FRAME_SIZE,
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001599 }
1600 }
1601 },
Michael Krufky77eed212011-09-06 09:31:57 -03001602 }},
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001603 }
1604 },
1605
1606 .identify_state = af9015_identify_state,
1607
Antti Palosaari1cd72782010-10-12 17:22:32 -03001608 .rc.core = {
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001609 .protocol = RC_TYPE_NEC,
Antti Palosaari1cd72782010-10-12 17:22:32 -03001610 .module_name = "af9015",
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001611 .rc_query = af9015_rc_query,
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001612 .rc_interval = AF9015_RC_INTERVAL,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001613 .allowed_protos = RC_TYPE_NEC,
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001614 },
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001615
1616 .i2c_algo = &af9015_i2c_algo,
1617
Antti Palosaaria44b91d2010-09-09 12:05:31 -03001618 .num_device_descs = 9, /* check max from dvb-usb.h */
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001619 .devices = {
Antti Palosaari1ed5fad2009-04-09 15:14:18 -03001620 {
1621 .name = "AverMedia AVerTV Volar GPS 805 (A805)",
1622 .cold_ids = {&af9015_usb_table[21], NULL},
1623 .warm_ids = {NULL},
1624 },
Marcel Jueling734dd232009-04-09 17:16:41 -03001625 {
1626 .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \
1627 "V3.0",
1628 .cold_ids = {&af9015_usb_table[22], NULL},
1629 .warm_ids = {NULL},
1630 },
Wen-chien Jesse Sung6e9c1a22009-04-28 01:11:22 -03001631 {
1632 .name = "KWorld Digial MC-810",
1633 .cold_ids = {&af9015_usb_table[23], NULL},
1634 .warm_ids = {NULL},
1635 },
Antti Palosaari22d46452009-05-31 17:07:01 -03001636 {
1637 .name = "Genius TVGo DVB-T03",
1638 .cold_ids = {&af9015_usb_table[24], NULL},
1639 .warm_ids = {NULL},
1640 },
Antti Palosaari486ba122009-09-18 13:37:57 -03001641 {
1642 .name = "KWorld PlusTV DVB-T PCI Pro Card " \
1643 "(DVB-T PC160-T)",
1644 .cold_ids = {&af9015_usb_table[26], NULL},
1645 .warm_ids = {NULL},
1646 },
Ignacio de Miguel Diaz52322632009-11-13 23:13:34 -03001647 {
1648 .name = "Sveon STV20 Tuner USB DVB-T HDTV",
1649 .cold_ids = {&af9015_usb_table[27], NULL},
1650 .warm_ids = {NULL},
1651 },
Antti Palosaari809c1e82010-02-10 20:07:30 -03001652 {
1653 .name = "Leadtek WinFast DTV2000DS",
1654 .cold_ids = {&af9015_usb_table[29], NULL},
1655 .warm_ids = {NULL},
1656 },
Antti Palosaariab9b4f22010-03-01 13:50:40 -03001657 {
1658 .name = "KWorld USB DVB-T Stick Mobile " \
1659 "(UB383-T)",
1660 .cold_ids = {&af9015_usb_table[30], NULL},
1661 .warm_ids = {NULL},
1662 },
Antti Palosaari2606cfa2010-05-23 18:26:37 -03001663 {
1664 .name = "AverMedia AVerTV Volar M (A815Mac)",
1665 .cold_ids = {&af9015_usb_table[32], NULL},
1666 .warm_ids = {NULL},
1667 },
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001668 }
1669 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001670};
Antti Palosaari80619de2008-09-15 17:18:09 -03001671
1672static int af9015_usb_probe(struct usb_interface *intf,
1673 const struct usb_device_id *id)
1674{
1675 int ret = 0;
1676 struct dvb_usb_device *d = NULL;
1677 struct usb_device *udev = interface_to_usbdev(intf);
1678 u8 i;
1679
1680 deb_info("%s: interface:%d\n", __func__,
1681 intf->cur_altsetting->desc.bInterfaceNumber);
1682
1683 /* interface 0 is used by DVB-T receiver and
1684 interface 1 is for remote controller (HID) */
1685 if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
1686 ret = af9015_read_config(udev);
1687 if (ret)
1688 return ret;
1689
1690 for (i = 0; i < af9015_properties_count; i++) {
1691 ret = dvb_usb_device_init(intf, &af9015_properties[i],
1692 THIS_MODULE, &d, adapter_nr);
1693 if (!ret)
1694 break;
1695 if (ret != -ENODEV)
1696 return ret;
1697 }
1698 if (ret)
1699 return ret;
1700
1701 if (d)
1702 ret = af9015_init(d);
1703 }
1704
1705 return ret;
1706}
1707
Antti Palosaari80619de2008-09-15 17:18:09 -03001708/* usb specific object needed to register this driver with the usb subsystem */
1709static struct usb_driver af9015_usb_driver = {
1710 .name = "dvb_usb_af9015",
1711 .probe = af9015_usb_probe,
Antti Palosaari713d9b52011-06-18 10:24:53 -03001712 .disconnect = dvb_usb_device_exit,
Antti Palosaari80619de2008-09-15 17:18:09 -03001713 .id_table = af9015_usb_table,
1714};
1715
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -08001716module_usb_driver(af9015_usb_driver);
Antti Palosaari80619de2008-09-15 17:18:09 -03001717
1718MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1719MODULE_DESCRIPTION("Driver for Afatech AF9015 DVB-T");
1720MODULE_LICENSE("GPL");