Commit | Line | Data |
---|---|---|
80619de8 AP |
1 | /* |
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 | ||
24 | #include "af9015.h" | |
80619de8 | 25 | |
349d042f | 26 | static int dvb_usb_af9015_remote; |
80619de8 AP |
27 | module_param_named(remote, dvb_usb_af9015_remote, int, 0644); |
28 | MODULE_PARM_DESC(remote, "select remote"); | |
80619de8 AP |
29 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
30 | ||
a3645e54 | 31 | static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) |
80619de8 | 32 | { |
06565d7a AP |
33 | #define REQ_HDR_LEN 8 /* send header size */ |
34 | #define ACK_HDR_LEN 2 /* rece header size */ | |
e8089661 | 35 | struct af9015_state *state = d_to_priv(d); |
a3645e54 | 36 | int ret, wlen, rlen; |
80619de8 | 37 | u8 write = 1; |
80619de8 | 38 | |
aff8c2d4 AP |
39 | mutex_lock(&d->usb_mutex); |
40 | ||
41 | state->buf[0] = req->cmd; | |
42 | state->buf[1] = state->seq++; | |
43 | state->buf[2] = req->i2c_addr; | |
44 | state->buf[3] = req->addr >> 8; | |
45 | state->buf[4] = req->addr & 0xff; | |
46 | state->buf[5] = req->mbox; | |
47 | state->buf[6] = req->addr_len; | |
48 | state->buf[7] = req->data_len; | |
80619de8 AP |
49 | |
50 | switch (req->cmd) { | |
51 | case GET_CONFIG: | |
80619de8 AP |
52 | case READ_MEMORY: |
53 | case RECONNECT_USB: | |
80619de8 AP |
54 | write = 0; |
55 | break; | |
56 | case READ_I2C: | |
57 | write = 0; | |
aff8c2d4 | 58 | state->buf[2] |= 0x01; /* set I2C direction */ |
80619de8 | 59 | case WRITE_I2C: |
aff8c2d4 | 60 | state->buf[0] = READ_WRITE_I2C; |
80619de8 AP |
61 | break; |
62 | case WRITE_MEMORY: | |
63 | if (((req->addr & 0xff00) == 0xff00) || | |
f4e96deb | 64 | ((req->addr & 0xff00) == 0xae00)) |
aff8c2d4 | 65 | state->buf[0] = WRITE_VIRTUAL_MEMORY; |
80619de8 AP |
66 | case WRITE_VIRTUAL_MEMORY: |
67 | case COPY_FIRMWARE: | |
68 | case DOWNLOAD_FIRMWARE: | |
ba1bc642 | 69 | case BOOT: |
80619de8 AP |
70 | break; |
71 | default: | |
f224749b AP |
72 | dev_err(&d->udev->dev, "%s: unknown command=%d\n", |
73 | KBUILD_MODNAME, req->cmd); | |
e1e9e510 | 74 | ret = -EIO; |
a3645e54 | 75 | goto error; |
80619de8 AP |
76 | } |
77 | ||
06565d7a AP |
78 | /* buffer overflow check */ |
79 | if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) || | |
f224749b AP |
80 | (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) { |
81 | dev_err(&d->udev->dev, "%s: too much data; cmd=%d len=%d\n", | |
82 | KBUILD_MODNAME, req->cmd, req->data_len); | |
06565d7a | 83 | ret = -EINVAL; |
a3645e54 | 84 | goto error; |
06565d7a AP |
85 | } |
86 | ||
a3645e54 AP |
87 | /* write receives seq + status = 2 bytes |
88 | read receives seq + status + data = 2 + N bytes */ | |
89 | wlen = REQ_HDR_LEN; | |
90 | rlen = ACK_HDR_LEN; | |
80619de8 | 91 | if (write) { |
a3645e54 | 92 | wlen += req->data_len; |
aff8c2d4 | 93 | memcpy(&state->buf[REQ_HDR_LEN], req->data, req->data_len); |
a3645e54 AP |
94 | } else { |
95 | rlen += req->data_len; | |
80619de8 | 96 | } |
06565d7a | 97 | |
a3645e54 | 98 | /* no ack for these packets */ |
80619de8 | 99 | if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB) |
a3645e54 | 100 | rlen = 0; |
80619de8 | 101 | |
aff8c2d4 AP |
102 | ret = dvb_usbv2_generic_rw_locked(d, |
103 | state->buf, wlen, state->buf, rlen); | |
a3645e54 AP |
104 | if (ret) |
105 | goto error; | |
80619de8 | 106 | |
80619de8 | 107 | /* check status */ |
aff8c2d4 | 108 | if (rlen && state->buf[1]) { |
f224749b | 109 | dev_err(&d->udev->dev, "%s: command failed=%d\n", |
aff8c2d4 | 110 | KBUILD_MODNAME, state->buf[1]); |
e1e9e510 | 111 | ret = -EIO; |
a3645e54 | 112 | goto error; |
80619de8 AP |
113 | } |
114 | ||
115 | /* read request, copy returned data to return buf */ | |
116 | if (!write) | |
aff8c2d4 | 117 | memcpy(req->data, &state->buf[ACK_HDR_LEN], req->data_len); |
a3645e54 | 118 | error: |
aff8c2d4 AP |
119 | mutex_unlock(&d->usb_mutex); |
120 | ||
80619de8 AP |
121 | return ret; |
122 | } | |
123 | ||
80619de8 AP |
124 | static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val, |
125 | u8 len) | |
126 | { | |
127 | struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, | |
128 | val}; | |
129 | return af9015_ctrl_msg(d, &req); | |
130 | } | |
131 | ||
74c8e3ad | 132 | static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len) |
80619de8 | 133 | { |
74c8e3ad AP |
134 | struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, |
135 | val}; | |
80619de8 AP |
136 | return af9015_ctrl_msg(d, &req); |
137 | } | |
138 | ||
a3645e54 AP |
139 | static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val) |
140 | { | |
141 | return af9015_write_regs(d, addr, &val, 1); | |
142 | } | |
143 | ||
74c8e3ad AP |
144 | static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) |
145 | { | |
146 | return af9015_read_regs(d, addr, val, 1); | |
147 | } | |
148 | ||
80619de8 AP |
149 | static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, |
150 | u8 val) | |
151 | { | |
e8089661 | 152 | struct af9015_state *state = d_to_priv(d); |
80619de8 AP |
153 | struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val}; |
154 | ||
a3645e54 AP |
155 | if (addr == state->af9013_config[0].i2c_addr || |
156 | addr == state->af9013_config[1].i2c_addr) | |
80619de8 AP |
157 | req.addr_len = 3; |
158 | ||
159 | return af9015_ctrl_msg(d, &req); | |
160 | } | |
161 | ||
162 | static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, | |
163 | u8 *val) | |
164 | { | |
e8089661 | 165 | struct af9015_state *state = d_to_priv(d); |
80619de8 AP |
166 | struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; |
167 | ||
a3645e54 AP |
168 | if (addr == state->af9013_config[0].i2c_addr || |
169 | addr == state->af9013_config[1].i2c_addr) | |
80619de8 AP |
170 | req.addr_len = 3; |
171 | ||
172 | return af9015_ctrl_msg(d, &req); | |
173 | } | |
174 | ||
a3645e54 AP |
175 | static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op) |
176 | { | |
177 | int ret; | |
178 | u8 val, mask = 0x01; | |
179 | ||
180 | ret = af9015_read_reg(d, addr, &val); | |
181 | if (ret) | |
182 | return ret; | |
183 | ||
184 | mask <<= bit; | |
185 | if (op) { | |
186 | /* set bit */ | |
187 | val |= mask; | |
188 | } else { | |
189 | /* clear bit */ | |
190 | mask ^= 0xff; | |
191 | val &= mask; | |
192 | } | |
193 | ||
194 | return af9015_write_reg(d, addr, val); | |
195 | } | |
196 | ||
197 | static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) | |
198 | { | |
199 | return af9015_do_reg_bit(d, addr, bit, 1); | |
200 | } | |
201 | ||
202 | static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) | |
203 | { | |
204 | return af9015_do_reg_bit(d, addr, bit, 0); | |
205 | } | |
206 | ||
80619de8 AP |
207 | static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], |
208 | int num) | |
209 | { | |
210 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | |
e8089661 | 211 | struct af9015_state *state = d_to_priv(d); |
80619de8 AP |
212 | int ret = 0, i = 0; |
213 | u16 addr; | |
675375d7 | 214 | u8 uninitialized_var(mbox), addr_len; |
80619de8 AP |
215 | struct req_t req; |
216 | ||
bc050e67 | 217 | /* |
80619de8 AP |
218 | The bus lock is needed because there is two tuners both using same I2C-address. |
219 | Due to that the only way to select correct tuner is use demodulator I2C-gate. | |
220 | ||
221 | ................................................ | |
222 | . AF9015 includes integrated AF9013 demodulator. | |
223 | . ____________ ____________ . ____________ | |
224 | .| uC | | demod | . | tuner | | |
225 | .|------------| |------------| . |------------| | |
226 | .| AF9015 | | AF9013/5 | . | MXL5003 | | |
227 | .| |--+----I2C-------|-----/ -----|-.-----I2C-------| | | |
228 | .| | | | addr 0x38 | . | addr 0xc6 | | |
229 | .|____________| | |____________| . |____________| | |
230 | .................|.............................. | |
231 | | ____________ ____________ | |
232 | | | demod | | tuner | | |
233 | | |------------| |------------| | |
234 | | | AF9013 | | MXL5003 | | |
235 | +----I2C-------|-----/ -----|-------I2C-------| | | |
236 | | addr 0x3a | | addr 0xc6 | | |
237 | |____________| |____________| | |
238 | */ | |
239 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | |
240 | return -EAGAIN; | |
241 | ||
242 | while (i < num) { | |
a3645e54 AP |
243 | if (msg[i].addr == state->af9013_config[0].i2c_addr || |
244 | msg[i].addr == state->af9013_config[1].i2c_addr) { | |
80619de8 AP |
245 | addr = msg[i].buf[0] << 8; |
246 | addr += msg[i].buf[1]; | |
247 | mbox = msg[i].buf[2]; | |
248 | addr_len = 3; | |
249 | } else { | |
250 | addr = msg[i].buf[0]; | |
251 | addr_len = 1; | |
675375d7 | 252 | /* mbox is don't care in that case */ |
80619de8 AP |
253 | } |
254 | ||
255 | if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { | |
709d9208 AP |
256 | if (msg[i].len > 3 || msg[i+1].len > 61) { |
257 | ret = -EOPNOTSUPP; | |
258 | goto error; | |
259 | } | |
a3645e54 | 260 | if (msg[i].addr == state->af9013_config[0].i2c_addr) |
80619de8 AP |
261 | req.cmd = READ_MEMORY; |
262 | else | |
263 | req.cmd = READ_I2C; | |
264 | req.i2c_addr = msg[i].addr; | |
265 | req.addr = addr; | |
266 | req.mbox = mbox; | |
267 | req.addr_len = addr_len; | |
268 | req.data_len = msg[i+1].len; | |
269 | req.data = &msg[i+1].buf[0]; | |
270 | ret = af9015_ctrl_msg(d, &req); | |
271 | i += 2; | |
d5633998 | 272 | } else if (msg[i].flags & I2C_M_RD) { |
709d9208 AP |
273 | if (msg[i].len > 61) { |
274 | ret = -EOPNOTSUPP; | |
275 | goto error; | |
276 | } | |
a3645e54 | 277 | if (msg[i].addr == state->af9013_config[0].i2c_addr) { |
16b2dc2a | 278 | ret = -EINVAL; |
d5633998 | 279 | goto error; |
16b2dc2a AP |
280 | } |
281 | req.cmd = READ_I2C; | |
d5633998 JF |
282 | req.i2c_addr = msg[i].addr; |
283 | req.addr = addr; | |
284 | req.mbox = mbox; | |
285 | req.addr_len = addr_len; | |
286 | req.data_len = msg[i].len; | |
287 | req.data = &msg[i].buf[0]; | |
288 | ret = af9015_ctrl_msg(d, &req); | |
289 | i += 1; | |
80619de8 | 290 | } else { |
709d9208 AP |
291 | if (msg[i].len > 21) { |
292 | ret = -EOPNOTSUPP; | |
293 | goto error; | |
294 | } | |
a3645e54 | 295 | if (msg[i].addr == state->af9013_config[0].i2c_addr) |
80619de8 AP |
296 | req.cmd = WRITE_MEMORY; |
297 | else | |
298 | req.cmd = WRITE_I2C; | |
299 | req.i2c_addr = msg[i].addr; | |
300 | req.addr = addr; | |
301 | req.mbox = mbox; | |
302 | req.addr_len = addr_len; | |
303 | req.data_len = msg[i].len-addr_len; | |
304 | req.data = &msg[i].buf[addr_len]; | |
305 | ret = af9015_ctrl_msg(d, &req); | |
306 | i += 1; | |
307 | } | |
308 | if (ret) | |
309 | goto error; | |
310 | ||
311 | } | |
312 | ret = i; | |
313 | ||
314 | error: | |
315 | mutex_unlock(&d->i2c_mutex); | |
316 | ||
317 | return ret; | |
318 | } | |
319 | ||
320 | static u32 af9015_i2c_func(struct i2c_adapter *adapter) | |
321 | { | |
322 | return I2C_FUNC_I2C; | |
323 | } | |
324 | ||
325 | static struct i2c_algorithm af9015_i2c_algo = { | |
326 | .master_xfer = af9015_i2c_xfer, | |
327 | .functionality = af9015_i2c_func, | |
328 | }; | |
329 | ||
a0921af7 | 330 | static int af9015_identify_state(struct dvb_usb_device *d, const char **name) |
80619de8 AP |
331 | { |
332 | int ret; | |
a3645e54 AP |
333 | u8 reply; |
334 | struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply}; | |
80619de8 | 335 | |
a3645e54 | 336 | ret = af9015_ctrl_msg(d, &req); |
80619de8 AP |
337 | if (ret) |
338 | return ret; | |
339 | ||
f224749b AP |
340 | dev_dbg(&d->udev->dev, "%s: reply=%02x\n", __func__, reply); |
341 | ||
a3645e54 AP |
342 | if (reply == 0x02) |
343 | ret = WARM; | |
344 | else | |
345 | ret = COLD; | |
80619de8 | 346 | |
a3645e54 | 347 | return ret; |
80619de8 AP |
348 | } |
349 | ||
a3645e54 AP |
350 | static int af9015_download_firmware(struct dvb_usb_device *d, |
351 | const struct firmware *fw) | |
80619de8 | 352 | { |
e8089661 | 353 | struct af9015_state *state = d_to_priv(d); |
a3645e54 AP |
354 | int i, len, remaining, ret; |
355 | struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; | |
356 | u16 checksum = 0; | |
f224749b | 357 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
80619de8 | 358 | |
a3645e54 AP |
359 | /* calc checksum */ |
360 | for (i = 0; i < fw->size; i++) | |
361 | checksum += fw->data[i]; | |
80619de8 | 362 | |
a3645e54 AP |
363 | state->firmware_size = fw->size; |
364 | state->firmware_checksum = checksum; | |
80619de8 | 365 | |
a3645e54 AP |
366 | #define FW_ADDR 0x5100 /* firmware start address */ |
367 | #define LEN_MAX 55 /* max packet size */ | |
368 | for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) { | |
369 | len = remaining; | |
370 | if (len > LEN_MAX) | |
371 | len = LEN_MAX; | |
80619de8 | 372 | |
a3645e54 AP |
373 | req.data_len = len; |
374 | req.data = (u8 *) &fw->data[fw->size - remaining]; | |
375 | req.addr = FW_ADDR + fw->size - remaining; | |
80619de8 | 376 | |
a3645e54 AP |
377 | ret = af9015_ctrl_msg(d, &req); |
378 | if (ret) { | |
f224749b AP |
379 | dev_err(&d->udev->dev, |
380 | "%s: firmware download failed=%d\n", | |
381 | KBUILD_MODNAME, ret); | |
a3645e54 AP |
382 | goto error; |
383 | } | |
80619de8 AP |
384 | } |
385 | ||
a3645e54 AP |
386 | /* firmware loaded, request boot */ |
387 | req.cmd = BOOT; | |
388 | req.data_len = 0; | |
389 | ret = af9015_ctrl_msg(d, &req); | |
390 | if (ret) { | |
f224749b AP |
391 | dev_err(&d->udev->dev, "%s: firmware boot failed=%d\n", |
392 | KBUILD_MODNAME, ret); | |
80619de8 | 393 | goto error; |
80619de8 | 394 | } |
a3645e54 AP |
395 | |
396 | error: | |
397 | return ret; | |
398 | } | |
399 | ||
65e2f1cb MCC |
400 | #define AF9015_EEPROM_SIZE 256 |
401 | ||
a3645e54 AP |
402 | /* hash (and dump) eeprom */ |
403 | static int af9015_eeprom_hash(struct dvb_usb_device *d) | |
404 | { | |
e8089661 | 405 | struct af9015_state *state = d_to_priv(d); |
2e35c66f | 406 | int ret, i; |
2e35c66f AP |
407 | u8 buf[AF9015_EEPROM_SIZE]; |
408 | struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, NULL}; | |
409 | ||
410 | /* read eeprom */ | |
411 | for (i = 0; i < AF9015_EEPROM_SIZE; i++) { | |
412 | req.addr = i; | |
413 | req.data = &buf[i]; | |
a3645e54 | 414 | ret = af9015_ctrl_msg(d, &req); |
2e35c66f AP |
415 | if (ret < 0) |
416 | goto err; | |
80619de8 | 417 | } |
a3645e54 | 418 | |
2e35c66f AP |
419 | /* calculate checksum */ |
420 | for (i = 0; i < AF9015_EEPROM_SIZE / sizeof(u32); i++) { | |
a3645e54 | 421 | state->eeprom_sum *= GOLDEN_RATIO_PRIME_32; |
74426324 | 422 | state->eeprom_sum += le32_to_cpu(((__le32 *)buf)[i]); |
80619de8 AP |
423 | } |
424 | ||
2e35c66f AP |
425 | for (i = 0; i < AF9015_EEPROM_SIZE; i += 16) |
426 | dev_dbg(&d->udev->dev, "%s: %*ph\n", __func__, 16, buf + i); | |
427 | ||
f224749b AP |
428 | dev_dbg(&d->udev->dev, "%s: eeprom sum=%.8x\n", |
429 | __func__, state->eeprom_sum); | |
2e35c66f AP |
430 | return 0; |
431 | err: | |
432 | dev_err(&d->udev->dev, "%s: eeprom failed=%d\n", KBUILD_MODNAME, ret); | |
80619de8 AP |
433 | return ret; |
434 | } | |
435 | ||
a3645e54 | 436 | static int af9015_read_config(struct dvb_usb_device *d) |
80619de8 | 437 | { |
e8089661 | 438 | struct af9015_state *state = d_to_priv(d); |
80619de8 | 439 | int ret; |
a3645e54 AP |
440 | u8 val, i, offset = 0; |
441 | struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; | |
80619de8 | 442 | |
f224749b | 443 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
80619de8 | 444 | |
a3645e54 AP |
445 | /* IR remote controller */ |
446 | req.addr = AF9015_EEPROM_IR_MODE; | |
447 | /* first message will timeout often due to possible hw bug */ | |
448 | for (i = 0; i < 4; i++) { | |
449 | ret = af9015_ctrl_msg(d, &req); | |
450 | if (!ret) | |
451 | break; | |
452 | } | |
453 | if (ret) | |
454 | goto error; | |
80619de8 | 455 | |
a3645e54 | 456 | ret = af9015_eeprom_hash(d); |
80619de8 AP |
457 | if (ret) |
458 | goto error; | |
80619de8 | 459 | |
a3645e54 | 460 | state->ir_mode = val; |
f224749b | 461 | dev_dbg(&d->udev->dev, "%s: IR mode=%d\n", __func__, val); |
80619de8 | 462 | |
a3645e54 AP |
463 | /* TS mode - one or two receivers */ |
464 | req.addr = AF9015_EEPROM_TS_MODE; | |
80619de8 | 465 | ret = af9015_ctrl_msg(d, &req); |
80619de8 AP |
466 | if (ret) |
467 | goto error; | |
6c614044 | 468 | |
a3645e54 | 469 | state->dual_mode = val; |
f224749b | 470 | dev_dbg(&d->udev->dev, "%s: TS mode=%d\n", __func__, state->dual_mode); |
6c614044 | 471 | |
a3645e54 AP |
472 | /* disable 2nd adapter because we don't have PID-filters */ |
473 | if (d->udev->speed == USB_SPEED_FULL) | |
474 | state->dual_mode = 0; | |
80619de8 | 475 | |
a3645e54 | 476 | if (state->dual_mode) { |
80619de8 AP |
477 | /* read 2nd demodulator I2C address */ |
478 | req.addr = AF9015_EEPROM_DEMOD2_I2C; | |
a3645e54 | 479 | ret = af9015_ctrl_msg(d, &req); |
80619de8 AP |
480 | if (ret) |
481 | goto error; | |
80619de8 | 482 | |
a3645e54 | 483 | state->af9013_config[1].i2c_addr = val; |
80619de8 AP |
484 | } |
485 | ||
a3645e54 | 486 | for (i = 0; i < state->dual_mode + 1; i++) { |
80619de8 AP |
487 | if (i == 1) |
488 | offset = AF9015_EEPROM_OFFSET; | |
489 | /* xtal */ | |
490 | req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset; | |
a3645e54 | 491 | ret = af9015_ctrl_msg(d, &req); |
80619de8 AP |
492 | if (ret) |
493 | goto error; | |
494 | switch (val) { | |
495 | case 0: | |
a3645e54 | 496 | state->af9013_config[i].clock = 28800000; |
80619de8 AP |
497 | break; |
498 | case 1: | |
a3645e54 | 499 | state->af9013_config[i].clock = 20480000; |
80619de8 AP |
500 | break; |
501 | case 2: | |
a3645e54 | 502 | state->af9013_config[i].clock = 28000000; |
80619de8 AP |
503 | break; |
504 | case 3: | |
a3645e54 | 505 | state->af9013_config[i].clock = 25000000; |
80619de8 | 506 | break; |
c2c1b415 | 507 | } |
f224749b AP |
508 | dev_dbg(&d->udev->dev, "%s: [%d] xtal=%d set clock=%d\n", |
509 | __func__, i, val, | |
510 | state->af9013_config[i].clock); | |
80619de8 | 511 | |
f571e004 | 512 | /* IF frequency */ |
80619de8 | 513 | req.addr = AF9015_EEPROM_IF1H + offset; |
a3645e54 | 514 | ret = af9015_ctrl_msg(d, &req); |
80619de8 AP |
515 | if (ret) |
516 | goto error; | |
f571e004 | 517 | |
a3645e54 | 518 | state->af9013_config[i].if_frequency = val << 8; |
f571e004 | 519 | |
80619de8 | 520 | req.addr = AF9015_EEPROM_IF1L + offset; |
a3645e54 | 521 | ret = af9015_ctrl_msg(d, &req); |
80619de8 AP |
522 | if (ret) |
523 | goto error; | |
f571e004 | 524 | |
a3645e54 AP |
525 | state->af9013_config[i].if_frequency += val; |
526 | state->af9013_config[i].if_frequency *= 1000; | |
f224749b AP |
527 | dev_dbg(&d->udev->dev, "%s: [%d] IF frequency=%d\n", __func__, |
528 | i, state->af9013_config[i].if_frequency); | |
80619de8 AP |
529 | |
530 | /* MT2060 IF1 */ | |
531 | req.addr = AF9015_EEPROM_MT2060_IF1H + offset; | |
a3645e54 | 532 | ret = af9015_ctrl_msg(d, &req); |
80619de8 AP |
533 | if (ret) |
534 | goto error; | |
a3645e54 | 535 | state->mt2060_if1[i] = val << 8; |
80619de8 | 536 | req.addr = AF9015_EEPROM_MT2060_IF1L + offset; |
a3645e54 | 537 | ret = af9015_ctrl_msg(d, &req); |
80619de8 AP |
538 | if (ret) |
539 | goto error; | |
a3645e54 | 540 | state->mt2060_if1[i] += val; |
f224749b | 541 | dev_dbg(&d->udev->dev, "%s: [%d] MT2060 IF1=%d\n", __func__, i, |
a3645e54 | 542 | state->mt2060_if1[i]); |
80619de8 AP |
543 | |
544 | /* tuner */ | |
545 | req.addr = AF9015_EEPROM_TUNER_ID1 + offset; | |
a3645e54 | 546 | ret = af9015_ctrl_msg(d, &req); |
80619de8 AP |
547 | if (ret) |
548 | goto error; | |
549 | switch (val) { | |
550 | case AF9013_TUNER_ENV77H11D5: | |
551 | case AF9013_TUNER_MT2060: | |
80619de8 AP |
552 | case AF9013_TUNER_QT1010: |
553 | case AF9013_TUNER_UNKNOWN: | |
554 | case AF9013_TUNER_MT2060_2: | |
555 | case AF9013_TUNER_TDA18271: | |
556 | case AF9013_TUNER_QT1010A: | |
ee3d440c | 557 | case AF9013_TUNER_TDA18218: |
a3645e54 | 558 | state->af9013_config[i].spec_inv = 1; |
80619de8 AP |
559 | break; |
560 | case AF9013_TUNER_MXL5003D: | |
561 | case AF9013_TUNER_MXL5005D: | |
562 | case AF9013_TUNER_MXL5005R: | |
ab07fdd6 | 563 | case AF9013_TUNER_MXL5007T: |
a3645e54 | 564 | state->af9013_config[i].spec_inv = 0; |
80619de8 | 565 | break; |
d5633998 | 566 | case AF9013_TUNER_MC44S803: |
a3645e54 AP |
567 | state->af9013_config[i].gpio[1] = AF9013_GPIO_LO; |
568 | state->af9013_config[i].spec_inv = 1; | |
d5633998 | 569 | break; |
80619de8 | 570 | default: |
f224749b AP |
571 | dev_err(&d->udev->dev, "%s: tuner id=%d not " \ |
572 | "supported, please report!\n", | |
573 | KBUILD_MODNAME, val); | |
80619de8 | 574 | return -ENODEV; |
c2c1b415 | 575 | } |
80619de8 | 576 | |
a3645e54 | 577 | state->af9013_config[i].tuner = val; |
f224749b AP |
578 | dev_dbg(&d->udev->dev, "%s: [%d] tuner id=%d\n", |
579 | __func__, i, val); | |
80619de8 AP |
580 | } |
581 | ||
582 | error: | |
583 | if (ret) | |
f224749b AP |
584 | dev_err(&d->udev->dev, "%s: eeprom read failed=%d\n", |
585 | KBUILD_MODNAME, ret); | |
80619de8 | 586 | |
3956fefc | 587 | /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM |
8ccdf1ae YM |
588 | content :-( Override some wrong values here. Ditto for the |
589 | AVerTV Red HD+ (A850T) device. */ | |
a3645e54 AP |
590 | if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA && |
591 | ((le16_to_cpu(d->udev->descriptor.idProduct) == | |
9a3ecc73 | 592 | USB_PID_AVERMEDIA_A850) || |
a3645e54 | 593 | (le16_to_cpu(d->udev->descriptor.idProduct) == |
9a3ecc73 | 594 | USB_PID_AVERMEDIA_A850T))) { |
f224749b AP |
595 | dev_dbg(&d->udev->dev, |
596 | "%s: AverMedia A850: overriding config\n", | |
597 | __func__); | |
3956fefc | 598 | /* disable dual mode */ |
a3645e54 | 599 | state->dual_mode = 0; |
3956fefc AP |
600 | |
601 | /* set correct IF */ | |
a3645e54 | 602 | state->af9013_config[0].if_frequency = 4570000; |
3956fefc AP |
603 | } |
604 | ||
80619de8 AP |
605 | return ret; |
606 | } | |
607 | ||
b905a2a1 | 608 | static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type, |
a3645e54 | 609 | struct usb_data_stream_properties *stream) |
80619de8 | 610 | { |
f224749b AP |
611 | struct dvb_usb_device *d = fe_to_d(fe); |
612 | dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, fe_to_adap(fe)->id); | |
d3bb73de | 613 | |
f224749b | 614 | if (d->udev->speed == USB_SPEED_FULL) |
a3645e54 | 615 | stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE; |
1e8750c2 | 616 | |
a3645e54 AP |
617 | return 0; |
618 | } | |
d3bb73de | 619 | |
a3645e54 AP |
620 | static int af9015_get_adapter_count(struct dvb_usb_device *d) |
621 | { | |
e8089661 | 622 | struct af9015_state *state = d_to_priv(d); |
a3645e54 | 623 | return state->dual_mode + 1; |
80619de8 AP |
624 | } |
625 | ||
e90ab840 | 626 | /* override demod callbacks for resource locking */ |
0009e0e3 | 627 | static int af9015_af9013_set_frontend(struct dvb_frontend *fe) |
e90ab840 AP |
628 | { |
629 | int ret; | |
e8089661 | 630 | struct af9015_state *state = fe_to_priv(fe); |
e90ab840 | 631 | |
a3645e54 | 632 | if (mutex_lock_interruptible(&state->fe_mutex)) |
e90ab840 AP |
633 | return -EAGAIN; |
634 | ||
e8089661 | 635 | ret = state->set_frontend[fe_to_adap(fe)->id](fe); |
e90ab840 | 636 | |
a3645e54 | 637 | mutex_unlock(&state->fe_mutex); |
e90ab840 AP |
638 | |
639 | return ret; | |
640 | } | |
641 | ||
642 | /* override demod callbacks for resource locking */ | |
643 | static int af9015_af9013_read_status(struct dvb_frontend *fe, | |
0df289a2 | 644 | enum fe_status *status) |
e90ab840 AP |
645 | { |
646 | int ret; | |
e8089661 | 647 | struct af9015_state *state = fe_to_priv(fe); |
e90ab840 | 648 | |
a3645e54 | 649 | if (mutex_lock_interruptible(&state->fe_mutex)) |
e90ab840 AP |
650 | return -EAGAIN; |
651 | ||
e8089661 | 652 | ret = state->read_status[fe_to_adap(fe)->id](fe, status); |
e90ab840 | 653 | |
a3645e54 | 654 | mutex_unlock(&state->fe_mutex); |
e90ab840 AP |
655 | |
656 | return ret; | |
657 | } | |
658 | ||
659 | /* override demod callbacks for resource locking */ | |
660 | static int af9015_af9013_init(struct dvb_frontend *fe) | |
661 | { | |
662 | int ret; | |
e8089661 | 663 | struct af9015_state *state = fe_to_priv(fe); |
e90ab840 | 664 | |
a3645e54 | 665 | if (mutex_lock_interruptible(&state->fe_mutex)) |
e90ab840 AP |
666 | return -EAGAIN; |
667 | ||
e8089661 | 668 | ret = state->init[fe_to_adap(fe)->id](fe); |
e90ab840 | 669 | |
a3645e54 | 670 | mutex_unlock(&state->fe_mutex); |
e90ab840 AP |
671 | |
672 | return ret; | |
673 | } | |
674 | ||
675 | /* override demod callbacks for resource locking */ | |
676 | static int af9015_af9013_sleep(struct dvb_frontend *fe) | |
677 | { | |
678 | int ret; | |
e8089661 | 679 | struct af9015_state *state = fe_to_priv(fe); |
e90ab840 | 680 | |
a3645e54 | 681 | if (mutex_lock_interruptible(&state->fe_mutex)) |
e90ab840 AP |
682 | return -EAGAIN; |
683 | ||
e8089661 | 684 | ret = state->sleep[fe_to_adap(fe)->id](fe); |
e90ab840 | 685 | |
a3645e54 | 686 | mutex_unlock(&state->fe_mutex); |
e90ab840 AP |
687 | |
688 | return ret; | |
689 | } | |
690 | ||
6d535bd8 AP |
691 | /* override tuner callbacks for resource locking */ |
692 | static int af9015_tuner_init(struct dvb_frontend *fe) | |
693 | { | |
694 | int ret; | |
e8089661 | 695 | struct af9015_state *state = fe_to_priv(fe); |
6d535bd8 | 696 | |
a3645e54 | 697 | if (mutex_lock_interruptible(&state->fe_mutex)) |
6d535bd8 AP |
698 | return -EAGAIN; |
699 | ||
e8089661 | 700 | ret = state->tuner_init[fe_to_adap(fe)->id](fe); |
6d535bd8 | 701 | |
a3645e54 | 702 | mutex_unlock(&state->fe_mutex); |
6d535bd8 AP |
703 | |
704 | return ret; | |
705 | } | |
706 | ||
707 | /* override tuner callbacks for resource locking */ | |
708 | static int af9015_tuner_sleep(struct dvb_frontend *fe) | |
709 | { | |
710 | int ret; | |
e8089661 | 711 | struct af9015_state *state = fe_to_priv(fe); |
6d535bd8 | 712 | |
a3645e54 | 713 | if (mutex_lock_interruptible(&state->fe_mutex)) |
6d535bd8 AP |
714 | return -EAGAIN; |
715 | ||
e8089661 | 716 | ret = state->tuner_sleep[fe_to_adap(fe)->id](fe); |
a3645e54 AP |
717 | |
718 | mutex_unlock(&state->fe_mutex); | |
719 | ||
720 | return ret; | |
721 | } | |
722 | ||
723 | static int af9015_copy_firmware(struct dvb_usb_device *d) | |
724 | { | |
e8089661 | 725 | struct af9015_state *state = d_to_priv(d); |
a3645e54 AP |
726 | int ret; |
727 | u8 fw_params[4]; | |
728 | u8 val, i; | |
729 | struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params), | |
730 | fw_params }; | |
f224749b | 731 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
a3645e54 AP |
732 | |
733 | fw_params[0] = state->firmware_size >> 8; | |
734 | fw_params[1] = state->firmware_size & 0xff; | |
735 | fw_params[2] = state->firmware_checksum >> 8; | |
736 | fw_params[3] = state->firmware_checksum & 0xff; | |
737 | ||
738 | /* wait 2nd demodulator ready */ | |
739 | msleep(100); | |
740 | ||
741 | ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr, | |
742 | 0x98be, &val); | |
743 | if (ret) | |
744 | goto error; | |
745 | else | |
f224749b AP |
746 | dev_dbg(&d->udev->dev, "%s: firmware status=%02x\n", |
747 | __func__, val); | |
a3645e54 AP |
748 | |
749 | if (val == 0x0c) /* fw is running, no need for download */ | |
750 | goto exit; | |
751 | ||
752 | /* set I2C master clock to fast (to speed up firmware copy) */ | |
753 | ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */ | |
754 | if (ret) | |
755 | goto error; | |
756 | ||
757 | msleep(50); | |
758 | ||
759 | /* copy firmware */ | |
760 | ret = af9015_ctrl_msg(d, &req); | |
761 | if (ret) | |
f224749b AP |
762 | dev_err(&d->udev->dev, "%s: firmware copy cmd failed=%d\n", |
763 | KBUILD_MODNAME, ret); | |
764 | ||
765 | dev_dbg(&d->udev->dev, "%s: firmware copy done\n", __func__); | |
a3645e54 AP |
766 | |
767 | /* set I2C master clock back to normal */ | |
768 | ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */ | |
769 | if (ret) | |
770 | goto error; | |
771 | ||
772 | /* request boot firmware */ | |
773 | ret = af9015_write_reg_i2c(d, state->af9013_config[1].i2c_addr, | |
774 | 0xe205, 1); | |
f224749b AP |
775 | dev_dbg(&d->udev->dev, "%s: firmware boot cmd status=%d\n", |
776 | __func__, ret); | |
a3645e54 AP |
777 | if (ret) |
778 | goto error; | |
779 | ||
780 | for (i = 0; i < 15; i++) { | |
781 | msleep(100); | |
6d535bd8 | 782 | |
a3645e54 AP |
783 | /* check firmware status */ |
784 | ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr, | |
785 | 0x98be, &val); | |
f224749b AP |
786 | dev_dbg(&d->udev->dev, "%s: firmware status cmd status=%d " \ |
787 | "firmware status=%02x\n", __func__, ret, val); | |
a3645e54 AP |
788 | if (ret) |
789 | goto error; | |
6d535bd8 | 790 | |
a3645e54 AP |
791 | if (val == 0x0c || val == 0x04) /* success or fail */ |
792 | break; | |
793 | } | |
794 | ||
795 | if (val == 0x04) { | |
f224749b AP |
796 | dev_err(&d->udev->dev, "%s: firmware did not run\n", |
797 | KBUILD_MODNAME); | |
e1e9e510 | 798 | ret = -ETIMEDOUT; |
a3645e54 | 799 | } else if (val != 0x0c) { |
f224749b AP |
800 | dev_err(&d->udev->dev, "%s: firmware boot timeout\n", |
801 | KBUILD_MODNAME); | |
e1e9e510 | 802 | ret = -ETIMEDOUT; |
a3645e54 AP |
803 | } |
804 | ||
805 | error: | |
806 | exit: | |
6d535bd8 AP |
807 | return ret; |
808 | } | |
809 | ||
80619de8 AP |
810 | static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) |
811 | { | |
812 | int ret; | |
e8089661 | 813 | struct af9015_state *state = adap_to_priv(adap); |
80619de8 | 814 | |
a3645e54 AP |
815 | if (adap->id == 0) { |
816 | state->af9013_config[0].ts_mode = AF9013_TS_USB; | |
817 | memcpy(state->af9013_config[0].api_version, "\x0\x1\x9\x0", 4); | |
818 | state->af9013_config[0].gpio[0] = AF9013_GPIO_HI; | |
819 | state->af9013_config[0].gpio[3] = AF9013_GPIO_TUNER_ON; | |
820 | } else if (adap->id == 1) { | |
821 | state->af9013_config[1].ts_mode = AF9013_TS_SERIAL; | |
822 | memcpy(state->af9013_config[1].api_version, "\x0\x1\x9\x0", 4); | |
823 | state->af9013_config[1].gpio[0] = AF9013_GPIO_TUNER_ON; | |
824 | state->af9013_config[1].gpio[1] = AF9013_GPIO_LO; | |
825 | ||
80619de8 | 826 | /* copy firmware to 2nd demodulator */ |
a3645e54 | 827 | if (state->dual_mode) { |
e8089661 | 828 | ret = af9015_copy_firmware(adap_to_d(adap)); |
80619de8 | 829 | if (ret) { |
f224749b AP |
830 | dev_err(&adap_to_d(adap)->udev->dev, |
831 | "%s: firmware copy to 2nd " \ | |
832 | "frontend failed, will " \ | |
833 | "disable it\n", KBUILD_MODNAME); | |
a3645e54 | 834 | state->dual_mode = 0; |
80619de8 AP |
835 | return -ENODEV; |
836 | } | |
837 | } else { | |
838 | return -ENODEV; | |
839 | } | |
840 | } | |
841 | ||
842 | /* attach demodulator */ | |
a3645e54 | 843 | adap->fe[0] = dvb_attach(af9013_attach, |
e8089661 | 844 | &state->af9013_config[adap->id], &adap_to_d(adap)->i2c_adap); |
80619de8 | 845 | |
e90ab840 AP |
846 | /* |
847 | * AF9015 firmware does not like if it gets interrupted by I2C adapter | |
848 | * request on some critical phases. During normal operation I2C adapter | |
849 | * is used only 2nd demodulator and tuner on dual tuner devices. | |
850 | * Override demodulator callbacks and use mutex for limit access to | |
851 | * those "critical" paths to keep AF9015 happy. | |
e90ab840 | 852 | */ |
a3645e54 | 853 | if (adap->fe[0]) { |
e90ab840 | 854 | state->set_frontend[adap->id] = |
a3645e54 AP |
855 | adap->fe[0]->ops.set_frontend; |
856 | adap->fe[0]->ops.set_frontend = | |
e90ab840 AP |
857 | af9015_af9013_set_frontend; |
858 | ||
859 | state->read_status[adap->id] = | |
a3645e54 AP |
860 | adap->fe[0]->ops.read_status; |
861 | adap->fe[0]->ops.read_status = | |
e90ab840 AP |
862 | af9015_af9013_read_status; |
863 | ||
a3645e54 AP |
864 | state->init[adap->id] = adap->fe[0]->ops.init; |
865 | adap->fe[0]->ops.init = af9015_af9013_init; | |
e90ab840 | 866 | |
a3645e54 AP |
867 | state->sleep[adap->id] = adap->fe[0]->ops.sleep; |
868 | adap->fe[0]->ops.sleep = af9015_af9013_sleep; | |
e90ab840 AP |
869 | } |
870 | ||
a3645e54 | 871 | return adap->fe[0] == NULL ? -ENODEV : 0; |
80619de8 AP |
872 | } |
873 | ||
874 | static struct mt2060_config af9015_mt2060_config = { | |
875 | .i2c_address = 0xc0, | |
876 | .clock_out = 0, | |
877 | }; | |
878 | ||
879 | static struct qt1010_config af9015_qt1010_config = { | |
880 | .i2c_address = 0xc4, | |
881 | }; | |
882 | ||
883 | static struct tda18271_config af9015_tda18271_config = { | |
884 | .gate = TDA18271_GATE_DIGITAL, | |
7655e594 | 885 | .small_i2c = TDA18271_16_BYTE_CHUNK_INIT, |
80619de8 AP |
886 | }; |
887 | ||
888 | static struct mxl5005s_config af9015_mxl5003_config = { | |
889 | .i2c_address = 0xc6, | |
890 | .if_freq = IF_FREQ_4570000HZ, | |
891 | .xtal_freq = CRYSTAL_FREQ_16000000HZ, | |
892 | .agc_mode = MXL_SINGLE_AGC, | |
893 | .tracking_filter = MXL_TF_DEFAULT, | |
a131077d | 894 | .rssi_enable = MXL_RSSI_ENABLE, |
80619de8 AP |
895 | .cap_select = MXL_CAP_SEL_ENABLE, |
896 | .div_out = MXL_DIV_OUT_4, | |
897 | .clock_out = MXL_CLOCK_OUT_DISABLE, | |
898 | .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, | |
899 | .top = MXL5005S_TOP_25P2, | |
900 | .mod_mode = MXL_DIGITAL_MODE, | |
901 | .if_mode = MXL_ZERO_IF, | |
902 | .AgcMasterByte = 0x00, | |
903 | }; | |
904 | ||
905 | static struct mxl5005s_config af9015_mxl5005_config = { | |
906 | .i2c_address = 0xc6, | |
907 | .if_freq = IF_FREQ_4570000HZ, | |
908 | .xtal_freq = CRYSTAL_FREQ_16000000HZ, | |
909 | .agc_mode = MXL_SINGLE_AGC, | |
910 | .tracking_filter = MXL_TF_OFF, | |
a131077d | 911 | .rssi_enable = MXL_RSSI_ENABLE, |
80619de8 AP |
912 | .cap_select = MXL_CAP_SEL_ENABLE, |
913 | .div_out = MXL_DIV_OUT_4, | |
914 | .clock_out = MXL_CLOCK_OUT_DISABLE, | |
915 | .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, | |
916 | .top = MXL5005S_TOP_25P2, | |
917 | .mod_mode = MXL_DIGITAL_MODE, | |
918 | .if_mode = MXL_ZERO_IF, | |
919 | .AgcMasterByte = 0x00, | |
920 | }; | |
921 | ||
d5633998 JF |
922 | static struct mc44s803_config af9015_mc44s803_config = { |
923 | .i2c_address = 0xc0, | |
924 | .dig_out = 1, | |
925 | }; | |
926 | ||
ee3d440c AP |
927 | static struct tda18218_config af9015_tda18218_config = { |
928 | .i2c_address = 0xc0, | |
929 | .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */ | |
930 | }; | |
931 | ||
ab07fdd6 AP |
932 | static struct mxl5007t_config af9015_mxl5007t_config = { |
933 | .xtal_freq_hz = MxL_XTAL_24_MHZ, | |
934 | .if_freq_hz = MxL_IF_4_57_MHZ, | |
935 | }; | |
936 | ||
80619de8 AP |
937 | static int af9015_tuner_attach(struct dvb_usb_adapter *adap) |
938 | { | |
f224749b AP |
939 | struct dvb_usb_device *d = adap_to_d(adap); |
940 | struct af9015_state *state = d_to_priv(d); | |
a3645e54 | 941 | int ret; |
f224749b | 942 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
80619de8 | 943 | |
a3645e54 | 944 | switch (state->af9013_config[adap->id].tuner) { |
80619de8 AP |
945 | case AF9013_TUNER_MT2060: |
946 | case AF9013_TUNER_MT2060_2: | |
a3645e54 | 947 | ret = dvb_attach(mt2060_attach, adap->fe[0], |
e8089661 | 948 | &adap_to_d(adap)->i2c_adap, &af9015_mt2060_config, |
a3645e54 | 949 | state->mt2060_if1[adap->id]) |
80619de8 AP |
950 | == NULL ? -ENODEV : 0; |
951 | break; | |
952 | case AF9013_TUNER_QT1010: | |
953 | case AF9013_TUNER_QT1010A: | |
a3645e54 | 954 | ret = dvb_attach(qt1010_attach, adap->fe[0], |
e8089661 | 955 | &adap_to_d(adap)->i2c_adap, |
80619de8 AP |
956 | &af9015_qt1010_config) == NULL ? -ENODEV : 0; |
957 | break; | |
958 | case AF9013_TUNER_TDA18271: | |
a3645e54 | 959 | ret = dvb_attach(tda18271_attach, adap->fe[0], 0xc0, |
e8089661 | 960 | &adap_to_d(adap)->i2c_adap, |
80619de8 AP |
961 | &af9015_tda18271_config) == NULL ? -ENODEV : 0; |
962 | break; | |
ee3d440c | 963 | case AF9013_TUNER_TDA18218: |
a3645e54 | 964 | ret = dvb_attach(tda18218_attach, adap->fe[0], |
e8089661 | 965 | &adap_to_d(adap)->i2c_adap, |
ee3d440c AP |
966 | &af9015_tda18218_config) == NULL ? -ENODEV : 0; |
967 | break; | |
80619de8 | 968 | case AF9013_TUNER_MXL5003D: |
a3645e54 | 969 | ret = dvb_attach(mxl5005s_attach, adap->fe[0], |
e8089661 | 970 | &adap_to_d(adap)->i2c_adap, |
80619de8 AP |
971 | &af9015_mxl5003_config) == NULL ? -ENODEV : 0; |
972 | break; | |
973 | case AF9013_TUNER_MXL5005D: | |
974 | case AF9013_TUNER_MXL5005R: | |
a3645e54 | 975 | ret = dvb_attach(mxl5005s_attach, adap->fe[0], |
e8089661 | 976 | &adap_to_d(adap)->i2c_adap, |
80619de8 AP |
977 | &af9015_mxl5005_config) == NULL ? -ENODEV : 0; |
978 | break; | |
979 | case AF9013_TUNER_ENV77H11D5: | |
a3645e54 | 980 | ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0xc0, |
e8089661 | 981 | &adap_to_d(adap)->i2c_adap, |
80619de8 AP |
982 | DVB_PLL_TDA665X) == NULL ? -ENODEV : 0; |
983 | break; | |
984 | case AF9013_TUNER_MC44S803: | |
a3645e54 | 985 | ret = dvb_attach(mc44s803_attach, adap->fe[0], |
e8089661 | 986 | &adap_to_d(adap)->i2c_adap, |
d5633998 | 987 | &af9015_mc44s803_config) == NULL ? -ENODEV : 0; |
80619de8 | 988 | break; |
ab07fdd6 | 989 | case AF9013_TUNER_MXL5007T: |
a3645e54 | 990 | ret = dvb_attach(mxl5007t_attach, adap->fe[0], |
e8089661 | 991 | &adap_to_d(adap)->i2c_adap, |
ab07fdd6 AP |
992 | 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0; |
993 | break; | |
80619de8 AP |
994 | case AF9013_TUNER_UNKNOWN: |
995 | default: | |
f224749b AP |
996 | dev_err(&d->udev->dev, "%s: unknown tuner id=%d\n", |
997 | KBUILD_MODNAME, | |
998 | state->af9013_config[adap->id].tuner); | |
80619de8 | 999 | ret = -ENODEV; |
80619de8 | 1000 | } |
be4a5e7f | 1001 | |
a3645e54 | 1002 | if (adap->fe[0]->ops.tuner_ops.init) { |
6d535bd8 | 1003 | state->tuner_init[adap->id] = |
a3645e54 AP |
1004 | adap->fe[0]->ops.tuner_ops.init; |
1005 | adap->fe[0]->ops.tuner_ops.init = af9015_tuner_init; | |
6d535bd8 AP |
1006 | } |
1007 | ||
a3645e54 | 1008 | if (adap->fe[0]->ops.tuner_ops.sleep) { |
6d535bd8 | 1009 | state->tuner_sleep[adap->id] = |
a3645e54 AP |
1010 | adap->fe[0]->ops.tuner_ops.sleep; |
1011 | adap->fe[0]->ops.tuner_ops.sleep = af9015_tuner_sleep; | |
1012 | } | |
1013 | ||
1014 | return ret; | |
1015 | } | |
1016 | ||
1017 | static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) | |
1018 | { | |
f224749b | 1019 | struct dvb_usb_device *d = adap_to_d(adap); |
a3645e54 | 1020 | int ret; |
f224749b | 1021 | dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff); |
a3645e54 AP |
1022 | |
1023 | if (onoff) | |
f224749b | 1024 | ret = af9015_set_reg_bit(d, 0xd503, 0); |
a3645e54 | 1025 | else |
f224749b | 1026 | ret = af9015_clear_reg_bit(d, 0xd503, 0); |
a3645e54 AP |
1027 | |
1028 | return ret; | |
1029 | } | |
1030 | ||
1031 | static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, | |
1032 | int onoff) | |
1033 | { | |
f224749b | 1034 | struct dvb_usb_device *d = adap_to_d(adap); |
a3645e54 AP |
1035 | int ret; |
1036 | u8 idx; | |
f224749b AP |
1037 | dev_dbg(&d->udev->dev, "%s: index=%d pid=%04x onoff=%d\n", |
1038 | __func__, index, pid, onoff); | |
a3645e54 | 1039 | |
f224749b | 1040 | ret = af9015_write_reg(d, 0xd505, (pid & 0xff)); |
a3645e54 AP |
1041 | if (ret) |
1042 | goto error; | |
1043 | ||
f224749b | 1044 | ret = af9015_write_reg(d, 0xd506, (pid >> 8)); |
a3645e54 AP |
1045 | if (ret) |
1046 | goto error; | |
1047 | ||
1048 | idx = ((index & 0x1f) | (1 << 5)); | |
f224749b | 1049 | ret = af9015_write_reg(d, 0xd504, idx); |
a3645e54 AP |
1050 | |
1051 | error: | |
1052 | return ret; | |
1053 | } | |
1054 | ||
1055 | static int af9015_init_endpoint(struct dvb_usb_device *d) | |
1056 | { | |
e8089661 | 1057 | struct af9015_state *state = d_to_priv(d); |
a3645e54 AP |
1058 | int ret; |
1059 | u16 frame_size; | |
1060 | u8 packet_size; | |
f224749b | 1061 | dev_dbg(&d->udev->dev, "%s: USB speed=%d\n", __func__, d->udev->speed); |
a3645e54 AP |
1062 | |
1063 | if (d->udev->speed == USB_SPEED_FULL) { | |
1064 | frame_size = TS_USB11_FRAME_SIZE/4; | |
1065 | packet_size = TS_USB11_MAX_PACKET_SIZE/4; | |
1066 | } else { | |
1067 | frame_size = TS_USB20_FRAME_SIZE/4; | |
1068 | packet_size = TS_USB20_MAX_PACKET_SIZE/4; | |
1069 | } | |
1070 | ||
1071 | ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */ | |
1072 | if (ret) | |
1073 | goto error; | |
1074 | ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */ | |
1075 | if (ret) | |
1076 | goto error; | |
1077 | ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */ | |
1078 | if (ret) | |
1079 | goto error; | |
1080 | ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */ | |
1081 | if (ret) | |
1082 | goto error; | |
1083 | ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */ | |
1084 | if (ret) | |
1085 | goto error; | |
1086 | if (state->dual_mode) { | |
1087 | ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */ | |
1088 | if (ret) | |
1089 | goto error; | |
1090 | } | |
1091 | ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */ | |
1092 | if (ret) | |
1093 | goto error; | |
1094 | if (state->dual_mode) { | |
1095 | ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */ | |
1096 | if (ret) | |
1097 | goto error; | |
1098 | } | |
1099 | /* EP4 xfer length */ | |
1100 | ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff); | |
1101 | if (ret) | |
1102 | goto error; | |
1103 | ret = af9015_write_reg(d, 0xdd89, frame_size >> 8); | |
1104 | if (ret) | |
1105 | goto error; | |
1106 | /* EP5 xfer length */ | |
1107 | ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff); | |
1108 | if (ret) | |
1109 | goto error; | |
1110 | ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8); | |
1111 | if (ret) | |
1112 | goto error; | |
1113 | ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */ | |
1114 | if (ret) | |
1115 | goto error; | |
1116 | ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */ | |
1117 | if (ret) | |
1118 | goto error; | |
1119 | ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */ | |
1120 | if (ret) | |
1121 | goto error; | |
1122 | if (state->dual_mode) { | |
1123 | ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */ | |
1124 | if (ret) | |
1125 | goto error; | |
6d535bd8 | 1126 | } |
be4a5e7f | 1127 | |
a3645e54 AP |
1128 | /* enable / disable mp2if2 */ |
1129 | if (state->dual_mode) | |
1130 | ret = af9015_set_reg_bit(d, 0xd50b, 0); | |
1131 | else | |
1132 | ret = af9015_clear_reg_bit(d, 0xd50b, 0); | |
1133 | ||
1134 | error: | |
1135 | if (ret) | |
f224749b AP |
1136 | dev_err(&d->udev->dev, "%s: endpoint init failed=%d\n", |
1137 | KBUILD_MODNAME, ret); | |
1138 | ||
a3645e54 AP |
1139 | return ret; |
1140 | } | |
1141 | ||
1142 | static int af9015_init(struct dvb_usb_device *d) | |
1143 | { | |
e8089661 | 1144 | struct af9015_state *state = d_to_priv(d); |
a3645e54 | 1145 | int ret; |
f224749b | 1146 | dev_dbg(&d->udev->dev, "%s:\n", __func__); |
a3645e54 AP |
1147 | |
1148 | mutex_init(&state->fe_mutex); | |
1149 | ||
1150 | /* init RC canary */ | |
1151 | ret = af9015_write_reg(d, 0x98e9, 0xff); | |
1152 | if (ret) | |
1153 | goto error; | |
1154 | ||
1155 | ret = af9015_init_endpoint(d); | |
1156 | if (ret) | |
1157 | goto error; | |
1158 | ||
1159 | error: | |
80619de8 AP |
1160 | return ret; |
1161 | } | |
1162 | ||
37b44a0f | 1163 | #if IS_ENABLED(CONFIG_RC_CORE) |
a3645e54 AP |
1164 | struct af9015_rc_setup { |
1165 | unsigned int id; | |
1166 | char *rc_codes; | |
d07b901f JN |
1167 | }; |
1168 | ||
a3645e54 AP |
1169 | static char *af9015_rc_setup_match(unsigned int id, |
1170 | const struct af9015_rc_setup *table) | |
1171 | { | |
1172 | for (; table->rc_codes; table++) | |
1173 | if (table->id == id) | |
1174 | return table->rc_codes; | |
1175 | return NULL; | |
1176 | } | |
1177 | ||
1178 | static const struct af9015_rc_setup af9015_rc_setup_modparam[] = { | |
1179 | { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M }, | |
1180 | { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II }, | |
1181 | { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND }, | |
1182 | { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE }, | |
1183 | { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS }, | |
d07b901f | 1184 | { } |
80619de8 | 1185 | }; |
80619de8 | 1186 | |
a3645e54 AP |
1187 | static const struct af9015_rc_setup af9015_rc_setup_hashes[] = { |
1188 | { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II }, | |
1189 | { 0xa3703d00, RC_MAP_ALINK_DTU_M }, | |
1190 | { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */ | |
1191 | { 0x5d49e3db, RC_MAP_DIGITTRADE }, /* LC-Power LC-USB-DVBT */ | |
1192 | { } | |
1193 | }; | |
80619de8 | 1194 | |
a3645e54 AP |
1195 | static int af9015_rc_query(struct dvb_usb_device *d) |
1196 | { | |
e8089661 | 1197 | struct af9015_state *state = d_to_priv(d); |
a3645e54 AP |
1198 | int ret; |
1199 | u8 buf[17]; | |
80619de8 | 1200 | |
a3645e54 AP |
1201 | /* read registers needed to detect remote controller code */ |
1202 | ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); | |
1203 | if (ret) | |
1204 | goto error; | |
80619de8 | 1205 | |
a3645e54 | 1206 | /* If any of these are non-zero, assume invalid data */ |
f224749b AP |
1207 | if (buf[1] || buf[2] || buf[3]) { |
1208 | dev_dbg(&d->udev->dev, "%s: invalid data\n", __func__); | |
a3645e54 | 1209 | return ret; |
f224749b | 1210 | } |
80619de8 | 1211 | |
a3645e54 AP |
1212 | /* Check for repeat of previous code */ |
1213 | if ((state->rc_repeat != buf[6] || buf[0]) && | |
1214 | !memcmp(&buf[12], state->rc_last, 4)) { | |
f224749b | 1215 | dev_dbg(&d->udev->dev, "%s: key repeated\n", __func__); |
120703f9 | 1216 | rc_repeat(d->rc_dev); |
a3645e54 AP |
1217 | state->rc_repeat = buf[6]; |
1218 | return ret; | |
1219 | } | |
85d7d7ca | 1220 | |
a3645e54 AP |
1221 | /* Only process key if canary killed */ |
1222 | if (buf[16] != 0xff && buf[0] != 0x01) { | |
f224749b AP |
1223 | dev_dbg(&d->udev->dev, "%s: key pressed %*ph\n", |
1224 | __func__, 4, buf + 12); | |
85d7d7ca | 1225 | |
a3645e54 AP |
1226 | /* Reset the canary */ |
1227 | ret = af9015_write_reg(d, 0x98e9, 0xff); | |
1228 | if (ret) | |
1229 | goto error; | |
85d7d7ca | 1230 | |
a3645e54 AP |
1231 | /* Remember this key */ |
1232 | memcpy(state->rc_last, &buf[12], 4); | |
1233 | if (buf[14] == (u8) ~buf[15]) { | |
1234 | if (buf[12] == (u8) ~buf[13]) { | |
1235 | /* NEC */ | |
120703f9 DH |
1236 | state->rc_keycode = RC_SCANCODE_NEC(buf[12], |
1237 | buf[14]); | |
a3645e54 AP |
1238 | } else { |
1239 | /* NEC extended*/ | |
120703f9 DH |
1240 | state->rc_keycode = RC_SCANCODE_NECX(buf[12] << 8 | |
1241 | buf[13], | |
1242 | buf[14]); | |
a3645e54 AP |
1243 | } |
1244 | } else { | |
1245 | /* 32 bit NEC */ | |
120703f9 DH |
1246 | state->rc_keycode = RC_SCANCODE_NEC32(buf[12] << 24 | |
1247 | buf[13] << 16 | | |
1248 | buf[14] << 8 | | |
1249 | buf[15]); | |
85d7d7ca | 1250 | } |
120703f9 | 1251 | rc_keydown(d->rc_dev, RC_TYPE_NEC, state->rc_keycode, 0); |
a3645e54 | 1252 | } else { |
f224749b | 1253 | dev_dbg(&d->udev->dev, "%s: no key press\n", __func__); |
a3645e54 AP |
1254 | /* Invalidate last keypress */ |
1255 | /* Not really needed, but helps with debug */ | |
1256 | state->rc_last[2] = state->rc_last[3]; | |
1257 | } | |
1258 | ||
1259 | state->rc_repeat = buf[6]; | |
eb29fbea | 1260 | state->rc_failed = false; |
a3645e54 AP |
1261 | |
1262 | error: | |
eb29fbea | 1263 | if (ret) { |
f224749b AP |
1264 | dev_warn(&d->udev->dev, "%s: rc query failed=%d\n", |
1265 | KBUILD_MODNAME, ret); | |
a3645e54 | 1266 | |
eb29fbea AP |
1267 | /* allow random errors as dvb-usb will stop polling on error */ |
1268 | if (!state->rc_failed) | |
1269 | ret = 0; | |
1270 | ||
1271 | state->rc_failed = true; | |
1272 | } | |
1273 | ||
a3645e54 AP |
1274 | return ret; |
1275 | } | |
80619de8 | 1276 | |
a3645e54 | 1277 | static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) |
80619de8 | 1278 | { |
e8089661 | 1279 | struct af9015_state *state = d_to_priv(d); |
a3645e54 AP |
1280 | u16 vid = le16_to_cpu(d->udev->descriptor.idVendor); |
1281 | ||
1282 | if (state->ir_mode == AF9015_IR_MODE_DISABLED) | |
1283 | return 0; | |
1284 | ||
1285 | /* try to load remote based module param */ | |
eb29fbea AP |
1286 | if (!rc->map_name) |
1287 | rc->map_name = af9015_rc_setup_match(dvb_usb_af9015_remote, | |
1288 | af9015_rc_setup_modparam); | |
80619de8 | 1289 | |
a3645e54 AP |
1290 | /* try to load remote based eeprom hash */ |
1291 | if (!rc->map_name) | |
1292 | rc->map_name = af9015_rc_setup_match(state->eeprom_sum, | |
1293 | af9015_rc_setup_hashes); | |
1294 | ||
1295 | /* try to load remote based USB iManufacturer string */ | |
1296 | if (!rc->map_name && vid == USB_VID_AFATECH) { | |
1297 | /* Check USB manufacturer and product strings and try | |
1298 | to determine correct remote in case of chip vendor | |
1299 | reference IDs are used. | |
1300 | DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */ | |
1301 | char manufacturer[10]; | |
1302 | memset(manufacturer, 0, sizeof(manufacturer)); | |
1303 | usb_string(d->udev, d->udev->descriptor.iManufacturer, | |
1304 | manufacturer, sizeof(manufacturer)); | |
1305 | if (!strcmp("MSI", manufacturer)) { | |
1306 | /* iManufacturer 1 MSI | |
1307 | iProduct 2 MSI K-VOX */ | |
1308 | rc->map_name = af9015_rc_setup_match( | |
1309 | AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, | |
1310 | af9015_rc_setup_modparam); | |
1311 | } | |
80619de8 AP |
1312 | } |
1313 | ||
de73beee AP |
1314 | /* load empty to enable rc */ |
1315 | if (!rc->map_name) | |
1316 | rc->map_name = RC_MAP_EMPTY; | |
1317 | ||
c003ab1b | 1318 | rc->allowed_protos = RC_BIT_NEC; |
a3645e54 AP |
1319 | rc->query = af9015_rc_query; |
1320 | rc->interval = 500; | |
1321 | ||
1322 | return 0; | |
80619de8 | 1323 | } |
b6215596 AP |
1324 | #else |
1325 | #define af9015_get_rc_config NULL | |
1326 | #endif | |
80619de8 | 1327 | |
e8c7aab5 AP |
1328 | static int af9015_probe(struct usb_interface *intf, |
1329 | const struct usb_device_id *id) | |
1330 | { | |
1331 | struct usb_device *udev = interface_to_usbdev(intf); | |
1332 | char manufacturer[sizeof("ITE Technologies, Inc.")]; | |
1333 | ||
1334 | memset(manufacturer, 0, sizeof(manufacturer)); | |
1335 | usb_string(udev, udev->descriptor.iManufacturer, | |
1336 | manufacturer, sizeof(manufacturer)); | |
1337 | /* | |
1338 | * There is two devices having same ID but different chipset. One uses | |
1339 | * AF9015 and the other IT9135 chipset. Only difference seen on lsusb | |
1340 | * is iManufacturer string. | |
1341 | * | |
1342 | * idVendor 0x0ccd TerraTec Electronic GmbH | |
1343 | * idProduct 0x0099 | |
1344 | * bcdDevice 2.00 | |
1345 | * iManufacturer 1 Afatech | |
1346 | * iProduct 2 DVB-T 2 | |
1347 | * | |
1348 | * idVendor 0x0ccd TerraTec Electronic GmbH | |
1349 | * idProduct 0x0099 | |
1350 | * bcdDevice 2.00 | |
1351 | * iManufacturer 1 ITE Technologies, Inc. | |
1352 | * iProduct 2 DVB-T TV Stick | |
1353 | */ | |
1354 | if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VID_TERRATEC) && | |
1355 | (le16_to_cpu(udev->descriptor.idProduct) == 0x0099)) { | |
1356 | if (!strcmp("ITE Technologies, Inc.", manufacturer)) { | |
1357 | dev_dbg(&udev->dev, "%s: rejecting device\n", __func__); | |
1358 | return -ENODEV; | |
1359 | } | |
1360 | } | |
1361 | ||
1362 | return dvb_usbv2_probe(intf, id); | |
1363 | } | |
1364 | ||
a3645e54 AP |
1365 | /* interface 0 is used by DVB-T receiver and |
1366 | interface 1 is for remote controller (HID) */ | |
1367 | static struct dvb_usb_device_properties af9015_props = { | |
1368 | .driver_name = KBUILD_MODNAME, | |
1369 | .owner = THIS_MODULE, | |
1370 | .adapter_nr = adapter_nr, | |
1371 | .size_of_priv = sizeof(struct af9015_state), | |
1372 | ||
1373 | .generic_bulk_ctrl_endpoint = 0x02, | |
1374 | .generic_bulk_ctrl_endpoint_response = 0x81, | |
1375 | ||
1376 | .identify_state = af9015_identify_state, | |
bab9b4fe | 1377 | .firmware = AF9015_FIRMWARE, |
a3645e54 AP |
1378 | .download_firmware = af9015_download_firmware, |
1379 | ||
a3645e54 | 1380 | .i2c_algo = &af9015_i2c_algo, |
2d2b37c7 AP |
1381 | .read_config = af9015_read_config, |
1382 | .frontend_attach = af9015_af9013_frontend_attach, | |
1383 | .tuner_attach = af9015_tuner_attach, | |
a3645e54 AP |
1384 | .init = af9015_init, |
1385 | .get_rc_config = af9015_get_rc_config, | |
b905a2a1 | 1386 | .get_stream_config = af9015_get_stream_config, |
a3645e54 AP |
1387 | |
1388 | .get_adapter_count = af9015_get_adapter_count, | |
1389 | .adapter = { | |
1390 | { | |
1391 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | |
1392 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | |
1393 | .pid_filter_count = 32, | |
1394 | .pid_filter = af9015_pid_filter, | |
1395 | .pid_filter_ctrl = af9015_pid_filter_ctrl, | |
1a590010 AP |
1396 | |
1397 | .stream = DVB_USB_STREAM_BULK(0x84, 8, TS_USB20_FRAME_SIZE), | |
1398 | }, { | |
1399 | .stream = DVB_USB_STREAM_BULK(0x85, 8, TS_USB20_FRAME_SIZE), | |
a3645e54 | 1400 | }, |
a3645e54 AP |
1401 | }, |
1402 | }; | |
1403 | ||
1404 | static const struct usb_device_id af9015_id_table[] = { | |
1405 | { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015, | |
1406 | &af9015_props, "Afatech AF9015 reference design", NULL) }, | |
1407 | { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016, | |
1408 | &af9015_props, "Afatech AF9015 reference design", NULL) }, | |
1409 | { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD, | |
1410 | &af9015_props, "Leadtek WinFast DTV Dongle Gold", RC_MAP_LEADTEK_Y04G0051) }, | |
1411 | { DVB_USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E, | |
1412 | &af9015_props, "Pinnacle PCTV 71e", NULL) }, | |
1413 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U, | |
1414 | &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) }, | |
1415 | { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN, | |
1416 | &af9015_props, "DigitalNow TinyTwin", RC_MAP_AZUREWAVE_AD_TU700) }, | |
1417 | { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700, | |
1418 | &af9015_props, "TwinHan AzureWave AD-TU700(704J)", RC_MAP_AZUREWAVE_AD_TU700) }, | |
1419 | { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2, | |
1420 | &af9015_props, "TerraTec Cinergy T USB XE", NULL) }, | |
1421 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T, | |
1422 | &af9015_props, "KWorld PlusTV Dual DVB-T PCI (DVB-T PC160-2T)", NULL) }, | |
1423 | { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X, | |
1424 | &af9015_props, "AVerMedia AVerTV DVB-T Volar X", RC_MAP_AVERMEDIA_M135A) }, | |
1425 | { DVB_USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380, | |
1426 | &af9015_props, "Xtensions XD-380", NULL) }, | |
1427 | { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO, | |
1428 | &af9015_props, "MSI DIGIVOX Duo", RC_MAP_MSI_DIGIVOX_III) }, | |
1429 | { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2, | |
1430 | &af9015_props, "Fujitsu-Siemens Slim Mobile USB DVB-T", NULL) }, | |
1431 | { DVB_USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2, | |
1432 | &af9015_props, "Telestar Starstick 2", NULL) }, | |
1433 | { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309, | |
1434 | &af9015_props, "AVerMedia A309", NULL) }, | |
1435 | { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III, | |
1436 | &af9015_props, "MSI Digi VOX mini III", RC_MAP_MSI_DIGIVOX_III) }, | |
1437 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U, | |
1438 | &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) }, | |
1439 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2, | |
1440 | &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) }, | |
1441 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3, | |
1442 | &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) }, | |
1443 | { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT, | |
1444 | &af9015_props, "TrekStor DVB-T USB Stick", RC_MAP_TREKSTOR) }, | |
1445 | { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850, | |
1446 | &af9015_props, "AverMedia AVerTV Volar Black HD (A850)", NULL) }, | |
1447 | { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805, | |
1448 | &af9015_props, "AverMedia AVerTV Volar GPS 805 (A805)", NULL) }, | |
1449 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU, | |
1450 | &af9015_props, "Conceptronic USB2.0 DVB-T CTVDIGRCU V3.0", NULL) }, | |
1451 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810, | |
1452 | &af9015_props, "KWorld Digial MC-810", NULL) }, | |
1453 | { DVB_USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03, | |
1454 | &af9015_props, "Genius TVGo DVB-T03", NULL) }, | |
1455 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2, | |
1456 | &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) }, | |
1457 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T, | |
1458 | &af9015_props, "KWorld PlusTV DVB-T PCI Pro Card (DVB-T PC160-T)", NULL) }, | |
1459 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20, | |
1460 | &af9015_props, "Sveon STV20 Tuner USB DVB-T HDTV", NULL) }, | |
1461 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2, | |
1462 | &af9015_props, "DigitalNow TinyTwin v2", RC_MAP_DIGITALNOW_TINYTWIN) }, | |
1463 | { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS, | |
1464 | &af9015_props, "Leadtek WinFast DTV2000DS", RC_MAP_LEADTEK_Y04G0051) }, | |
1465 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T, | |
1466 | &af9015_props, "KWorld USB DVB-T Stick Mobile (UB383-T)", NULL) }, | |
1467 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4, | |
1468 | &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) }, | |
1469 | { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M, | |
1470 | &af9015_props, "AverMedia AVerTV Volar M (A815Mac)", NULL) }, | |
1471 | { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC, | |
1472 | &af9015_props, "TerraTec Cinergy T Stick RC", RC_MAP_TERRATEC_SLIM_2) }, | |
e8c7aab5 | 1473 | /* XXX: that same ID [0ccd:0099] is used by af9035 driver too */ |
a3645e54 AP |
1474 | { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, |
1475 | &af9015_props, "TerraTec Cinergy T Stick Dual RC", RC_MAP_TERRATEC_SLIM) }, | |
1476 | { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T, | |
1477 | &af9015_props, "AverMedia AVerTV Red HD+ (A850T)", NULL) }, | |
1478 | { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3, | |
1479 | &af9015_props, "DigitalNow TinyTwin v3", RC_MAP_DIGITALNOW_TINYTWIN) }, | |
1480 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22, | |
1481 | &af9015_props, "Sveon STV22 Dual USB DVB-T Tuner HDTV", RC_MAP_MSI_DIGIVOX_III) }, | |
1482 | { } | |
1483 | }; | |
1484 | MODULE_DEVICE_TABLE(usb, af9015_id_table); | |
1485 | ||
80619de8 AP |
1486 | /* usb specific object needed to register this driver with the usb subsystem */ |
1487 | static struct usb_driver af9015_usb_driver = { | |
a3645e54 | 1488 | .name = KBUILD_MODNAME, |
2d2b37c7 | 1489 | .id_table = af9015_id_table, |
e8c7aab5 | 1490 | .probe = af9015_probe, |
a3645e54 | 1491 | .disconnect = dvb_usbv2_disconnect, |
53dc194f AP |
1492 | .suspend = dvb_usbv2_suspend, |
1493 | .resume = dvb_usbv2_resume, | |
04966aa8 | 1494 | .reset_resume = dvb_usbv2_reset_resume, |
a3645e54 | 1495 | .no_dynamic_id = 1, |
77f54517 | 1496 | .soft_unbind = 1, |
80619de8 AP |
1497 | }; |
1498 | ||
ecb3b2b3 | 1499 | module_usb_driver(af9015_usb_driver); |
80619de8 AP |
1500 | |
1501 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | |
bc050e67 | 1502 | MODULE_DESCRIPTION("Afatech AF9015 driver"); |
80619de8 | 1503 | MODULE_LICENSE("GPL"); |
bab9b4fe | 1504 | MODULE_FIRMWARE(AF9015_FIRMWARE); |