blob: 2fb24c3f47748810de5d4094d436531d81ab4fe1 [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 Palosaari80619de2008-09-15 17:18:09 -030034
Antti Palosaari349d0422008-11-05 16:31:24 -030035static int dvb_usb_af9015_debug;
Antti Palosaari80619de2008-09-15 17:18:09 -030036module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
37MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
Antti Palosaari349d0422008-11-05 16:31:24 -030038static int dvb_usb_af9015_remote;
Antti Palosaari80619de2008-09-15 17:18:09 -030039module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
40MODULE_PARM_DESC(remote, "select remote");
Antti Palosaari80619de2008-09-15 17:18:09 -030041DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
42
43static DEFINE_MUTEX(af9015_usb_mutex);
44
45static struct af9015_config af9015_config;
Antti Palosaari85d7d7c2009-04-09 09:16:12 -030046static struct dvb_usb_device_properties af9015_properties[3];
Antti Palosaari349d0422008-11-05 16:31:24 -030047static int af9015_properties_count = ARRAY_SIZE(af9015_properties);
Antti Palosaari80619de2008-09-15 17:18:09 -030048
49static struct af9013_config af9015_af9013_config[] = {
50 {
51 .demod_address = AF9015_I2C_DEMOD,
52 .output_mode = AF9013_OUTPUT_MODE_USB,
53 .api_version = { 0, 1, 9, 0 },
54 .gpio[0] = AF9013_GPIO_HI,
Antti Palosaari80619de2008-09-15 17:18:09 -030055 .gpio[3] = AF9013_GPIO_TUNER_ON,
56
57 }, {
58 .output_mode = AF9013_OUTPUT_MODE_SERIAL,
59 .api_version = { 0, 1, 9, 0 },
60 .gpio[0] = AF9013_GPIO_TUNER_ON,
61 .gpio[1] = AF9013_GPIO_LO,
62 }
63};
64
65static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
66{
Antti Palosaari06565d72009-09-12 20:46:30 -030067#define BUF_LEN 63
68#define REQ_HDR_LEN 8 /* send header size */
69#define ACK_HDR_LEN 2 /* rece header size */
Antti Palosaari80619de2008-09-15 17:18:09 -030070 int act_len, ret;
Antti Palosaari06565d72009-09-12 20:46:30 -030071 u8 buf[BUF_LEN];
Antti Palosaari80619de2008-09-15 17:18:09 -030072 u8 write = 1;
Antti Palosaari06565d72009-09-12 20:46:30 -030073 u8 msg_len = REQ_HDR_LEN;
Antti Palosaari80619de2008-09-15 17:18:09 -030074 static u8 seq; /* packet sequence number */
75
76 if (mutex_lock_interruptible(&af9015_usb_mutex) < 0)
77 return -EAGAIN;
78
79 buf[0] = req->cmd;
80 buf[1] = seq++;
81 buf[2] = req->i2c_addr;
82 buf[3] = req->addr >> 8;
83 buf[4] = req->addr & 0xff;
84 buf[5] = req->mbox;
85 buf[6] = req->addr_len;
86 buf[7] = req->data_len;
87
88 switch (req->cmd) {
89 case GET_CONFIG:
Antti Palosaari80619de2008-09-15 17:18:09 -030090 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) ||
Antti Palosaarif4e96de2009-09-12 21:25:59 -0300103 ((req->addr & 0xff00) == 0xae00))
Antti Palosaari80619de2008-09-15 17:18:09 -0300104 buf[0] = WRITE_VIRTUAL_MEMORY;
105 case WRITE_VIRTUAL_MEMORY:
106 case COPY_FIRMWARE:
107 case DOWNLOAD_FIRMWARE:
Nils Kassubeba1bc642009-07-28 11:54:52 -0300108 case BOOT:
Antti Palosaari80619de2008-09-15 17:18:09 -0300109 break;
110 default:
111 err("unknown command:%d", req->cmd);
112 ret = -1;
113 goto error_unlock;
114 }
115
Antti Palosaari06565d72009-09-12 20:46:30 -0300116 /* buffer overflow check */
117 if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
118 (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
119 err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
120 ret = -EINVAL;
121 goto error_unlock;
122 }
123
Antti Palosaari80619de2008-09-15 17:18:09 -0300124 /* write requested */
125 if (write) {
Antti Palosaari06565d72009-09-12 20:46:30 -0300126 memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
Antti Palosaari80619de2008-09-15 17:18:09 -0300127 msg_len += req->data_len;
128 }
Antti Palosaari06565d72009-09-12 20:46:30 -0300129
Antti Palosaari80619de2008-09-15 17:18:09 -0300130 deb_xfer(">>> ");
131 debug_dump(buf, msg_len, deb_xfer);
132
133 /* send req */
134 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
Antti Palosaari06565d72009-09-12 20:46:30 -0300135 &act_len, AF9015_USB_TIMEOUT);
Antti Palosaari80619de2008-09-15 17:18:09 -0300136 if (ret)
137 err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len);
138 else
139 if (act_len != msg_len)
140 ret = -1; /* all data is not send */
141 if (ret)
142 goto error_unlock;
143
144 /* no ack for those packets */
145 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
146 goto exit_unlock;
147
Antti Palosaari06565d72009-09-12 20:46:30 -0300148 /* write receives seq + status = 2 bytes
149 read receives seq + status + data = 2 + N bytes */
150 msg_len = ACK_HDR_LEN;
151 if (!write)
152 msg_len += req->data_len;
153
Antti Palosaari80619de2008-09-15 17:18:09 -0300154 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
Antti Palosaari06565d72009-09-12 20:46:30 -0300155 &act_len, AF9015_USB_TIMEOUT);
Antti Palosaari80619de2008-09-15 17:18:09 -0300156 if (ret) {
157 err("recv bulk message failed:%d", ret);
158 ret = -1;
159 goto error_unlock;
160 }
161
162 deb_xfer("<<< ");
163 debug_dump(buf, act_len, deb_xfer);
164
165 /* remote controller query status is 1 if remote code is not received */
166 if (req->cmd == GET_IR_CODE && buf[1] == 1) {
167 buf[1] = 0; /* clear command "error" status */
168 memset(&buf[2], 0, req->data_len);
169 buf[3] = 1; /* no remote code received mark */
170 }
171
172 /* check status */
173 if (buf[1]) {
174 err("command failed:%d", buf[1]);
175 ret = -1;
176 goto error_unlock;
177 }
178
179 /* read request, copy returned data to return buf */
180 if (!write)
Antti Palosaari06565d72009-09-12 20:46:30 -0300181 memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
Antti Palosaari80619de2008-09-15 17:18:09 -0300182
183error_unlock:
184exit_unlock:
185 mutex_unlock(&af9015_usb_mutex);
186
187 return ret;
188}
189
190static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
191{
192 return af9015_rw_udev(d->udev, req);
193}
194
195static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
196 u8 len)
197{
198 struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
199 val};
200 return af9015_ctrl_msg(d, &req);
201}
202
203static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
204{
205 return af9015_write_regs(d, addr, &val, 1);
206}
207
208static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
209{
210 struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, 1, val};
211 return af9015_ctrl_msg(d, &req);
212}
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;
244 u8 mbox, addr_len;
245 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;
283 mbox = 0;
284 }
285
286 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
287 if (msg[i].addr ==
288 af9015_af9013_config[0].demod_address)
289 req.cmd = READ_MEMORY;
290 else
291 req.cmd = READ_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+1].len;
297 req.data = &msg[i+1].buf[0];
298 ret = af9015_ctrl_msg(d, &req);
299 i += 2;
Jochen Friedrichd5633992009-02-02 14:59:50 -0300300 } else if (msg[i].flags & I2C_M_RD) {
301 ret = -EINVAL;
302 if (msg[i].addr ==
303 af9015_af9013_config[0].demod_address)
304 goto error;
305 else
306 req.cmd = READ_I2C;
307 req.i2c_addr = msg[i].addr;
308 req.addr = addr;
309 req.mbox = mbox;
310 req.addr_len = addr_len;
311 req.data_len = msg[i].len;
312 req.data = &msg[i].buf[0];
313 ret = af9015_ctrl_msg(d, &req);
314 i += 1;
Antti Palosaari80619de2008-09-15 17:18:09 -0300315 } else {
316 if (msg[i].addr ==
317 af9015_af9013_config[0].demod_address)
318 req.cmd = WRITE_MEMORY;
319 else
320 req.cmd = WRITE_I2C;
321 req.i2c_addr = msg[i].addr;
322 req.addr = addr;
323 req.mbox = mbox;
324 req.addr_len = addr_len;
325 req.data_len = msg[i].len-addr_len;
326 req.data = &msg[i].buf[addr_len];
327 ret = af9015_ctrl_msg(d, &req);
328 i += 1;
329 }
330 if (ret)
331 goto error;
332
333 }
334 ret = i;
335
336error:
337 mutex_unlock(&d->i2c_mutex);
338
339 return ret;
340}
341
342static u32 af9015_i2c_func(struct i2c_adapter *adapter)
343{
344 return I2C_FUNC_I2C;
345}
346
347static struct i2c_algorithm af9015_i2c_algo = {
348 .master_xfer = af9015_i2c_xfer,
349 .functionality = af9015_i2c_func,
350};
351
352static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
353{
354 int ret;
355 u8 val, mask = 0x01;
356
357 ret = af9015_read_reg(d, addr, &val);
358 if (ret)
359 return ret;
360
361 mask <<= bit;
362 if (op) {
363 /* set bit */
364 val |= mask;
365 } else {
366 /* clear bit */
367 mask ^= 0xff;
368 val &= mask;
369 }
370
371 return af9015_write_reg(d, addr, val);
372}
373
374static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
375{
376 return af9015_do_reg_bit(d, addr, bit, 1);
377}
378
379static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
380{
381 return af9015_do_reg_bit(d, addr, bit, 0);
382}
383
384static int af9015_init_endpoint(struct dvb_usb_device *d)
385{
386 int ret;
387 u16 frame_size;
388 u8 packet_size;
389 deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
390
Antti Palosaari9c863272009-09-12 13:35:29 -0300391 /* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
392 We use smaller - about 1/4 from the original, 5 and 87. */
Antti Palosaari80619de2008-09-15 17:18:09 -0300393#define TS_PACKET_SIZE 188
394
Antti Palosaari9c863272009-09-12 13:35:29 -0300395#define TS_USB20_PACKET_COUNT 87
Antti Palosaari80619de2008-09-15 17:18:09 -0300396#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
397
Antti Palosaari9c863272009-09-12 13:35:29 -0300398#define TS_USB11_PACKET_COUNT 5
Antti Palosaari80619de2008-09-15 17:18:09 -0300399#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
400
401#define TS_USB20_MAX_PACKET_SIZE 512
402#define TS_USB11_MAX_PACKET_SIZE 64
403
404 if (d->udev->speed == USB_SPEED_FULL) {
405 frame_size = TS_USB11_FRAME_SIZE/4;
406 packet_size = TS_USB11_MAX_PACKET_SIZE/4;
407 } else {
408 frame_size = TS_USB20_FRAME_SIZE/4;
409 packet_size = TS_USB20_MAX_PACKET_SIZE/4;
410 }
411
412 ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
413 if (ret)
414 goto error;
415 ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
416 if (ret)
417 goto error;
418 ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
419 if (ret)
420 goto error;
421 ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
422 if (ret)
423 goto error;
424 ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
425 if (ret)
426 goto error;
427 if (af9015_config.dual_mode) {
428 ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
429 if (ret)
430 goto error;
431 }
432 ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
433 if (ret)
434 goto error;
435 if (af9015_config.dual_mode) {
436 ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
437 if (ret)
438 goto error;
439 }
440 /* EP4 xfer length */
441 ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
442 if (ret)
443 goto error;
444 ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
445 if (ret)
446 goto error;
447 /* EP5 xfer length */
448 ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
449 if (ret)
450 goto error;
451 ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
452 if (ret)
453 goto error;
454 ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
455 if (ret)
456 goto error;
457 ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
458 if (ret)
459 goto error;
460 ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
461 if (ret)
462 goto error;
463 if (af9015_config.dual_mode) {
464 ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
465 if (ret)
466 goto error;
467 }
468
469 /* enable / disable mp2if2 */
470 if (af9015_config.dual_mode)
471 ret = af9015_set_reg_bit(d, 0xd50b, 0);
472 else
473 ret = af9015_clear_reg_bit(d, 0xd50b, 0);
474error:
475 if (ret)
476 err("endpoint init failed:%d", ret);
477 return ret;
478}
479
480static int af9015_copy_firmware(struct dvb_usb_device *d)
481{
482 int ret;
483 u8 fw_params[4];
484 u8 val, i;
485 struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
486 fw_params };
487 deb_info("%s:\n", __func__);
488
489 fw_params[0] = af9015_config.firmware_size >> 8;
490 fw_params[1] = af9015_config.firmware_size & 0xff;
491 fw_params[2] = af9015_config.firmware_checksum >> 8;
492 fw_params[3] = af9015_config.firmware_checksum & 0xff;
493
494 /* wait 2nd demodulator ready */
495 msleep(100);
496
497 ret = af9015_read_reg_i2c(d, 0x3a, 0x98be, &val);
498 if (ret)
499 goto error;
500 else
501 deb_info("%s: firmware status:%02x\n", __func__, val);
502
503 if (val == 0x0c) /* fw is running, no need for download */
504 goto exit;
505
506 /* set I2C master clock to fast (to speed up firmware copy) */
507 ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
508 if (ret)
509 goto error;
510
511 msleep(50);
512
513 /* copy firmware */
514 ret = af9015_ctrl_msg(d, &req);
515 if (ret)
516 err("firmware copy cmd failed:%d", ret);
517 deb_info("%s: firmware copy done\n", __func__);
518
519 /* set I2C master clock back to normal */
520 ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
521 if (ret)
522 goto error;
523
524 /* request boot firmware */
525 ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].demod_address,
526 0xe205, 1);
527 deb_info("%s: firmware boot cmd status:%d\n", __func__, ret);
528 if (ret)
529 goto error;
530
531 for (i = 0; i < 15; i++) {
532 msleep(100);
533
534 /* check firmware status */
535 ret = af9015_read_reg_i2c(d,
536 af9015_af9013_config[1].demod_address, 0x98be, &val);
537 deb_info("%s: firmware status cmd status:%d fw status:%02x\n",
538 __func__, ret, val);
539 if (ret)
540 goto error;
541
542 if (val == 0x0c || val == 0x04) /* success or fail */
543 break;
544 }
545
546 if (val == 0x04) {
547 err("firmware did not run");
548 ret = -1;
549 } else if (val != 0x0c) {
550 err("firmware boot timeout");
551 ret = -1;
552 }
553
554error:
555exit:
556 return ret;
557}
558
Jiri Slaby6c614042010-01-22 12:10:52 -0300559/* hash (and dump) eeprom */
560static int af9015_eeprom_hash(struct usb_device *udev)
Antti Palosaari80619de2008-09-15 17:18:09 -0300561{
Jiri Slaby6c614042010-01-22 12:10:52 -0300562 static const unsigned int eeprom_size = 256;
563 unsigned int reg;
564 int ret;
565 u8 val, *eeprom;
566 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
Antti Palosaari80619de2008-09-15 17:18:09 -0300567
Jiri Slaby6c614042010-01-22 12:10:52 -0300568 eeprom = kmalloc(eeprom_size, GFP_KERNEL);
569 if (eeprom == NULL)
570 return -ENOMEM;
571
572 for (reg = 0; reg < eeprom_size; reg++) {
573 req.addr = reg;
574 ret = af9015_rw_udev(udev, &req);
575 if (ret)
576 goto free;
577 eeprom[reg] = val;
Antti Palosaari80619de2008-09-15 17:18:09 -0300578 }
Jiri Slaby6c614042010-01-22 12:10:52 -0300579
580 if (dvb_usb_af9015_debug & 0x01)
581 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
582 eeprom_size);
583
584 BUG_ON(eeprom_size % 4);
585
586 af9015_config.eeprom_sum = 0;
587 for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
588 af9015_config.eeprom_sum *= GOLDEN_RATIO_PRIME_32;
589 af9015_config.eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
590 }
591
592 deb_info("%s: eeprom sum=%.8x\n", __func__, af9015_config.eeprom_sum);
593
594 ret = 0;
595free:
596 kfree(eeprom);
597 return ret;
Antti Palosaari80619de2008-09-15 17:18:09 -0300598}
599
Antti Palosaari349d0422008-11-05 16:31:24 -0300600static int af9015_download_ir_table(struct dvb_usb_device *d)
Antti Palosaari80619de2008-09-15 17:18:09 -0300601{
602 int i, packets = 0, ret;
603 u16 addr = 0x9a56; /* ir-table start address */
604 struct req_t req = {WRITE_MEMORY, 0, 0, 0, 0, 1, NULL};
605 u8 *data = NULL;
606 deb_info("%s:\n", __func__);
607
608 data = af9015_config.ir_table;
609 packets = af9015_config.ir_table_size;
610
611 /* no remote */
612 if (!packets)
613 goto exit;
614
615 /* load remote ir-table */
616 for (i = 0; i < packets; i++) {
617 req.addr = addr + i;
618 req.data = &data[i];
619 ret = af9015_ctrl_msg(d, &req);
620 if (ret) {
621 err("ir-table download failed at packet %d with " \
622 "code %d", i, ret);
623 return ret;
624 }
625 }
626
627exit:
628 return 0;
629}
630
631static int af9015_init(struct dvb_usb_device *d)
632{
633 int ret;
634 deb_info("%s:\n", __func__);
635
636 ret = af9015_init_endpoint(d);
637 if (ret)
638 goto error;
639
640 ret = af9015_download_ir_table(d);
641 if (ret)
642 goto error;
643
644error:
645 return ret;
646}
647
648static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
649{
650 int ret;
651 deb_info("%s: onoff:%d\n", __func__, onoff);
652
653 if (onoff)
654 ret = af9015_set_reg_bit(adap->dev, 0xd503, 0);
655 else
656 ret = af9015_clear_reg_bit(adap->dev, 0xd503, 0);
657
658 return ret;
659}
660
661static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
662 int onoff)
663{
664 int ret;
665 u8 idx;
666
667 deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
668 __func__, index, pid, onoff);
669
670 ret = af9015_write_reg(adap->dev, 0xd505, (pid & 0xff));
671 if (ret)
672 goto error;
673
674 ret = af9015_write_reg(adap->dev, 0xd506, (pid >> 8));
675 if (ret)
676 goto error;
677
678 idx = ((index & 0x1f) | (1 << 5));
679 ret = af9015_write_reg(adap->dev, 0xd504, idx);
680
681error:
682 return ret;
683}
684
685static int af9015_download_firmware(struct usb_device *udev,
686 const struct firmware *fw)
687{
688 int i, len, packets, remainder, ret;
689 struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
690 u16 addr = 0x5100; /* firmware start address */
691 u16 checksum = 0;
692
693 deb_info("%s:\n", __func__);
694
695 /* calc checksum */
696 for (i = 0; i < fw->size; i++)
697 checksum += fw->data[i];
698
699 af9015_config.firmware_size = fw->size;
700 af9015_config.firmware_checksum = checksum;
701
702 #define FW_PACKET_MAX_DATA 55
703
704 packets = fw->size / FW_PACKET_MAX_DATA;
705 remainder = fw->size % FW_PACKET_MAX_DATA;
706 len = FW_PACKET_MAX_DATA;
707 for (i = 0; i <= packets; i++) {
708 if (i == packets) /* set size of the last packet */
709 len = remainder;
710
711 req.data_len = len;
Antti Palosaari541dfa82008-10-06 13:57:45 -0300712 req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
Antti Palosaari80619de2008-09-15 17:18:09 -0300713 req.addr = addr;
714 addr += FW_PACKET_MAX_DATA;
715
716 ret = af9015_rw_udev(udev, &req);
717 if (ret) {
718 err("firmware download failed at packet %d with " \
719 "code %d", i, ret);
720 goto error;
721 }
722 }
Antti Palosaari80619de2008-09-15 17:18:09 -0300723
724 /* firmware loaded, request boot */
725 req.cmd = BOOT;
726 ret = af9015_rw_udev(udev, &req);
727 if (ret) {
728 err("firmware boot failed:%d", ret);
729 goto error;
730 }
731
Antti Palosaari80619de2008-09-15 17:18:09 -0300732error:
733 return ret;
734}
735
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300736struct af9015_setup {
737 unsigned int id;
738 struct dvb_usb_rc_key *rc_key_map;
739 unsigned int rc_key_map_size;
740 u8 *ir_table;
741 unsigned int ir_table_size;
742};
743
744static const struct af9015_setup *af9015_setup_match(unsigned int id,
745 const struct af9015_setup *table)
746{
747 for (; table->rc_key_map; table++)
748 if (table->id == id)
749 return table;
750 return NULL;
751}
752
753static const struct af9015_setup af9015_setup_modparam[] = {
754 { AF9015_REMOTE_A_LINK_DTU_M,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300755 ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link),
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300756 af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
757 { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300758 ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi),
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300759 af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
760 { AF9015_REMOTE_MYGICTV_U718,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300761 ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv),
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300762 af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
763 { AF9015_REMOTE_DIGITTRADE_DVB_T,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300764 ir_codes_af9015_table_digittrade, ARRAY_SIZE(ir_codes_af9015_table_digittrade),
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300765 af9015_ir_table_digittrade, ARRAY_SIZE(af9015_ir_table_digittrade) },
766 { AF9015_REMOTE_AVERMEDIA_KS,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300767 ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia),
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300768 af9015_ir_table_avermedia_ks, ARRAY_SIZE(af9015_ir_table_avermedia_ks) },
769 { }
770};
771
772/* don't add new entries here anymore, use hashes instead */
773static const struct af9015_setup af9015_setup_usbids[] = {
774 { USB_VID_LEADTEK,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300775 ir_codes_af9015_table_leadtek, ARRAY_SIZE(ir_codes_af9015_table_leadtek),
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300776 af9015_ir_table_leadtek, ARRAY_SIZE(af9015_ir_table_leadtek) },
777 { USB_VID_VISIONPLUS,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300778 ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan),
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300779 af9015_ir_table_twinhan, ARRAY_SIZE(af9015_ir_table_twinhan) },
780 { USB_VID_KWORLD_2, /* TODO: use correct rc keys */
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300781 ir_codes_af9015_table_twinhan, ARRAY_SIZE(ir_codes_af9015_table_twinhan),
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300782 af9015_ir_table_kworld, ARRAY_SIZE(af9015_ir_table_kworld) },
783 { USB_VID_AVERMEDIA,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300784 ir_codes_af9015_table_avermedia, ARRAY_SIZE(ir_codes_af9015_table_avermedia),
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300785 af9015_ir_table_avermedia, ARRAY_SIZE(af9015_ir_table_avermedia) },
786 { USB_VID_MSI_2,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300787 ir_codes_af9015_table_msi_digivox_iii, ARRAY_SIZE(ir_codes_af9015_table_msi_digivox_iii),
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300788 af9015_ir_table_msi_digivox_iii, ARRAY_SIZE(af9015_ir_table_msi_digivox_iii) },
789 { }
790};
791
Jiri Slabye3a0cc62010-01-22 12:10:55 -0300792static const struct af9015_setup af9015_setup_hashes[] = {
793 { 0xb8feb708,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300794 ir_codes_af9015_table_msi, ARRAY_SIZE(ir_codes_af9015_table_msi),
Jiri Slabye3a0cc62010-01-22 12:10:55 -0300795 af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) },
Antti Palosaaridb02d9d2010-02-10 20:20:41 -0300796 { 0xa3703d00,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300797 ir_codes_af9015_table_a_link, ARRAY_SIZE(ir_codes_af9015_table_a_link),
Antti Palosaaridb02d9d2010-02-10 20:20:41 -0300798 af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) },
Antti Palosaari58c811df2010-02-10 20:44:12 -0300799 { 0x9b7dc64e,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300800 ir_codes_af9015_table_mygictv, ARRAY_SIZE(ir_codes_af9015_table_mygictv),
Antti Palosaari58c811df2010-02-10 20:44:12 -0300801 af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) },
Jiri Slabye3a0cc62010-01-22 12:10:55 -0300802 { }
803};
804
Jiri Slaby634d2d72010-01-22 12:10:53 -0300805static void af9015_set_remote_config(struct usb_device *udev,
806 struct dvb_usb_device_properties *props)
807{
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300808 const struct af9015_setup *table = NULL;
809
Jiri Slaby634d2d72010-01-22 12:10:53 -0300810 if (dvb_usb_af9015_remote) {
811 /* load remote defined as module param */
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300812 table = af9015_setup_match(dvb_usb_af9015_remote,
813 af9015_setup_modparam);
Jiri Slaby634d2d72010-01-22 12:10:53 -0300814 } else {
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300815 u16 vendor = le16_to_cpu(udev->descriptor.idVendor);
816
Jiri Slabye3a0cc62010-01-22 12:10:55 -0300817 table = af9015_setup_match(af9015_config.eeprom_sum,
818 af9015_setup_hashes);
819
820 if (!table && vendor == USB_VID_AFATECH) {
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300821 /* Check USB manufacturer and product strings and try
822 to determine correct remote in case of chip vendor
823 reference IDs are used.
824 DO NOT ADD ANYTHING NEW HERE. Use hashes instead.
825 */
Jiri Slaby634d2d72010-01-22 12:10:53 -0300826 char manufacturer[10];
827 memset(manufacturer, 0, sizeof(manufacturer));
828 usb_string(udev, udev->descriptor.iManufacturer,
829 manufacturer, sizeof(manufacturer));
Antti Palosaari58c811df2010-02-10 20:44:12 -0300830 if (!strcmp("MSI", manufacturer)) {
Jiri Slaby634d2d72010-01-22 12:10:53 -0300831 /* iManufacturer 1 MSI
832 iProduct 2 MSI K-VOX */
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300833 table = af9015_setup_match(
834 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
835 af9015_setup_modparam);
Jiri Slaby634d2d72010-01-22 12:10:53 -0300836 } else if (udev->descriptor.idProduct ==
837 cpu_to_le16(USB_PID_TREKSTOR_DVBT)) {
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300838 table = &(const struct af9015_setup){ 0,
Mauro Carvalho Chehabe27e9712010-04-01 21:35:32 -0300839 ir_codes_af9015_table_trekstor,
840 ARRAY_SIZE(ir_codes_af9015_table_trekstor),
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300841 af9015_ir_table_trekstor,
842 ARRAY_SIZE(af9015_ir_table_trekstor)
843 };
Jiri Slaby634d2d72010-01-22 12:10:53 -0300844 }
Jiri Slabye3a0cc62010-01-22 12:10:55 -0300845 } else if (!table)
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300846 table = af9015_setup_match(vendor, af9015_setup_usbids);
847 }
848
849 if (table) {
850 props->rc_key_map = table->rc_key_map;
851 props->rc_key_map_size = table->rc_key_map_size;
852 af9015_config.ir_table = table->ir_table;
853 af9015_config.ir_table_size = table->ir_table_size;
Jiri Slaby634d2d72010-01-22 12:10:53 -0300854 }
855}
856
Antti Palosaari80619de2008-09-15 17:18:09 -0300857static int af9015_read_config(struct usb_device *udev)
858{
859 int ret;
860 u8 val, i, offset = 0;
861 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
Antti Palosaari80619de2008-09-15 17:18:09 -0300862
863 /* IR remote controller */
864 req.addr = AF9015_EEPROM_IR_MODE;
Antti Palosaarid1a470f2009-01-20 14:56:20 -0300865 /* first message will timeout often due to possible hw bug */
866 for (i = 0; i < 4; i++) {
867 ret = af9015_rw_udev(udev, &req);
868 if (!ret)
869 break;
870 }
Antti Palosaari80619de2008-09-15 17:18:09 -0300871 if (ret)
872 goto error;
Jiri Slaby6c614042010-01-22 12:10:52 -0300873
874 ret = af9015_eeprom_hash(udev);
875 if (ret)
876 goto error;
877
Antti Palosaari80619de2008-09-15 17:18:09 -0300878 deb_info("%s: IR mode:%d\n", __func__, val);
879 for (i = 0; i < af9015_properties_count; i++) {
Antti Palosaari0f017212009-09-21 21:26:37 -0300880 if (val == AF9015_IR_MODE_DISABLED) {
Antti Palosaari80619de2008-09-15 17:18:09 -0300881 af9015_properties[i].rc_key_map = NULL;
882 af9015_properties[i].rc_key_map_size = 0;
Jiri Slaby634d2d72010-01-22 12:10:53 -0300883 } else
884 af9015_set_remote_config(udev, &af9015_properties[i]);
Antti Palosaari80619de2008-09-15 17:18:09 -0300885 }
886
887 /* TS mode - one or two receivers */
888 req.addr = AF9015_EEPROM_TS_MODE;
889 ret = af9015_rw_udev(udev, &req);
890 if (ret)
891 goto error;
892 af9015_config.dual_mode = val;
893 deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode);
Antti Palosaari80619de2008-09-15 17:18:09 -0300894
Antti Palosaarif0830eb2009-01-13 13:08:29 -0300895 /* Set adapter0 buffer size according to USB port speed, adapter1 buffer
896 size can be static because it is enabled only USB2.0 */
Antti Palosaari80619de2008-09-15 17:18:09 -0300897 for (i = 0; i < af9015_properties_count; i++) {
898 /* USB1.1 set smaller buffersize and disable 2nd adapter */
899 if (udev->speed == USB_SPEED_FULL) {
Antti Palosaarif0830eb2009-01-13 13:08:29 -0300900 af9015_properties[i].adapter[0].stream.u.bulk.buffersize
Antti Palosaari9c863272009-09-12 13:35:29 -0300901 = TS_USB11_FRAME_SIZE;
Antti Palosaari80619de2008-09-15 17:18:09 -0300902 /* disable 2nd adapter because we don't have
903 PID-filters */
904 af9015_config.dual_mode = 0;
905 } else {
Antti Palosaarif0830eb2009-01-13 13:08:29 -0300906 af9015_properties[i].adapter[0].stream.u.bulk.buffersize
Jose Alberto Reguero353330c2009-09-12 09:51:36 -0300907 = TS_USB20_FRAME_SIZE;
Antti Palosaari80619de2008-09-15 17:18:09 -0300908 }
909 }
910
911 if (af9015_config.dual_mode) {
912 /* read 2nd demodulator I2C address */
913 req.addr = AF9015_EEPROM_DEMOD2_I2C;
914 ret = af9015_rw_udev(udev, &req);
915 if (ret)
916 goto error;
917 af9015_af9013_config[1].demod_address = val;
918
919 /* enable 2nd adapter */
920 for (i = 0; i < af9015_properties_count; i++)
921 af9015_properties[i].num_adapters = 2;
922
923 } else {
924 /* disable 2nd adapter */
925 for (i = 0; i < af9015_properties_count; i++)
926 af9015_properties[i].num_adapters = 1;
927 }
928
929 for (i = 0; i < af9015_properties[0].num_adapters; i++) {
930 if (i == 1)
931 offset = AF9015_EEPROM_OFFSET;
932 /* xtal */
933 req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
934 ret = af9015_rw_udev(udev, &req);
935 if (ret)
936 goto error;
937 switch (val) {
938 case 0:
939 af9015_af9013_config[i].adc_clock = 28800;
940 break;
941 case 1:
942 af9015_af9013_config[i].adc_clock = 20480;
943 break;
944 case 2:
945 af9015_af9013_config[i].adc_clock = 28000;
946 break;
947 case 3:
948 af9015_af9013_config[i].adc_clock = 25000;
949 break;
950 };
951 deb_info("%s: [%d] xtal:%d set adc_clock:%d\n", __func__, i,
952 val, af9015_af9013_config[i].adc_clock);
953
954 /* tuner IF */
955 req.addr = AF9015_EEPROM_IF1H + offset;
956 ret = af9015_rw_udev(udev, &req);
957 if (ret)
958 goto error;
959 af9015_af9013_config[i].tuner_if = val << 8;
960 req.addr = AF9015_EEPROM_IF1L + offset;
961 ret = af9015_rw_udev(udev, &req);
962 if (ret)
963 goto error;
964 af9015_af9013_config[i].tuner_if += val;
965 deb_info("%s: [%d] IF1:%d\n", __func__, i,
966 af9015_af9013_config[0].tuner_if);
967
968 /* MT2060 IF1 */
969 req.addr = AF9015_EEPROM_MT2060_IF1H + offset;
970 ret = af9015_rw_udev(udev, &req);
971 if (ret)
972 goto error;
973 af9015_config.mt2060_if1[i] = val << 8;
974 req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
975 ret = af9015_rw_udev(udev, &req);
976 if (ret)
977 goto error;
978 af9015_config.mt2060_if1[i] += val;
979 deb_info("%s: [%d] MT2060 IF1:%d\n", __func__, i,
980 af9015_config.mt2060_if1[i]);
981
982 /* tuner */
983 req.addr = AF9015_EEPROM_TUNER_ID1 + offset;
984 ret = af9015_rw_udev(udev, &req);
985 if (ret)
986 goto error;
987 switch (val) {
988 case AF9013_TUNER_ENV77H11D5:
989 case AF9013_TUNER_MT2060:
Antti Palosaari80619de2008-09-15 17:18:09 -0300990 case AF9013_TUNER_QT1010:
991 case AF9013_TUNER_UNKNOWN:
992 case AF9013_TUNER_MT2060_2:
993 case AF9013_TUNER_TDA18271:
994 case AF9013_TUNER_QT1010A:
995 af9015_af9013_config[i].rf_spec_inv = 1;
996 break;
997 case AF9013_TUNER_MXL5003D:
998 case AF9013_TUNER_MXL5005D:
999 case AF9013_TUNER_MXL5005R:
1000 af9015_af9013_config[i].rf_spec_inv = 0;
1001 break;
Jochen Friedrichd5633992009-02-02 14:59:50 -03001002 case AF9013_TUNER_MC44S803:
1003 af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
1004 af9015_af9013_config[i].rf_spec_inv = 1;
1005 break;
Antti Palosaari8ef4c212010-02-10 21:33:12 -03001006 case AF9013_TUNER_TDA18218:
1007 warn("tuner NXP TDA18218 not supported yet");
1008 return -ENODEV;
Antti Palosaari80619de2008-09-15 17:18:09 -03001009 default:
1010 warn("tuner id:%d not supported, please report!", val);
1011 return -ENODEV;
1012 };
1013
1014 af9015_af9013_config[i].tuner = val;
1015 deb_info("%s: [%d] tuner id:%d\n", __func__, i, val);
1016 }
1017
1018error:
1019 if (ret)
1020 err("eeprom read failed:%d", ret);
1021
Antti Palosaari3956fef2009-03-31 17:01:02 -03001022 /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
1023 content :-( Override some wrong values here. */
1024 if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
1025 le16_to_cpu(udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) {
1026 deb_info("%s: AverMedia A850: overriding config\n", __func__);
1027 /* disable dual mode */
1028 af9015_config.dual_mode = 0;
1029 /* disable 2nd adapter */
1030 for (i = 0; i < af9015_properties_count; i++)
1031 af9015_properties[i].num_adapters = 1;
1032
1033 /* set correct IF */
1034 af9015_af9013_config[0].tuner_if = 4570;
1035 }
1036
Antti Palosaari80619de2008-09-15 17:18:09 -03001037 return ret;
1038}
1039
1040static int af9015_identify_state(struct usb_device *udev,
1041 struct dvb_usb_device_properties *props,
1042 struct dvb_usb_device_description **desc,
1043 int *cold)
1044{
1045 int ret;
1046 u8 reply;
1047 struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
1048
1049 ret = af9015_rw_udev(udev, &req);
1050 if (ret)
1051 return ret;
1052
1053 deb_info("%s: reply:%02x\n", __func__, reply);
1054 if (reply == 0x02)
1055 *cold = 0;
1056 else
1057 *cold = 1;
1058
1059 return ret;
1060}
1061
1062static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
1063{
1064 u8 buf[8];
1065 struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf};
1066 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
1067 int i, ret;
1068
1069 memset(buf, 0, sizeof(buf));
1070
1071 ret = af9015_ctrl_msg(d, &req);
1072 if (ret)
1073 return ret;
1074
1075 *event = 0;
1076 *state = REMOTE_NO_KEY_PRESSED;
1077
1078 for (i = 0; i < d->props.rc_key_map_size; i++) {
Mauro Carvalho Chehab2e365882009-08-29 15:19:31 -03001079 if (!buf[1] && rc5_custom(&keymap[i]) == buf[0] &&
1080 rc5_data(&keymap[i]) == buf[2]) {
Antti Palosaari80619de2008-09-15 17:18:09 -03001081 *event = keymap[i].event;
1082 *state = REMOTE_KEY_PRESSED;
1083 break;
1084 }
1085 }
1086 if (!buf[1])
1087 deb_rc("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n",
1088 __func__, buf[0], buf[1], buf[2], buf[3], buf[4],
1089 buf[5], buf[6], buf[7]);
1090
1091 return 0;
1092}
1093
1094/* init 2nd I2C adapter */
Antti Palosaari349d0422008-11-05 16:31:24 -03001095static int af9015_i2c_init(struct dvb_usb_device *d)
Antti Palosaari80619de2008-09-15 17:18:09 -03001096{
1097 int ret;
1098 struct af9015_state *state = d->priv;
1099 deb_info("%s:\n", __func__);
1100
1101 strncpy(state->i2c_adap.name, d->desc->name,
1102 sizeof(state->i2c_adap.name));
1103#ifdef I2C_ADAP_CLASS_TV_DIGITAL
1104 state->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
1105#else
1106 state->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
1107#endif
1108 state->i2c_adap.algo = d->props.i2c_algo;
1109 state->i2c_adap.algo_data = NULL;
1110 state->i2c_adap.dev.parent = &d->udev->dev;
1111
1112 i2c_set_adapdata(&state->i2c_adap, d);
1113
1114 ret = i2c_add_adapter(&state->i2c_adap);
1115 if (ret < 0)
1116 err("could not add i2c adapter");
1117
1118 return ret;
1119}
1120
1121static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
1122{
1123 int ret;
1124 struct af9015_state *state = adap->dev->priv;
1125 struct i2c_adapter *i2c_adap;
1126
1127 if (adap->id == 0) {
1128 /* select I2C adapter */
1129 i2c_adap = &adap->dev->i2c_adap;
1130
1131 deb_info("%s: init I2C\n", __func__);
1132 ret = af9015_i2c_init(adap->dev);
Antti Palosaari80619de2008-09-15 17:18:09 -03001133 } else {
1134 /* select I2C adapter */
1135 i2c_adap = &state->i2c_adap;
1136
1137 /* copy firmware to 2nd demodulator */
1138 if (af9015_config.dual_mode) {
1139 ret = af9015_copy_firmware(adap->dev);
1140 if (ret) {
1141 err("firmware copy to 2nd frontend " \
1142 "failed, will disable it");
1143 af9015_config.dual_mode = 0;
1144 return -ENODEV;
1145 }
1146 } else {
1147 return -ENODEV;
1148 }
1149 }
1150
1151 /* attach demodulator */
1152 adap->fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id],
1153 i2c_adap);
1154
1155 return adap->fe == NULL ? -ENODEV : 0;
1156}
1157
1158static struct mt2060_config af9015_mt2060_config = {
1159 .i2c_address = 0xc0,
1160 .clock_out = 0,
1161};
1162
1163static struct qt1010_config af9015_qt1010_config = {
1164 .i2c_address = 0xc4,
1165};
1166
1167static struct tda18271_config af9015_tda18271_config = {
1168 .gate = TDA18271_GATE_DIGITAL,
1169 .small_i2c = 1,
1170};
1171
1172static struct mxl5005s_config af9015_mxl5003_config = {
1173 .i2c_address = 0xc6,
1174 .if_freq = IF_FREQ_4570000HZ,
1175 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1176 .agc_mode = MXL_SINGLE_AGC,
1177 .tracking_filter = MXL_TF_DEFAULT,
Antti Palosaaria1310772008-09-22 13:59:25 -03001178 .rssi_enable = MXL_RSSI_ENABLE,
Antti Palosaari80619de2008-09-15 17:18:09 -03001179 .cap_select = MXL_CAP_SEL_ENABLE,
1180 .div_out = MXL_DIV_OUT_4,
1181 .clock_out = MXL_CLOCK_OUT_DISABLE,
1182 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1183 .top = MXL5005S_TOP_25P2,
1184 .mod_mode = MXL_DIGITAL_MODE,
1185 .if_mode = MXL_ZERO_IF,
1186 .AgcMasterByte = 0x00,
1187};
1188
1189static struct mxl5005s_config af9015_mxl5005_config = {
1190 .i2c_address = 0xc6,
1191 .if_freq = IF_FREQ_4570000HZ,
1192 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1193 .agc_mode = MXL_SINGLE_AGC,
1194 .tracking_filter = MXL_TF_OFF,
Antti Palosaaria1310772008-09-22 13:59:25 -03001195 .rssi_enable = MXL_RSSI_ENABLE,
Antti Palosaari80619de2008-09-15 17:18:09 -03001196 .cap_select = MXL_CAP_SEL_ENABLE,
1197 .div_out = MXL_DIV_OUT_4,
1198 .clock_out = MXL_CLOCK_OUT_DISABLE,
1199 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1200 .top = MXL5005S_TOP_25P2,
1201 .mod_mode = MXL_DIGITAL_MODE,
1202 .if_mode = MXL_ZERO_IF,
1203 .AgcMasterByte = 0x00,
1204};
1205
Jochen Friedrichd5633992009-02-02 14:59:50 -03001206static struct mc44s803_config af9015_mc44s803_config = {
1207 .i2c_address = 0xc0,
1208 .dig_out = 1,
1209};
1210
Antti Palosaari80619de2008-09-15 17:18:09 -03001211static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
1212{
1213 struct af9015_state *state = adap->dev->priv;
1214 struct i2c_adapter *i2c_adap;
1215 int ret;
1216 deb_info("%s: \n", __func__);
1217
1218 /* select I2C adapter */
1219 if (adap->id == 0)
1220 i2c_adap = &adap->dev->i2c_adap;
1221 else
1222 i2c_adap = &state->i2c_adap;
1223
1224 switch (af9015_af9013_config[adap->id].tuner) {
1225 case AF9013_TUNER_MT2060:
1226 case AF9013_TUNER_MT2060_2:
1227 ret = dvb_attach(mt2060_attach, adap->fe, i2c_adap,
1228 &af9015_mt2060_config,
1229 af9015_config.mt2060_if1[adap->id])
1230 == NULL ? -ENODEV : 0;
1231 break;
1232 case AF9013_TUNER_QT1010:
1233 case AF9013_TUNER_QT1010A:
1234 ret = dvb_attach(qt1010_attach, adap->fe, i2c_adap,
1235 &af9015_qt1010_config) == NULL ? -ENODEV : 0;
1236 break;
1237 case AF9013_TUNER_TDA18271:
1238 ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap,
1239 &af9015_tda18271_config) == NULL ? -ENODEV : 0;
1240 break;
1241 case AF9013_TUNER_MXL5003D:
1242 ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap,
1243 &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
1244 break;
1245 case AF9013_TUNER_MXL5005D:
1246 case AF9013_TUNER_MXL5005R:
1247 ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap,
1248 &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
1249 break;
1250 case AF9013_TUNER_ENV77H11D5:
1251 ret = dvb_attach(dvb_pll_attach, adap->fe, 0xc0, i2c_adap,
1252 DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
1253 break;
1254 case AF9013_TUNER_MC44S803:
Jochen Friedrichd5633992009-02-02 14:59:50 -03001255 ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap,
1256 &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
Antti Palosaari80619de2008-09-15 17:18:09 -03001257 break;
1258 case AF9013_TUNER_UNKNOWN:
1259 default:
1260 ret = -ENODEV;
1261 err("Unknown tuner id:%d",
1262 af9015_af9013_config[adap->id].tuner);
1263 }
1264 return ret;
1265}
1266
1267static struct usb_device_id af9015_usb_table[] = {
1268/* 0 */{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)},
1269 {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)},
1270 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)},
1271 {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)},
1272 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)},
1273/* 5 */{USB_DEVICE(USB_VID_VISIONPLUS,
1274 USB_PID_TINYTWIN)},
1275 {USB_DEVICE(USB_VID_VISIONPLUS,
1276 USB_PID_AZUREWAVE_AD_TU700)},
1277 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)},
1278 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)},
1279 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)},
1280/* 10 */{USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)},
1281 {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)},
1282 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)},
Antti Palosaaria3765882008-09-19 18:34:06 -03001283 {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
Antti Palosaari05c1cab2008-09-22 12:32:37 -03001284 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
Herbert Graeber641015a2008-10-07 10:06:36 -03001285/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
Antti Palosaari163e9cd2008-11-04 12:57:47 -03001286 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
Antti Palosaari71bf2e02009-01-13 12:47:28 -03001287 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
Antti Palosaari58fe1592009-03-26 20:41:05 -03001288 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)},
Marc Schneider26144842009-03-26 21:07:18 -03001289 {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)},
Antti Palosaari1ed5fad2009-04-09 15:14:18 -03001290/* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
1291 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)},
Marcel Jueling734dd232009-04-09 17:16:41 -03001292 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
Wen-chien Jesse Sung6e9c1a22009-04-28 01:11:22 -03001293 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
Antti Palosaari22d46452009-05-31 17:07:01 -03001294 {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
Mart Raudseppc92f0562009-07-24 13:45:41 -03001295/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
Antti Palosaari486ba122009-09-18 13:37:57 -03001296 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)},
Ignacio de Miguel Diaz52322632009-11-13 23:13:34 -03001297 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)},
Antti Palosaarifa1df552010-02-10 20:05:48 -03001298 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)},
Antti Palosaari809c1e82010-02-10 20:07:30 -03001299 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)},
Antti Palosaariab9b4f22010-03-01 13:50:40 -03001300/* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
Antti Palosaari7fc87092010-03-01 14:06:52 -03001301 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
Antti Palosaari2606cfa2010-05-23 18:26:37 -03001302 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)},
Antti Palosaari80619de2008-09-15 17:18:09 -03001303 {0},
1304};
1305MODULE_DEVICE_TABLE(usb, af9015_usb_table);
1306
1307static struct dvb_usb_device_properties af9015_properties[] = {
1308 {
1309 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1310
1311 .usb_ctrl = DEVICE_SPECIFIC,
1312 .download_firmware = af9015_download_firmware,
1313 .firmware = "dvb-usb-af9015.fw",
Jose Alberto Reguerocce25712008-11-13 14:14:18 -03001314 .no_reconnect = 1,
Antti Palosaari80619de2008-09-15 17:18:09 -03001315
Antti Palosaari02542942009-09-16 20:33:03 -03001316 .size_of_priv = sizeof(struct af9015_state),
Antti Palosaari80619de2008-09-15 17:18:09 -03001317
1318 .num_adapters = 2,
1319 .adapter = {
1320 {
1321 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1322 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1323
1324 .pid_filter_count = 32,
1325 .pid_filter = af9015_pid_filter,
1326 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1327
1328 .frontend_attach =
1329 af9015_af9013_frontend_attach,
1330 .tuner_attach = af9015_tuner_attach,
1331 .stream = {
1332 .type = USB_BULK,
1333 .count = 6,
1334 .endpoint = 0x84,
1335 },
1336 },
1337 {
1338 .frontend_attach =
1339 af9015_af9013_frontend_attach,
1340 .tuner_attach = af9015_tuner_attach,
1341 .stream = {
1342 .type = USB_BULK,
1343 .count = 6,
1344 .endpoint = 0x85,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001345 .u = {
1346 .bulk = {
1347 .buffersize =
Jose Alberto Reguero353330c2009-09-12 09:51:36 -03001348 TS_USB20_FRAME_SIZE,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001349 }
1350 }
Antti Palosaari80619de2008-09-15 17:18:09 -03001351 },
1352 }
1353 },
1354
1355 .identify_state = af9015_identify_state,
1356
1357 .rc_query = af9015_rc_query,
1358 .rc_interval = 150,
1359
1360 .i2c_algo = &af9015_i2c_algo,
1361
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001362 .num_device_descs = 9, /* max 9 */
Antti Palosaari80619de2008-09-15 17:18:09 -03001363 .devices = {
1364 {
1365 .name = "Afatech AF9015 DVB-T USB2.0 stick",
1366 .cold_ids = {&af9015_usb_table[0],
1367 &af9015_usb_table[1], NULL},
1368 .warm_ids = {NULL},
1369 },
1370 {
1371 .name = "Leadtek WinFast DTV Dongle Gold",
1372 .cold_ids = {&af9015_usb_table[2], NULL},
1373 .warm_ids = {NULL},
1374 },
1375 {
1376 .name = "Pinnacle PCTV 71e",
1377 .cold_ids = {&af9015_usb_table[3], NULL},
1378 .warm_ids = {NULL},
1379 },
1380 {
1381 .name = "KWorld PlusTV Dual DVB-T Stick " \
1382 "(DVB-T 399U)",
Mart Raudseppc92f0562009-07-24 13:45:41 -03001383 .cold_ids = {&af9015_usb_table[4],
1384 &af9015_usb_table[25], NULL},
Antti Palosaari80619de2008-09-15 17:18:09 -03001385 .warm_ids = {NULL},
1386 },
1387 {
1388 .name = "DigitalNow TinyTwin DVB-T Receiver",
Antti Palosaarifa1df552010-02-10 20:05:48 -03001389 .cold_ids = {&af9015_usb_table[5],
1390 &af9015_usb_table[28], 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 },
1414 }
1415 }, {
1416 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1417
1418 .usb_ctrl = DEVICE_SPECIFIC,
1419 .download_firmware = af9015_download_firmware,
1420 .firmware = "dvb-usb-af9015.fw",
Jose Alberto Reguerocce25712008-11-13 14:14:18 -03001421 .no_reconnect = 1,
Antti Palosaari80619de2008-09-15 17:18:09 -03001422
Antti Palosaari02542942009-09-16 20:33:03 -03001423 .size_of_priv = sizeof(struct af9015_state),
Antti Palosaari80619de2008-09-15 17:18:09 -03001424
1425 .num_adapters = 2,
1426 .adapter = {
1427 {
1428 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1429 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1430
1431 .pid_filter_count = 32,
1432 .pid_filter = af9015_pid_filter,
1433 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1434
1435 .frontend_attach =
1436 af9015_af9013_frontend_attach,
1437 .tuner_attach = af9015_tuner_attach,
1438 .stream = {
1439 .type = USB_BULK,
1440 .count = 6,
1441 .endpoint = 0x84,
1442 },
1443 },
1444 {
1445 .frontend_attach =
1446 af9015_af9013_frontend_attach,
1447 .tuner_attach = af9015_tuner_attach,
1448 .stream = {
1449 .type = USB_BULK,
1450 .count = 6,
1451 .endpoint = 0x85,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001452 .u = {
1453 .bulk = {
1454 .buffersize =
Jose Alberto Reguero353330c2009-09-12 09:51:36 -03001455 TS_USB20_FRAME_SIZE,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001456 }
1457 }
Antti Palosaari80619de2008-09-15 17:18:09 -03001458 },
1459 }
1460 },
1461
1462 .identify_state = af9015_identify_state,
1463
1464 .rc_query = af9015_rc_query,
1465 .rc_interval = 150,
1466
1467 .i2c_algo = &af9015_i2c_algo,
1468
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001469 .num_device_descs = 9, /* max 9 */
Antti Palosaari80619de2008-09-15 17:18:09 -03001470 .devices = {
1471 {
1472 .name = "Xtensions XD-380",
1473 .cold_ids = {&af9015_usb_table[10], NULL},
1474 .warm_ids = {NULL},
1475 },
1476 {
1477 .name = "MSI DIGIVOX Duo",
1478 .cold_ids = {&af9015_usb_table[11], NULL},
1479 .warm_ids = {NULL},
1480 },
1481 {
1482 .name = "Fujitsu-Siemens Slim Mobile USB DVB-T",
1483 .cold_ids = {&af9015_usb_table[12], NULL},
1484 .warm_ids = {NULL},
1485 },
Mikko Ohtamaa111f9ec2008-09-19 18:26:05 -03001486 {
Antti Palosaaria3765882008-09-19 18:34:06 -03001487 .name = "Telestar Starstick 2",
Mikko Ohtamaa111f9ec2008-09-19 18:26:05 -03001488 .cold_ids = {&af9015_usb_table[13], NULL},
1489 .warm_ids = {NULL},
1490 },
Antti Palosaari05c1cab2008-09-22 12:32:37 -03001491 {
1492 .name = "AVerMedia A309",
1493 .cold_ids = {&af9015_usb_table[14], NULL},
1494 .warm_ids = {NULL},
1495 },
Herbert Graeber641015a2008-10-07 10:06:36 -03001496 {
1497 .name = "MSI Digi VOX mini III",
1498 .cold_ids = {&af9015_usb_table[15], NULL},
1499 .warm_ids = {NULL},
1500 },
Antti Palosaari163e9cd2008-11-04 12:57:47 -03001501 {
1502 .name = "KWorld USB DVB-T TV Stick II " \
1503 "(VS-DVB-T 395U)",
Antti Palosaari71bf2e02009-01-13 12:47:28 -03001504 .cold_ids = {&af9015_usb_table[16],
Antti Palosaari58fe1592009-03-26 20:41:05 -03001505 &af9015_usb_table[17],
Antti Palosaari7fc87092010-03-01 14:06:52 -03001506 &af9015_usb_table[18],
1507 &af9015_usb_table[31], NULL},
Antti Palosaari163e9cd2008-11-04 12:57:47 -03001508 .warm_ids = {NULL},
1509 },
Marc Schneider26144842009-03-26 21:07:18 -03001510 {
1511 .name = "TrekStor DVB-T USB Stick",
1512 .cold_ids = {&af9015_usb_table[19], NULL},
1513 .warm_ids = {NULL},
1514 },
Antti Palosaari3956fef2009-03-31 17:01:02 -03001515 {
1516 .name = "AverMedia AVerTV Volar Black HD " \
1517 "(A850)",
1518 .cold_ids = {&af9015_usb_table[20], NULL},
1519 .warm_ids = {NULL},
1520 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001521 }
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001522 }, {
1523 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1524
1525 .usb_ctrl = DEVICE_SPECIFIC,
1526 .download_firmware = af9015_download_firmware,
1527 .firmware = "dvb-usb-af9015.fw",
1528 .no_reconnect = 1,
1529
Antti Palosaari02542942009-09-16 20:33:03 -03001530 .size_of_priv = sizeof(struct af9015_state),
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001531
1532 .num_adapters = 2,
1533 .adapter = {
1534 {
1535 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1536 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1537
1538 .pid_filter_count = 32,
1539 .pid_filter = af9015_pid_filter,
1540 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1541
1542 .frontend_attach =
1543 af9015_af9013_frontend_attach,
1544 .tuner_attach = af9015_tuner_attach,
1545 .stream = {
1546 .type = USB_BULK,
1547 .count = 6,
1548 .endpoint = 0x84,
1549 },
1550 },
1551 {
1552 .frontend_attach =
1553 af9015_af9013_frontend_attach,
1554 .tuner_attach = af9015_tuner_attach,
1555 .stream = {
1556 .type = USB_BULK,
1557 .count = 6,
1558 .endpoint = 0x85,
1559 .u = {
1560 .bulk = {
1561 .buffersize =
Jose Alberto Reguero353330c2009-09-12 09:51:36 -03001562 TS_USB20_FRAME_SIZE,
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001563 }
1564 }
1565 },
1566 }
1567 },
1568
1569 .identify_state = af9015_identify_state,
1570
1571 .rc_query = af9015_rc_query,
1572 .rc_interval = 150,
1573
1574 .i2c_algo = &af9015_i2c_algo,
1575
Antti Palosaari2606cfa2010-05-23 18:26:37 -03001576 .num_device_descs = 9, /* max 9 */
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001577 .devices = {
Antti Palosaari1ed5fad2009-04-09 15:14:18 -03001578 {
1579 .name = "AverMedia AVerTV Volar GPS 805 (A805)",
1580 .cold_ids = {&af9015_usb_table[21], NULL},
1581 .warm_ids = {NULL},
1582 },
Marcel Jueling734dd232009-04-09 17:16:41 -03001583 {
1584 .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \
1585 "V3.0",
1586 .cold_ids = {&af9015_usb_table[22], NULL},
1587 .warm_ids = {NULL},
1588 },
Wen-chien Jesse Sung6e9c1a22009-04-28 01:11:22 -03001589 {
1590 .name = "KWorld Digial MC-810",
1591 .cold_ids = {&af9015_usb_table[23], NULL},
1592 .warm_ids = {NULL},
1593 },
Antti Palosaari22d46452009-05-31 17:07:01 -03001594 {
1595 .name = "Genius TVGo DVB-T03",
1596 .cold_ids = {&af9015_usb_table[24], NULL},
1597 .warm_ids = {NULL},
1598 },
Antti Palosaari486ba122009-09-18 13:37:57 -03001599 {
1600 .name = "KWorld PlusTV DVB-T PCI Pro Card " \
1601 "(DVB-T PC160-T)",
1602 .cold_ids = {&af9015_usb_table[26], NULL},
1603 .warm_ids = {NULL},
1604 },
Ignacio de Miguel Diaz52322632009-11-13 23:13:34 -03001605 {
1606 .name = "Sveon STV20 Tuner USB DVB-T HDTV",
1607 .cold_ids = {&af9015_usb_table[27], NULL},
1608 .warm_ids = {NULL},
1609 },
Antti Palosaari809c1e82010-02-10 20:07:30 -03001610 {
1611 .name = "Leadtek WinFast DTV2000DS",
1612 .cold_ids = {&af9015_usb_table[29], NULL},
1613 .warm_ids = {NULL},
1614 },
Antti Palosaariab9b4f22010-03-01 13:50:40 -03001615 {
1616 .name = "KWorld USB DVB-T Stick Mobile " \
1617 "(UB383-T)",
1618 .cold_ids = {&af9015_usb_table[30], NULL},
1619 .warm_ids = {NULL},
1620 },
Antti Palosaari2606cfa2010-05-23 18:26:37 -03001621 {
1622 .name = "AverMedia AVerTV Volar M (A815Mac)",
1623 .cold_ids = {&af9015_usb_table[32], NULL},
1624 .warm_ids = {NULL},
1625 },
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001626 }
1627 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001628};
Antti Palosaari80619de2008-09-15 17:18:09 -03001629
1630static int af9015_usb_probe(struct usb_interface *intf,
1631 const struct usb_device_id *id)
1632{
1633 int ret = 0;
1634 struct dvb_usb_device *d = NULL;
1635 struct usb_device *udev = interface_to_usbdev(intf);
1636 u8 i;
1637
1638 deb_info("%s: interface:%d\n", __func__,
1639 intf->cur_altsetting->desc.bInterfaceNumber);
1640
1641 /* interface 0 is used by DVB-T receiver and
1642 interface 1 is for remote controller (HID) */
1643 if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
1644 ret = af9015_read_config(udev);
1645 if (ret)
1646 return ret;
1647
1648 for (i = 0; i < af9015_properties_count; i++) {
1649 ret = dvb_usb_device_init(intf, &af9015_properties[i],
1650 THIS_MODULE, &d, adapter_nr);
1651 if (!ret)
1652 break;
1653 if (ret != -ENODEV)
1654 return ret;
1655 }
1656 if (ret)
1657 return ret;
1658
1659 if (d)
1660 ret = af9015_init(d);
1661 }
1662
1663 return ret;
1664}
1665
Antti Palosaari349d0422008-11-05 16:31:24 -03001666static void af9015_i2c_exit(struct dvb_usb_device *d)
Antti Palosaari80619de2008-09-15 17:18:09 -03001667{
1668 struct af9015_state *state = d->priv;
1669 deb_info("%s: \n", __func__);
1670
1671 /* remove 2nd I2C adapter */
1672 if (d->state & DVB_USB_STATE_I2C)
1673 i2c_del_adapter(&state->i2c_adap);
1674}
1675
1676static void af9015_usb_device_exit(struct usb_interface *intf)
1677{
1678 struct dvb_usb_device *d = usb_get_intfdata(intf);
1679 deb_info("%s: \n", __func__);
1680
1681 /* remove 2nd I2C adapter */
1682 if (d != NULL && d->desc != NULL)
1683 af9015_i2c_exit(d);
1684
1685 dvb_usb_device_exit(intf);
1686}
1687
1688/* usb specific object needed to register this driver with the usb subsystem */
1689static struct usb_driver af9015_usb_driver = {
1690 .name = "dvb_usb_af9015",
1691 .probe = af9015_usb_probe,
1692 .disconnect = af9015_usb_device_exit,
1693 .id_table = af9015_usb_table,
1694};
1695
1696/* module stuff */
1697static int __init af9015_usb_module_init(void)
1698{
1699 int ret;
1700 ret = usb_register(&af9015_usb_driver);
1701 if (ret)
1702 err("module init failed:%d", ret);
1703
1704 return ret;
1705}
1706
1707static void __exit af9015_usb_module_exit(void)
1708{
1709 /* deregister this driver from the USB subsystem */
1710 usb_deregister(&af9015_usb_driver);
1711}
1712
1713module_init(af9015_usb_module_init);
1714module_exit(af9015_usb_module_exit);
1715
1716MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1717MODULE_DESCRIPTION("Driver for Afatech AF9015 DVB-T");
1718MODULE_LICENSE("GPL");