diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-06-14 15:35:56 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 22:26:31 -0400 |
commit | 786baecfe78f8e25547c628b48a60fc8e5636056 (patch) | |
tree | bb4101ce010f55cbbfc6d93ee13b44b496a028cc /drivers/media/usb/dvb-usb-v2/mxl111sf.c | |
parent | 616300bd51bee80d2d122c205866aa4c20adbaa8 (diff) |
[media] dvb-usb: move it to drivers/media/usb/dvb-usb
As media/dvb will be removed, move it to a proper place.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/dvb-usb-v2/mxl111sf.c')
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/mxl111sf.c | 1431 |
1 files changed, 1431 insertions, 0 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c new file mode 100644 index 000000000000..efdcb15358f1 --- /dev/null +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c | |||
@@ -0,0 +1,1431 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com) | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the Free | ||
6 | * Software Foundation, version 2. | ||
7 | * | ||
8 | * see Documentation/dvb/README.dvb-usb for more information | ||
9 | */ | ||
10 | |||
11 | #include <linux/vmalloc.h> | ||
12 | #include <linux/i2c.h> | ||
13 | |||
14 | #include "mxl111sf.h" | ||
15 | #include "mxl111sf-reg.h" | ||
16 | #include "mxl111sf-phy.h" | ||
17 | #include "mxl111sf-i2c.h" | ||
18 | #include "mxl111sf-gpio.h" | ||
19 | |||
20 | #include "mxl111sf-demod.h" | ||
21 | #include "mxl111sf-tuner.h" | ||
22 | |||
23 | #include "lgdt3305.h" | ||
24 | #include "lg2160.h" | ||
25 | |||
26 | int dvb_usb_mxl111sf_debug; | ||
27 | module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644); | ||
28 | MODULE_PARM_DESC(debug, "set debugging level " | ||
29 | "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able))."); | ||
30 | |||
31 | int dvb_usb_mxl111sf_isoc; | ||
32 | module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644); | ||
33 | MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc)."); | ||
34 | |||
35 | int dvb_usb_mxl111sf_spi; | ||
36 | module_param_named(spi, dvb_usb_mxl111sf_spi, int, 0644); | ||
37 | MODULE_PARM_DESC(spi, "use spi rather than tp for data xfer (0=tp, 1=spi)."); | ||
38 | |||
39 | #define ANT_PATH_AUTO 0 | ||
40 | #define ANT_PATH_EXTERNAL 1 | ||
41 | #define ANT_PATH_INTERNAL 2 | ||
42 | |||
43 | int dvb_usb_mxl111sf_rfswitch = | ||
44 | #if 0 | ||
45 | ANT_PATH_AUTO; | ||
46 | #else | ||
47 | ANT_PATH_EXTERNAL; | ||
48 | #endif | ||
49 | |||
50 | module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644); | ||
51 | MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int)."); | ||
52 | |||
53 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
54 | |||
55 | #define deb_info pr_debug | ||
56 | #define deb_reg pr_debug | ||
57 | #define deb_adv pr_debug | ||
58 | #define err pr_err | ||
59 | #define info pr_info | ||
60 | |||
61 | int mxl111sf_ctrl_msg(struct dvb_usb_device *d, | ||
62 | u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) | ||
63 | { | ||
64 | int wo = (rbuf == NULL || rlen == 0); /* write-only */ | ||
65 | int ret; | ||
66 | u8 sndbuf[1+wlen]; | ||
67 | |||
68 | deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen); | ||
69 | |||
70 | memset(sndbuf, 0, 1+wlen); | ||
71 | |||
72 | sndbuf[0] = cmd; | ||
73 | memcpy(&sndbuf[1], wbuf, wlen); | ||
74 | |||
75 | ret = (wo) ? dvb_usbv2_generic_write(d, sndbuf, 1+wlen) : | ||
76 | dvb_usbv2_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen); | ||
77 | mxl_fail(ret); | ||
78 | |||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | /* ------------------------------------------------------------------------ */ | ||
83 | |||
84 | #define MXL_CMD_REG_READ 0xaa | ||
85 | #define MXL_CMD_REG_WRITE 0x55 | ||
86 | |||
87 | int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data) | ||
88 | { | ||
89 | u8 buf[2]; | ||
90 | int ret; | ||
91 | |||
92 | ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2); | ||
93 | if (mxl_fail(ret)) { | ||
94 | mxl_debug("error reading reg: 0x%02x", addr); | ||
95 | goto fail; | ||
96 | } | ||
97 | |||
98 | if (buf[0] == addr) | ||
99 | *data = buf[1]; | ||
100 | else { | ||
101 | err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x", | ||
102 | addr, buf[0], buf[1]); | ||
103 | ret = -EINVAL; | ||
104 | } | ||
105 | |||
106 | deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data); | ||
107 | fail: | ||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data) | ||
112 | { | ||
113 | u8 buf[] = { addr, data }; | ||
114 | int ret; | ||
115 | |||
116 | deb_reg("W: (0x%02x, 0x%02x)\n", addr, data); | ||
117 | |||
118 | ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0); | ||
119 | if (mxl_fail(ret)) | ||
120 | err("error writing reg: 0x%02x, val: 0x%02x", addr, data); | ||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | /* ------------------------------------------------------------------------ */ | ||
125 | |||
126 | int mxl111sf_write_reg_mask(struct mxl111sf_state *state, | ||
127 | u8 addr, u8 mask, u8 data) | ||
128 | { | ||
129 | int ret; | ||
130 | u8 val; | ||
131 | |||
132 | if (mask != 0xff) { | ||
133 | ret = mxl111sf_read_reg(state, addr, &val); | ||
134 | #if 1 | ||
135 | /* dont know why this usually errors out on the first try */ | ||
136 | if (mxl_fail(ret)) | ||
137 | err("error writing addr: 0x%02x, mask: 0x%02x, " | ||
138 | "data: 0x%02x, retrying...", addr, mask, data); | ||
139 | |||
140 | ret = mxl111sf_read_reg(state, addr, &val); | ||
141 | #endif | ||
142 | if (mxl_fail(ret)) | ||
143 | goto fail; | ||
144 | } | ||
145 | val &= ~mask; | ||
146 | val |= data; | ||
147 | |||
148 | ret = mxl111sf_write_reg(state, addr, val); | ||
149 | mxl_fail(ret); | ||
150 | fail: | ||
151 | return ret; | ||
152 | } | ||
153 | |||
154 | /* ------------------------------------------------------------------------ */ | ||
155 | |||
156 | int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state, | ||
157 | struct mxl111sf_reg_ctrl_info *ctrl_reg_info) | ||
158 | { | ||
159 | int i, ret = 0; | ||
160 | |||
161 | for (i = 0; ctrl_reg_info[i].addr | | ||
162 | ctrl_reg_info[i].mask | | ||
163 | ctrl_reg_info[i].data; i++) { | ||
164 | |||
165 | ret = mxl111sf_write_reg_mask(state, | ||
166 | ctrl_reg_info[i].addr, | ||
167 | ctrl_reg_info[i].mask, | ||
168 | ctrl_reg_info[i].data); | ||
169 | if (mxl_fail(ret)) { | ||
170 | err("failed on reg #%d (0x%02x)", i, | ||
171 | ctrl_reg_info[i].addr); | ||
172 | break; | ||
173 | } | ||
174 | } | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | /* ------------------------------------------------------------------------ */ | ||
179 | |||
180 | static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state) | ||
181 | { | ||
182 | int ret; | ||
183 | u8 id, ver; | ||
184 | char *mxl_chip, *mxl_rev; | ||
185 | |||
186 | if ((state->chip_id) && (state->chip_ver)) | ||
187 | return 0; | ||
188 | |||
189 | ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id); | ||
190 | if (mxl_fail(ret)) | ||
191 | goto fail; | ||
192 | state->chip_id = id; | ||
193 | |||
194 | ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver); | ||
195 | if (mxl_fail(ret)) | ||
196 | goto fail; | ||
197 | state->chip_ver = ver; | ||
198 | |||
199 | switch (id) { | ||
200 | case 0x61: | ||
201 | mxl_chip = "MxL101SF"; | ||
202 | break; | ||
203 | case 0x63: | ||
204 | mxl_chip = "MxL111SF"; | ||
205 | break; | ||
206 | default: | ||
207 | mxl_chip = "UNKNOWN MxL1X1"; | ||
208 | break; | ||
209 | } | ||
210 | switch (ver) { | ||
211 | case 0x36: | ||
212 | state->chip_rev = MXL111SF_V6; | ||
213 | mxl_rev = "v6"; | ||
214 | break; | ||
215 | case 0x08: | ||
216 | state->chip_rev = MXL111SF_V8_100; | ||
217 | mxl_rev = "v8_100"; | ||
218 | break; | ||
219 | case 0x18: | ||
220 | state->chip_rev = MXL111SF_V8_200; | ||
221 | mxl_rev = "v8_200"; | ||
222 | break; | ||
223 | default: | ||
224 | state->chip_rev = 0; | ||
225 | mxl_rev = "UNKNOWN REVISION"; | ||
226 | break; | ||
227 | } | ||
228 | info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver); | ||
229 | fail: | ||
230 | return ret; | ||
231 | } | ||
232 | |||
233 | #define get_chip_info(state) \ | ||
234 | ({ \ | ||
235 | int ___ret; \ | ||
236 | ___ret = mxl1x1sf_get_chip_info(state); \ | ||
237 | if (mxl_fail(___ret)) { \ | ||
238 | mxl_debug("failed to get chip info" \ | ||
239 | " on first probe attempt"); \ | ||
240 | ___ret = mxl1x1sf_get_chip_info(state); \ | ||
241 | if (mxl_fail(___ret)) \ | ||
242 | err("failed to get chip info during probe"); \ | ||
243 | else \ | ||
244 | mxl_debug("probe needed a retry " \ | ||
245 | "in order to succeed."); \ | ||
246 | } \ | ||
247 | ___ret; \ | ||
248 | }) | ||
249 | |||
250 | /* ------------------------------------------------------------------------ */ | ||
251 | #if 0 | ||
252 | static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff) | ||
253 | { | ||
254 | /* power control depends on which adapter is being woken: | ||
255 | * save this for init, instead, via mxl111sf_adap_fe_init */ | ||
256 | return 0; | ||
257 | } | ||
258 | #endif | ||
259 | |||
260 | static int mxl111sf_adap_fe_init(struct dvb_frontend *fe) | ||
261 | { | ||
262 | struct dvb_usb_device *d = fe_to_d(fe); | ||
263 | struct mxl111sf_state *state = fe_to_priv(fe); | ||
264 | struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id]; | ||
265 | int err; | ||
266 | |||
267 | /* exit if we didnt initialize the driver yet */ | ||
268 | if (!state->chip_id) { | ||
269 | mxl_debug("driver not yet initialized, exit."); | ||
270 | goto fail; | ||
271 | } | ||
272 | |||
273 | deb_info("%s()\n", __func__); | ||
274 | |||
275 | mutex_lock(&state->fe_lock); | ||
276 | |||
277 | state->alt_mode = adap_state->alt_mode; | ||
278 | |||
279 | if (usb_set_interface(d->udev, 0, state->alt_mode) < 0) | ||
280 | err("set interface failed"); | ||
281 | |||
282 | err = mxl1x1sf_soft_reset(state); | ||
283 | mxl_fail(err); | ||
284 | err = mxl111sf_init_tuner_demod(state); | ||
285 | mxl_fail(err); | ||
286 | err = mxl1x1sf_set_device_mode(state, adap_state->device_mode); | ||
287 | |||
288 | mxl_fail(err); | ||
289 | mxl111sf_enable_usb_output(state); | ||
290 | mxl_fail(err); | ||
291 | mxl1x1sf_top_master_ctrl(state, 1); | ||
292 | mxl_fail(err); | ||
293 | |||
294 | if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) && | ||
295 | (state->chip_rev > MXL111SF_V6)) { | ||
296 | mxl111sf_config_pin_mux_modes(state, | ||
297 | PIN_MUX_TS_SPI_IN_MODE_1); | ||
298 | mxl_fail(err); | ||
299 | } | ||
300 | err = mxl111sf_init_port_expander(state); | ||
301 | if (!mxl_fail(err)) { | ||
302 | state->gpio_mode = adap_state->gpio_mode; | ||
303 | err = mxl111sf_gpio_mode_switch(state, state->gpio_mode); | ||
304 | mxl_fail(err); | ||
305 | #if 0 | ||
306 | err = fe->ops.init(fe); | ||
307 | #endif | ||
308 | msleep(100); /* add short delay after enabling | ||
309 | * the demod before touching it */ | ||
310 | } | ||
311 | |||
312 | return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0; | ||
313 | fail: | ||
314 | return -ENODEV; | ||
315 | } | ||
316 | |||
317 | static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe) | ||
318 | { | ||
319 | struct mxl111sf_state *state = fe_to_priv(fe); | ||
320 | struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id]; | ||
321 | int err; | ||
322 | |||
323 | /* exit if we didnt initialize the driver yet */ | ||
324 | if (!state->chip_id) { | ||
325 | mxl_debug("driver not yet initialized, exit."); | ||
326 | goto fail; | ||
327 | } | ||
328 | |||
329 | deb_info("%s()\n", __func__); | ||
330 | |||
331 | err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0; | ||
332 | |||
333 | mutex_unlock(&state->fe_lock); | ||
334 | |||
335 | return err; | ||
336 | fail: | ||
337 | return -ENODEV; | ||
338 | } | ||
339 | |||
340 | |||
341 | static int mxl111sf_ep6_streaming_ctrl(struct dvb_frontend *fe, int onoff) | ||
342 | { | ||
343 | struct mxl111sf_state *state = fe_to_priv(fe); | ||
344 | struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id]; | ||
345 | int ret = 0; | ||
346 | |||
347 | deb_info("%s(%d)\n", __func__, onoff); | ||
348 | |||
349 | if (onoff) { | ||
350 | ret = mxl111sf_enable_usb_output(state); | ||
351 | mxl_fail(ret); | ||
352 | ret = mxl111sf_config_mpeg_in(state, 1, 1, | ||
353 | adap_state->ep6_clockphase, | ||
354 | 0, 0); | ||
355 | mxl_fail(ret); | ||
356 | #if 0 | ||
357 | } else { | ||
358 | ret = mxl111sf_disable_656_port(state); | ||
359 | mxl_fail(ret); | ||
360 | #endif | ||
361 | } | ||
362 | |||
363 | return ret; | ||
364 | } | ||
365 | |||
366 | static int mxl111sf_ep5_streaming_ctrl(struct dvb_frontend *fe, int onoff) | ||
367 | { | ||
368 | struct mxl111sf_state *state = fe_to_priv(fe); | ||
369 | int ret = 0; | ||
370 | |||
371 | deb_info("%s(%d)\n", __func__, onoff); | ||
372 | |||
373 | if (onoff) { | ||
374 | ret = mxl111sf_enable_usb_output(state); | ||
375 | mxl_fail(ret); | ||
376 | |||
377 | ret = mxl111sf_init_i2s_port(state, 200); | ||
378 | mxl_fail(ret); | ||
379 | ret = mxl111sf_config_i2s(state, 0, 15); | ||
380 | mxl_fail(ret); | ||
381 | } else { | ||
382 | ret = mxl111sf_disable_i2s_port(state); | ||
383 | mxl_fail(ret); | ||
384 | } | ||
385 | if (state->chip_rev > MXL111SF_V6) | ||
386 | ret = mxl111sf_config_spi(state, onoff); | ||
387 | mxl_fail(ret); | ||
388 | |||
389 | return ret; | ||
390 | } | ||
391 | |||
392 | static int mxl111sf_ep4_streaming_ctrl(struct dvb_frontend *fe, int onoff) | ||
393 | { | ||
394 | struct mxl111sf_state *state = fe_to_priv(fe); | ||
395 | int ret = 0; | ||
396 | |||
397 | deb_info("%s(%d)\n", __func__, onoff); | ||
398 | |||
399 | if (onoff) { | ||
400 | ret = mxl111sf_enable_usb_output(state); | ||
401 | mxl_fail(ret); | ||
402 | } | ||
403 | |||
404 | return ret; | ||
405 | } | ||
406 | |||
407 | /* ------------------------------------------------------------------------ */ | ||
408 | |||
409 | static struct lgdt3305_config hauppauge_lgdt3305_config = { | ||
410 | .i2c_addr = 0xb2 >> 1, | ||
411 | .mpeg_mode = LGDT3305_MPEG_SERIAL, | ||
412 | .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE, | ||
413 | .tpvalid_polarity = LGDT3305_TP_VALID_HIGH, | ||
414 | .deny_i2c_rptr = 1, | ||
415 | .spectral_inversion = 0, | ||
416 | .qam_if_khz = 6000, | ||
417 | .vsb_if_khz = 6000, | ||
418 | }; | ||
419 | |||
420 | static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id) | ||
421 | { | ||
422 | struct dvb_usb_device *d = adap_to_d(adap); | ||
423 | struct mxl111sf_state *state = d_to_priv(d); | ||
424 | struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id]; | ||
425 | int ret; | ||
426 | |||
427 | deb_adv("%s()\n", __func__); | ||
428 | |||
429 | /* save a pointer to the dvb_usb_device in device state */ | ||
430 | state->d = d; | ||
431 | adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1; | ||
432 | state->alt_mode = adap_state->alt_mode; | ||
433 | |||
434 | if (usb_set_interface(d->udev, 0, state->alt_mode) < 0) | ||
435 | err("set interface failed"); | ||
436 | |||
437 | state->gpio_mode = MXL111SF_GPIO_MOD_ATSC; | ||
438 | adap_state->gpio_mode = state->gpio_mode; | ||
439 | adap_state->device_mode = MXL_TUNER_MODE; | ||
440 | adap_state->ep6_clockphase = 1; | ||
441 | |||
442 | ret = mxl1x1sf_soft_reset(state); | ||
443 | if (mxl_fail(ret)) | ||
444 | goto fail; | ||
445 | ret = mxl111sf_init_tuner_demod(state); | ||
446 | if (mxl_fail(ret)) | ||
447 | goto fail; | ||
448 | |||
449 | ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode); | ||
450 | if (mxl_fail(ret)) | ||
451 | goto fail; | ||
452 | |||
453 | ret = mxl111sf_enable_usb_output(state); | ||
454 | if (mxl_fail(ret)) | ||
455 | goto fail; | ||
456 | ret = mxl1x1sf_top_master_ctrl(state, 1); | ||
457 | if (mxl_fail(ret)) | ||
458 | goto fail; | ||
459 | |||
460 | ret = mxl111sf_init_port_expander(state); | ||
461 | if (mxl_fail(ret)) | ||
462 | goto fail; | ||
463 | ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode); | ||
464 | if (mxl_fail(ret)) | ||
465 | goto fail; | ||
466 | |||
467 | adap->fe[fe_id] = dvb_attach(lgdt3305_attach, | ||
468 | &hauppauge_lgdt3305_config, | ||
469 | &d->i2c_adap); | ||
470 | if (adap->fe[fe_id]) { | ||
471 | state->num_frontends++; | ||
472 | adap_state->fe_init = adap->fe[fe_id]->ops.init; | ||
473 | adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init; | ||
474 | adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep; | ||
475 | adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep; | ||
476 | return 0; | ||
477 | } | ||
478 | ret = -EIO; | ||
479 | fail: | ||
480 | return ret; | ||
481 | } | ||
482 | |||
483 | static struct lg2160_config hauppauge_lg2160_config = { | ||
484 | .lg_chip = LG2160, | ||
485 | .i2c_addr = 0x1c >> 1, | ||
486 | .deny_i2c_rptr = 1, | ||
487 | .spectral_inversion = 0, | ||
488 | .if_khz = 6000, | ||
489 | }; | ||
490 | |||
491 | static int mxl111sf_lg2160_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id) | ||
492 | { | ||
493 | struct dvb_usb_device *d = adap_to_d(adap); | ||
494 | struct mxl111sf_state *state = d_to_priv(d); | ||
495 | struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id]; | ||
496 | int ret; | ||
497 | |||
498 | deb_adv("%s()\n", __func__); | ||
499 | |||
500 | /* save a pointer to the dvb_usb_device in device state */ | ||
501 | state->d = d; | ||
502 | adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1; | ||
503 | state->alt_mode = adap_state->alt_mode; | ||
504 | |||
505 | if (usb_set_interface(d->udev, 0, state->alt_mode) < 0) | ||
506 | err("set interface failed"); | ||
507 | |||
508 | state->gpio_mode = MXL111SF_GPIO_MOD_MH; | ||
509 | adap_state->gpio_mode = state->gpio_mode; | ||
510 | adap_state->device_mode = MXL_TUNER_MODE; | ||
511 | adap_state->ep6_clockphase = 1; | ||
512 | |||
513 | ret = mxl1x1sf_soft_reset(state); | ||
514 | if (mxl_fail(ret)) | ||
515 | goto fail; | ||
516 | ret = mxl111sf_init_tuner_demod(state); | ||
517 | if (mxl_fail(ret)) | ||
518 | goto fail; | ||
519 | |||
520 | ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode); | ||
521 | if (mxl_fail(ret)) | ||
522 | goto fail; | ||
523 | |||
524 | ret = mxl111sf_enable_usb_output(state); | ||
525 | if (mxl_fail(ret)) | ||
526 | goto fail; | ||
527 | ret = mxl1x1sf_top_master_ctrl(state, 1); | ||
528 | if (mxl_fail(ret)) | ||
529 | goto fail; | ||
530 | |||
531 | ret = mxl111sf_init_port_expander(state); | ||
532 | if (mxl_fail(ret)) | ||
533 | goto fail; | ||
534 | ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode); | ||
535 | if (mxl_fail(ret)) | ||
536 | goto fail; | ||
537 | |||
538 | ret = get_chip_info(state); | ||
539 | if (mxl_fail(ret)) | ||
540 | goto fail; | ||
541 | |||
542 | adap->fe[fe_id] = dvb_attach(lg2160_attach, | ||
543 | &hauppauge_lg2160_config, | ||
544 | &d->i2c_adap); | ||
545 | if (adap->fe[fe_id]) { | ||
546 | state->num_frontends++; | ||
547 | adap_state->fe_init = adap->fe[fe_id]->ops.init; | ||
548 | adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init; | ||
549 | adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep; | ||
550 | adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep; | ||
551 | return 0; | ||
552 | } | ||
553 | ret = -EIO; | ||
554 | fail: | ||
555 | return ret; | ||
556 | } | ||
557 | |||
558 | static struct lg2160_config hauppauge_lg2161_1019_config = { | ||
559 | .lg_chip = LG2161_1019, | ||
560 | .i2c_addr = 0x1c >> 1, | ||
561 | .deny_i2c_rptr = 1, | ||
562 | .spectral_inversion = 0, | ||
563 | .if_khz = 6000, | ||
564 | .output_if = 2, /* LG2161_OIF_SPI_MAS */ | ||
565 | }; | ||
566 | |||
567 | static struct lg2160_config hauppauge_lg2161_1040_config = { | ||
568 | .lg_chip = LG2161_1040, | ||
569 | .i2c_addr = 0x1c >> 1, | ||
570 | .deny_i2c_rptr = 1, | ||
571 | .spectral_inversion = 0, | ||
572 | .if_khz = 6000, | ||
573 | .output_if = 4, /* LG2161_OIF_SPI_MAS */ | ||
574 | }; | ||
575 | |||
576 | static int mxl111sf_lg2161_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id) | ||
577 | { | ||
578 | struct dvb_usb_device *d = adap_to_d(adap); | ||
579 | struct mxl111sf_state *state = d_to_priv(d); | ||
580 | struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id]; | ||
581 | int ret; | ||
582 | |||
583 | deb_adv("%s()\n", __func__); | ||
584 | |||
585 | /* save a pointer to the dvb_usb_device in device state */ | ||
586 | state->d = d; | ||
587 | adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1; | ||
588 | state->alt_mode = adap_state->alt_mode; | ||
589 | |||
590 | if (usb_set_interface(d->udev, 0, state->alt_mode) < 0) | ||
591 | err("set interface failed"); | ||
592 | |||
593 | state->gpio_mode = MXL111SF_GPIO_MOD_MH; | ||
594 | adap_state->gpio_mode = state->gpio_mode; | ||
595 | adap_state->device_mode = MXL_TUNER_MODE; | ||
596 | adap_state->ep6_clockphase = 1; | ||
597 | |||
598 | ret = mxl1x1sf_soft_reset(state); | ||
599 | if (mxl_fail(ret)) | ||
600 | goto fail; | ||
601 | ret = mxl111sf_init_tuner_demod(state); | ||
602 | if (mxl_fail(ret)) | ||
603 | goto fail; | ||
604 | |||
605 | ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode); | ||
606 | if (mxl_fail(ret)) | ||
607 | goto fail; | ||
608 | |||
609 | ret = mxl111sf_enable_usb_output(state); | ||
610 | if (mxl_fail(ret)) | ||
611 | goto fail; | ||
612 | ret = mxl1x1sf_top_master_ctrl(state, 1); | ||
613 | if (mxl_fail(ret)) | ||
614 | goto fail; | ||
615 | |||
616 | ret = mxl111sf_init_port_expander(state); | ||
617 | if (mxl_fail(ret)) | ||
618 | goto fail; | ||
619 | ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode); | ||
620 | if (mxl_fail(ret)) | ||
621 | goto fail; | ||
622 | |||
623 | ret = get_chip_info(state); | ||
624 | if (mxl_fail(ret)) | ||
625 | goto fail; | ||
626 | |||
627 | adap->fe[fe_id] = dvb_attach(lg2160_attach, | ||
628 | (MXL111SF_V8_200 == state->chip_rev) ? | ||
629 | &hauppauge_lg2161_1040_config : | ||
630 | &hauppauge_lg2161_1019_config, | ||
631 | &d->i2c_adap); | ||
632 | if (adap->fe[fe_id]) { | ||
633 | state->num_frontends++; | ||
634 | adap_state->fe_init = adap->fe[fe_id]->ops.init; | ||
635 | adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init; | ||
636 | adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep; | ||
637 | adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep; | ||
638 | return 0; | ||
639 | } | ||
640 | ret = -EIO; | ||
641 | fail: | ||
642 | return ret; | ||
643 | } | ||
644 | |||
645 | static struct lg2160_config hauppauge_lg2161_1019_ep6_config = { | ||
646 | .lg_chip = LG2161_1019, | ||
647 | .i2c_addr = 0x1c >> 1, | ||
648 | .deny_i2c_rptr = 1, | ||
649 | .spectral_inversion = 0, | ||
650 | .if_khz = 6000, | ||
651 | .output_if = 1, /* LG2161_OIF_SERIAL_TS */ | ||
652 | }; | ||
653 | |||
654 | static struct lg2160_config hauppauge_lg2161_1040_ep6_config = { | ||
655 | .lg_chip = LG2161_1040, | ||
656 | .i2c_addr = 0x1c >> 1, | ||
657 | .deny_i2c_rptr = 1, | ||
658 | .spectral_inversion = 0, | ||
659 | .if_khz = 6000, | ||
660 | .output_if = 7, /* LG2161_OIF_SERIAL_TS */ | ||
661 | }; | ||
662 | |||
663 | static int mxl111sf_lg2161_ep6_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id) | ||
664 | { | ||
665 | struct dvb_usb_device *d = adap_to_d(adap); | ||
666 | struct mxl111sf_state *state = d_to_priv(d); | ||
667 | struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id]; | ||
668 | int ret; | ||
669 | |||
670 | deb_adv("%s()\n", __func__); | ||
671 | |||
672 | /* save a pointer to the dvb_usb_device in device state */ | ||
673 | state->d = d; | ||
674 | adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1; | ||
675 | state->alt_mode = adap_state->alt_mode; | ||
676 | |||
677 | if (usb_set_interface(d->udev, 0, state->alt_mode) < 0) | ||
678 | err("set interface failed"); | ||
679 | |||
680 | state->gpio_mode = MXL111SF_GPIO_MOD_MH; | ||
681 | adap_state->gpio_mode = state->gpio_mode; | ||
682 | adap_state->device_mode = MXL_TUNER_MODE; | ||
683 | adap_state->ep6_clockphase = 0; | ||
684 | |||
685 | ret = mxl1x1sf_soft_reset(state); | ||
686 | if (mxl_fail(ret)) | ||
687 | goto fail; | ||
688 | ret = mxl111sf_init_tuner_demod(state); | ||
689 | if (mxl_fail(ret)) | ||
690 | goto fail; | ||
691 | |||
692 | ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode); | ||
693 | if (mxl_fail(ret)) | ||
694 | goto fail; | ||
695 | |||
696 | ret = mxl111sf_enable_usb_output(state); | ||
697 | if (mxl_fail(ret)) | ||
698 | goto fail; | ||
699 | ret = mxl1x1sf_top_master_ctrl(state, 1); | ||
700 | if (mxl_fail(ret)) | ||
701 | goto fail; | ||
702 | |||
703 | ret = mxl111sf_init_port_expander(state); | ||
704 | if (mxl_fail(ret)) | ||
705 | goto fail; | ||
706 | ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode); | ||
707 | if (mxl_fail(ret)) | ||
708 | goto fail; | ||
709 | |||
710 | ret = get_chip_info(state); | ||
711 | if (mxl_fail(ret)) | ||
712 | goto fail; | ||
713 | |||
714 | adap->fe[fe_id] = dvb_attach(lg2160_attach, | ||
715 | (MXL111SF_V8_200 == state->chip_rev) ? | ||
716 | &hauppauge_lg2161_1040_ep6_config : | ||
717 | &hauppauge_lg2161_1019_ep6_config, | ||
718 | &d->i2c_adap); | ||
719 | if (adap->fe[fe_id]) { | ||
720 | state->num_frontends++; | ||
721 | adap_state->fe_init = adap->fe[fe_id]->ops.init; | ||
722 | adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init; | ||
723 | adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep; | ||
724 | adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep; | ||
725 | return 0; | ||
726 | } | ||
727 | ret = -EIO; | ||
728 | fail: | ||
729 | return ret; | ||
730 | } | ||
731 | |||
732 | static struct mxl111sf_demod_config mxl_demod_config = { | ||
733 | .read_reg = mxl111sf_read_reg, | ||
734 | .write_reg = mxl111sf_write_reg, | ||
735 | .program_regs = mxl111sf_ctrl_program_regs, | ||
736 | }; | ||
737 | |||
738 | static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap, u8 fe_id) | ||
739 | { | ||
740 | struct dvb_usb_device *d = adap_to_d(adap); | ||
741 | struct mxl111sf_state *state = d_to_priv(d); | ||
742 | struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id]; | ||
743 | int ret; | ||
744 | |||
745 | deb_adv("%s()\n", __func__); | ||
746 | |||
747 | /* save a pointer to the dvb_usb_device in device state */ | ||
748 | state->d = d; | ||
749 | adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2; | ||
750 | state->alt_mode = adap_state->alt_mode; | ||
751 | |||
752 | if (usb_set_interface(d->udev, 0, state->alt_mode) < 0) | ||
753 | err("set interface failed"); | ||
754 | |||
755 | state->gpio_mode = MXL111SF_GPIO_MOD_DVBT; | ||
756 | adap_state->gpio_mode = state->gpio_mode; | ||
757 | adap_state->device_mode = MXL_SOC_MODE; | ||
758 | adap_state->ep6_clockphase = 1; | ||
759 | |||
760 | ret = mxl1x1sf_soft_reset(state); | ||
761 | if (mxl_fail(ret)) | ||
762 | goto fail; | ||
763 | ret = mxl111sf_init_tuner_demod(state); | ||
764 | if (mxl_fail(ret)) | ||
765 | goto fail; | ||
766 | |||
767 | ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode); | ||
768 | if (mxl_fail(ret)) | ||
769 | goto fail; | ||
770 | |||
771 | ret = mxl111sf_enable_usb_output(state); | ||
772 | if (mxl_fail(ret)) | ||
773 | goto fail; | ||
774 | ret = mxl1x1sf_top_master_ctrl(state, 1); | ||
775 | if (mxl_fail(ret)) | ||
776 | goto fail; | ||
777 | |||
778 | /* dont care if this fails */ | ||
779 | mxl111sf_init_port_expander(state); | ||
780 | |||
781 | adap->fe[fe_id] = dvb_attach(mxl111sf_demod_attach, state, | ||
782 | &mxl_demod_config); | ||
783 | if (adap->fe[fe_id]) { | ||
784 | state->num_frontends++; | ||
785 | adap_state->fe_init = adap->fe[fe_id]->ops.init; | ||
786 | adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init; | ||
787 | adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep; | ||
788 | adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep; | ||
789 | return 0; | ||
790 | } | ||
791 | ret = -EIO; | ||
792 | fail: | ||
793 | return ret; | ||
794 | } | ||
795 | |||
796 | static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state, | ||
797 | int antpath) | ||
798 | { | ||
799 | return mxl111sf_idac_config(state, 1, 1, | ||
800 | (antpath == ANT_PATH_INTERNAL) ? | ||
801 | 0x3f : 0x00, 0); | ||
802 | } | ||
803 | |||
804 | #define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \ | ||
805 | err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \ | ||
806 | __func__, __LINE__, \ | ||
807 | (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \ | ||
808 | pwr0, pwr1, pwr2, pwr3) | ||
809 | |||
810 | #define ANT_HUNT_SLEEP 90 | ||
811 | #define ANT_EXT_TWEAK 0 | ||
812 | |||
813 | static int mxl111sf_ant_hunt(struct dvb_frontend *fe) | ||
814 | { | ||
815 | struct mxl111sf_state *state = fe_to_priv(fe); | ||
816 | int antctrl = dvb_usb_mxl111sf_rfswitch; | ||
817 | |||
818 | u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2; | ||
819 | |||
820 | /* FIXME: must force EXTERNAL for QAM - done elsewhere */ | ||
821 | mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ? | ||
822 | ANT_PATH_EXTERNAL : antctrl); | ||
823 | |||
824 | if (antctrl == ANT_PATH_AUTO) { | ||
825 | #if 0 | ||
826 | msleep(ANT_HUNT_SLEEP); | ||
827 | #endif | ||
828 | fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA); | ||
829 | |||
830 | mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL); | ||
831 | msleep(ANT_HUNT_SLEEP); | ||
832 | fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0); | ||
833 | |||
834 | mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL); | ||
835 | msleep(ANT_HUNT_SLEEP); | ||
836 | fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1); | ||
837 | |||
838 | mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL); | ||
839 | msleep(ANT_HUNT_SLEEP); | ||
840 | fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2); | ||
841 | |||
842 | if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) { | ||
843 | /* return with EXTERNAL enabled */ | ||
844 | mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL); | ||
845 | DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA, | ||
846 | rxPwr0, rxPwr1, rxPwr2); | ||
847 | } else { | ||
848 | /* return with INTERNAL enabled */ | ||
849 | DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA, | ||
850 | rxPwr0, rxPwr1, rxPwr2); | ||
851 | } | ||
852 | } | ||
853 | return 0; | ||
854 | } | ||
855 | |||
856 | static struct mxl111sf_tuner_config mxl_tuner_config = { | ||
857 | .if_freq = MXL_IF_6_0, /* applies to external IF output, only */ | ||
858 | .invert_spectrum = 0, | ||
859 | .read_reg = mxl111sf_read_reg, | ||
860 | .write_reg = mxl111sf_write_reg, | ||
861 | .program_regs = mxl111sf_ctrl_program_regs, | ||
862 | .top_master_ctrl = mxl1x1sf_top_master_ctrl, | ||
863 | .ant_hunt = mxl111sf_ant_hunt, | ||
864 | }; | ||
865 | |||
866 | static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap) | ||
867 | { | ||
868 | struct mxl111sf_state *state = adap_to_priv(adap); | ||
869 | int i; | ||
870 | |||
871 | deb_adv("%s()\n", __func__); | ||
872 | |||
873 | for (i = 0; i < state->num_frontends; i++) { | ||
874 | if (dvb_attach(mxl111sf_tuner_attach, adap->fe[i], state, | ||
875 | &mxl_tuner_config) == NULL) | ||
876 | return -EIO; | ||
877 | adap->fe[i]->ops.read_signal_strength = adap->fe[i]->ops.tuner_ops.get_rf_strength; | ||
878 | } | ||
879 | |||
880 | return 0; | ||
881 | } | ||
882 | |||
883 | static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter) | ||
884 | { | ||
885 | return I2C_FUNC_I2C; | ||
886 | } | ||
887 | |||
888 | struct i2c_algorithm mxl111sf_i2c_algo = { | ||
889 | .master_xfer = mxl111sf_i2c_xfer, | ||
890 | .functionality = mxl111sf_i2c_func, | ||
891 | #ifdef NEED_ALGO_CONTROL | ||
892 | .algo_control = dummy_algo_control, | ||
893 | #endif | ||
894 | }; | ||
895 | |||
896 | static int mxl111sf_init(struct dvb_usb_device *d) | ||
897 | { | ||
898 | struct mxl111sf_state *state = d_to_priv(d); | ||
899 | int ret; | ||
900 | static u8 eeprom[256]; | ||
901 | struct i2c_client c; | ||
902 | |||
903 | ret = get_chip_info(state); | ||
904 | if (mxl_fail(ret)) | ||
905 | err("failed to get chip info during probe"); | ||
906 | |||
907 | mutex_init(&state->fe_lock); | ||
908 | |||
909 | if (state->chip_rev > MXL111SF_V6) | ||
910 | mxl111sf_config_pin_mux_modes(state, PIN_MUX_TS_SPI_IN_MODE_1); | ||
911 | |||
912 | c.adapter = &d->i2c_adap; | ||
913 | c.addr = 0xa0 >> 1; | ||
914 | |||
915 | ret = tveeprom_read(&c, eeprom, sizeof(eeprom)); | ||
916 | if (mxl_fail(ret)) | ||
917 | return 0; | ||
918 | tveeprom_hauppauge_analog(&c, &state->tv, (0x84 == eeprom[0xa0]) ? | ||
919 | eeprom + 0xa0 : eeprom + 0x80); | ||
920 | #if 0 | ||
921 | switch (state->tv.model) { | ||
922 | case 117001: | ||
923 | case 126001: | ||
924 | case 138001: | ||
925 | break; | ||
926 | default: | ||
927 | printk(KERN_WARNING "%s: warning: " | ||
928 | "unknown hauppauge model #%d\n", | ||
929 | __func__, state->tv.model); | ||
930 | } | ||
931 | #endif | ||
932 | return 0; | ||
933 | } | ||
934 | |||
935 | static int mxl111sf_frontend_attach_dvbt(struct dvb_usb_adapter *adap) | ||
936 | { | ||
937 | return mxl111sf_attach_demod(adap, 0); | ||
938 | } | ||
939 | |||
940 | static int mxl111sf_frontend_attach_atsc(struct dvb_usb_adapter *adap) | ||
941 | { | ||
942 | return mxl111sf_lgdt3305_frontend_attach(adap, 0); | ||
943 | } | ||
944 | |||
945 | static int mxl111sf_frontend_attach_mh(struct dvb_usb_adapter *adap) | ||
946 | { | ||
947 | return mxl111sf_lg2160_frontend_attach(adap, 0); | ||
948 | } | ||
949 | |||
950 | static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap) | ||
951 | { | ||
952 | int ret; | ||
953 | deb_info("%s\n", __func__); | ||
954 | |||
955 | ret = mxl111sf_lgdt3305_frontend_attach(adap, 0); | ||
956 | if (ret < 0) | ||
957 | return ret; | ||
958 | |||
959 | ret = mxl111sf_attach_demod(adap, 1); | ||
960 | if (ret < 0) | ||
961 | return ret; | ||
962 | |||
963 | ret = mxl111sf_lg2160_frontend_attach(adap, 2); | ||
964 | if (ret < 0) | ||
965 | return ret; | ||
966 | |||
967 | return ret; | ||
968 | } | ||
969 | |||
970 | static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap) | ||
971 | { | ||
972 | int ret; | ||
973 | deb_info("%s\n", __func__); | ||
974 | |||
975 | ret = mxl111sf_lgdt3305_frontend_attach(adap, 0); | ||
976 | if (ret < 0) | ||
977 | return ret; | ||
978 | |||
979 | ret = mxl111sf_attach_demod(adap, 1); | ||
980 | if (ret < 0) | ||
981 | return ret; | ||
982 | |||
983 | ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 2); | ||
984 | if (ret < 0) | ||
985 | return ret; | ||
986 | |||
987 | return ret; | ||
988 | } | ||
989 | |||
990 | static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap) | ||
991 | { | ||
992 | int ret; | ||
993 | deb_info("%s\n", __func__); | ||
994 | |||
995 | ret = mxl111sf_attach_demod(adap, 0); | ||
996 | if (ret < 0) | ||
997 | return ret; | ||
998 | |||
999 | if (dvb_usb_mxl111sf_spi) | ||
1000 | ret = mxl111sf_lg2161_frontend_attach(adap, 1); | ||
1001 | else | ||
1002 | ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 1); | ||
1003 | |||
1004 | return ret; | ||
1005 | } | ||
1006 | |||
1007 | static void mxl111sf_stream_config_bulk(struct usb_data_stream_properties *stream, u8 endpoint) | ||
1008 | { | ||
1009 | deb_info("%s: endpoint=%d size=8192\n", __func__, endpoint); | ||
1010 | stream->type = USB_BULK; | ||
1011 | stream->count = 5; | ||
1012 | stream->endpoint = endpoint; | ||
1013 | stream->u.bulk.buffersize = 8192; | ||
1014 | } | ||
1015 | |||
1016 | static void mxl111sf_stream_config_isoc(struct usb_data_stream_properties *stream, | ||
1017 | u8 endpoint, int framesperurb, int framesize) | ||
1018 | { | ||
1019 | deb_info("%s: endpoint=%d size=%d\n", __func__, endpoint, | ||
1020 | framesperurb * framesize); | ||
1021 | stream->type = USB_ISOC; | ||
1022 | stream->count = 5; | ||
1023 | stream->endpoint = endpoint; | ||
1024 | stream->u.isoc.framesperurb = framesperurb; | ||
1025 | stream->u.isoc.framesize = framesize; | ||
1026 | stream->u.isoc.interval = 1; | ||
1027 | } | ||
1028 | |||
1029 | /* DVB USB Driver stuff */ | ||
1030 | |||
1031 | /* dvbt mxl111sf | ||
1032 | * bulk EP4/BULK/5/8192 | ||
1033 | * isoc EP4/ISOC/5/96/564 | ||
1034 | */ | ||
1035 | static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe, | ||
1036 | u8 *ts_type, struct usb_data_stream_properties *stream) | ||
1037 | { | ||
1038 | deb_info("%s: fe=%d\n", __func__, fe->id); | ||
1039 | |||
1040 | *ts_type = DVB_USB_FE_TS_TYPE_188; | ||
1041 | if (dvb_usb_mxl111sf_isoc) | ||
1042 | mxl111sf_stream_config_isoc(stream, 4, 96, 564); | ||
1043 | else | ||
1044 | mxl111sf_stream_config_bulk(stream, 4); | ||
1045 | return 0; | ||
1046 | } | ||
1047 | |||
1048 | static struct dvb_usb_device_properties mxl111sf_props_dvbt = { | ||
1049 | .driver_name = KBUILD_MODNAME, | ||
1050 | .owner = THIS_MODULE, | ||
1051 | .adapter_nr = adapter_nr, | ||
1052 | .size_of_priv = sizeof(struct mxl111sf_state), | ||
1053 | |||
1054 | .generic_bulk_ctrl_endpoint = 0x02, | ||
1055 | .generic_bulk_ctrl_endpoint_response = 0x81, | ||
1056 | |||
1057 | .i2c_algo = &mxl111sf_i2c_algo, | ||
1058 | .frontend_attach = mxl111sf_frontend_attach_dvbt, | ||
1059 | .tuner_attach = mxl111sf_attach_tuner, | ||
1060 | .init = mxl111sf_init, | ||
1061 | .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, | ||
1062 | .get_stream_config = mxl111sf_get_stream_config_dvbt, | ||
1063 | |||
1064 | .num_adapters = 1, | ||
1065 | .adapter = { | ||
1066 | { | ||
1067 | .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1), | ||
1068 | } | ||
1069 | } | ||
1070 | }; | ||
1071 | |||
1072 | /* atsc lgdt3305 | ||
1073 | * bulk EP6/BULK/5/8192 | ||
1074 | * isoc EP6/ISOC/5/24/3072 | ||
1075 | */ | ||
1076 | static int mxl111sf_get_stream_config_atsc(struct dvb_frontend *fe, | ||
1077 | u8 *ts_type, struct usb_data_stream_properties *stream) | ||
1078 | { | ||
1079 | deb_info("%s: fe=%d\n", __func__, fe->id); | ||
1080 | |||
1081 | *ts_type = DVB_USB_FE_TS_TYPE_188; | ||
1082 | if (dvb_usb_mxl111sf_isoc) | ||
1083 | mxl111sf_stream_config_isoc(stream, 6, 24, 3072); | ||
1084 | else | ||
1085 | mxl111sf_stream_config_bulk(stream, 6); | ||
1086 | return 0; | ||
1087 | } | ||
1088 | |||
1089 | static struct dvb_usb_device_properties mxl111sf_props_atsc = { | ||
1090 | .driver_name = KBUILD_MODNAME, | ||
1091 | .owner = THIS_MODULE, | ||
1092 | .adapter_nr = adapter_nr, | ||
1093 | .size_of_priv = sizeof(struct mxl111sf_state), | ||
1094 | |||
1095 | .generic_bulk_ctrl_endpoint = 0x02, | ||
1096 | .generic_bulk_ctrl_endpoint_response = 0x81, | ||
1097 | |||
1098 | .i2c_algo = &mxl111sf_i2c_algo, | ||
1099 | .frontend_attach = mxl111sf_frontend_attach_atsc, | ||
1100 | .tuner_attach = mxl111sf_attach_tuner, | ||
1101 | .init = mxl111sf_init, | ||
1102 | .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, | ||
1103 | .get_stream_config = mxl111sf_get_stream_config_atsc, | ||
1104 | |||
1105 | .num_adapters = 1, | ||
1106 | .adapter = { | ||
1107 | { | ||
1108 | .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1), | ||
1109 | } | ||
1110 | } | ||
1111 | }; | ||
1112 | |||
1113 | /* mh lg2160 | ||
1114 | * bulk EP5/BULK/5/8192/RAW | ||
1115 | * isoc EP5/ISOC/5/96/200/RAW | ||
1116 | */ | ||
1117 | static int mxl111sf_get_stream_config_mh(struct dvb_frontend *fe, | ||
1118 | u8 *ts_type, struct usb_data_stream_properties *stream) | ||
1119 | { | ||
1120 | deb_info("%s: fe=%d\n", __func__, fe->id); | ||
1121 | |||
1122 | *ts_type = DVB_USB_FE_TS_TYPE_RAW; | ||
1123 | if (dvb_usb_mxl111sf_isoc) | ||
1124 | mxl111sf_stream_config_isoc(stream, 5, 96, 200); | ||
1125 | else | ||
1126 | mxl111sf_stream_config_bulk(stream, 5); | ||
1127 | return 0; | ||
1128 | } | ||
1129 | |||
1130 | static struct dvb_usb_device_properties mxl111sf_props_mh = { | ||
1131 | .driver_name = KBUILD_MODNAME, | ||
1132 | .owner = THIS_MODULE, | ||
1133 | .adapter_nr = adapter_nr, | ||
1134 | .size_of_priv = sizeof(struct mxl111sf_state), | ||
1135 | |||
1136 | .generic_bulk_ctrl_endpoint = 0x02, | ||
1137 | .generic_bulk_ctrl_endpoint_response = 0x81, | ||
1138 | |||
1139 | .i2c_algo = &mxl111sf_i2c_algo, | ||
1140 | .frontend_attach = mxl111sf_frontend_attach_mh, | ||
1141 | .tuner_attach = mxl111sf_attach_tuner, | ||
1142 | .init = mxl111sf_init, | ||
1143 | .streaming_ctrl = mxl111sf_ep5_streaming_ctrl, | ||
1144 | .get_stream_config = mxl111sf_get_stream_config_mh, | ||
1145 | |||
1146 | .num_adapters = 1, | ||
1147 | .adapter = { | ||
1148 | { | ||
1149 | .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1), | ||
1150 | } | ||
1151 | } | ||
1152 | }; | ||
1153 | |||
1154 | /* atsc mh lgdt3305 mxl111sf lg2160 | ||
1155 | * bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP5/BULK/5/8192/RAW | ||
1156 | * isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW | ||
1157 | */ | ||
1158 | static int mxl111sf_get_stream_config_atsc_mh(struct dvb_frontend *fe, | ||
1159 | u8 *ts_type, struct usb_data_stream_properties *stream) | ||
1160 | { | ||
1161 | deb_info("%s: fe=%d\n", __func__, fe->id); | ||
1162 | |||
1163 | if (fe->id == 0) { | ||
1164 | *ts_type = DVB_USB_FE_TS_TYPE_188; | ||
1165 | if (dvb_usb_mxl111sf_isoc) | ||
1166 | mxl111sf_stream_config_isoc(stream, 6, 24, 3072); | ||
1167 | else | ||
1168 | mxl111sf_stream_config_bulk(stream, 6); | ||
1169 | } else if (fe->id == 1) { | ||
1170 | *ts_type = DVB_USB_FE_TS_TYPE_188; | ||
1171 | if (dvb_usb_mxl111sf_isoc) | ||
1172 | mxl111sf_stream_config_isoc(stream, 4, 96, 564); | ||
1173 | else | ||
1174 | mxl111sf_stream_config_bulk(stream, 4); | ||
1175 | } else if (fe->id == 2) { | ||
1176 | *ts_type = DVB_USB_FE_TS_TYPE_RAW; | ||
1177 | if (dvb_usb_mxl111sf_isoc) | ||
1178 | mxl111sf_stream_config_isoc(stream, 5, 96, 200); | ||
1179 | else | ||
1180 | mxl111sf_stream_config_bulk(stream, 5); | ||
1181 | } | ||
1182 | return 0; | ||
1183 | } | ||
1184 | |||
1185 | static int mxl111sf_streaming_ctrl_atsc_mh(struct dvb_frontend *fe, int onoff) | ||
1186 | { | ||
1187 | deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff); | ||
1188 | |||
1189 | if (fe->id == 0) | ||
1190 | return mxl111sf_ep6_streaming_ctrl(fe, onoff); | ||
1191 | else if (fe->id == 1) | ||
1192 | return mxl111sf_ep4_streaming_ctrl(fe, onoff); | ||
1193 | else if (fe->id == 2) | ||
1194 | return mxl111sf_ep5_streaming_ctrl(fe, onoff); | ||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1198 | static struct dvb_usb_device_properties mxl111sf_props_atsc_mh = { | ||
1199 | .driver_name = KBUILD_MODNAME, | ||
1200 | .owner = THIS_MODULE, | ||
1201 | .adapter_nr = adapter_nr, | ||
1202 | .size_of_priv = sizeof(struct mxl111sf_state), | ||
1203 | |||
1204 | .generic_bulk_ctrl_endpoint = 0x02, | ||
1205 | .generic_bulk_ctrl_endpoint_response = 0x81, | ||
1206 | |||
1207 | .i2c_algo = &mxl111sf_i2c_algo, | ||
1208 | .frontend_attach = mxl111sf_frontend_attach_atsc_mh, | ||
1209 | .tuner_attach = mxl111sf_attach_tuner, | ||
1210 | .init = mxl111sf_init, | ||
1211 | .streaming_ctrl = mxl111sf_streaming_ctrl_atsc_mh, | ||
1212 | .get_stream_config = mxl111sf_get_stream_config_atsc_mh, | ||
1213 | |||
1214 | .num_adapters = 1, | ||
1215 | .adapter = { | ||
1216 | { | ||
1217 | .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1), | ||
1218 | } | ||
1219 | } | ||
1220 | }; | ||
1221 | |||
1222 | /* mercury lgdt3305 mxl111sf lg2161 | ||
1223 | * tp bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP6/BULK/5/8192/RAW | ||
1224 | * tp isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW | ||
1225 | * spi bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP5/BULK/5/8192/RAW | ||
1226 | * spi isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW | ||
1227 | */ | ||
1228 | static int mxl111sf_get_stream_config_mercury(struct dvb_frontend *fe, | ||
1229 | u8 *ts_type, struct usb_data_stream_properties *stream) | ||
1230 | { | ||
1231 | deb_info("%s: fe=%d\n", __func__, fe->id); | ||
1232 | |||
1233 | if (fe->id == 0) { | ||
1234 | *ts_type = DVB_USB_FE_TS_TYPE_188; | ||
1235 | if (dvb_usb_mxl111sf_isoc) | ||
1236 | mxl111sf_stream_config_isoc(stream, 6, 24, 3072); | ||
1237 | else | ||
1238 | mxl111sf_stream_config_bulk(stream, 6); | ||
1239 | } else if (fe->id == 1) { | ||
1240 | *ts_type = DVB_USB_FE_TS_TYPE_188; | ||
1241 | if (dvb_usb_mxl111sf_isoc) | ||
1242 | mxl111sf_stream_config_isoc(stream, 4, 96, 564); | ||
1243 | else | ||
1244 | mxl111sf_stream_config_bulk(stream, 4); | ||
1245 | } else if (fe->id == 2 && dvb_usb_mxl111sf_spi) { | ||
1246 | *ts_type = DVB_USB_FE_TS_TYPE_RAW; | ||
1247 | if (dvb_usb_mxl111sf_isoc) | ||
1248 | mxl111sf_stream_config_isoc(stream, 5, 96, 200); | ||
1249 | else | ||
1250 | mxl111sf_stream_config_bulk(stream, 5); | ||
1251 | } else if (fe->id == 2 && !dvb_usb_mxl111sf_spi) { | ||
1252 | *ts_type = DVB_USB_FE_TS_TYPE_RAW; | ||
1253 | if (dvb_usb_mxl111sf_isoc) | ||
1254 | mxl111sf_stream_config_isoc(stream, 6, 24, 3072); | ||
1255 | else | ||
1256 | mxl111sf_stream_config_bulk(stream, 6); | ||
1257 | } | ||
1258 | return 0; | ||
1259 | } | ||
1260 | |||
1261 | static int mxl111sf_streaming_ctrl_mercury(struct dvb_frontend *fe, int onoff) | ||
1262 | { | ||
1263 | deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff); | ||
1264 | |||
1265 | if (fe->id == 0) | ||
1266 | return mxl111sf_ep6_streaming_ctrl(fe, onoff); | ||
1267 | else if (fe->id == 1) | ||
1268 | return mxl111sf_ep4_streaming_ctrl(fe, onoff); | ||
1269 | else if (fe->id == 2 && dvb_usb_mxl111sf_spi) | ||
1270 | return mxl111sf_ep5_streaming_ctrl(fe, onoff); | ||
1271 | else if (fe->id == 2 && !dvb_usb_mxl111sf_spi) | ||
1272 | return mxl111sf_ep6_streaming_ctrl(fe, onoff); | ||
1273 | return 0; | ||
1274 | } | ||
1275 | |||
1276 | static struct dvb_usb_device_properties mxl111sf_props_mercury = { | ||
1277 | .driver_name = KBUILD_MODNAME, | ||
1278 | .owner = THIS_MODULE, | ||
1279 | .adapter_nr = adapter_nr, | ||
1280 | .size_of_priv = sizeof(struct mxl111sf_state), | ||
1281 | |||
1282 | .generic_bulk_ctrl_endpoint = 0x02, | ||
1283 | .generic_bulk_ctrl_endpoint_response = 0x81, | ||
1284 | |||
1285 | .i2c_algo = &mxl111sf_i2c_algo, | ||
1286 | .frontend_attach = mxl111sf_frontend_attach_mercury, | ||
1287 | .tuner_attach = mxl111sf_attach_tuner, | ||
1288 | .init = mxl111sf_init, | ||
1289 | .streaming_ctrl = mxl111sf_streaming_ctrl_mercury, | ||
1290 | .get_stream_config = mxl111sf_get_stream_config_mercury, | ||
1291 | |||
1292 | .num_adapters = 1, | ||
1293 | .adapter = { | ||
1294 | { | ||
1295 | .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1), | ||
1296 | } | ||
1297 | } | ||
1298 | }; | ||
1299 | |||
1300 | /* mercury mh mxl111sf lg2161 | ||
1301 | * tp bulk EP4/BULK/5/8192 EP6/BULK/5/8192/RAW | ||
1302 | * tp isoc EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW | ||
1303 | * spi bulk EP4/BULK/5/8192 EP5/BULK/5/8192/RAW | ||
1304 | * spi isoc EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW | ||
1305 | */ | ||
1306 | static int mxl111sf_get_stream_config_mercury_mh(struct dvb_frontend *fe, | ||
1307 | u8 *ts_type, struct usb_data_stream_properties *stream) | ||
1308 | { | ||
1309 | deb_info("%s: fe=%d\n", __func__, fe->id); | ||
1310 | |||
1311 | if (fe->id == 0) { | ||
1312 | *ts_type = DVB_USB_FE_TS_TYPE_188; | ||
1313 | if (dvb_usb_mxl111sf_isoc) | ||
1314 | mxl111sf_stream_config_isoc(stream, 4, 96, 564); | ||
1315 | else | ||
1316 | mxl111sf_stream_config_bulk(stream, 4); | ||
1317 | } else if (fe->id == 1 && dvb_usb_mxl111sf_spi) { | ||
1318 | *ts_type = DVB_USB_FE_TS_TYPE_RAW; | ||
1319 | if (dvb_usb_mxl111sf_isoc) | ||
1320 | mxl111sf_stream_config_isoc(stream, 5, 96, 200); | ||
1321 | else | ||
1322 | mxl111sf_stream_config_bulk(stream, 5); | ||
1323 | } else if (fe->id == 1 && !dvb_usb_mxl111sf_spi) { | ||
1324 | *ts_type = DVB_USB_FE_TS_TYPE_RAW; | ||
1325 | if (dvb_usb_mxl111sf_isoc) | ||
1326 | mxl111sf_stream_config_isoc(stream, 6, 24, 3072); | ||
1327 | else | ||
1328 | mxl111sf_stream_config_bulk(stream, 6); | ||
1329 | } | ||
1330 | return 0; | ||
1331 | } | ||
1332 | |||
1333 | static int mxl111sf_streaming_ctrl_mercury_mh(struct dvb_frontend *fe, int onoff) | ||
1334 | { | ||
1335 | deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff); | ||
1336 | |||
1337 | if (fe->id == 0) | ||
1338 | return mxl111sf_ep4_streaming_ctrl(fe, onoff); | ||
1339 | else if (fe->id == 1 && dvb_usb_mxl111sf_spi) | ||
1340 | return mxl111sf_ep5_streaming_ctrl(fe, onoff); | ||
1341 | else if (fe->id == 1 && !dvb_usb_mxl111sf_spi) | ||
1342 | return mxl111sf_ep6_streaming_ctrl(fe, onoff); | ||
1343 | return 0; | ||
1344 | } | ||
1345 | |||
1346 | static struct dvb_usb_device_properties mxl111sf_props_mercury_mh = { | ||
1347 | .driver_name = KBUILD_MODNAME, | ||
1348 | .owner = THIS_MODULE, | ||
1349 | .adapter_nr = adapter_nr, | ||
1350 | .size_of_priv = sizeof(struct mxl111sf_state), | ||
1351 | |||
1352 | .generic_bulk_ctrl_endpoint = 0x02, | ||
1353 | .generic_bulk_ctrl_endpoint_response = 0x81, | ||
1354 | |||
1355 | .i2c_algo = &mxl111sf_i2c_algo, | ||
1356 | .frontend_attach = mxl111sf_frontend_attach_mercury_mh, | ||
1357 | .tuner_attach = mxl111sf_attach_tuner, | ||
1358 | .init = mxl111sf_init, | ||
1359 | .streaming_ctrl = mxl111sf_streaming_ctrl_mercury_mh, | ||
1360 | .get_stream_config = mxl111sf_get_stream_config_mercury_mh, | ||
1361 | |||
1362 | .num_adapters = 1, | ||
1363 | .adapter = { | ||
1364 | { | ||
1365 | .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1), | ||
1366 | } | ||
1367 | } | ||
1368 | }; | ||
1369 | |||
1370 | static const struct usb_device_id mxl111sf_id_table[] = { | ||
1371 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) }, | ||
1372 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) }, | ||
1373 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602, &mxl111sf_props_mh, "HCW 126xxx", NULL) }, | ||
1374 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) }, | ||
1375 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) }, | ||
1376 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) }, | ||
1377 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a, &mxl111sf_props_mh, "HCW 126xxx", NULL) }, | ||
1378 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) }, | ||
1379 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) }, | ||
1380 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) }, | ||
1381 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) }, | ||
1382 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) }, | ||
1383 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) }, | ||
1384 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702, &mxl111sf_props_mh, "HCW 117xxx", NULL) }, | ||
1385 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) }, | ||
1386 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) }, | ||
1387 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) }, | ||
1388 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) }, | ||
1389 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) }, | ||
1390 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) }, | ||
1391 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) }, | ||
1392 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) }, | ||
1393 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) }, | ||
1394 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) }, | ||
1395 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) }, | ||
1396 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) }, | ||
1397 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) }, | ||
1398 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) }, | ||
1399 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) }, | ||
1400 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) }, | ||
1401 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) }, | ||
1402 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) }, | ||
1403 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) }, | ||
1404 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) }, | ||
1405 | { } | ||
1406 | }; | ||
1407 | MODULE_DEVICE_TABLE(usb, mxl111sf_id_table); | ||
1408 | |||
1409 | static struct usb_driver mxl111sf_usb_driver = { | ||
1410 | .name = KBUILD_MODNAME, | ||
1411 | .id_table = mxl111sf_id_table, | ||
1412 | .probe = dvb_usbv2_probe, | ||
1413 | .disconnect = dvb_usbv2_disconnect, | ||
1414 | .suspend = dvb_usbv2_suspend, | ||
1415 | .resume = dvb_usbv2_resume, | ||
1416 | .no_dynamic_id = 1, | ||
1417 | .soft_unbind = 1, | ||
1418 | }; | ||
1419 | |||
1420 | module_usb_driver(mxl111sf_usb_driver); | ||
1421 | |||
1422 | MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>"); | ||
1423 | MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF"); | ||
1424 | MODULE_VERSION("1.0"); | ||
1425 | MODULE_LICENSE("GPL"); | ||
1426 | |||
1427 | /* | ||
1428 | * Local variables: | ||
1429 | * c-basic-offset: 8 | ||
1430 | * End: | ||
1431 | */ | ||