1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* DVB USB compliant Linux driver for the Afatech 9005 |
3 | * USB1.1 DVB-T receiver. |
4 | * |
5 | * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) |
6 | * |
7 | * Thanks to Afatech who kindly provided information. |
8 | * |
9 | * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information |
10 | */ |
11 | #include "af9005.h" |
12 | |
13 | /* debug */ |
14 | int dvb_usb_af9005_debug; |
15 | module_param_named(debug, dvb_usb_af9005_debug, int, 0644); |
16 | MODULE_PARM_DESC(debug, |
17 | "set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))." |
18 | DVB_USB_DEBUG_STATUS); |
19 | /* enable obnoxious led */ |
20 | bool dvb_usb_af9005_led = true; |
21 | module_param_named(led, dvb_usb_af9005_led, bool, 0644); |
22 | MODULE_PARM_DESC(led, "enable led (default: 1)." ); |
23 | |
24 | /* eeprom dump */ |
25 | static int dvb_usb_af9005_dump_eeprom; |
26 | module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0); |
27 | MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom." ); |
28 | |
29 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
30 | |
31 | /* remote control decoder */ |
32 | static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len, |
33 | u32 *event, int *state); |
34 | static void *rc_keys; |
35 | static int *rc_keys_size; |
36 | |
37 | u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; |
38 | |
39 | struct af9005_device_state { |
40 | u8 sequence; |
41 | int led_state; |
42 | unsigned char data[256]; |
43 | }; |
44 | |
45 | static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg, |
46 | int readwrite, int type, u8 * values, int len) |
47 | { |
48 | struct af9005_device_state *st = d->priv; |
49 | u8 command, seq; |
50 | int i, ret; |
51 | |
52 | if (len < 1) { |
53 | err("generic read/write, less than 1 byte. Makes no sense." ); |
54 | return -EINVAL; |
55 | } |
56 | if (len > 8) { |
57 | err("generic read/write, more than 8 bytes. Not supported." ); |
58 | return -EINVAL; |
59 | } |
60 | |
61 | mutex_lock(&d->data_mutex); |
62 | st->data[0] = 14; /* rest of buffer length low */ |
63 | st->data[1] = 0; /* rest of buffer length high */ |
64 | |
65 | st->data[2] = AF9005_REGISTER_RW; /* register operation */ |
66 | st->data[3] = 12; /* rest of buffer length */ |
67 | |
68 | st->data[4] = seq = st->sequence++; /* sequence number */ |
69 | |
70 | st->data[5] = (u8) (reg >> 8); /* register address */ |
71 | st->data[6] = (u8) (reg & 0xff); |
72 | |
73 | if (type == AF9005_OFDM_REG) { |
74 | command = AF9005_CMD_OFDM_REG; |
75 | } else { |
76 | command = AF9005_CMD_TUNER; |
77 | } |
78 | |
79 | if (len > 1) |
80 | command |= |
81 | AF9005_CMD_BURST | AF9005_CMD_AUTOINC | (len - 1) << 3; |
82 | command |= readwrite; |
83 | if (readwrite == AF9005_CMD_WRITE) |
84 | for (i = 0; i < len; i++) |
85 | st->data[8 + i] = values[i]; |
86 | else if (type == AF9005_TUNER_REG) |
87 | /* read command for tuner, the first byte contains the i2c address */ |
88 | st->data[8] = values[0]; |
89 | st->data[7] = command; |
90 | |
91 | ret = dvb_usb_generic_rw(d, st->data, 16, st->data, 17, 0); |
92 | if (ret) |
93 | goto ret; |
94 | |
95 | /* sanity check */ |
96 | if (st->data[2] != AF9005_REGISTER_RW_ACK) { |
97 | err("generic read/write, wrong reply code." ); |
98 | ret = -EIO; |
99 | goto ret; |
100 | } |
101 | if (st->data[3] != 0x0d) { |
102 | err("generic read/write, wrong length in reply." ); |
103 | ret = -EIO; |
104 | goto ret; |
105 | } |
106 | if (st->data[4] != seq) { |
107 | err("generic read/write, wrong sequence in reply." ); |
108 | ret = -EIO; |
109 | goto ret; |
110 | } |
111 | /* |
112 | * In thesis, both input and output buffers should have |
113 | * identical values for st->data[5] to st->data[8]. |
114 | * However, windows driver doesn't check these fields, in fact |
115 | * sometimes the register in the reply is different that what |
116 | * has been sent |
117 | */ |
118 | if (st->data[16] != 0x01) { |
119 | err("generic read/write wrong status code in reply." ); |
120 | ret = -EIO; |
121 | goto ret; |
122 | } |
123 | |
124 | if (readwrite == AF9005_CMD_READ) |
125 | for (i = 0; i < len; i++) |
126 | values[i] = st->data[8 + i]; |
127 | |
128 | ret: |
129 | mutex_unlock(lock: &d->data_mutex); |
130 | return ret; |
131 | |
132 | } |
133 | |
134 | int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 * value) |
135 | { |
136 | int ret; |
137 | deb_reg("read register %x " , reg); |
138 | ret = af9005_generic_read_write(d, reg, |
139 | AF9005_CMD_READ, AF9005_OFDM_REG, |
140 | values: value, len: 1); |
141 | if (ret) |
142 | deb_reg("failed\n" ); |
143 | else |
144 | deb_reg("value %x\n" , *value); |
145 | return ret; |
146 | } |
147 | |
148 | int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg, |
149 | u8 * values, int len) |
150 | { |
151 | int ret; |
152 | deb_reg("read %d registers %x " , len, reg); |
153 | ret = af9005_generic_read_write(d, reg, |
154 | AF9005_CMD_READ, AF9005_OFDM_REG, |
155 | values, len); |
156 | if (ret) |
157 | deb_reg("failed\n" ); |
158 | else |
159 | debug_dump(values, len, deb_reg); |
160 | return ret; |
161 | } |
162 | |
163 | int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 value) |
164 | { |
165 | int ret; |
166 | u8 temp = value; |
167 | deb_reg("write register %x value %x " , reg, value); |
168 | ret = af9005_generic_read_write(d, reg, |
169 | AF9005_CMD_WRITE, AF9005_OFDM_REG, |
170 | values: &temp, len: 1); |
171 | if (ret) |
172 | deb_reg("failed\n" ); |
173 | else |
174 | deb_reg("ok\n" ); |
175 | return ret; |
176 | } |
177 | |
178 | int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg, |
179 | u8 * values, int len) |
180 | { |
181 | int ret; |
182 | deb_reg("write %d registers %x values " , len, reg); |
183 | debug_dump(values, len, deb_reg); |
184 | |
185 | ret = af9005_generic_read_write(d, reg, |
186 | AF9005_CMD_WRITE, AF9005_OFDM_REG, |
187 | values, len); |
188 | if (ret) |
189 | deb_reg("failed\n" ); |
190 | else |
191 | deb_reg("ok\n" ); |
192 | return ret; |
193 | } |
194 | |
195 | int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos, |
196 | u8 len, u8 * value) |
197 | { |
198 | u8 temp; |
199 | int ret; |
200 | deb_reg("read bits %x %x %x" , reg, pos, len); |
201 | ret = af9005_read_ofdm_register(d, reg, value: &temp); |
202 | if (ret) { |
203 | deb_reg(" failed\n" ); |
204 | return ret; |
205 | } |
206 | *value = (temp >> pos) & regmask[len - 1]; |
207 | deb_reg(" value %x\n" , *value); |
208 | return 0; |
209 | |
210 | } |
211 | |
212 | int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos, |
213 | u8 len, u8 value) |
214 | { |
215 | u8 temp, mask; |
216 | int ret; |
217 | deb_reg("write bits %x %x %x value %x\n" , reg, pos, len, value); |
218 | if (pos == 0 && len == 8) |
219 | return af9005_write_ofdm_register(d, reg, value); |
220 | ret = af9005_read_ofdm_register(d, reg, value: &temp); |
221 | if (ret) |
222 | return ret; |
223 | mask = regmask[len - 1] << pos; |
224 | temp = (temp & ~mask) | ((value << pos) & mask); |
225 | return af9005_write_ofdm_register(d, reg, value: temp); |
226 | |
227 | } |
228 | |
229 | static int af9005_usb_read_tuner_registers(struct dvb_usb_device *d, |
230 | u16 reg, u8 * values, int len) |
231 | { |
232 | return af9005_generic_read_write(d, reg, |
233 | AF9005_CMD_READ, AF9005_TUNER_REG, |
234 | values, len); |
235 | } |
236 | |
237 | static int af9005_usb_write_tuner_registers(struct dvb_usb_device *d, |
238 | u16 reg, u8 * values, int len) |
239 | { |
240 | return af9005_generic_read_write(d, reg, |
241 | AF9005_CMD_WRITE, |
242 | AF9005_TUNER_REG, values, len); |
243 | } |
244 | |
245 | int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg, |
246 | u8 * values, int len) |
247 | { |
248 | /* don't let the name of this function mislead you: it's just used |
249 | as an interface from the firmware to the i2c bus. The actual |
250 | i2c addresses are contained in the data */ |
251 | int ret, i, done = 0, fail = 0; |
252 | u8 temp; |
253 | ret = af9005_usb_write_tuner_registers(d, reg, values, len); |
254 | if (ret) |
255 | return ret; |
256 | if (reg != 0xffff) { |
257 | /* check if write done (0xa40d bit 1) or fail (0xa40d bit 2) */ |
258 | for (i = 0; i < 200; i++) { |
259 | ret = |
260 | af9005_read_ofdm_register(d, |
261 | xd_I2C_i2c_m_status_wdat_done, |
262 | value: &temp); |
263 | if (ret) |
264 | return ret; |
265 | done = temp & (regmask[i2c_m_status_wdat_done_len - 1] |
266 | << i2c_m_status_wdat_done_pos); |
267 | if (done) |
268 | break; |
269 | fail = temp & (regmask[i2c_m_status_wdat_fail_len - 1] |
270 | << i2c_m_status_wdat_fail_pos); |
271 | if (fail) |
272 | break; |
273 | msleep(msecs: 50); |
274 | } |
275 | if (i == 200) |
276 | return -ETIMEDOUT; |
277 | if (fail) { |
278 | /* clear write fail bit */ |
279 | af9005_write_register_bits(d, |
280 | xd_I2C_i2c_m_status_wdat_fail, |
281 | i2c_m_status_wdat_fail_pos, |
282 | i2c_m_status_wdat_fail_len, |
283 | value: 1); |
284 | return -EIO; |
285 | } |
286 | /* clear write done bit */ |
287 | ret = |
288 | af9005_write_register_bits(d, |
289 | xd_I2C_i2c_m_status_wdat_fail, |
290 | i2c_m_status_wdat_done_pos, |
291 | i2c_m_status_wdat_done_len, value: 1); |
292 | if (ret) |
293 | return ret; |
294 | } |
295 | return 0; |
296 | } |
297 | |
298 | int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, u8 addr, |
299 | u8 * values, int len) |
300 | { |
301 | /* don't let the name of this function mislead you: it's just used |
302 | as an interface from the firmware to the i2c bus. The actual |
303 | i2c addresses are contained in the data */ |
304 | int ret, i; |
305 | u8 temp, buf[2]; |
306 | |
307 | buf[0] = addr; /* tuner i2c address */ |
308 | buf[1] = values[0]; /* tuner register */ |
309 | |
310 | values[0] = addr + 0x01; /* i2c read address */ |
311 | |
312 | if (reg == APO_REG_I2C_RW_SILICON_TUNER) { |
313 | /* write tuner i2c address to tuner, 0c00c0 undocumented, found by sniffing */ |
314 | ret = af9005_write_tuner_registers(d, reg: 0x00c0, values: buf, len: 2); |
315 | if (ret) |
316 | return ret; |
317 | } |
318 | |
319 | /* send read command to ofsm */ |
320 | ret = af9005_usb_read_tuner_registers(d, reg, values, len: 1); |
321 | if (ret) |
322 | return ret; |
323 | |
324 | /* check if read done */ |
325 | for (i = 0; i < 200; i++) { |
326 | ret = af9005_read_ofdm_register(d, reg: 0xa408, value: &temp); |
327 | if (ret) |
328 | return ret; |
329 | if (temp & 0x01) |
330 | break; |
331 | msleep(msecs: 50); |
332 | } |
333 | if (i == 200) |
334 | return -ETIMEDOUT; |
335 | |
336 | /* clear read done bit (by writing 1) */ |
337 | ret = af9005_write_ofdm_register(d, xd_I2C_i2c_m_data8, value: 1); |
338 | if (ret) |
339 | return ret; |
340 | |
341 | /* get read data (available from 0xa400) */ |
342 | for (i = 0; i < len; i++) { |
343 | ret = af9005_read_ofdm_register(d, reg: 0xa400 + i, value: &temp); |
344 | if (ret) |
345 | return ret; |
346 | values[i] = temp; |
347 | } |
348 | return 0; |
349 | } |
350 | |
351 | static int af9005_i2c_write(struct dvb_usb_device *d, u8 i2caddr, u8 reg, |
352 | u8 * data, int len) |
353 | { |
354 | int ret, i; |
355 | u8 buf[3]; |
356 | deb_i2c("i2c_write i2caddr %x, reg %x, len %d data " , i2caddr, |
357 | reg, len); |
358 | debug_dump(data, len, deb_i2c); |
359 | |
360 | for (i = 0; i < len; i++) { |
361 | buf[0] = i2caddr; |
362 | buf[1] = reg + (u8) i; |
363 | buf[2] = data[i]; |
364 | ret = |
365 | af9005_write_tuner_registers(d, |
366 | APO_REG_I2C_RW_SILICON_TUNER, |
367 | values: buf, len: 3); |
368 | if (ret) { |
369 | deb_i2c("i2c_write failed\n" ); |
370 | return ret; |
371 | } |
372 | } |
373 | deb_i2c("i2c_write ok\n" ); |
374 | return 0; |
375 | } |
376 | |
377 | static int af9005_i2c_read(struct dvb_usb_device *d, u8 i2caddr, u8 reg, |
378 | u8 * data, int len) |
379 | { |
380 | int ret, i; |
381 | u8 temp; |
382 | deb_i2c("i2c_read i2caddr %x, reg %x, len %d\n " , i2caddr, reg, len); |
383 | for (i = 0; i < len; i++) { |
384 | temp = reg + i; |
385 | ret = |
386 | af9005_read_tuner_registers(d, |
387 | APO_REG_I2C_RW_SILICON_TUNER, |
388 | addr: i2caddr, values: &temp, len: 1); |
389 | if (ret) { |
390 | deb_i2c("i2c_read failed\n" ); |
391 | return ret; |
392 | } |
393 | data[i] = temp; |
394 | } |
395 | deb_i2c("i2c data read: " ); |
396 | debug_dump(data, len, deb_i2c); |
397 | return 0; |
398 | } |
399 | |
400 | static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], |
401 | int num) |
402 | { |
403 | /* only implements what the mt2060 module does, don't know how |
404 | to make it really generic */ |
405 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
406 | int ret; |
407 | u8 reg, addr; |
408 | u8 *value; |
409 | |
410 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
411 | return -EAGAIN; |
412 | |
413 | if (num > 2) |
414 | warn("more than 2 i2c messages at a time is not handled yet. TODO." ); |
415 | |
416 | if (num == 2) { |
417 | /* reads a single register */ |
418 | reg = *msg[0].buf; |
419 | addr = msg[0].addr; |
420 | value = msg[1].buf; |
421 | ret = af9005_i2c_read(d, i2caddr: addr, reg, data: value, len: 1); |
422 | if (ret == 0) |
423 | ret = 2; |
424 | } else { |
425 | if (msg[0].len < 2) { |
426 | ret = -EOPNOTSUPP; |
427 | goto unlock; |
428 | } |
429 | /* write one or more registers */ |
430 | reg = msg[0].buf[0]; |
431 | addr = msg[0].addr; |
432 | value = &msg[0].buf[1]; |
433 | ret = af9005_i2c_write(d, i2caddr: addr, reg, data: value, len: msg[0].len - 1); |
434 | if (ret == 0) |
435 | ret = 1; |
436 | } |
437 | |
438 | unlock: |
439 | mutex_unlock(lock: &d->i2c_mutex); |
440 | return ret; |
441 | } |
442 | |
443 | static u32 af9005_i2c_func(struct i2c_adapter *adapter) |
444 | { |
445 | return I2C_FUNC_I2C; |
446 | } |
447 | |
448 | static struct i2c_algorithm af9005_i2c_algo = { |
449 | .master_xfer = af9005_i2c_xfer, |
450 | .functionality = af9005_i2c_func, |
451 | }; |
452 | |
453 | int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf, |
454 | int wlen, u8 * rbuf, int rlen) |
455 | { |
456 | struct af9005_device_state *st = d->priv; |
457 | |
458 | int ret, i, packet_len; |
459 | u8 seq; |
460 | |
461 | if (wlen < 0) { |
462 | err("send command, wlen less than 0 bytes. Makes no sense." ); |
463 | return -EINVAL; |
464 | } |
465 | if (wlen > 54) { |
466 | err("send command, wlen more than 54 bytes. Not supported." ); |
467 | return -EINVAL; |
468 | } |
469 | if (rlen > 54) { |
470 | err("send command, rlen more than 54 bytes. Not supported." ); |
471 | return -EINVAL; |
472 | } |
473 | packet_len = wlen + 5; |
474 | |
475 | mutex_lock(&d->data_mutex); |
476 | |
477 | st->data[0] = (u8) (packet_len & 0xff); |
478 | st->data[1] = (u8) ((packet_len & 0xff00) >> 8); |
479 | |
480 | st->data[2] = 0x26; /* packet type */ |
481 | st->data[3] = wlen + 3; |
482 | st->data[4] = seq = st->sequence++; |
483 | st->data[5] = command; |
484 | st->data[6] = wlen; |
485 | for (i = 0; i < wlen; i++) |
486 | st->data[7 + i] = wbuf[i]; |
487 | ret = dvb_usb_generic_rw(d, st->data, wlen + 7, st->data, rlen + 7, 0); |
488 | if (st->data[2] != 0x27) { |
489 | err("send command, wrong reply code." ); |
490 | ret = -EIO; |
491 | } else if (st->data[4] != seq) { |
492 | err("send command, wrong sequence in reply." ); |
493 | ret = -EIO; |
494 | } else if (st->data[5] != 0x01) { |
495 | err("send command, wrong status code in reply." ); |
496 | ret = -EIO; |
497 | } else if (st->data[6] != rlen) { |
498 | err("send command, invalid data length in reply." ); |
499 | ret = -EIO; |
500 | } |
501 | if (!ret) { |
502 | for (i = 0; i < rlen; i++) |
503 | rbuf[i] = st->data[i + 7]; |
504 | } |
505 | |
506 | mutex_unlock(lock: &d->data_mutex); |
507 | return ret; |
508 | } |
509 | |
510 | int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values, |
511 | int len) |
512 | { |
513 | struct af9005_device_state *st = d->priv; |
514 | u8 seq; |
515 | int ret, i; |
516 | |
517 | mutex_lock(&d->data_mutex); |
518 | |
519 | memset(st->data, 0, sizeof(st->data)); |
520 | |
521 | st->data[0] = 14; /* length of rest of packet low */ |
522 | st->data[1] = 0; /* length of rest of packer high */ |
523 | |
524 | st->data[2] = 0x2a; /* read/write eeprom */ |
525 | |
526 | st->data[3] = 12; /* size */ |
527 | |
528 | st->data[4] = seq = st->sequence++; |
529 | |
530 | st->data[5] = 0; /* read */ |
531 | |
532 | st->data[6] = len; |
533 | st->data[7] = address; |
534 | ret = dvb_usb_generic_rw(d, st->data, 16, st->data, 14, 0); |
535 | if (st->data[2] != 0x2b) { |
536 | err("Read eeprom, invalid reply code" ); |
537 | ret = -EIO; |
538 | } else if (st->data[3] != 10) { |
539 | err("Read eeprom, invalid reply length" ); |
540 | ret = -EIO; |
541 | } else if (st->data[4] != seq) { |
542 | err("Read eeprom, wrong sequence in reply " ); |
543 | ret = -EIO; |
544 | } else if (st->data[5] != 1) { |
545 | err("Read eeprom, wrong status in reply " ); |
546 | ret = -EIO; |
547 | } |
548 | |
549 | if (!ret) { |
550 | for (i = 0; i < len; i++) |
551 | values[i] = st->data[6 + i]; |
552 | } |
553 | mutex_unlock(lock: &d->data_mutex); |
554 | |
555 | return ret; |
556 | } |
557 | |
558 | static int af9005_boot_packet(struct usb_device *udev, int type, u8 *reply, |
559 | u8 *buf, int size) |
560 | { |
561 | u16 checksum; |
562 | int act_len = 0, i, ret; |
563 | |
564 | memset(buf, 0, size); |
565 | buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff); |
566 | buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff); |
567 | switch (type) { |
568 | case FW_CONFIG: |
569 | buf[2] = 0x11; |
570 | buf[3] = 0x04; |
571 | buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */ |
572 | buf[5] = 0x03; |
573 | checksum = buf[4] + buf[5]; |
574 | buf[6] = (u8) ((checksum >> 8) & 0xff); |
575 | buf[7] = (u8) (checksum & 0xff); |
576 | break; |
577 | case FW_CONFIRM: |
578 | buf[2] = 0x11; |
579 | buf[3] = 0x04; |
580 | buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */ |
581 | buf[5] = 0x01; |
582 | checksum = buf[4] + buf[5]; |
583 | buf[6] = (u8) ((checksum >> 8) & 0xff); |
584 | buf[7] = (u8) (checksum & 0xff); |
585 | break; |
586 | case FW_BOOT: |
587 | buf[2] = 0x10; |
588 | buf[3] = 0x08; |
589 | buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */ |
590 | buf[5] = 0x97; |
591 | buf[6] = 0xaa; |
592 | buf[7] = 0x55; |
593 | buf[8] = 0xa5; |
594 | buf[9] = 0x5a; |
595 | checksum = 0; |
596 | for (i = 4; i <= 9; i++) |
597 | checksum += buf[i]; |
598 | buf[10] = (u8) ((checksum >> 8) & 0xff); |
599 | buf[11] = (u8) (checksum & 0xff); |
600 | break; |
601 | default: |
602 | err("boot packet invalid boot packet type" ); |
603 | return -EINVAL; |
604 | } |
605 | deb_fw(">>> " ); |
606 | debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw); |
607 | |
608 | ret = usb_bulk_msg(usb_dev: udev, |
609 | usb_sndbulkpipe(udev, 0x02), |
610 | data: buf, FW_BULKOUT_SIZE + 2, actual_length: &act_len, timeout: 2000); |
611 | if (ret) |
612 | err("boot packet bulk message failed: %d (%d/%d)" , ret, |
613 | FW_BULKOUT_SIZE + 2, act_len); |
614 | else |
615 | ret = act_len != FW_BULKOUT_SIZE + 2 ? -1 : 0; |
616 | if (ret) |
617 | return ret; |
618 | memset(buf, 0, 9); |
619 | ret = usb_bulk_msg(usb_dev: udev, |
620 | usb_rcvbulkpipe(udev, 0x01), data: buf, len: 9, actual_length: &act_len, timeout: 2000); |
621 | if (ret) { |
622 | err("boot packet recv bulk message failed: %d" , ret); |
623 | return ret; |
624 | } |
625 | deb_fw("<<< " ); |
626 | debug_dump(buf, act_len, deb_fw); |
627 | checksum = 0; |
628 | switch (type) { |
629 | case FW_CONFIG: |
630 | if (buf[2] != 0x11) { |
631 | err("boot bad config header." ); |
632 | return -EIO; |
633 | } |
634 | if (buf[3] != 0x05) { |
635 | err("boot bad config size." ); |
636 | return -EIO; |
637 | } |
638 | if (buf[4] != 0x00) { |
639 | err("boot bad config sequence." ); |
640 | return -EIO; |
641 | } |
642 | if (buf[5] != 0x04) { |
643 | err("boot bad config subtype." ); |
644 | return -EIO; |
645 | } |
646 | for (i = 4; i <= 6; i++) |
647 | checksum += buf[i]; |
648 | if (buf[7] * 256 + buf[8] != checksum) { |
649 | err("boot bad config checksum." ); |
650 | return -EIO; |
651 | } |
652 | *reply = buf[6]; |
653 | break; |
654 | case FW_CONFIRM: |
655 | if (buf[2] != 0x11) { |
656 | err("boot bad confirm header." ); |
657 | return -EIO; |
658 | } |
659 | if (buf[3] != 0x05) { |
660 | err("boot bad confirm size." ); |
661 | return -EIO; |
662 | } |
663 | if (buf[4] != 0x00) { |
664 | err("boot bad confirm sequence." ); |
665 | return -EIO; |
666 | } |
667 | if (buf[5] != 0x02) { |
668 | err("boot bad confirm subtype." ); |
669 | return -EIO; |
670 | } |
671 | for (i = 4; i <= 6; i++) |
672 | checksum += buf[i]; |
673 | if (buf[7] * 256 + buf[8] != checksum) { |
674 | err("boot bad confirm checksum." ); |
675 | return -EIO; |
676 | } |
677 | *reply = buf[6]; |
678 | break; |
679 | case FW_BOOT: |
680 | if (buf[2] != 0x10) { |
681 | err("boot bad boot header." ); |
682 | return -EIO; |
683 | } |
684 | if (buf[3] != 0x05) { |
685 | err("boot bad boot size." ); |
686 | return -EIO; |
687 | } |
688 | if (buf[4] != 0x00) { |
689 | err("boot bad boot sequence." ); |
690 | return -EIO; |
691 | } |
692 | if (buf[5] != 0x01) { |
693 | err("boot bad boot pattern 01." ); |
694 | return -EIO; |
695 | } |
696 | if (buf[6] != 0x10) { |
697 | err("boot bad boot pattern 10." ); |
698 | return -EIO; |
699 | } |
700 | for (i = 4; i <= 6; i++) |
701 | checksum += buf[i]; |
702 | if (buf[7] * 256 + buf[8] != checksum) { |
703 | err("boot bad boot checksum." ); |
704 | return -EIO; |
705 | } |
706 | break; |
707 | |
708 | } |
709 | |
710 | return 0; |
711 | } |
712 | |
713 | static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw) |
714 | { |
715 | int i, packets, ret, act_len; |
716 | |
717 | u8 *buf; |
718 | u8 reply; |
719 | |
720 | buf = kmalloc(FW_BULKOUT_SIZE + 2, GFP_KERNEL); |
721 | if (!buf) |
722 | return -ENOMEM; |
723 | |
724 | ret = af9005_boot_packet(udev, type: FW_CONFIG, reply: &reply, buf, |
725 | FW_BULKOUT_SIZE + 2); |
726 | if (ret) |
727 | goto err; |
728 | if (reply != 0x01) { |
729 | err("before downloading firmware, FW_CONFIG expected 0x01, received 0x%x" , reply); |
730 | ret = -EIO; |
731 | goto err; |
732 | } |
733 | packets = fw->size / FW_BULKOUT_SIZE; |
734 | buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff); |
735 | buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff); |
736 | for (i = 0; i < packets; i++) { |
737 | memcpy(&buf[2], fw->data + i * FW_BULKOUT_SIZE, |
738 | FW_BULKOUT_SIZE); |
739 | deb_fw(">>> " ); |
740 | debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw); |
741 | ret = usb_bulk_msg(usb_dev: udev, |
742 | usb_sndbulkpipe(udev, 0x02), |
743 | data: buf, FW_BULKOUT_SIZE + 2, actual_length: &act_len, timeout: 1000); |
744 | if (ret) { |
745 | err("firmware download failed at packet %d with code %d" , i, ret); |
746 | goto err; |
747 | } |
748 | } |
749 | ret = af9005_boot_packet(udev, type: FW_CONFIRM, reply: &reply, |
750 | buf, FW_BULKOUT_SIZE + 2); |
751 | if (ret) |
752 | goto err; |
753 | if (reply != (u8) (packets & 0xff)) { |
754 | err("after downloading firmware, FW_CONFIRM expected 0x%x, received 0x%x" , packets & 0xff, reply); |
755 | ret = -EIO; |
756 | goto err; |
757 | } |
758 | ret = af9005_boot_packet(udev, type: FW_BOOT, reply: &reply, buf, |
759 | FW_BULKOUT_SIZE + 2); |
760 | if (ret) |
761 | goto err; |
762 | ret = af9005_boot_packet(udev, type: FW_CONFIG, reply: &reply, buf, |
763 | FW_BULKOUT_SIZE + 2); |
764 | if (ret) |
765 | goto err; |
766 | if (reply != 0x02) { |
767 | err("after downloading firmware, FW_CONFIG expected 0x02, received 0x%x" , reply); |
768 | ret = -EIO; |
769 | goto err; |
770 | } |
771 | |
772 | err: |
773 | kfree(objp: buf); |
774 | return ret; |
775 | |
776 | } |
777 | |
778 | int af9005_led_control(struct dvb_usb_device *d, int onoff) |
779 | { |
780 | struct af9005_device_state *st = d->priv; |
781 | int temp, ret; |
782 | |
783 | if (onoff && dvb_usb_af9005_led) |
784 | temp = 1; |
785 | else |
786 | temp = 0; |
787 | if (st->led_state != temp) { |
788 | ret = |
789 | af9005_write_register_bits(d, xd_p_reg_top_locken1, |
790 | reg_top_locken1_pos, |
791 | reg_top_locken1_len, value: temp); |
792 | if (ret) |
793 | return ret; |
794 | ret = |
795 | af9005_write_register_bits(d, xd_p_reg_top_lock1, |
796 | reg_top_lock1_pos, |
797 | reg_top_lock1_len, value: temp); |
798 | if (ret) |
799 | return ret; |
800 | st->led_state = temp; |
801 | } |
802 | return 0; |
803 | } |
804 | |
805 | static int af9005_frontend_attach(struct dvb_usb_adapter *adap) |
806 | { |
807 | u8 buf[8]; |
808 | int i; |
809 | |
810 | /* without these calls the first commands after downloading |
811 | the firmware fail. I put these calls here to simulate |
812 | what it is done in dvb-usb-init.c. |
813 | */ |
814 | struct usb_device *udev = adap->dev->udev; |
815 | usb_clear_halt(dev: udev, usb_sndbulkpipe(udev, 2)); |
816 | usb_clear_halt(dev: udev, usb_rcvbulkpipe(udev, 1)); |
817 | if (dvb_usb_af9005_dump_eeprom) { |
818 | printk("EEPROM DUMP\n" ); |
819 | for (i = 0; i < 255; i += 8) { |
820 | af9005_read_eeprom(d: adap->dev, address: i, values: buf, len: 8); |
821 | debug_dump(buf, 8, printk); |
822 | } |
823 | } |
824 | adap->fe_adap[0].fe = af9005_fe_attach(d: adap->dev); |
825 | return 0; |
826 | } |
827 | |
828 | static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state) |
829 | { |
830 | struct af9005_device_state *st = d->priv; |
831 | int ret, len; |
832 | u8 seq; |
833 | |
834 | *state = REMOTE_NO_KEY_PRESSED; |
835 | if (rc_decode == NULL) { |
836 | /* it shouldn't never come here */ |
837 | return 0; |
838 | } |
839 | |
840 | mutex_lock(&d->data_mutex); |
841 | |
842 | /* deb_info("rc_query\n"); */ |
843 | st->data[0] = 3; /* rest of packet length low */ |
844 | st->data[1] = 0; /* rest of packet length high */ |
845 | st->data[2] = 0x40; /* read remote */ |
846 | st->data[3] = 1; /* rest of packet length */ |
847 | st->data[4] = seq = st->sequence++; /* sequence number */ |
848 | ret = dvb_usb_generic_rw(d, st->data, 5, st->data, 256, 0); |
849 | if (ret) { |
850 | err("rc query failed" ); |
851 | goto ret; |
852 | } |
853 | if (st->data[2] != 0x41) { |
854 | err("rc query bad header." ); |
855 | ret = -EIO; |
856 | goto ret; |
857 | } else if (st->data[4] != seq) { |
858 | err("rc query bad sequence." ); |
859 | ret = -EIO; |
860 | goto ret; |
861 | } |
862 | len = st->data[5]; |
863 | if (len > 246) { |
864 | err("rc query invalid length" ); |
865 | ret = -EIO; |
866 | goto ret; |
867 | } |
868 | if (len > 0) { |
869 | deb_rc("rc data (%d) " , len); |
870 | debug_dump((st->data + 6), len, deb_rc); |
871 | ret = rc_decode(d, &st->data[6], len, event, state); |
872 | if (ret) { |
873 | err("rc_decode failed" ); |
874 | goto ret; |
875 | } else { |
876 | deb_rc("rc_decode state %x event %x\n" , *state, *event); |
877 | if (*state == REMOTE_KEY_REPEAT) |
878 | *event = d->last_event; |
879 | } |
880 | } |
881 | |
882 | ret: |
883 | mutex_unlock(lock: &d->data_mutex); |
884 | return ret; |
885 | } |
886 | |
887 | static int af9005_power_ctrl(struct dvb_usb_device *d, int onoff) |
888 | { |
889 | |
890 | return 0; |
891 | } |
892 | |
893 | static int af9005_pid_filter_control(struct dvb_usb_adapter *adap, int onoff) |
894 | { |
895 | int ret; |
896 | deb_info("pid filter control onoff %d\n" , onoff); |
897 | if (onoff) { |
898 | ret = |
899 | af9005_write_ofdm_register(d: adap->dev, XD_MP2IF_DMX_CTRL, value: 1); |
900 | if (ret) |
901 | return ret; |
902 | ret = |
903 | af9005_write_register_bits(d: adap->dev, |
904 | XD_MP2IF_DMX_CTRL, pos: 1, len: 1, value: 1); |
905 | if (ret) |
906 | return ret; |
907 | ret = |
908 | af9005_write_ofdm_register(d: adap->dev, XD_MP2IF_DMX_CTRL, value: 1); |
909 | } else |
910 | ret = |
911 | af9005_write_ofdm_register(d: adap->dev, XD_MP2IF_DMX_CTRL, value: 0); |
912 | if (ret) |
913 | return ret; |
914 | deb_info("pid filter control ok\n" ); |
915 | return 0; |
916 | } |
917 | |
918 | static int af9005_pid_filter(struct dvb_usb_adapter *adap, int index, |
919 | u16 pid, int onoff) |
920 | { |
921 | u8 cmd = index & 0x1f; |
922 | int ret; |
923 | deb_info("set pid filter, index %d, pid %x, onoff %d\n" , index, |
924 | pid, onoff); |
925 | if (onoff) { |
926 | /* cannot use it as pid_filter_ctrl since it has to be done |
927 | before setting the first pid */ |
928 | if (adap->feedcount == 1) { |
929 | deb_info("first pid set, enable pid table\n" ); |
930 | ret = af9005_pid_filter_control(adap, onoff); |
931 | if (ret) |
932 | return ret; |
933 | } |
934 | ret = |
935 | af9005_write_ofdm_register(d: adap->dev, |
936 | XD_MP2IF_PID_DATA_L, |
937 | value: (u8) (pid & 0xff)); |
938 | if (ret) |
939 | return ret; |
940 | ret = |
941 | af9005_write_ofdm_register(d: adap->dev, |
942 | XD_MP2IF_PID_DATA_H, |
943 | value: (u8) (pid >> 8)); |
944 | if (ret) |
945 | return ret; |
946 | cmd |= 0x20 | 0x40; |
947 | } else { |
948 | if (adap->feedcount == 0) { |
949 | deb_info("last pid unset, disable pid table\n" ); |
950 | ret = af9005_pid_filter_control(adap, onoff); |
951 | if (ret) |
952 | return ret; |
953 | } |
954 | } |
955 | ret = af9005_write_ofdm_register(d: adap->dev, XD_MP2IF_PID_IDX, value: cmd); |
956 | if (ret) |
957 | return ret; |
958 | deb_info("set pid ok\n" ); |
959 | return 0; |
960 | } |
961 | |
962 | static int af9005_identify_state(struct usb_device *udev, |
963 | const struct dvb_usb_device_properties *props, |
964 | const struct dvb_usb_device_description **desc, |
965 | int *cold) |
966 | { |
967 | int ret; |
968 | u8 reply, *buf; |
969 | |
970 | buf = kmalloc(FW_BULKOUT_SIZE + 2, GFP_KERNEL); |
971 | if (!buf) |
972 | return -ENOMEM; |
973 | |
974 | ret = af9005_boot_packet(udev, type: FW_CONFIG, reply: &reply, |
975 | buf, FW_BULKOUT_SIZE + 2); |
976 | if (ret) |
977 | goto err; |
978 | deb_info("result of FW_CONFIG in identify state %d\n" , reply); |
979 | if (reply == 0x01) |
980 | *cold = 1; |
981 | else if (reply == 0x02) |
982 | *cold = 0; |
983 | else |
984 | ret = -EIO; |
985 | if (!ret) |
986 | deb_info("Identify state cold = %d\n" , *cold); |
987 | |
988 | err: |
989 | kfree(objp: buf); |
990 | return ret; |
991 | } |
992 | |
993 | static struct dvb_usb_device_properties af9005_properties; |
994 | |
995 | static int af9005_usb_probe(struct usb_interface *intf, |
996 | const struct usb_device_id *id) |
997 | { |
998 | return dvb_usb_device_init(intf, &af9005_properties, |
999 | THIS_MODULE, NULL, adapter_nums: adapter_nr); |
1000 | } |
1001 | |
1002 | enum { |
1003 | AFATECH_AF9005, |
1004 | TERRATEC_CINERGY_T_USB_XE, |
1005 | ANSONIC_DVBT_USB, |
1006 | }; |
1007 | |
1008 | static struct usb_device_id af9005_usb_table[] = { |
1009 | DVB_USB_DEV(AFATECH, AFATECH_AF9005), |
1010 | DVB_USB_DEV(TERRATEC, TERRATEC_CINERGY_T_USB_XE), |
1011 | DVB_USB_DEV(ANSONIC, ANSONIC_DVBT_USB), |
1012 | { } |
1013 | }; |
1014 | |
1015 | MODULE_DEVICE_TABLE(usb, af9005_usb_table); |
1016 | |
1017 | static struct dvb_usb_device_properties af9005_properties = { |
1018 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
1019 | |
1020 | .usb_ctrl = DEVICE_SPECIFIC, |
1021 | .firmware = "af9005.fw" , |
1022 | .download_firmware = af9005_download_firmware, |
1023 | .no_reconnect = 1, |
1024 | |
1025 | .size_of_priv = sizeof(struct af9005_device_state), |
1026 | |
1027 | .num_adapters = 1, |
1028 | .adapter = { |
1029 | { |
1030 | .num_frontends = 1, |
1031 | .fe = {{ |
1032 | .caps = |
1033 | DVB_USB_ADAP_HAS_PID_FILTER | |
1034 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, |
1035 | .pid_filter_count = 32, |
1036 | .pid_filter = af9005_pid_filter, |
1037 | /* .pid_filter_ctrl = af9005_pid_filter_control, */ |
1038 | .frontend_attach = af9005_frontend_attach, |
1039 | /* .tuner_attach = af9005_tuner_attach, */ |
1040 | /* parameter for the MPEG2-data transfer */ |
1041 | .stream = { |
1042 | .type = USB_BULK, |
1043 | .count = 10, |
1044 | .endpoint = 0x04, |
1045 | .u = { |
1046 | .bulk = { |
1047 | .buffersize = 4096, /* actual size seen is 3948 */ |
1048 | } |
1049 | } |
1050 | }, |
1051 | }}, |
1052 | } |
1053 | }, |
1054 | .power_ctrl = af9005_power_ctrl, |
1055 | .identify_state = af9005_identify_state, |
1056 | |
1057 | .i2c_algo = &af9005_i2c_algo, |
1058 | |
1059 | .rc.legacy = { |
1060 | .rc_interval = 200, |
1061 | .rc_map_table = NULL, |
1062 | .rc_map_size = 0, |
1063 | .rc_query = af9005_rc_query, |
1064 | }, |
1065 | |
1066 | .generic_bulk_ctrl_endpoint = 2, |
1067 | .generic_bulk_ctrl_endpoint_response = 1, |
1068 | |
1069 | .num_device_descs = 3, |
1070 | .devices = { |
1071 | {.name = "Afatech DVB-T USB1.1 stick" , |
1072 | .cold_ids = {&af9005_usb_table[AFATECH_AF9005], NULL}, |
1073 | .warm_ids = {NULL}, |
1074 | }, |
1075 | {.name = "TerraTec Cinergy T USB XE" , |
1076 | .cold_ids = {&af9005_usb_table[TERRATEC_CINERGY_T_USB_XE], NULL}, |
1077 | .warm_ids = {NULL}, |
1078 | }, |
1079 | {.name = "Ansonic DVB-T USB1.1 stick" , |
1080 | .cold_ids = {&af9005_usb_table[ANSONIC_DVBT_USB], NULL}, |
1081 | .warm_ids = {NULL}, |
1082 | }, |
1083 | {NULL}, |
1084 | } |
1085 | }; |
1086 | |
1087 | /* usb specific object needed to register this driver with the usb subsystem */ |
1088 | static struct usb_driver af9005_usb_driver = { |
1089 | .name = "dvb_usb_af9005" , |
1090 | .probe = af9005_usb_probe, |
1091 | .disconnect = dvb_usb_device_exit, |
1092 | .id_table = af9005_usb_table, |
1093 | }; |
1094 | |
1095 | /* module stuff */ |
1096 | static int __init af9005_usb_module_init(void) |
1097 | { |
1098 | int result; |
1099 | if ((result = usb_register(&af9005_usb_driver))) { |
1100 | err("usb_register failed. (%d)" , result); |
1101 | return result; |
1102 | } |
1103 | #if IS_MODULE(CONFIG_DVB_USB_AF9005) || defined(CONFIG_DVB_USB_AF9005_REMOTE) |
1104 | /* FIXME: convert to todays kernel IR infrastructure */ |
1105 | rc_decode = symbol_request(af9005_rc_decode); |
1106 | rc_keys = symbol_request(rc_map_af9005_table); |
1107 | rc_keys_size = symbol_request(rc_map_af9005_table_size); |
1108 | #endif |
1109 | if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) { |
1110 | err("af9005_rc_decode function not found, disabling remote" ); |
1111 | af9005_properties.rc.legacy.rc_query = NULL; |
1112 | } else { |
1113 | af9005_properties.rc.legacy.rc_map_table = rc_keys; |
1114 | af9005_properties.rc.legacy.rc_map_size = *rc_keys_size; |
1115 | } |
1116 | |
1117 | return 0; |
1118 | } |
1119 | |
1120 | static void __exit af9005_usb_module_exit(void) |
1121 | { |
1122 | /* release rc decode symbols */ |
1123 | if (rc_decode != NULL) |
1124 | symbol_put(af9005_rc_decode); |
1125 | if (rc_keys != NULL) |
1126 | symbol_put(rc_map_af9005_table); |
1127 | if (rc_keys_size != NULL) |
1128 | symbol_put(rc_map_af9005_table_size); |
1129 | /* deregister this driver from the USB subsystem */ |
1130 | usb_deregister(&af9005_usb_driver); |
1131 | } |
1132 | |
1133 | module_init(af9005_usb_module_init); |
1134 | module_exit(af9005_usb_module_exit); |
1135 | |
1136 | MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>" ); |
1137 | MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick" ); |
1138 | MODULE_VERSION("1.0" ); |
1139 | MODULE_LICENSE("GPL" ); |
1140 | |