blob: be6306b48a5df6d6ede3f6c412b4e87f92ea911b [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 Palosaari04599c22011-03-19 14:25:36 -0300747 { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_RC,
748 RC_MAP_TERRATEC_SLIM_2 },
Antti Palosaari1cd72782010-10-12 17:22:32 -0300749 { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
750 RC_MAP_TERRATEC_SLIM },
751 { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700,
752 RC_MAP_AZUREWAVE_AD_TU700 },
753 { (USB_VID_VISIONPLUS << 16) + USB_PID_TINYTWIN,
754 RC_MAP_AZUREWAVE_AD_TU700 },
755 { (USB_VID_MSI_2 << 16) + USB_PID_MSI_DIGI_VOX_MINI_III,
756 RC_MAP_MSI_DIGIVOX_III },
Antti Palosaariae81aab2011-06-15 11:29:47 -0300757 { (USB_VID_MSI_2 << 16) + USB_PID_MSI_DIGIVOX_DUO,
758 RC_MAP_MSI_DIGIVOX_III },
Antti Palosaari1cd72782010-10-12 17:22:32 -0300759 { (USB_VID_LEADTEK << 16) + USB_PID_WINFAST_DTV_DONGLE_GOLD,
760 RC_MAP_LEADTEK_Y04G0051 },
761 { (USB_VID_AVERMEDIA << 16) + USB_PID_AVERMEDIA_VOLAR_X,
762 RC_MAP_AVERMEDIA_M135A },
763 { (USB_VID_AFATECH << 16) + USB_PID_TREKSTOR_DVBT,
764 RC_MAP_TREKSTOR },
Antti Palosaaribd864ce2010-10-22 20:37:11 -0300765 { (USB_VID_KWORLD_2 << 16) + USB_PID_TINYTWIN_2,
766 RC_MAP_DIGITALNOW_TINYTWIN },
Antti Palosaarif8c61272010-10-23 07:35:31 -0300767 { (USB_VID_GTEK << 16) + USB_PID_TINYTWIN_3,
768 RC_MAP_DIGITALNOW_TINYTWIN },
Jiri Slabye3a0cc62010-01-22 12:10:55 -0300769 { }
770};
771
Jiri Slaby634d2d72010-01-22 12:10:53 -0300772static void af9015_set_remote_config(struct usb_device *udev,
773 struct dvb_usb_device_properties *props)
774{
Antti Palosaari1cd72782010-10-12 17:22:32 -0300775 u16 vid = le16_to_cpu(udev->descriptor.idVendor);
776 u16 pid = le16_to_cpu(udev->descriptor.idProduct);
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300777
Antti Palosaari1cd72782010-10-12 17:22:32 -0300778 /* try to load remote based module param */
779 props->rc.core.rc_codes = af9015_rc_setup_match(
780 dvb_usb_af9015_remote, af9015_rc_setup_modparam);
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300781
Antti Palosaari1cd72782010-10-12 17:22:32 -0300782 /* try to load remote based eeprom hash */
783 if (!props->rc.core.rc_codes)
784 props->rc.core.rc_codes = af9015_rc_setup_match(
785 af9015_config.eeprom_sum, af9015_rc_setup_hashes);
Jiri Slabye3a0cc62010-01-22 12:10:55 -0300786
Antti Palosaari1cd72782010-10-12 17:22:32 -0300787 /* try to load remote based USB ID */
788 if (!props->rc.core.rc_codes)
789 props->rc.core.rc_codes = af9015_rc_setup_match(
790 (vid << 16) + pid, af9015_rc_setup_usbids);
791
792 /* try to load remote based USB iManufacturer string */
793 if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) {
794 /* Check USB manufacturer and product strings and try
795 to determine correct remote in case of chip vendor
796 reference IDs are used.
797 DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
798 char manufacturer[10];
799 memset(manufacturer, 0, sizeof(manufacturer));
800 usb_string(udev, udev->descriptor.iManufacturer,
801 manufacturer, sizeof(manufacturer));
802 if (!strcmp("MSI", manufacturer)) {
803 /* iManufacturer 1 MSI
804 iProduct 2 MSI K-VOX */
805 props->rc.core.rc_codes = af9015_rc_setup_match(
806 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
807 af9015_rc_setup_modparam);
808 }
Jiri Slaby26c3b8b2010-01-22 12:10:54 -0300809 }
Antti Palosaari74c8e3a2010-10-22 18:45:18 -0300810
811 /* finally load "empty" just for leaving IR receiver enabled */
812 if (!props->rc.core.rc_codes)
813 props->rc.core.rc_codes = RC_MAP_EMPTY;
814
Antti Palosaari1cd72782010-10-12 17:22:32 -0300815 return;
Jiri Slaby634d2d72010-01-22 12:10:53 -0300816}
817
Antti Palosaari80619de2008-09-15 17:18:09 -0300818static int af9015_read_config(struct usb_device *udev)
819{
820 int ret;
821 u8 val, i, offset = 0;
822 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
Antti Palosaari80619de2008-09-15 17:18:09 -0300823
824 /* IR remote controller */
825 req.addr = AF9015_EEPROM_IR_MODE;
Antti Palosaarid1a470f2009-01-20 14:56:20 -0300826 /* first message will timeout often due to possible hw bug */
827 for (i = 0; i < 4; i++) {
828 ret = af9015_rw_udev(udev, &req);
829 if (!ret)
830 break;
831 }
Antti Palosaari80619de2008-09-15 17:18:09 -0300832 if (ret)
833 goto error;
Jiri Slaby6c614042010-01-22 12:10:52 -0300834
835 ret = af9015_eeprom_hash(udev);
836 if (ret)
837 goto error;
838
Antti Palosaari80619de2008-09-15 17:18:09 -0300839 deb_info("%s: IR mode:%d\n", __func__, val);
840 for (i = 0; i < af9015_properties_count; i++) {
Antti Palosaari74c8e3a2010-10-22 18:45:18 -0300841 if (val == AF9015_IR_MODE_DISABLED)
842 af9015_properties[i].rc.core.rc_codes = NULL;
843 else
Jiri Slaby634d2d72010-01-22 12:10:53 -0300844 af9015_set_remote_config(udev, &af9015_properties[i]);
Antti Palosaari80619de2008-09-15 17:18:09 -0300845 }
846
847 /* TS mode - one or two receivers */
848 req.addr = AF9015_EEPROM_TS_MODE;
849 ret = af9015_rw_udev(udev, &req);
850 if (ret)
851 goto error;
852 af9015_config.dual_mode = val;
853 deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode);
Antti Palosaari80619de2008-09-15 17:18:09 -0300854
Antti Palosaarif0830eb2009-01-13 13:08:29 -0300855 /* Set adapter0 buffer size according to USB port speed, adapter1 buffer
856 size can be static because it is enabled only USB2.0 */
Antti Palosaari80619de2008-09-15 17:18:09 -0300857 for (i = 0; i < af9015_properties_count; i++) {
858 /* USB1.1 set smaller buffersize and disable 2nd adapter */
859 if (udev->speed == USB_SPEED_FULL) {
Antti Palosaarif0830eb2009-01-13 13:08:29 -0300860 af9015_properties[i].adapter[0].stream.u.bulk.buffersize
Antti Palosaari9c863272009-09-12 13:35:29 -0300861 = TS_USB11_FRAME_SIZE;
Antti Palosaari80619de2008-09-15 17:18:09 -0300862 /* disable 2nd adapter because we don't have
863 PID-filters */
864 af9015_config.dual_mode = 0;
865 } else {
Antti Palosaarif0830eb2009-01-13 13:08:29 -0300866 af9015_properties[i].adapter[0].stream.u.bulk.buffersize
Jose Alberto Reguero353330c2009-09-12 09:51:36 -0300867 = TS_USB20_FRAME_SIZE;
Antti Palosaari80619de2008-09-15 17:18:09 -0300868 }
869 }
870
871 if (af9015_config.dual_mode) {
872 /* read 2nd demodulator I2C address */
873 req.addr = AF9015_EEPROM_DEMOD2_I2C;
874 ret = af9015_rw_udev(udev, &req);
875 if (ret)
876 goto error;
877 af9015_af9013_config[1].demod_address = val;
878
879 /* enable 2nd adapter */
880 for (i = 0; i < af9015_properties_count; i++)
881 af9015_properties[i].num_adapters = 2;
882
883 } else {
884 /* disable 2nd adapter */
885 for (i = 0; i < af9015_properties_count; i++)
886 af9015_properties[i].num_adapters = 1;
887 }
888
889 for (i = 0; i < af9015_properties[0].num_adapters; i++) {
890 if (i == 1)
891 offset = AF9015_EEPROM_OFFSET;
892 /* xtal */
893 req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
894 ret = af9015_rw_udev(udev, &req);
895 if (ret)
896 goto error;
897 switch (val) {
898 case 0:
899 af9015_af9013_config[i].adc_clock = 28800;
900 break;
901 case 1:
902 af9015_af9013_config[i].adc_clock = 20480;
903 break;
904 case 2:
905 af9015_af9013_config[i].adc_clock = 28000;
906 break;
907 case 3:
908 af9015_af9013_config[i].adc_clock = 25000;
909 break;
910 };
911 deb_info("%s: [%d] xtal:%d set adc_clock:%d\n", __func__, i,
912 val, af9015_af9013_config[i].adc_clock);
913
914 /* tuner IF */
915 req.addr = AF9015_EEPROM_IF1H + offset;
916 ret = af9015_rw_udev(udev, &req);
917 if (ret)
918 goto error;
919 af9015_af9013_config[i].tuner_if = val << 8;
920 req.addr = AF9015_EEPROM_IF1L + offset;
921 ret = af9015_rw_udev(udev, &req);
922 if (ret)
923 goto error;
924 af9015_af9013_config[i].tuner_if += val;
925 deb_info("%s: [%d] IF1:%d\n", __func__, i,
926 af9015_af9013_config[0].tuner_if);
927
928 /* MT2060 IF1 */
929 req.addr = AF9015_EEPROM_MT2060_IF1H + offset;
930 ret = af9015_rw_udev(udev, &req);
931 if (ret)
932 goto error;
933 af9015_config.mt2060_if1[i] = val << 8;
934 req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
935 ret = af9015_rw_udev(udev, &req);
936 if (ret)
937 goto error;
938 af9015_config.mt2060_if1[i] += val;
939 deb_info("%s: [%d] MT2060 IF1:%d\n", __func__, i,
940 af9015_config.mt2060_if1[i]);
941
942 /* tuner */
943 req.addr = AF9015_EEPROM_TUNER_ID1 + offset;
944 ret = af9015_rw_udev(udev, &req);
945 if (ret)
946 goto error;
947 switch (val) {
948 case AF9013_TUNER_ENV77H11D5:
949 case AF9013_TUNER_MT2060:
Antti Palosaari80619de2008-09-15 17:18:09 -0300950 case AF9013_TUNER_QT1010:
951 case AF9013_TUNER_UNKNOWN:
952 case AF9013_TUNER_MT2060_2:
953 case AF9013_TUNER_TDA18271:
954 case AF9013_TUNER_QT1010A:
Antti Palosaariee3d4402010-08-13 03:51:26 -0300955 case AF9013_TUNER_TDA18218:
Antti Palosaari80619de2008-09-15 17:18:09 -0300956 af9015_af9013_config[i].rf_spec_inv = 1;
957 break;
958 case AF9013_TUNER_MXL5003D:
959 case AF9013_TUNER_MXL5005D:
960 case AF9013_TUNER_MXL5005R:
Antti Palosaariab07fdd2010-09-09 14:59:10 -0300961 case AF9013_TUNER_MXL5007T:
Antti Palosaari80619de2008-09-15 17:18:09 -0300962 af9015_af9013_config[i].rf_spec_inv = 0;
963 break;
Jochen Friedrichd5633992009-02-02 14:59:50 -0300964 case AF9013_TUNER_MC44S803:
965 af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
966 af9015_af9013_config[i].rf_spec_inv = 1;
967 break;
Antti Palosaari80619de2008-09-15 17:18:09 -0300968 default:
969 warn("tuner id:%d not supported, please report!", val);
970 return -ENODEV;
971 };
972
973 af9015_af9013_config[i].tuner = val;
974 deb_info("%s: [%d] tuner id:%d\n", __func__, i, val);
975 }
976
977error:
978 if (ret)
979 err("eeprom read failed:%d", ret);
980
Antti Palosaari3956fef2009-03-31 17:01:02 -0300981 /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
Yann E. MORIN8ccdf1a2010-10-01 16:55:43 -0300982 content :-( Override some wrong values here. Ditto for the
983 AVerTV Red HD+ (A850T) device. */
Antti Palosaari3956fef2009-03-31 17:01:02 -0300984 if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
Antti Palosaari9a3ecc72010-10-07 21:37:06 -0300985 ((le16_to_cpu(udev->descriptor.idProduct) ==
986 USB_PID_AVERMEDIA_A850) ||
987 (le16_to_cpu(udev->descriptor.idProduct) ==
988 USB_PID_AVERMEDIA_A850T))) {
Antti Palosaari3956fef2009-03-31 17:01:02 -0300989 deb_info("%s: AverMedia A850: overriding config\n", __func__);
990 /* disable dual mode */
991 af9015_config.dual_mode = 0;
992 /* disable 2nd adapter */
993 for (i = 0; i < af9015_properties_count; i++)
994 af9015_properties[i].num_adapters = 1;
995
996 /* set correct IF */
997 af9015_af9013_config[0].tuner_if = 4570;
998 }
999
Antti Palosaari80619de2008-09-15 17:18:09 -03001000 return ret;
1001}
1002
1003static int af9015_identify_state(struct usb_device *udev,
1004 struct dvb_usb_device_properties *props,
1005 struct dvb_usb_device_description **desc,
1006 int *cold)
1007{
1008 int ret;
1009 u8 reply;
1010 struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
1011
1012 ret = af9015_rw_udev(udev, &req);
1013 if (ret)
1014 return ret;
1015
1016 deb_info("%s: reply:%02x\n", __func__, reply);
1017 if (reply == 0x02)
1018 *cold = 0;
1019 else
1020 *cold = 1;
1021
1022 return ret;
1023}
1024
Antti Palosaari1cd72782010-10-12 17:22:32 -03001025static int af9015_rc_query(struct dvb_usb_device *d)
Antti Palosaari80619de2008-09-15 17:18:09 -03001026{
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001027 struct af9015_state *priv = d->priv;
1028 int ret;
Ian Armstrongc1e13972011-03-18 19:23:05 -03001029 u8 buf[17];
Antti Palosaari80619de2008-09-15 17:18:09 -03001030
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001031 /* read registers needed to detect remote controller code */
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001032 ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
Antti Palosaari80619de2008-09-15 17:18:09 -03001033 if (ret)
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001034 goto error;
Antti Palosaari80619de2008-09-15 17:18:09 -03001035
Ian Armstrongc1e13972011-03-18 19:23:05 -03001036 /* If any of these are non-zero, assume invalid data */
1037 if (buf[1] || buf[2] || buf[3])
1038 return ret;
1039
1040 /* Check for repeat of previous code */
1041 if ((priv->rc_repeat != buf[6] || buf[0]) &&
1042 !memcmp(&buf[12], priv->rc_last, 4)) {
1043 deb_rc("%s: key repeated\n", __func__);
1044 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
1045 priv->rc_repeat = buf[6];
1046 return ret;
1047 }
1048
1049 /* Only process key if canary killed */
1050 if (buf[16] != 0xff && buf[0] != 0x01) {
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001051 deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
1052 buf[12], buf[13], buf[14], buf[15]);
Antti Palosaari80619de2008-09-15 17:18:09 -03001053
Antti Palosaari1e8750c2011-03-18 19:36:42 -03001054 /* Reset the canary */
1055 ret = af9015_write_reg(d, 0x98e9, 0xff);
1056 if (ret)
1057 goto error;
1058
Ian Armstrongc1e13972011-03-18 19:23:05 -03001059 /* Remember this key */
1060 memcpy(priv->rc_last, &buf[12], 4);
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001061 if (buf[14] == (u8) ~buf[15]) {
1062 if (buf[12] == (u8) ~buf[13]) {
Antti Palosaari1cd72782010-10-12 17:22:32 -03001063 /* NEC */
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001064 priv->rc_keycode = buf[12] << 8 | buf[14];
Antti Palosaari1cd72782010-10-12 17:22:32 -03001065 } else {
1066 /* NEC extended*/
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001067 priv->rc_keycode = buf[12] << 16 |
1068 buf[13] << 8 | buf[14];
Antti Palosaari1cd72782010-10-12 17:22:32 -03001069 }
Antti Palosaari1cd72782010-10-12 17:22:32 -03001070 } else {
Antti Palosaari1e8750c2011-03-18 19:36:42 -03001071 /* 32 bit NEC */
Ian Armstrongc1e13972011-03-18 19:23:05 -03001072 priv->rc_keycode = buf[12] << 24 | buf[13] << 16 |
1073 buf[14] << 8 | buf[15];
Antti Palosaari1cd72782010-10-12 17:22:32 -03001074 }
Mauro Carvalho Chehabca866742010-11-17 13:53:11 -03001075 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001076 } else {
1077 deb_rc("%s: no key press\n", __func__);
Ian Armstrongc1e13972011-03-18 19:23:05 -03001078 /* Invalidate last keypress */
1079 /* Not really needed, but helps with debug */
1080 priv->rc_last[2] = priv->rc_last[3];
Antti Palosaari80619de2008-09-15 17:18:09 -03001081 }
Antti Palosaari80619de2008-09-15 17:18:09 -03001082
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001083 priv->rc_repeat = buf[6];
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001084
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001085error:
1086 if (ret)
1087 err("%s: failed:%d", __func__, ret);
1088
1089 return ret;
Antti Palosaari80619de2008-09-15 17:18:09 -03001090}
1091
Antti Palosaari80619de2008-09-15 17:18:09 -03001092static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
1093{
1094 int ret;
Antti Palosaari80619de2008-09-15 17:18:09 -03001095
Antti Palosaari713d9b52011-06-18 10:24:53 -03001096 if (adap->id == 1) {
Antti Palosaari80619de2008-09-15 17:18:09 -03001097 /* copy firmware to 2nd demodulator */
1098 if (af9015_config.dual_mode) {
1099 ret = af9015_copy_firmware(adap->dev);
1100 if (ret) {
1101 err("firmware copy to 2nd frontend " \
1102 "failed, will disable it");
1103 af9015_config.dual_mode = 0;
1104 return -ENODEV;
1105 }
1106 } else {
1107 return -ENODEV;
1108 }
1109 }
1110
1111 /* attach demodulator */
1112 adap->fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id],
Antti Palosaari713d9b52011-06-18 10:24:53 -03001113 &adap->dev->i2c_adap);
Antti Palosaari80619de2008-09-15 17:18:09 -03001114
1115 return adap->fe == NULL ? -ENODEV : 0;
1116}
1117
1118static struct mt2060_config af9015_mt2060_config = {
1119 .i2c_address = 0xc0,
1120 .clock_out = 0,
1121};
1122
1123static struct qt1010_config af9015_qt1010_config = {
1124 .i2c_address = 0xc4,
1125};
1126
1127static struct tda18271_config af9015_tda18271_config = {
1128 .gate = TDA18271_GATE_DIGITAL,
Mauro Carvalho Chehab7655e592010-10-27 14:55:34 -02001129 .small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
Antti Palosaari80619de2008-09-15 17:18:09 -03001130};
1131
1132static struct mxl5005s_config af9015_mxl5003_config = {
1133 .i2c_address = 0xc6,
1134 .if_freq = IF_FREQ_4570000HZ,
1135 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1136 .agc_mode = MXL_SINGLE_AGC,
1137 .tracking_filter = MXL_TF_DEFAULT,
Antti Palosaaria1310772008-09-22 13:59:25 -03001138 .rssi_enable = MXL_RSSI_ENABLE,
Antti Palosaari80619de2008-09-15 17:18:09 -03001139 .cap_select = MXL_CAP_SEL_ENABLE,
1140 .div_out = MXL_DIV_OUT_4,
1141 .clock_out = MXL_CLOCK_OUT_DISABLE,
1142 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1143 .top = MXL5005S_TOP_25P2,
1144 .mod_mode = MXL_DIGITAL_MODE,
1145 .if_mode = MXL_ZERO_IF,
1146 .AgcMasterByte = 0x00,
1147};
1148
1149static struct mxl5005s_config af9015_mxl5005_config = {
1150 .i2c_address = 0xc6,
1151 .if_freq = IF_FREQ_4570000HZ,
1152 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1153 .agc_mode = MXL_SINGLE_AGC,
1154 .tracking_filter = MXL_TF_OFF,
Antti Palosaaria1310772008-09-22 13:59:25 -03001155 .rssi_enable = MXL_RSSI_ENABLE,
Antti Palosaari80619de2008-09-15 17:18:09 -03001156 .cap_select = MXL_CAP_SEL_ENABLE,
1157 .div_out = MXL_DIV_OUT_4,
1158 .clock_out = MXL_CLOCK_OUT_DISABLE,
1159 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1160 .top = MXL5005S_TOP_25P2,
1161 .mod_mode = MXL_DIGITAL_MODE,
1162 .if_mode = MXL_ZERO_IF,
1163 .AgcMasterByte = 0x00,
1164};
1165
Jochen Friedrichd5633992009-02-02 14:59:50 -03001166static struct mc44s803_config af9015_mc44s803_config = {
1167 .i2c_address = 0xc0,
1168 .dig_out = 1,
1169};
1170
Antti Palosaariee3d4402010-08-13 03:51:26 -03001171static struct tda18218_config af9015_tda18218_config = {
1172 .i2c_address = 0xc0,
1173 .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
1174};
1175
Antti Palosaariab07fdd2010-09-09 14:59:10 -03001176static struct mxl5007t_config af9015_mxl5007t_config = {
1177 .xtal_freq_hz = MxL_XTAL_24_MHZ,
1178 .if_freq_hz = MxL_IF_4_57_MHZ,
1179};
1180
Antti Palosaari80619de2008-09-15 17:18:09 -03001181static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
1182{
Antti Palosaari80619de2008-09-15 17:18:09 -03001183 int ret;
Antti Palosaari9a3ecc72010-10-07 21:37:06 -03001184 deb_info("%s:\n", __func__);
Antti Palosaari80619de2008-09-15 17:18:09 -03001185
Antti Palosaari80619de2008-09-15 17:18:09 -03001186 switch (af9015_af9013_config[adap->id].tuner) {
1187 case AF9013_TUNER_MT2060:
1188 case AF9013_TUNER_MT2060_2:
Antti Palosaari713d9b52011-06-18 10:24:53 -03001189 ret = dvb_attach(mt2060_attach, adap->fe, &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001190 &af9015_mt2060_config,
1191 af9015_config.mt2060_if1[adap->id])
1192 == NULL ? -ENODEV : 0;
1193 break;
1194 case AF9013_TUNER_QT1010:
1195 case AF9013_TUNER_QT1010A:
Antti Palosaari713d9b52011-06-18 10:24:53 -03001196 ret = dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001197 &af9015_qt1010_config) == NULL ? -ENODEV : 0;
1198 break;
1199 case AF9013_TUNER_TDA18271:
Antti Palosaari713d9b52011-06-18 10:24:53 -03001200 ret = dvb_attach(tda18271_attach, adap->fe, 0xc0,
1201 &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001202 &af9015_tda18271_config) == NULL ? -ENODEV : 0;
1203 break;
Antti Palosaariee3d4402010-08-13 03:51:26 -03001204 case AF9013_TUNER_TDA18218:
Antti Palosaari713d9b52011-06-18 10:24:53 -03001205 ret = dvb_attach(tda18218_attach, adap->fe,
1206 &adap->dev->i2c_adap,
Antti Palosaariee3d4402010-08-13 03:51:26 -03001207 &af9015_tda18218_config) == NULL ? -ENODEV : 0;
1208 break;
Antti Palosaari80619de2008-09-15 17:18:09 -03001209 case AF9013_TUNER_MXL5003D:
Antti Palosaari713d9b52011-06-18 10:24:53 -03001210 ret = dvb_attach(mxl5005s_attach, adap->fe,
1211 &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001212 &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
1213 break;
1214 case AF9013_TUNER_MXL5005D:
1215 case AF9013_TUNER_MXL5005R:
Antti Palosaari713d9b52011-06-18 10:24:53 -03001216 ret = dvb_attach(mxl5005s_attach, adap->fe,
1217 &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001218 &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
1219 break;
1220 case AF9013_TUNER_ENV77H11D5:
Antti Palosaari713d9b52011-06-18 10:24:53 -03001221 ret = dvb_attach(dvb_pll_attach, adap->fe, 0xc0,
1222 &adap->dev->i2c_adap,
Antti Palosaari80619de2008-09-15 17:18:09 -03001223 DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
1224 break;
1225 case AF9013_TUNER_MC44S803:
Antti Palosaari713d9b52011-06-18 10:24:53 -03001226 ret = dvb_attach(mc44s803_attach, adap->fe,
1227 &adap->dev->i2c_adap,
Jochen Friedrichd5633992009-02-02 14:59:50 -03001228 &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
Antti Palosaari80619de2008-09-15 17:18:09 -03001229 break;
Antti Palosaariab07fdd2010-09-09 14:59:10 -03001230 case AF9013_TUNER_MXL5007T:
Antti Palosaari713d9b52011-06-18 10:24:53 -03001231 ret = dvb_attach(mxl5007t_attach, adap->fe,
1232 &adap->dev->i2c_adap,
Antti Palosaariab07fdd2010-09-09 14:59:10 -03001233 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
1234 break;
Antti Palosaari80619de2008-09-15 17:18:09 -03001235 case AF9013_TUNER_UNKNOWN:
1236 default:
1237 ret = -ENODEV;
1238 err("Unknown tuner id:%d",
1239 af9015_af9013_config[adap->id].tuner);
1240 }
1241 return ret;
1242}
1243
1244static struct usb_device_id af9015_usb_table[] = {
1245/* 0 */{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)},
1246 {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)},
1247 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)},
1248 {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)},
1249 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)},
1250/* 5 */{USB_DEVICE(USB_VID_VISIONPLUS,
1251 USB_PID_TINYTWIN)},
1252 {USB_DEVICE(USB_VID_VISIONPLUS,
1253 USB_PID_AZUREWAVE_AD_TU700)},
1254 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)},
1255 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)},
1256 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)},
1257/* 10 */{USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)},
1258 {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)},
1259 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)},
Antti Palosaaria3765882008-09-19 18:34:06 -03001260 {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
Antti Palosaari05c1cab2008-09-22 12:32:37 -03001261 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
Herbert Graeber641015a2008-10-07 10:06:36 -03001262/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
Antti Palosaari163e9cd2008-11-04 12:57:47 -03001263 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
Antti Palosaari71bf2e02009-01-13 12:47:28 -03001264 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
Antti Palosaari58fe1592009-03-26 20:41:05 -03001265 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)},
Marc Schneider26144842009-03-26 21:07:18 -03001266 {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)},
Antti Palosaari1ed5fad2009-04-09 15:14:18 -03001267/* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
1268 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)},
Marcel Jueling734dd232009-04-09 17:16:41 -03001269 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
Wen-chien Jesse Sung6e9c1a22009-04-28 01:11:22 -03001270 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
Antti Palosaari22d46452009-05-31 17:07:01 -03001271 {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
Mart Raudseppc92f0562009-07-24 13:45:41 -03001272/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
Antti Palosaari486ba122009-09-18 13:37:57 -03001273 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)},
Ignacio de Miguel Diaz52322632009-11-13 23:13:34 -03001274 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)},
Antti Palosaarifa1df552010-02-10 20:05:48 -03001275 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)},
Antti Palosaari809c1e82010-02-10 20:07:30 -03001276 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)},
Antti Palosaariab9b4f22010-03-01 13:50:40 -03001277/* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
Antti Palosaari7fc87092010-03-01 14:06:52 -03001278 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
Antti Palosaari2606cfa2010-05-23 18:26:37 -03001279 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)},
Stefan Lippers-Hollmannd7ef4852010-08-25 10:08:48 -03001280 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)},
Antti Palosaariab07fdd2010-09-09 14:59:10 -03001281 {USB_DEVICE(USB_VID_TERRATEC,
1282 USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)},
Yann E. MORIN8ccdf1a2010-10-01 16:55:43 -03001283/* 35 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)},
Antti Palosaarif8c61272010-10-23 07:35:31 -03001284 {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)},
Antti Palosaari80619de2008-09-15 17:18:09 -03001285 {0},
1286};
1287MODULE_DEVICE_TABLE(usb, af9015_usb_table);
1288
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001289#define AF9015_RC_INTERVAL 500
Antti Palosaari80619de2008-09-15 17:18:09 -03001290static struct dvb_usb_device_properties af9015_properties[] = {
1291 {
1292 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1293
1294 .usb_ctrl = DEVICE_SPECIFIC,
1295 .download_firmware = af9015_download_firmware,
1296 .firmware = "dvb-usb-af9015.fw",
Jose Alberto Reguerocce25712008-11-13 14:14:18 -03001297 .no_reconnect = 1,
Antti Palosaari80619de2008-09-15 17:18:09 -03001298
Antti Palosaari02542942009-09-16 20:33:03 -03001299 .size_of_priv = sizeof(struct af9015_state),
Antti Palosaari80619de2008-09-15 17:18:09 -03001300
1301 .num_adapters = 2,
1302 .adapter = {
1303 {
1304 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1305 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1306
1307 .pid_filter_count = 32,
1308 .pid_filter = af9015_pid_filter,
1309 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1310
1311 .frontend_attach =
1312 af9015_af9013_frontend_attach,
1313 .tuner_attach = af9015_tuner_attach,
1314 .stream = {
1315 .type = USB_BULK,
1316 .count = 6,
1317 .endpoint = 0x84,
1318 },
1319 },
1320 {
1321 .frontend_attach =
1322 af9015_af9013_frontend_attach,
1323 .tuner_attach = af9015_tuner_attach,
1324 .stream = {
1325 .type = USB_BULK,
1326 .count = 6,
1327 .endpoint = 0x85,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001328 .u = {
1329 .bulk = {
1330 .buffersize =
Jose Alberto Reguero353330c2009-09-12 09:51:36 -03001331 TS_USB20_FRAME_SIZE,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001332 }
1333 }
Antti Palosaari80619de2008-09-15 17:18:09 -03001334 },
1335 }
1336 },
1337
1338 .identify_state = af9015_identify_state,
1339
Antti Palosaari1cd72782010-10-12 17:22:32 -03001340 .rc.core = {
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001341 .protocol = RC_TYPE_NEC,
Antti Palosaari1cd72782010-10-12 17:22:32 -03001342 .module_name = "af9015",
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001343 .rc_query = af9015_rc_query,
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001344 .rc_interval = AF9015_RC_INTERVAL,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001345 .allowed_protos = RC_TYPE_NEC,
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001346 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001347
1348 .i2c_algo = &af9015_i2c_algo,
1349
Yann E. MORIN8ccdf1a2010-10-01 16:55:43 -03001350 .num_device_descs = 12, /* check max from dvb-usb.h */
Antti Palosaari80619de2008-09-15 17:18:09 -03001351 .devices = {
1352 {
1353 .name = "Afatech AF9015 DVB-T USB2.0 stick",
1354 .cold_ids = {&af9015_usb_table[0],
1355 &af9015_usb_table[1], NULL},
1356 .warm_ids = {NULL},
1357 },
1358 {
1359 .name = "Leadtek WinFast DTV Dongle Gold",
1360 .cold_ids = {&af9015_usb_table[2], NULL},
1361 .warm_ids = {NULL},
1362 },
1363 {
1364 .name = "Pinnacle PCTV 71e",
1365 .cold_ids = {&af9015_usb_table[3], NULL},
1366 .warm_ids = {NULL},
1367 },
1368 {
1369 .name = "KWorld PlusTV Dual DVB-T Stick " \
1370 "(DVB-T 399U)",
Mart Raudseppc92f0562009-07-24 13:45:41 -03001371 .cold_ids = {&af9015_usb_table[4],
1372 &af9015_usb_table[25], NULL},
Antti Palosaari80619de2008-09-15 17:18:09 -03001373 .warm_ids = {NULL},
1374 },
1375 {
1376 .name = "DigitalNow TinyTwin DVB-T Receiver",
Antti Palosaarifa1df552010-02-10 20:05:48 -03001377 .cold_ids = {&af9015_usb_table[5],
Antti Palosaarif8c61272010-10-23 07:35:31 -03001378 &af9015_usb_table[28],
1379 &af9015_usb_table[36], NULL},
Antti Palosaari80619de2008-09-15 17:18:09 -03001380 .warm_ids = {NULL},
1381 },
1382 {
1383 .name = "TwinHan AzureWave AD-TU700(704J)",
1384 .cold_ids = {&af9015_usb_table[6], NULL},
1385 .warm_ids = {NULL},
1386 },
1387 {
1388 .name = "TerraTec Cinergy T USB XE",
1389 .cold_ids = {&af9015_usb_table[7], NULL},
1390 .warm_ids = {NULL},
1391 },
1392 {
1393 .name = "KWorld PlusTV Dual DVB-T PCI " \
1394 "(DVB-T PC160-2T)",
1395 .cold_ids = {&af9015_usb_table[8], NULL},
1396 .warm_ids = {NULL},
1397 },
1398 {
1399 .name = "AVerMedia AVerTV DVB-T Volar X",
1400 .cold_ids = {&af9015_usb_table[9], NULL},
1401 .warm_ids = {NULL},
1402 },
Antti Palosaari76391a72010-09-09 12:10:50 -03001403 {
1404 .name = "TerraTec Cinergy T Stick RC",
1405 .cold_ids = {&af9015_usb_table[33], NULL},
1406 .warm_ids = {NULL},
1407 },
Antti Palosaariab07fdd2010-09-09 14:59:10 -03001408 {
1409 .name = "TerraTec Cinergy T Stick Dual RC",
1410 .cold_ids = {&af9015_usb_table[34], NULL},
1411 .warm_ids = {NULL},
1412 },
Yann E. MORIN8ccdf1a2010-10-01 16:55:43 -03001413 {
1414 .name = "AverMedia AVerTV Red HD+ (A850T)",
1415 .cold_ids = {&af9015_usb_table[35], NULL},
1416 .warm_ids = {NULL},
1417 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001418 }
1419 }, {
1420 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1421
1422 .usb_ctrl = DEVICE_SPECIFIC,
1423 .download_firmware = af9015_download_firmware,
1424 .firmware = "dvb-usb-af9015.fw",
Jose Alberto Reguerocce25712008-11-13 14:14:18 -03001425 .no_reconnect = 1,
Antti Palosaari80619de2008-09-15 17:18:09 -03001426
Antti Palosaari02542942009-09-16 20:33:03 -03001427 .size_of_priv = sizeof(struct af9015_state),
Antti Palosaari80619de2008-09-15 17:18:09 -03001428
1429 .num_adapters = 2,
1430 .adapter = {
1431 {
1432 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1433 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1434
1435 .pid_filter_count = 32,
1436 .pid_filter = af9015_pid_filter,
1437 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1438
1439 .frontend_attach =
1440 af9015_af9013_frontend_attach,
1441 .tuner_attach = af9015_tuner_attach,
1442 .stream = {
1443 .type = USB_BULK,
1444 .count = 6,
1445 .endpoint = 0x84,
1446 },
1447 },
1448 {
1449 .frontend_attach =
1450 af9015_af9013_frontend_attach,
1451 .tuner_attach = af9015_tuner_attach,
1452 .stream = {
1453 .type = USB_BULK,
1454 .count = 6,
1455 .endpoint = 0x85,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001456 .u = {
1457 .bulk = {
1458 .buffersize =
Jose Alberto Reguero353330c2009-09-12 09:51:36 -03001459 TS_USB20_FRAME_SIZE,
Antti Palosaarif0830eb2009-01-13 13:08:29 -03001460 }
1461 }
Antti Palosaari80619de2008-09-15 17:18:09 -03001462 },
1463 }
1464 },
1465
1466 .identify_state = af9015_identify_state,
1467
Antti Palosaari1cd72782010-10-12 17:22:32 -03001468 .rc.core = {
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001469 .protocol = RC_TYPE_NEC,
Antti Palosaari1cd72782010-10-12 17:22:32 -03001470 .module_name = "af9015",
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001471 .rc_query = af9015_rc_query,
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001472 .rc_interval = AF9015_RC_INTERVAL,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001473 .allowed_protos = RC_TYPE_NEC,
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001474 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001475
1476 .i2c_algo = &af9015_i2c_algo,
1477
Antti Palosaaria44b91d2010-09-09 12:05:31 -03001478 .num_device_descs = 9, /* check max from dvb-usb.h */
Antti Palosaari80619de2008-09-15 17:18:09 -03001479 .devices = {
1480 {
1481 .name = "Xtensions XD-380",
1482 .cold_ids = {&af9015_usb_table[10], NULL},
1483 .warm_ids = {NULL},
1484 },
1485 {
1486 .name = "MSI DIGIVOX Duo",
1487 .cold_ids = {&af9015_usb_table[11], NULL},
1488 .warm_ids = {NULL},
1489 },
1490 {
1491 .name = "Fujitsu-Siemens Slim Mobile USB DVB-T",
1492 .cold_ids = {&af9015_usb_table[12], NULL},
1493 .warm_ids = {NULL},
1494 },
Mikko Ohtamaa111f9ec2008-09-19 18:26:05 -03001495 {
Antti Palosaaria3765882008-09-19 18:34:06 -03001496 .name = "Telestar Starstick 2",
Mikko Ohtamaa111f9ec2008-09-19 18:26:05 -03001497 .cold_ids = {&af9015_usb_table[13], NULL},
1498 .warm_ids = {NULL},
1499 },
Antti Palosaari05c1cab2008-09-22 12:32:37 -03001500 {
1501 .name = "AVerMedia A309",
1502 .cold_ids = {&af9015_usb_table[14], NULL},
1503 .warm_ids = {NULL},
1504 },
Herbert Graeber641015a2008-10-07 10:06:36 -03001505 {
1506 .name = "MSI Digi VOX mini III",
1507 .cold_ids = {&af9015_usb_table[15], NULL},
1508 .warm_ids = {NULL},
1509 },
Antti Palosaari163e9cd2008-11-04 12:57:47 -03001510 {
1511 .name = "KWorld USB DVB-T TV Stick II " \
1512 "(VS-DVB-T 395U)",
Antti Palosaari71bf2e02009-01-13 12:47:28 -03001513 .cold_ids = {&af9015_usb_table[16],
Antti Palosaari58fe1592009-03-26 20:41:05 -03001514 &af9015_usb_table[17],
Antti Palosaari7fc87092010-03-01 14:06:52 -03001515 &af9015_usb_table[18],
1516 &af9015_usb_table[31], NULL},
Antti Palosaari163e9cd2008-11-04 12:57:47 -03001517 .warm_ids = {NULL},
1518 },
Marc Schneider26144842009-03-26 21:07:18 -03001519 {
1520 .name = "TrekStor DVB-T USB Stick",
1521 .cold_ids = {&af9015_usb_table[19], NULL},
1522 .warm_ids = {NULL},
1523 },
Antti Palosaari3956fef2009-03-31 17:01:02 -03001524 {
1525 .name = "AverMedia AVerTV Volar Black HD " \
1526 "(A850)",
1527 .cold_ids = {&af9015_usb_table[20], NULL},
1528 .warm_ids = {NULL},
1529 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001530 }
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001531 }, {
1532 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1533
1534 .usb_ctrl = DEVICE_SPECIFIC,
1535 .download_firmware = af9015_download_firmware,
1536 .firmware = "dvb-usb-af9015.fw",
1537 .no_reconnect = 1,
1538
Antti Palosaari02542942009-09-16 20:33:03 -03001539 .size_of_priv = sizeof(struct af9015_state),
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001540
1541 .num_adapters = 2,
1542 .adapter = {
1543 {
1544 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1545 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1546
1547 .pid_filter_count = 32,
1548 .pid_filter = af9015_pid_filter,
1549 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1550
1551 .frontend_attach =
1552 af9015_af9013_frontend_attach,
1553 .tuner_attach = af9015_tuner_attach,
1554 .stream = {
1555 .type = USB_BULK,
1556 .count = 6,
1557 .endpoint = 0x84,
1558 },
1559 },
1560 {
1561 .frontend_attach =
1562 af9015_af9013_frontend_attach,
1563 .tuner_attach = af9015_tuner_attach,
1564 .stream = {
1565 .type = USB_BULK,
1566 .count = 6,
1567 .endpoint = 0x85,
1568 .u = {
1569 .bulk = {
1570 .buffersize =
Jose Alberto Reguero353330c2009-09-12 09:51:36 -03001571 TS_USB20_FRAME_SIZE,
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001572 }
1573 }
1574 },
1575 }
1576 },
1577
1578 .identify_state = af9015_identify_state,
1579
Antti Palosaari1cd72782010-10-12 17:22:32 -03001580 .rc.core = {
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001581 .protocol = RC_TYPE_NEC,
Antti Palosaari1cd72782010-10-12 17:22:32 -03001582 .module_name = "af9015",
Antti Palosaari74c8e3a2010-10-22 18:45:18 -03001583 .rc_query = af9015_rc_query,
Antti Palosaarid3bb73d2010-09-12 13:31:56 -03001584 .rc_interval = AF9015_RC_INTERVAL,
Mauro Carvalho Chehab52b66142010-11-17 14:20:52 -03001585 .allowed_protos = RC_TYPE_NEC,
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001586 },
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001587
1588 .i2c_algo = &af9015_i2c_algo,
1589
Antti Palosaaria44b91d2010-09-09 12:05:31 -03001590 .num_device_descs = 9, /* check max from dvb-usb.h */
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001591 .devices = {
Antti Palosaari1ed5fad2009-04-09 15:14:18 -03001592 {
1593 .name = "AverMedia AVerTV Volar GPS 805 (A805)",
1594 .cold_ids = {&af9015_usb_table[21], NULL},
1595 .warm_ids = {NULL},
1596 },
Marcel Jueling734dd232009-04-09 17:16:41 -03001597 {
1598 .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \
1599 "V3.0",
1600 .cold_ids = {&af9015_usb_table[22], NULL},
1601 .warm_ids = {NULL},
1602 },
Wen-chien Jesse Sung6e9c1a22009-04-28 01:11:22 -03001603 {
1604 .name = "KWorld Digial MC-810",
1605 .cold_ids = {&af9015_usb_table[23], NULL},
1606 .warm_ids = {NULL},
1607 },
Antti Palosaari22d46452009-05-31 17:07:01 -03001608 {
1609 .name = "Genius TVGo DVB-T03",
1610 .cold_ids = {&af9015_usb_table[24], NULL},
1611 .warm_ids = {NULL},
1612 },
Antti Palosaari486ba122009-09-18 13:37:57 -03001613 {
1614 .name = "KWorld PlusTV DVB-T PCI Pro Card " \
1615 "(DVB-T PC160-T)",
1616 .cold_ids = {&af9015_usb_table[26], NULL},
1617 .warm_ids = {NULL},
1618 },
Ignacio de Miguel Diaz52322632009-11-13 23:13:34 -03001619 {
1620 .name = "Sveon STV20 Tuner USB DVB-T HDTV",
1621 .cold_ids = {&af9015_usb_table[27], NULL},
1622 .warm_ids = {NULL},
1623 },
Antti Palosaari809c1e82010-02-10 20:07:30 -03001624 {
1625 .name = "Leadtek WinFast DTV2000DS",
1626 .cold_ids = {&af9015_usb_table[29], NULL},
1627 .warm_ids = {NULL},
1628 },
Antti Palosaariab9b4f22010-03-01 13:50:40 -03001629 {
1630 .name = "KWorld USB DVB-T Stick Mobile " \
1631 "(UB383-T)",
1632 .cold_ids = {&af9015_usb_table[30], NULL},
1633 .warm_ids = {NULL},
1634 },
Antti Palosaari2606cfa2010-05-23 18:26:37 -03001635 {
1636 .name = "AverMedia AVerTV Volar M (A815Mac)",
1637 .cold_ids = {&af9015_usb_table[32], NULL},
1638 .warm_ids = {NULL},
1639 },
Antti Palosaari85d7d7c2009-04-09 09:16:12 -03001640 }
1641 },
Antti Palosaari80619de2008-09-15 17:18:09 -03001642};
Antti Palosaari80619de2008-09-15 17:18:09 -03001643
1644static int af9015_usb_probe(struct usb_interface *intf,
1645 const struct usb_device_id *id)
1646{
1647 int ret = 0;
1648 struct dvb_usb_device *d = NULL;
1649 struct usb_device *udev = interface_to_usbdev(intf);
1650 u8 i;
1651
1652 deb_info("%s: interface:%d\n", __func__,
1653 intf->cur_altsetting->desc.bInterfaceNumber);
1654
1655 /* interface 0 is used by DVB-T receiver and
1656 interface 1 is for remote controller (HID) */
1657 if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
1658 ret = af9015_read_config(udev);
1659 if (ret)
1660 return ret;
1661
1662 for (i = 0; i < af9015_properties_count; i++) {
1663 ret = dvb_usb_device_init(intf, &af9015_properties[i],
1664 THIS_MODULE, &d, adapter_nr);
1665 if (!ret)
1666 break;
1667 if (ret != -ENODEV)
1668 return ret;
1669 }
1670 if (ret)
1671 return ret;
1672
1673 if (d)
1674 ret = af9015_init(d);
1675 }
1676
1677 return ret;
1678}
1679
Antti Palosaari80619de2008-09-15 17:18:09 -03001680/* usb specific object needed to register this driver with the usb subsystem */
1681static struct usb_driver af9015_usb_driver = {
1682 .name = "dvb_usb_af9015",
1683 .probe = af9015_usb_probe,
Antti Palosaari713d9b52011-06-18 10:24:53 -03001684 .disconnect = dvb_usb_device_exit,
Antti Palosaari80619de2008-09-15 17:18:09 -03001685 .id_table = af9015_usb_table,
1686};
1687
1688/* module stuff */
1689static int __init af9015_usb_module_init(void)
1690{
1691 int ret;
1692 ret = usb_register(&af9015_usb_driver);
1693 if (ret)
1694 err("module init failed:%d", ret);
1695
1696 return ret;
1697}
1698
1699static void __exit af9015_usb_module_exit(void)
1700{
1701 /* deregister this driver from the USB subsystem */
1702 usb_deregister(&af9015_usb_driver);
1703}
1704
1705module_init(af9015_usb_module_init);
1706module_exit(af9015_usb_module_exit);
1707
1708MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1709MODULE_DESCRIPTION("Driver for Afatech AF9015 DVB-T");
1710MODULE_LICENSE("GPL");