blob: b257780fb380a7592b46f84a393209dc66f2edac [file] [log] [blame]
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001/* DVB USB compliant Linux driver for the Afatech 9005
2 * USB1.1 DVB-T receiver.
3 *
4 * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
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 *
Paul Bolle395cf962011-08-15 02:02:26 +020022 * see Documentation/dvb/README.dvb-usb for more information
Luca Olivettiaf4e0672007-05-07 15:19:32 -030023 */
24#include "af9005.h"
25
26/* debug */
27int dvb_usb_af9005_debug;
28module_param_named(debug, dvb_usb_af9005_debug, int, 0644);
29MODULE_PARM_DESC(debug,
30 "set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))."
31 DVB_USB_DEBUG_STATUS);
32/* enable obnoxious led */
Mauro Carvalho Chehab61f6a052014-09-03 16:18:48 -030033bool dvb_usb_af9005_led = true;
Luca Olivettiaf4e0672007-05-07 15:19:32 -030034module_param_named(led, dvb_usb_af9005_led, bool, 0644);
35MODULE_PARM_DESC(led, "enable led (default: 1).");
36
37/* eeprom dump */
Hans Verkuild45b9b82008-09-04 03:33:43 -030038static int dvb_usb_af9005_dump_eeprom;
Luca Olivettiaf4e0672007-05-07 15:19:32 -030039module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0);
40MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom.");
41
Janne Grunau78e920062008-04-09 19:13:13 -030042DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
43
Luca Olivettiaf4e0672007-05-07 15:19:32 -030044/* remote control decoder */
Hans Verkuild45b9b82008-09-04 03:33:43 -030045static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len,
46 u32 *event, int *state);
47static void *rc_keys;
48static int *rc_keys_size;
Luca Olivettiaf4e0672007-05-07 15:19:32 -030049
50u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
51
52struct af9005_device_state {
53 u8 sequence;
54 int led_state;
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -030055 unsigned char data[256];
56 struct mutex data_mutex;
Luca Olivettiaf4e0672007-05-07 15:19:32 -030057};
58
Hans Verkuild45b9b82008-09-04 03:33:43 -030059static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
Luca Olivettiaf4e0672007-05-07 15:19:32 -030060 int readwrite, int type, u8 * values, int len)
61{
62 struct af9005_device_state *st = d->priv;
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -030063 u8 command, seq;
64 int i, ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -030065
66 if (len < 1) {
67 err("generic read/write, less than 1 byte. Makes no sense.");
68 return -EINVAL;
69 }
70 if (len > 8) {
71 err("generic read/write, more than 8 bytes. Not supported.");
72 return -EINVAL;
73 }
74
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -030075 mutex_lock(&st->data_mutex);
76 st->data[0] = 14; /* rest of buffer length low */
77 st->data[1] = 0; /* rest of buffer length high */
Luca Olivettiaf4e0672007-05-07 15:19:32 -030078
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -030079 st->data[2] = AF9005_REGISTER_RW; /* register operation */
80 st->data[3] = 12; /* rest of buffer length */
Luca Olivettiaf4e0672007-05-07 15:19:32 -030081
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -030082 st->data[4] = seq = st->sequence++; /* sequence number */
Luca Olivettiaf4e0672007-05-07 15:19:32 -030083
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -030084 st->data[5] = (u8) (reg >> 8); /* register address */
85 st->data[6] = (u8) (reg & 0xff);
Luca Olivettiaf4e0672007-05-07 15:19:32 -030086
87 if (type == AF9005_OFDM_REG) {
88 command = AF9005_CMD_OFDM_REG;
89 } else {
90 command = AF9005_CMD_TUNER;
91 }
92
93 if (len > 1)
94 command |=
95 AF9005_CMD_BURST | AF9005_CMD_AUTOINC | (len - 1) << 3;
96 command |= readwrite;
97 if (readwrite == AF9005_CMD_WRITE)
98 for (i = 0; i < len; i++)
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -030099 st->data[8 + i] = values[i];
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300100 else if (type == AF9005_TUNER_REG)
101 /* read command for tuner, the first byte contains the i2c address */
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300102 st->data[8] = values[0];
103 st->data[7] = command;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300104
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300105 ret = dvb_usb_generic_rw(d, st->data, 16, st->data, 17, 0);
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300106 if (ret)
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300107 goto ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300108
109 /* sanity check */
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300110 if (st->data[2] != AF9005_REGISTER_RW_ACK) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300111 err("generic read/write, wrong reply code.");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300112 ret = -EIO;
113 goto ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300114 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300115 if (st->data[3] != 0x0d) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300116 err("generic read/write, wrong length in reply.");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300117 ret = -EIO;
118 goto ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300119 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300120 if (st->data[4] != seq) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300121 err("generic read/write, wrong sequence in reply.");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300122 ret = -EIO;
123 goto ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300124 }
125 /*
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300126 * In thesis, both input and output buffers should have
127 * identical values for st->data[5] to st->data[8].
128 * However, windows driver doesn't check these fields, in fact
129 * sometimes the register in the reply is different that what
130 * has been sent
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300131 */
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300132 if (st->data[16] != 0x01) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300133 err("generic read/write wrong status code in reply.");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300134 ret = -EIO;
135 goto ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300136 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300137
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300138 if (readwrite == AF9005_CMD_READ)
139 for (i = 0; i < len; i++)
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300140 values[i] = st->data[8 + i];
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300141
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300142ret:
143 mutex_unlock(&st->data_mutex);
144 return ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300145
146}
147
148int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 * value)
149{
150 int ret;
151 deb_reg("read register %x ", reg);
152 ret = af9005_generic_read_write(d, reg,
153 AF9005_CMD_READ, AF9005_OFDM_REG,
154 value, 1);
155 if (ret)
156 deb_reg("failed\n");
157 else
158 deb_reg("value %x\n", *value);
159 return ret;
160}
161
162int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg,
163 u8 * values, int len)
164{
165 int ret;
166 deb_reg("read %d registers %x ", len, reg);
167 ret = af9005_generic_read_write(d, reg,
168 AF9005_CMD_READ, AF9005_OFDM_REG,
169 values, len);
170 if (ret)
171 deb_reg("failed\n");
172 else
173 debug_dump(values, len, deb_reg);
174 return ret;
175}
176
177int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 value)
178{
179 int ret;
180 u8 temp = value;
181 deb_reg("write register %x value %x ", reg, value);
182 ret = af9005_generic_read_write(d, reg,
183 AF9005_CMD_WRITE, AF9005_OFDM_REG,
184 &temp, 1);
185 if (ret)
186 deb_reg("failed\n");
187 else
188 deb_reg("ok\n");
189 return ret;
190}
191
192int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg,
193 u8 * values, int len)
194{
195 int ret;
196 deb_reg("write %d registers %x values ", len, reg);
197 debug_dump(values, len, deb_reg);
198
199 ret = af9005_generic_read_write(d, reg,
200 AF9005_CMD_WRITE, AF9005_OFDM_REG,
201 values, len);
202 if (ret)
203 deb_reg("failed\n");
204 else
205 deb_reg("ok\n");
206 return ret;
207}
208
209int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
210 u8 len, u8 * value)
211{
212 u8 temp;
213 int ret;
214 deb_reg("read bits %x %x %x", reg, pos, len);
215 ret = af9005_read_ofdm_register(d, reg, &temp);
216 if (ret) {
217 deb_reg(" failed\n");
218 return ret;
219 }
220 *value = (temp >> pos) & regmask[len - 1];
221 deb_reg(" value %x\n", *value);
222 return 0;
223
224}
225
226int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
227 u8 len, u8 value)
228{
229 u8 temp, mask;
230 int ret;
231 deb_reg("write bits %x %x %x value %x\n", reg, pos, len, value);
232 if (pos == 0 && len == 8)
233 return af9005_write_ofdm_register(d, reg, value);
234 ret = af9005_read_ofdm_register(d, reg, &temp);
235 if (ret)
236 return ret;
237 mask = regmask[len - 1] << pos;
238 temp = (temp & ~mask) | ((value << pos) & mask);
239 return af9005_write_ofdm_register(d, reg, temp);
240
241}
242
243static int af9005_usb_read_tuner_registers(struct dvb_usb_device *d,
244 u16 reg, u8 * values, int len)
245{
246 return af9005_generic_read_write(d, reg,
247 AF9005_CMD_READ, AF9005_TUNER_REG,
248 values, len);
249}
250
251static int af9005_usb_write_tuner_registers(struct dvb_usb_device *d,
252 u16 reg, u8 * values, int len)
253{
254 return af9005_generic_read_write(d, reg,
255 AF9005_CMD_WRITE,
256 AF9005_TUNER_REG, values, len);
257}
258
259int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg,
260 u8 * values, int len)
261{
262 /* don't let the name of this function mislead you: it's just used
263 as an interface from the firmware to the i2c bus. The actual
264 i2c addresses are contained in the data */
265 int ret, i, done = 0, fail = 0;
266 u8 temp;
267 ret = af9005_usb_write_tuner_registers(d, reg, values, len);
268 if (ret)
269 return ret;
270 if (reg != 0xffff) {
271 /* check if write done (0xa40d bit 1) or fail (0xa40d bit 2) */
272 for (i = 0; i < 200; i++) {
273 ret =
274 af9005_read_ofdm_register(d,
275 xd_I2C_i2c_m_status_wdat_done,
276 &temp);
277 if (ret)
278 return ret;
279 done = temp & (regmask[i2c_m_status_wdat_done_len - 1]
280 << i2c_m_status_wdat_done_pos);
281 if (done)
282 break;
283 fail = temp & (regmask[i2c_m_status_wdat_fail_len - 1]
284 << i2c_m_status_wdat_fail_pos);
285 if (fail)
286 break;
287 msleep(50);
288 }
289 if (i == 200)
290 return -ETIMEDOUT;
291 if (fail) {
292 /* clear write fail bit */
293 af9005_write_register_bits(d,
294 xd_I2C_i2c_m_status_wdat_fail,
295 i2c_m_status_wdat_fail_pos,
296 i2c_m_status_wdat_fail_len,
297 1);
298 return -EIO;
299 }
300 /* clear write done bit */
301 ret =
302 af9005_write_register_bits(d,
303 xd_I2C_i2c_m_status_wdat_fail,
304 i2c_m_status_wdat_done_pos,
305 i2c_m_status_wdat_done_len, 1);
306 if (ret)
307 return ret;
308 }
309 return 0;
310}
311
312int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, u8 addr,
313 u8 * values, int len)
314{
315 /* don't let the name of this function mislead you: it's just used
316 as an interface from the firmware to the i2c bus. The actual
317 i2c addresses are contained in the data */
318 int ret, i;
319 u8 temp, buf[2];
320
321 buf[0] = addr; /* tuner i2c address */
322 buf[1] = values[0]; /* tuner register */
323
324 values[0] = addr + 0x01; /* i2c read address */
325
326 if (reg == APO_REG_I2C_RW_SILICON_TUNER) {
327 /* write tuner i2c address to tuner, 0c00c0 undocumented, found by sniffing */
328 ret = af9005_write_tuner_registers(d, 0x00c0, buf, 2);
329 if (ret)
330 return ret;
331 }
332
333 /* send read command to ofsm */
334 ret = af9005_usb_read_tuner_registers(d, reg, values, 1);
335 if (ret)
336 return ret;
337
338 /* check if read done */
339 for (i = 0; i < 200; i++) {
340 ret = af9005_read_ofdm_register(d, 0xa408, &temp);
341 if (ret)
342 return ret;
343 if (temp & 0x01)
344 break;
345 msleep(50);
346 }
347 if (i == 200)
348 return -ETIMEDOUT;
349
350 /* clear read done bit (by writing 1) */
351 ret = af9005_write_ofdm_register(d, xd_I2C_i2c_m_data8, 1);
352 if (ret)
353 return ret;
354
355 /* get read data (available from 0xa400) */
356 for (i = 0; i < len; i++) {
357 ret = af9005_read_ofdm_register(d, 0xa400 + i, &temp);
358 if (ret)
359 return ret;
360 values[i] = temp;
361 }
362 return 0;
363}
364
365static int af9005_i2c_write(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
366 u8 * data, int len)
367{
368 int ret, i;
369 u8 buf[3];
370 deb_i2c("i2c_write i2caddr %x, reg %x, len %d data ", i2caddr,
371 reg, len);
372 debug_dump(data, len, deb_i2c);
373
374 for (i = 0; i < len; i++) {
375 buf[0] = i2caddr;
376 buf[1] = reg + (u8) i;
377 buf[2] = data[i];
378 ret =
379 af9005_write_tuner_registers(d,
380 APO_REG_I2C_RW_SILICON_TUNER,
381 buf, 3);
382 if (ret) {
383 deb_i2c("i2c_write failed\n");
384 return ret;
385 }
386 }
387 deb_i2c("i2c_write ok\n");
388 return 0;
389}
390
391static int af9005_i2c_read(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
392 u8 * data, int len)
393{
394 int ret, i;
395 u8 temp;
396 deb_i2c("i2c_read i2caddr %x, reg %x, len %d\n ", i2caddr, reg, len);
397 for (i = 0; i < len; i++) {
398 temp = reg + i;
399 ret =
400 af9005_read_tuner_registers(d,
401 APO_REG_I2C_RW_SILICON_TUNER,
402 i2caddr, &temp, 1);
403 if (ret) {
404 deb_i2c("i2c_read failed\n");
405 return ret;
406 }
407 data[i] = temp;
408 }
409 deb_i2c("i2c data read: ");
410 debug_dump(data, len, deb_i2c);
411 return 0;
412}
413
414static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
415 int num)
416{
417 /* only implements what the mt2060 module does, don't know how
418 to make it really generic */
419 struct dvb_usb_device *d = i2c_get_adapdata(adap);
420 int ret;
421 u8 reg, addr;
422 u8 *value;
423
424 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
425 return -EAGAIN;
426
427 if (num > 2)
428 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
429
430 if (num == 2) {
431 /* reads a single register */
432 reg = *msg[0].buf;
433 addr = msg[0].addr;
434 value = msg[1].buf;
435 ret = af9005_i2c_read(d, addr, reg, value, 1);
436 if (ret == 0)
437 ret = 2;
438 } else {
439 /* write one or more registers */
440 reg = msg[0].buf[0];
441 addr = msg[0].addr;
442 value = &msg[0].buf[1];
443 ret = af9005_i2c_write(d, addr, reg, value, msg[0].len - 1);
444 if (ret == 0)
445 ret = 1;
446 }
447
448 mutex_unlock(&d->i2c_mutex);
449 return ret;
450}
451
452static u32 af9005_i2c_func(struct i2c_adapter *adapter)
453{
454 return I2C_FUNC_I2C;
455}
456
457static struct i2c_algorithm af9005_i2c_algo = {
458 .master_xfer = af9005_i2c_xfer,
459 .functionality = af9005_i2c_func,
460};
461
462int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf,
463 int wlen, u8 * rbuf, int rlen)
464{
465 struct af9005_device_state *st = d->priv;
466
467 int ret, i, packet_len;
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300468 u8 seq;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300469
470 if (wlen < 0) {
471 err("send command, wlen less than 0 bytes. Makes no sense.");
472 return -EINVAL;
473 }
474 if (wlen > 54) {
475 err("send command, wlen more than 54 bytes. Not supported.");
476 return -EINVAL;
477 }
478 if (rlen > 54) {
479 err("send command, rlen more than 54 bytes. Not supported.");
480 return -EINVAL;
481 }
482 packet_len = wlen + 5;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300483
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300484 mutex_lock(&st->data_mutex);
485
486 st->data[0] = (u8) (packet_len & 0xff);
487 st->data[1] = (u8) ((packet_len & 0xff00) >> 8);
488
489 st->data[2] = 0x26; /* packet type */
490 st->data[3] = wlen + 3;
491 st->data[4] = seq = st->sequence++;
492 st->data[5] = command;
493 st->data[6] = wlen;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300494 for (i = 0; i < wlen; i++)
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300495 st->data[7 + i] = wbuf[i];
496 ret = dvb_usb_generic_rw(d, st->data, wlen + 7, st->data, rlen + 7, 0);
497 if (st->data[2] != 0x27) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300498 err("send command, wrong reply code.");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300499 ret = -EIO;
500 } else if (st->data[4] != seq) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300501 err("send command, wrong sequence in reply.");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300502 ret = -EIO;
503 } else if (st->data[5] != 0x01) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300504 err("send command, wrong status code in reply.");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300505 ret = -EIO;
506 } else if (st->data[6] != rlen) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300507 err("send command, invalid data length in reply.");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300508 ret = -EIO;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300509 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300510 if (!ret) {
511 for (i = 0; i < rlen; i++)
512 rbuf[i] = st->data[i + 7];
513 }
514
515 mutex_unlock(&st->data_mutex);
516 return ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300517}
518
519int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values,
520 int len)
521{
522 struct af9005_device_state *st = d->priv;
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300523 u8 seq;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300524 int ret, i;
525
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300526 mutex_lock(&st->data_mutex);
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300527
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300528 memset(st->data, 0, sizeof(st->data));
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300529
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300530 st->data[0] = 14; /* length of rest of packet low */
531 st->data[1] = 0; /* length of rest of packer high */
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300532
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300533 st->data[2] = 0x2a; /* read/write eeprom */
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300534
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300535 st->data[3] = 12; /* size */
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300536
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300537 st->data[4] = seq = st->sequence++;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300538
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300539 st->data[5] = 0; /* read */
540
541 st->data[6] = len;
542 st->data[7] = address;
543 ret = dvb_usb_generic_rw(d, st->data, 16, st->data, 14, 0);
544 if (st->data[2] != 0x2b) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300545 err("Read eeprom, invalid reply code");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300546 ret = -EIO;
547 } else if (st->data[3] != 10) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300548 err("Read eeprom, invalid reply length");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300549 ret = -EIO;
550 } else if (st->data[4] != seq) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300551 err("Read eeprom, wrong sequence in reply ");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300552 ret = -EIO;
553 } else if (st->data[5] != 1) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300554 err("Read eeprom, wrong status in reply ");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300555 ret = -EIO;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300556 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300557
558 if (!ret) {
559 for (i = 0; i < len; i++)
560 values[i] = st->data[6 + i];
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300561 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300562 mutex_unlock(&st->data_mutex);
563
564 return ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300565}
566
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300567static int af9005_boot_packet(struct usb_device *udev, int type, u8 *reply,
568 u8 *buf, int size)
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300569{
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300570 u16 checksum;
571 int act_len, i, ret;
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300572
573 memset(buf, 0, size);
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300574 buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
575 buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
576 switch (type) {
577 case FW_CONFIG:
578 buf[2] = 0x11;
579 buf[3] = 0x04;
580 buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
581 buf[5] = 0x03;
582 checksum = buf[4] + buf[5];
583 buf[6] = (u8) ((checksum >> 8) & 0xff);
584 buf[7] = (u8) (checksum & 0xff);
585 break;
586 case FW_CONFIRM:
587 buf[2] = 0x11;
588 buf[3] = 0x04;
589 buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
590 buf[5] = 0x01;
591 checksum = buf[4] + buf[5];
592 buf[6] = (u8) ((checksum >> 8) & 0xff);
593 buf[7] = (u8) (checksum & 0xff);
594 break;
595 case FW_BOOT:
596 buf[2] = 0x10;
597 buf[3] = 0x08;
598 buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
599 buf[5] = 0x97;
600 buf[6] = 0xaa;
601 buf[7] = 0x55;
602 buf[8] = 0xa5;
603 buf[9] = 0x5a;
604 checksum = 0;
605 for (i = 4; i <= 9; i++)
606 checksum += buf[i];
607 buf[10] = (u8) ((checksum >> 8) & 0xff);
608 buf[11] = (u8) (checksum & 0xff);
609 break;
610 default:
611 err("boot packet invalid boot packet type");
612 return -EINVAL;
613 }
614 deb_fw(">>> ");
615 debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
616
617 ret = usb_bulk_msg(udev,
618 usb_sndbulkpipe(udev, 0x02),
619 buf, FW_BULKOUT_SIZE + 2, &act_len, 2000);
620 if (ret)
621 err("boot packet bulk message failed: %d (%d/%d)", ret,
622 FW_BULKOUT_SIZE + 2, act_len);
623 else
624 ret = act_len != FW_BULKOUT_SIZE + 2 ? -1 : 0;
625 if (ret)
626 return ret;
627 memset(buf, 0, 9);
628 ret = usb_bulk_msg(udev,
629 usb_rcvbulkpipe(udev, 0x01), buf, 9, &act_len, 2000);
630 if (ret) {
631 err("boot packet recv bulk message failed: %d", ret);
632 return ret;
633 }
634 deb_fw("<<< ");
635 debug_dump(buf, act_len, deb_fw);
636 checksum = 0;
637 switch (type) {
638 case FW_CONFIG:
639 if (buf[2] != 0x11) {
640 err("boot bad config header.");
641 return -EIO;
642 }
643 if (buf[3] != 0x05) {
644 err("boot bad config size.");
645 return -EIO;
646 }
647 if (buf[4] != 0x00) {
648 err("boot bad config sequence.");
649 return -EIO;
650 }
651 if (buf[5] != 0x04) {
652 err("boot bad config subtype.");
653 return -EIO;
654 }
655 for (i = 4; i <= 6; i++)
656 checksum += buf[i];
657 if (buf[7] * 256 + buf[8] != checksum) {
658 err("boot bad config checksum.");
659 return -EIO;
660 }
661 *reply = buf[6];
662 break;
663 case FW_CONFIRM:
664 if (buf[2] != 0x11) {
665 err("boot bad confirm header.");
666 return -EIO;
667 }
668 if (buf[3] != 0x05) {
669 err("boot bad confirm size.");
670 return -EIO;
671 }
672 if (buf[4] != 0x00) {
673 err("boot bad confirm sequence.");
674 return -EIO;
675 }
676 if (buf[5] != 0x02) {
677 err("boot bad confirm subtype.");
678 return -EIO;
679 }
680 for (i = 4; i <= 6; i++)
681 checksum += buf[i];
682 if (buf[7] * 256 + buf[8] != checksum) {
683 err("boot bad confirm checksum.");
684 return -EIO;
685 }
686 *reply = buf[6];
687 break;
688 case FW_BOOT:
689 if (buf[2] != 0x10) {
690 err("boot bad boot header.");
691 return -EIO;
692 }
693 if (buf[3] != 0x05) {
694 err("boot bad boot size.");
695 return -EIO;
696 }
697 if (buf[4] != 0x00) {
698 err("boot bad boot sequence.");
699 return -EIO;
700 }
701 if (buf[5] != 0x01) {
702 err("boot bad boot pattern 01.");
703 return -EIO;
704 }
705 if (buf[6] != 0x10) {
706 err("boot bad boot pattern 10.");
707 return -EIO;
708 }
709 for (i = 4; i <= 6; i++)
710 checksum += buf[i];
711 if (buf[7] * 256 + buf[8] != checksum) {
712 err("boot bad boot checksum.");
713 return -EIO;
714 }
715 break;
716
717 }
718
719 return 0;
720}
721
Hans Verkuild45b9b82008-09-04 03:33:43 -0300722static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw)
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300723{
724 int i, packets, ret, act_len;
725
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300726 u8 *buf;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300727 u8 reply;
728
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300729 buf = kmalloc(FW_BULKOUT_SIZE + 2, GFP_KERNEL);
730 if (!buf)
731 return -ENOMEM;
732
733 ret = af9005_boot_packet(udev, FW_CONFIG, &reply, buf,
734 FW_BULKOUT_SIZE + 2);
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300735 if (ret)
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300736 goto err;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300737 if (reply != 0x01) {
738 err("before downloading firmware, FW_CONFIG expected 0x01, received 0x%x", reply);
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300739 ret = -EIO;
740 goto err;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300741 }
742 packets = fw->size / FW_BULKOUT_SIZE;
743 buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
744 buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
745 for (i = 0; i < packets; i++) {
746 memcpy(&buf[2], fw->data + i * FW_BULKOUT_SIZE,
747 FW_BULKOUT_SIZE);
748 deb_fw(">>> ");
749 debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
750 ret = usb_bulk_msg(udev,
751 usb_sndbulkpipe(udev, 0x02),
752 buf, FW_BULKOUT_SIZE + 2, &act_len, 1000);
753 if (ret) {
754 err("firmware download failed at packet %d with code %d", i, ret);
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300755 goto err;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300756 }
757 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300758 ret = af9005_boot_packet(udev, FW_CONFIRM, &reply,
759 buf, FW_BULKOUT_SIZE + 2);
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300760 if (ret)
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300761 goto err;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300762 if (reply != (u8) (packets & 0xff)) {
763 err("after downloading firmware, FW_CONFIRM expected 0x%x, received 0x%x", packets & 0xff, reply);
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300764 ret = -EIO;
765 goto err;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300766 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300767 ret = af9005_boot_packet(udev, FW_BOOT, &reply, buf,
768 FW_BULKOUT_SIZE + 2);
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300769 if (ret)
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300770 goto err;
771 ret = af9005_boot_packet(udev, FW_CONFIG, &reply, buf,
772 FW_BULKOUT_SIZE + 2);
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300773 if (ret)
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300774 goto err;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300775 if (reply != 0x02) {
776 err("after downloading firmware, FW_CONFIG expected 0x02, received 0x%x", reply);
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300777 ret = -EIO;
778 goto err;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300779 }
780
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300781err:
782 kfree(buf);
783 return ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300784
785}
786
787int af9005_led_control(struct dvb_usb_device *d, int onoff)
788{
789 struct af9005_device_state *st = d->priv;
790 int temp, ret;
791
792 if (onoff && dvb_usb_af9005_led)
793 temp = 1;
794 else
795 temp = 0;
796 if (st->led_state != temp) {
797 ret =
798 af9005_write_register_bits(d, xd_p_reg_top_locken1,
799 reg_top_locken1_pos,
800 reg_top_locken1_len, temp);
801 if (ret)
802 return ret;
803 ret =
804 af9005_write_register_bits(d, xd_p_reg_top_lock1,
805 reg_top_lock1_pos,
806 reg_top_lock1_len, temp);
807 if (ret)
808 return ret;
809 st->led_state = temp;
810 }
811 return 0;
812}
813
814static int af9005_frontend_attach(struct dvb_usb_adapter *adap)
815{
816 u8 buf[8];
817 int i;
818
819 /* without these calls the first commands after downloading
820 the firmware fail. I put these calls here to simulate
821 what it is done in dvb-usb-init.c.
822 */
823 struct usb_device *udev = adap->dev->udev;
824 usb_clear_halt(udev, usb_sndbulkpipe(udev, 2));
825 usb_clear_halt(udev, usb_rcvbulkpipe(udev, 1));
826 if (dvb_usb_af9005_dump_eeprom) {
827 printk("EEPROM DUMP\n");
828 for (i = 0; i < 255; i += 8) {
829 af9005_read_eeprom(adap->dev, i, buf, 8);
830 printk("ADDR %x ", i);
831 debug_dump(buf, 8, printk);
832 }
833 }
Michael Krufky77eed212011-09-06 09:31:57 -0300834 adap->fe_adap[0].fe = af9005_fe_attach(adap->dev);
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300835 return 0;
836}
837
838static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state)
839{
840 struct af9005_device_state *st = d->priv;
841 int ret, len;
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300842 u8 seq;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300843
844 *state = REMOTE_NO_KEY_PRESSED;
845 if (rc_decode == NULL) {
846 /* it shouldn't never come here */
847 return 0;
848 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300849
850 mutex_lock(&st->data_mutex);
851
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300852 /* deb_info("rc_query\n"); */
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300853 st->data[0] = 3; /* rest of packet length low */
854 st->data[1] = 0; /* rest of packet lentgh high */
855 st->data[2] = 0x40; /* read remote */
856 st->data[3] = 1; /* rest of packet length */
857 st->data[4] = seq = st->sequence++; /* sequence number */
858 ret = dvb_usb_generic_rw(d, st->data, 5, st->data, 256, 0);
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300859 if (ret) {
860 err("rc query failed");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300861 goto ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300862 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300863 if (st->data[2] != 0x41) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300864 err("rc query bad header.");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300865 ret = -EIO;
866 goto ret;
867 } else if (st->data[4] != seq) {
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300868 err("rc query bad sequence.");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300869 ret = -EIO;
870 goto ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300871 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300872 len = st->data[5];
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300873 if (len > 246) {
874 err("rc query invalid length");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300875 ret = -EIO;
876 goto ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300877 }
878 if (len > 0) {
879 deb_rc("rc data (%d) ", len);
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300880 debug_dump((st->data + 6), len, deb_rc);
881 ret = rc_decode(d, &st->data[6], len, event, state);
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300882 if (ret) {
883 err("rc_decode failed");
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300884 goto ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300885 } else {
886 deb_rc("rc_decode state %x event %x\n", *state, *event);
887 if (*state == REMOTE_KEY_REPEAT)
888 *event = d->last_event;
889 }
890 }
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300891
892ret:
893 mutex_unlock(&st->data_mutex);
894 return ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300895}
896
897static int af9005_power_ctrl(struct dvb_usb_device *d, int onoff)
898{
899
900 return 0;
901}
902
903static int af9005_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
904{
905 int ret;
906 deb_info("pid filter control onoff %d\n", onoff);
907 if (onoff) {
908 ret =
909 af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
910 if (ret)
911 return ret;
912 ret =
913 af9005_write_register_bits(adap->dev,
914 XD_MP2IF_DMX_CTRL, 1, 1, 1);
915 if (ret)
916 return ret;
917 ret =
918 af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
919 } else
920 ret =
921 af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 0);
922 if (ret)
923 return ret;
924 deb_info("pid filter control ok\n");
925 return 0;
926}
927
928static int af9005_pid_filter(struct dvb_usb_adapter *adap, int index,
929 u16 pid, int onoff)
930{
931 u8 cmd = index & 0x1f;
932 int ret;
933 deb_info("set pid filter, index %d, pid %x, onoff %d\n", index,
934 pid, onoff);
935 if (onoff) {
936 /* cannot use it as pid_filter_ctrl since it has to be done
937 before setting the first pid */
938 if (adap->feedcount == 1) {
939 deb_info("first pid set, enable pid table\n");
940 ret = af9005_pid_filter_control(adap, onoff);
941 if (ret)
942 return ret;
943 }
944 ret =
945 af9005_write_ofdm_register(adap->dev,
946 XD_MP2IF_PID_DATA_L,
947 (u8) (pid & 0xff));
948 if (ret)
949 return ret;
950 ret =
951 af9005_write_ofdm_register(adap->dev,
952 XD_MP2IF_PID_DATA_H,
953 (u8) (pid >> 8));
954 if (ret)
955 return ret;
956 cmd |= 0x20 | 0x40;
957 } else {
958 if (adap->feedcount == 0) {
959 deb_info("last pid unset, disable pid table\n");
960 ret = af9005_pid_filter_control(adap, onoff);
961 if (ret)
962 return ret;
963 }
964 }
965 ret = af9005_write_ofdm_register(adap->dev, XD_MP2IF_PID_IDX, cmd);
966 if (ret)
967 return ret;
968 deb_info("set pid ok\n");
969 return 0;
970}
971
972static int af9005_identify_state(struct usb_device *udev,
973 struct dvb_usb_device_properties *props,
974 struct dvb_usb_device_description **desc,
975 int *cold)
976{
977 int ret;
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300978 u8 reply, *buf;
979
980 buf = kmalloc(FW_BULKOUT_SIZE + 2, GFP_KERNEL);
981 if (!buf)
982 return -ENOMEM;
983
984 ret = af9005_boot_packet(udev, FW_CONFIG, &reply,
985 buf, FW_BULKOUT_SIZE + 2);
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300986 if (ret)
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300987 goto err;
Luca Olivettiaf4e0672007-05-07 15:19:32 -0300988 deb_info("result of FW_CONFIG in identify state %d\n", reply);
989 if (reply == 0x01)
990 *cold = 1;
991 else if (reply == 0x02)
992 *cold = 0;
993 else
994 return -EIO;
995 deb_info("Identify state cold = %d\n", *cold);
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -0300996
997err:
998 kfree(buf);
999 return ret;
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001000}
1001
1002static struct dvb_usb_device_properties af9005_properties;
1003
1004static int af9005_usb_probe(struct usb_interface *intf,
1005 const struct usb_device_id *id)
1006{
Mauro Carvalho Chehabc58b84e2016-10-05 06:46:49 -03001007 struct dvb_usb_device *d;
1008 struct af9005_device_state *st;
1009 int ret;
1010
1011 ret = dvb_usb_device_init(intf, &af9005_properties,
1012 THIS_MODULE, &d, adapter_nr);
1013
1014 if (ret < 0)
1015 return ret;
1016
1017 st = d->priv;
1018 mutex_init(&st->data_mutex);
1019
1020 return 0;
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001021}
1022
Jonathan Niederd07b9012012-01-07 04:11:27 -03001023enum af9005_usb_table_entry {
1024 AFATECH_AF9005,
1025 TERRATEC_AF9005,
1026 ANSONIC_AF9005,
1027};
1028
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001029static struct usb_device_id af9005_usb_table[] = {
Jonathan Niederd07b9012012-01-07 04:11:27 -03001030 [AFATECH_AF9005] = {USB_DEVICE(USB_VID_AFATECH,
1031 USB_PID_AFATECH_AF9005)},
1032 [TERRATEC_AF9005] = {USB_DEVICE(USB_VID_TERRATEC,
1033 USB_PID_TERRATEC_CINERGY_T_USB_XE)},
1034 [ANSONIC_AF9005] = {USB_DEVICE(USB_VID_ANSONIC,
1035 USB_PID_ANSONIC_DVBT_USB)},
1036 { }
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001037};
1038
1039MODULE_DEVICE_TABLE(usb, af9005_usb_table);
1040
1041static struct dvb_usb_device_properties af9005_properties = {
1042 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1043
1044 .usb_ctrl = DEVICE_SPECIFIC,
1045 .firmware = "af9005.fw",
1046 .download_firmware = af9005_download_firmware,
1047 .no_reconnect = 1,
1048
1049 .size_of_priv = sizeof(struct af9005_device_state),
1050
1051 .num_adapters = 1,
1052 .adapter = {
1053 {
Michael Krufky77eed212011-09-06 09:31:57 -03001054 .num_frontends = 1,
1055 .fe = {{
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001056 .caps =
1057 DVB_USB_ADAP_HAS_PID_FILTER |
1058 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1059 .pid_filter_count = 32,
1060 .pid_filter = af9005_pid_filter,
1061 /* .pid_filter_ctrl = af9005_pid_filter_control, */
1062 .frontend_attach = af9005_frontend_attach,
1063 /* .tuner_attach = af9005_tuner_attach, */
1064 /* parameter for the MPEG2-data transfer */
1065 .stream = {
1066 .type = USB_BULK,
1067 .count = 10,
1068 .endpoint = 0x04,
1069 .u = {
1070 .bulk = {
1071 .buffersize = 4096, /* actual size seen is 3948 */
1072 }
1073 }
1074 },
Michael Krufky77eed212011-09-06 09:31:57 -03001075 }},
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001076 }
1077 },
1078 .power_ctrl = af9005_power_ctrl,
1079 .identify_state = af9005_identify_state,
1080
1081 .i2c_algo = &af9005_i2c_algo,
1082
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001083 .rc.legacy = {
1084 .rc_interval = 200,
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001085 .rc_map_table = NULL,
1086 .rc_map_size = 0,
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001087 .rc_query = af9005_rc_query,
1088 },
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001089
Michael Krufky17f93e12010-06-21 01:49:42 -03001090 .generic_bulk_ctrl_endpoint = 2,
1091 .generic_bulk_ctrl_endpoint_response = 1,
1092
Luca Olivetti8cb93292008-01-20 17:56:43 -03001093 .num_device_descs = 3,
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001094 .devices = {
1095 {.name = "Afatech DVB-T USB1.1 stick",
Jonathan Niederd07b9012012-01-07 04:11:27 -03001096 .cold_ids = {&af9005_usb_table[AFATECH_AF9005], NULL},
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001097 .warm_ids = {NULL},
1098 },
1099 {.name = "TerraTec Cinergy T USB XE",
Jonathan Niederd07b9012012-01-07 04:11:27 -03001100 .cold_ids = {&af9005_usb_table[TERRATEC_AF9005], NULL},
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001101 .warm_ids = {NULL},
1102 },
Luca Olivetti8cb93292008-01-20 17:56:43 -03001103 {.name = "Ansonic DVB-T USB1.1 stick",
Jonathan Niederd07b9012012-01-07 04:11:27 -03001104 .cold_ids = {&af9005_usb_table[ANSONIC_AF9005], NULL},
Luca Olivetti8cb93292008-01-20 17:56:43 -03001105 .warm_ids = {NULL},
1106 },
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001107 {NULL},
1108 }
1109};
1110
1111/* usb specific object needed to register this driver with the usb subsystem */
1112static struct usb_driver af9005_usb_driver = {
1113 .name = "dvb_usb_af9005",
1114 .probe = af9005_usb_probe,
1115 .disconnect = dvb_usb_device_exit,
1116 .id_table = af9005_usb_table,
1117};
1118
1119/* module stuff */
1120static int __init af9005_usb_module_init(void)
1121{
1122 int result;
1123 if ((result = usb_register(&af9005_usb_driver))) {
1124 err("usb_register failed. (%d)", result);
1125 return result;
1126 }
Frank Schaefer22799482014-09-29 15:17:35 -03001127#if IS_MODULE(CONFIG_DVB_USB_AF9005) || defined(CONFIG_DVB_USB_AF9005_REMOTE)
1128 /* FIXME: convert to todays kernel IR infrastructure */
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001129 rc_decode = symbol_request(af9005_rc_decode);
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001130 rc_keys = symbol_request(rc_map_af9005_table);
1131 rc_keys_size = symbol_request(rc_map_af9005_table_size);
Frank Schaefer22799482014-09-29 15:17:35 -03001132#endif
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001133 if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
1134 err("af9005_rc_decode function not found, disabling remote");
Mauro Carvalho Chehabf72a27b2010-07-31 18:04:09 -03001135 af9005_properties.rc.legacy.rc_query = NULL;
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001136 } else {
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001137 af9005_properties.rc.legacy.rc_map_table = rc_keys;
1138 af9005_properties.rc.legacy.rc_map_size = *rc_keys_size;
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001139 }
1140
1141 return 0;
1142}
1143
1144static void __exit af9005_usb_module_exit(void)
1145{
1146 /* release rc decode symbols */
1147 if (rc_decode != NULL)
1148 symbol_put(af9005_rc_decode);
1149 if (rc_keys != NULL)
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001150 symbol_put(rc_map_af9005_table);
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001151 if (rc_keys_size != NULL)
Mauro Carvalho Chehab2f4f58d2010-11-17 15:46:09 -03001152 symbol_put(rc_map_af9005_table_size);
Luca Olivettiaf4e0672007-05-07 15:19:32 -03001153 /* deregister this driver from the USB subsystem */
1154 usb_deregister(&af9005_usb_driver);
1155}
1156
1157module_init(af9005_usb_module_init);
1158module_exit(af9005_usb_module_exit);
1159
1160MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
1161MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick");
1162MODULE_VERSION("1.0");
1163MODULE_LICENSE("GPL");