blob: 3da452a1a06f01d388aa7fa1e47bb3a5bb82cc6b [file] [log] [blame]
Michael Krufky4c66c922011-08-29 00:05:35 -03001/*
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-tuner.h"
21
22#include "lgdt3305.h"
23
24int dvb_usb_mxl111sf_debug;
25module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
26MODULE_PARM_DESC(debug, "set debugging level "
27 "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
28
29int dvb_usb_mxl111sf_isoc;
30module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
31MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");
32
33#define ANT_PATH_AUTO 0
34#define ANT_PATH_EXTERNAL 1
35#define ANT_PATH_INTERNAL 2
36
37int dvb_usb_mxl111sf_rfswitch =
38#if 0
39 ANT_PATH_AUTO;
40#else
41 ANT_PATH_EXTERNAL;
42#endif
43
44module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);
45MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");
46
47DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
48
49#define deb_info(args...) dprintk(dvb_usb_mxl111sf_debug, 0x13, args)
50#define deb_reg(args...) dprintk(dvb_usb_mxl111sf_debug, 0x08, args)
51#define deb_adv(args...) dprintk(dvb_usb_mxl111sf_debug, MXL_ADV_DBG, args)
52
53int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
54 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
55{
56 int wo = (rbuf == NULL || rlen == 0); /* write-only */
57 int ret;
58 u8 sndbuf[1+wlen];
59
60 deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
61
62 memset(sndbuf, 0, 1+wlen);
63
64 sndbuf[0] = cmd;
65 memcpy(&sndbuf[1], wbuf, wlen);
66
67 ret = (wo) ? dvb_usb_generic_write(d, sndbuf, 1+wlen) :
68 dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
69 mxl_fail(ret);
70
71 return ret;
72}
73
74/* ------------------------------------------------------------------------ */
75
76#define MXL_CMD_REG_READ 0xaa
77#define MXL_CMD_REG_WRITE 0x55
78
79int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data)
80{
81 u8 buf[2];
82 int ret;
83
84 ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
85 if (mxl_fail(ret)) {
86 mxl_debug("error reading reg: 0x%02x", addr);
87 goto fail;
88 }
89
90 if (buf[0] == addr)
91 *data = buf[1];
92 else {
93 err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
94 addr, buf[0], buf[1]);
95 ret = -EINVAL;
96 }
97
98 deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
99fail:
100 return ret;
101}
102
103int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)
104{
105 u8 buf[] = { addr, data };
106 int ret;
107
108 deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
109
110 ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
111 if (mxl_fail(ret))
112 err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
113 return ret;
114}
115
116/* ------------------------------------------------------------------------ */
117
118int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
119 u8 addr, u8 mask, u8 data)
120{
121 int ret;
122 u8 val;
123
124 if (mask != 0xff) {
125 ret = mxl111sf_read_reg(state, addr, &val);
126#if 1
127 /* dont know why this usually errors out on the first try */
128 if (mxl_fail(ret))
129 err("error writing addr: 0x%02x, mask: 0x%02x, "
130 "data: 0x%02x, retrying...", addr, mask, data);
131
132 ret = mxl111sf_read_reg(state, addr, &val);
133#endif
134 if (mxl_fail(ret))
135 goto fail;
136 }
137 val &= ~mask;
138 val |= data;
139
140 ret = mxl111sf_write_reg(state, addr, val);
141 mxl_fail(ret);
142fail:
143 return ret;
144}
145
146/* ------------------------------------------------------------------------ */
147
148int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
149 struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
150{
151 int i, ret = 0;
152
153 for (i = 0; ctrl_reg_info[i].addr |
154 ctrl_reg_info[i].mask |
155 ctrl_reg_info[i].data; i++) {
156
157 ret = mxl111sf_write_reg_mask(state,
158 ctrl_reg_info[i].addr,
159 ctrl_reg_info[i].mask,
160 ctrl_reg_info[i].data);
161 if (mxl_fail(ret)) {
162 err("failed on reg #%d (0x%02x)", i,
163 ctrl_reg_info[i].addr);
164 break;
165 }
166 }
167 return ret;
168}
169
170/* ------------------------------------------------------------------------ */
171
172static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)
173{
174 int ret;
175 u8 id, ver;
176 char *mxl_chip, *mxl_rev;
177
178 if ((state->chip_id) && (state->chip_ver))
179 return 0;
180
181 ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);
182 if (mxl_fail(ret))
183 goto fail;
184 state->chip_id = id;
185
186 ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);
187 if (mxl_fail(ret))
188 goto fail;
189 state->chip_ver = ver;
190
191 switch (id) {
192 case 0x61:
193 mxl_chip = "MxL101SF";
194 break;
195 case 0x63:
196 mxl_chip = "MxL111SF";
197 break;
198 default:
199 mxl_chip = "UNKNOWN MxL1X1";
200 break;
201 }
202 switch (ver) {
203 case 0x36:
204 state->chip_rev = MXL111SF_V6;
205 mxl_rev = "v6";
206 break;
207 case 0x08:
208 state->chip_rev = MXL111SF_V8_100;
209 mxl_rev = "v8_100";
210 break;
211 case 0x18:
212 state->chip_rev = MXL111SF_V8_200;
213 mxl_rev = "v8_200";
214 break;
215 default:
216 state->chip_rev = 0;
217 mxl_rev = "UNKNOWN REVISION";
218 break;
219 }
220 info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
221fail:
222 return ret;
223}
224
225#define get_chip_info(state) \
226({ \
227 int ___ret; \
228 ___ret = mxl1x1sf_get_chip_info(state); \
229 if (mxl_fail(___ret)) { \
230 mxl_debug("failed to get chip info" \
231 " on first probe attempt"); \
232 ___ret = mxl1x1sf_get_chip_info(state); \
233 if (mxl_fail(___ret)) \
234 err("failed to get chip info during probe"); \
235 else \
236 mxl_debug("probe needed a retry " \
237 "in order to succeed."); \
238 } \
239 ___ret; \
240})
241
242/* ------------------------------------------------------------------------ */
243
244static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff)
245{
246 /* power control depends on which adapter is being woken:
247 * save this for init, instead, via mxl111sf_adap_fe_init */
248 return 0;
249}
250
251static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
252{
253 struct dvb_usb_adapter *adap = fe->dvb->priv;
254 struct dvb_usb_device *d = adap->dev;
255 struct mxl111sf_state *state = d->priv;
256 struct mxl111sf_adap_state *adap_state = adap->priv;
257 int err;
258
259 /* exit if we didnt initialize the driver yet */
260 if (!state->chip_id) {
261 mxl_debug("driver not yet initialized, exit.");
262 goto fail;
263 }
264
265 deb_info("%s()\n", __func__);
266
267 mutex_lock(&state->fe_lock);
268
269 state->alt_mode = adap_state->alt_mode;
270
271 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
272 err("set interface failed");
273
274 err = mxl1x1sf_soft_reset(state);
275 mxl_fail(err);
276 err = mxl111sf_init_tuner_demod(state);
277 mxl_fail(err);
278 err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
279
280 mxl_fail(err);
281 mxl111sf_enable_usb_output(state);
282 mxl_fail(err);
283 mxl1x1sf_top_master_ctrl(state, 1);
284 mxl_fail(err);
285
286 if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) &&
287 (state->chip_rev > MXL111SF_V6)) {
288 mxl111sf_config_pin_mux_modes(state,
289 PIN_MUX_TS_SPI_IN_MODE_1);
290 mxl_fail(err);
291 }
292 err = mxl111sf_init_port_expander(state);
293 if (!mxl_fail(err)) {
294 state->gpio_mode = adap_state->gpio_mode;
295 err = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
296 mxl_fail(err);
297#if 0
298 err = fe->ops.init(fe);
299#endif
300 msleep(100); /* add short delay after enabling
301 * the demod before touching it */
302 }
303
304 return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0;
305fail:
306 return -ENODEV;
307}
308
309static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
310{
311 struct dvb_usb_adapter *adap = fe->dvb->priv;
312 struct dvb_usb_device *d = adap->dev;
313 struct mxl111sf_state *state = d->priv;
314 struct mxl111sf_adap_state *adap_state = adap->priv;
315 int err;
316
317 /* exit if we didnt initialize the driver yet */
318 if (!state->chip_id) {
319 mxl_debug("driver not yet initialized, exit.");
320 goto fail;
321 }
322
323 deb_info("%s()\n", __func__);
324
325 err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
326
327 mutex_unlock(&state->fe_lock);
328
329 return err;
330fail:
331 return -ENODEV;
332}
333
334
335static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
336{
337 struct dvb_usb_device *d = adap->dev;
338 struct mxl111sf_state *state = d->priv;
339 struct mxl111sf_adap_state *adap_state = adap->priv;
340 int ret = 0;
341 u8 tmp;
342
343 deb_info("%s(%d)\n", __func__, onoff);
344
345 if (onoff) {
346 ret = mxl111sf_enable_usb_output(state);
347 mxl_fail(ret);
348 ret = mxl111sf_config_mpeg_in(state, 1, 1,
349 adap_state->ep6_clockphase,
350 0, 0);
351 mxl_fail(ret);
352 } else {
353 ret = mxl111sf_disable_656_port(state);
354 mxl_fail(ret);
355 }
356
357 mxl111sf_read_reg(state, 0x12, &tmp);
358 tmp &= ~0x04;
359 mxl111sf_write_reg(state, 0x12, tmp);
360
361 return ret;
362}
363
364/* ------------------------------------------------------------------------ */
365
366static struct lgdt3305_config hauppauge_lgdt3305_config = {
367 .i2c_addr = 0xb2 >> 1,
368 .mpeg_mode = LGDT3305_MPEG_SERIAL,
369 .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,
370 .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
371 .deny_i2c_rptr = 1,
372 .spectral_inversion = 0,
373 .qam_if_khz = 6000,
374 .vsb_if_khz = 6000,
375};
376
377static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
378{
379 struct dvb_usb_device *d = adap->dev;
380 struct mxl111sf_state *state = d->priv;
381 struct mxl111sf_adap_state *adap_state = adap->priv;
382 int ret;
383
384 deb_adv("%s()\n", __func__);
385
386 /* save a pointer to the dvb_usb_device in device state */
387 state->d = d;
388 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
389 state->alt_mode = adap_state->alt_mode;
390
391 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
392 err("set interface failed");
393
394 state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
395 adap_state->gpio_mode = state->gpio_mode;
396 adap_state->device_mode = MXL_TUNER_MODE;
397 adap_state->ep6_clockphase = 1;
398
399 ret = mxl1x1sf_soft_reset(state);
400 if (mxl_fail(ret))
401 goto fail;
402 ret = mxl111sf_init_tuner_demod(state);
403 if (mxl_fail(ret))
404 goto fail;
405
406 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
407 if (mxl_fail(ret))
408 goto fail;
409
410 ret = mxl111sf_enable_usb_output(state);
411 if (mxl_fail(ret))
412 goto fail;
413 ret = mxl1x1sf_top_master_ctrl(state, 1);
414 if (mxl_fail(ret))
415 goto fail;
416
417 ret = mxl111sf_init_port_expander(state);
418 if (mxl_fail(ret))
419 goto fail;
420 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
421 if (mxl_fail(ret))
422 goto fail;
423
424 adap->fe[0] = dvb_attach(lgdt3305_attach,
425 &hauppauge_lgdt3305_config,
426 &adap->dev->i2c_adap);
427 if (adap->fe[0]) {
428 adap_state->fe_init = adap->fe[0]->ops.init;
429 adap->fe[0]->ops.init = mxl111sf_adap_fe_init;
430 adap_state->fe_sleep = adap->fe[0]->ops.sleep;
431 adap->fe[0]->ops.sleep = mxl111sf_adap_fe_sleep;
432 return 0;
433 }
434 ret = -EIO;
435fail:
436 return ret;
437}
438
439static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
440 int antpath)
441{
442 return mxl111sf_idac_config(state, 1, 1,
443 (antpath == ANT_PATH_INTERNAL) ?
444 0x3f : 0x00, 0);
445}
446
447#define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
448 err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
449 __func__, __LINE__, \
450 (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
451 pwr0, pwr1, pwr2, pwr3)
452
453#define ANT_HUNT_SLEEP 90
454#define ANT_EXT_TWEAK 0
455
456static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
457{
458 struct dvb_usb_adapter *adap = fe->dvb->priv;
459 struct dvb_usb_device *d = adap->dev;
460 struct mxl111sf_state *state = d->priv;
461
462 int antctrl = dvb_usb_mxl111sf_rfswitch;
463
464 u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
465
466 /* FIXME: must force EXTERNAL for QAM - done elsewhere */
467 mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
468 ANT_PATH_EXTERNAL : antctrl);
469
470 if (antctrl == ANT_PATH_AUTO) {
471#if 0
472 msleep(ANT_HUNT_SLEEP);
473#endif
474 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
475
476 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
477 msleep(ANT_HUNT_SLEEP);
478 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
479
480 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
481 msleep(ANT_HUNT_SLEEP);
482 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
483
484 mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
485 msleep(ANT_HUNT_SLEEP);
486 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
487
488 if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
489 /* return with EXTERNAL enabled */
490 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
491 DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
492 rxPwr0, rxPwr1, rxPwr2);
493 } else {
494 /* return with INTERNAL enabled */
495 DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
496 rxPwr0, rxPwr1, rxPwr2);
497 }
498 }
499 return 0;
500}
501
502static struct mxl111sf_tuner_config mxl_tuner_config = {
503 .if_freq = MXL_IF_6_0, /* applies to external IF output, only */
504 .invert_spectrum = 0,
505 .read_reg = mxl111sf_read_reg,
506 .write_reg = mxl111sf_write_reg,
507 .program_regs = mxl111sf_ctrl_program_regs,
508 .top_master_ctrl = mxl1x1sf_top_master_ctrl,
509 .ant_hunt = mxl111sf_ant_hunt,
510};
511
512static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
513{
514 struct dvb_usb_device *d = adap->dev;
515 struct mxl111sf_state *state = d->priv;
516
517 deb_adv("%s()\n", __func__);
518
519 if (NULL != dvb_attach(mxl111sf_tuner_attach, adap->fe[0], state,
520 &mxl_tuner_config))
521 return 0;
522
523 return -EIO;
524}
525
526static int mxl111sf_fe_ioctl_override(struct dvb_frontend *fe,
527 unsigned int cmd, void *parg,
528 unsigned int stage)
529{
530 int err = 0;
531
532 switch (stage) {
533 case DVB_FE_IOCTL_PRE:
534
535 switch (cmd) {
536 case FE_READ_SIGNAL_STRENGTH:
537 err = fe->ops.tuner_ops.get_rf_strength(fe, parg);
538 /* If no error occurs, prevent dvb-core from handling
539 * this IOCTL, otherwise return the error */
540 if (0 == err)
541 err = 1;
542 break;
543 }
544 break;
545
546 case DVB_FE_IOCTL_POST:
547 /* no post-ioctl handling required */
548 break;
549 }
550 return err;
551};
552
553static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
554{
555 return I2C_FUNC_I2C;
556}
557
558struct i2c_algorithm mxl111sf_i2c_algo = {
559 .master_xfer = mxl111sf_i2c_xfer,
560 .functionality = mxl111sf_i2c_func,
561#ifdef NEED_ALGO_CONTROL
562 .algo_control = dummy_algo_control,
563#endif
564};
565
566/* DVB USB Driver stuff */
567static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
568static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
569
570static int mxl111sf_probe(struct usb_interface *intf,
571 const struct usb_device_id *id)
572{
573 struct dvb_usb_device *d = NULL;
574
575 deb_adv("%s()\n", __func__);
576
577 if (((dvb_usb_mxl111sf_isoc) &&
578 (0 == dvb_usb_device_init(intf,
579 &mxl111sf_atsc_isoc_properties,
580 THIS_MODULE, &d, adapter_nr))) ||
581 0 == dvb_usb_device_init(intf,
582 &mxl111sf_atsc_bulk_properties,
583 THIS_MODULE, &d, adapter_nr) || 0) {
584
585 struct mxl111sf_state *state = d->priv;
586 static u8 eeprom[256];
587 struct i2c_client c;
588 int ret;
589
590 ret = get_chip_info(state);
591 if (mxl_fail(ret))
592 err("failed to get chip info during probe");
593
594 mutex_init(&state->fe_lock);
595
596 if (state->chip_rev > MXL111SF_V6)
597 mxl111sf_config_pin_mux_modes(state,
598 PIN_MUX_TS_SPI_IN_MODE_1);
599
600 c.adapter = &d->i2c_adap;
601 c.addr = 0xa0 >> 1;
602
603 ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
604 if (mxl_fail(ret))
605 return 0;
606 tveeprom_hauppauge_analog(&c, &state->tv,
607 (0x84 == eeprom[0xa0]) ?
608 eeprom + 0xa0 : eeprom + 0x80);
609#if 0
610 switch (state->tv.model) {
611 case 117001:
612 case 126001:
613 case 138001:
614 break;
615 default:
616 printk(KERN_WARNING "%s: warning: "
617 "unknown hauppauge model #%d\n",
618 __func__, state->tv.model);
619 }
620#endif
621 return 0;
622 }
623 err("Your device is not yet supported by this driver. "
624 "See kernellabs.com for more info");
625 return -EINVAL;
626}
627
628static struct usb_device_id mxl111sf_table[] = {
629/* 0 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600) }, /* ATSC+ IR */
630 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601) }, /* ATSC */
631 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602) }, /* + */
632 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603) }, /* ATSC+ */
633 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604) }, /* DVBT */
634/* 5 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609) }, /* ATSC IR */
635 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a) }, /* + IR */
636 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b) }, /* ATSC+ IR */
637 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c) }, /* DVBT IR */
638 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653) }, /* ATSC+ */
639/*10 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b) }, /* ATSC+ IR */
640 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700) }, /* ATSC+ sw */
641 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701) }, /* ATSC sw */
642 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702) }, /* + sw */
643 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703) }, /* ATSC+ sw */
644/*15 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704) }, /* DVBT sw */
645 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753) }, /* ATSC+ sw */
646 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763) }, /* ATSC+ no */
647 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764) }, /* DVBT no */
648 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853) }, /* ATSC+ sw */
649/*20 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854) }, /* DVBT sw */
650 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863) }, /* ATSC+ no */
651 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864) }, /* DVBT no */
652 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3) }, /* ATSC+ sw */
653 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4) }, /* DVBT sw */
654/*25 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3) }, /* ATSC+ no */
655 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4) }, /* DVBT no */
656 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff) }, /* ATSC+ */
657 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612) }, /* + */
658 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613) }, /* ATSC+ */
659/*30 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a) }, /* + IR */
660 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b) }, /* ATSC+ IR */
661 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757) }, /* ATSC+DVBT sw */
662 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767) }, /* ATSC+DVBT no */
663 {} /* Terminating entry */
664};
665MODULE_DEVICE_TABLE(usb, mxl111sf_table);
666
667
668#define MXL111SF_EP6_BULK_STREAMING_CONFIG \
669 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
670 .stream = { \
671 .type = USB_BULK, \
672 .count = 5, \
673 .endpoint = 0x06, \
674 .u = { \
675 .bulk = { \
676 .buffersize = 8192, \
677 } \
678 } \
679 }
680
681/* FIXME */
682#define MXL111SF_EP6_ISOC_STREAMING_CONFIG \
683 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
684 .stream = { \
685 .type = USB_ISOC, \
686 .count = 5, \
687 .endpoint = 0x06, \
688 .u = { \
689 .isoc = { \
690 .framesperurb = 24, \
691 .framesize = 3072, \
692 .interval = 1, \
693 } \
694 } \
695 }
696
697#define MXL111SF_DEFAULT_DEVICE_PROPERTIES \
698 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
699 .usb_ctrl = DEVICE_SPECIFIC, \
700 /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t), \
701 EP6 BULK transfer (atsc/qam), \
702 use usb alt setting 2 for EP4 BULK transfer (dvb-t), \
703 EP6 ISOC transfer (atsc/qam), \
704 */ \
705 .power_ctrl = mxl111sf_power_ctrl, \
706 .i2c_algo = &mxl111sf_i2c_algo, \
707 .generic_bulk_ctrl_endpoint = MXL_EP2_REG_WRITE, \
708 .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \
709 .size_of_priv = sizeof(struct mxl111sf_state)
710
711static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
712 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
713
714 .num_adapters = 1,
715 .adapter = {
716 {
717 .size_of_priv = sizeof(struct mxl111sf_adap_state),
718 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
719
720 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
721 .tuner_attach = mxl111sf_attach_tuner,
722
723 MXL111SF_EP6_BULK_STREAMING_CONFIG,
724 },
725 },
726 .num_device_descs = 6,
727 .devices = {
728 { "Hauppauge 126xxx ATSC (bulk)",
729 { NULL },
730 { &mxl111sf_table[1], &mxl111sf_table[5],
731 NULL },
732 },
733 { "Hauppauge 117xxx ATSC (bulk)",
734 { NULL },
735 { &mxl111sf_table[12],
736 NULL },
737 },
738 { "Hauppauge 126xxx ATSC+ (bulk)",
739 { NULL },
740 { &mxl111sf_table[0], &mxl111sf_table[3],
741 &mxl111sf_table[7], &mxl111sf_table[9],
742 &mxl111sf_table[10], NULL },
743 },
744 { "Hauppauge 117xxx ATSC+ (bulk)",
745 { NULL },
746 { &mxl111sf_table[11], &mxl111sf_table[14],
747 &mxl111sf_table[16], &mxl111sf_table[17],
748 &mxl111sf_table[32], &mxl111sf_table[33],
749 NULL },
750 },
751 { "Hauppauge Mercury (tp-bulk)",
752 { NULL },
753 { &mxl111sf_table[19], &mxl111sf_table[21],
754 &mxl111sf_table[23], &mxl111sf_table[25],
755 &mxl111sf_table[27], NULL },
756 },
757 { "Hauppauge WinTV-Aero-M",
758 { NULL },
759 { &mxl111sf_table[29], &mxl111sf_table[31],
760 NULL },
761 },
762 }
763};
764
765static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
766 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
767
768 .num_adapters = 1,
769 .adapter = {
770 {
771 .size_of_priv = sizeof(struct mxl111sf_adap_state),
772 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
773
774 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
775 .tuner_attach = mxl111sf_attach_tuner,
776
777 MXL111SF_EP6_ISOC_STREAMING_CONFIG,
778 },
779 },
780 .num_device_descs = 6,
781 .devices = {
782 { "Hauppauge 126xxx ATSC (isoc)",
783 { NULL },
784 { &mxl111sf_table[1], &mxl111sf_table[5],
785 NULL },
786 },
787 { "Hauppauge 117xxx ATSC (isoc)",
788 { NULL },
789 { &mxl111sf_table[12],
790 NULL },
791 },
792 { "Hauppauge 126xxx ATSC+ (isoc)",
793 { NULL },
794 { &mxl111sf_table[0], &mxl111sf_table[3],
795 &mxl111sf_table[7], &mxl111sf_table[9],
796 &mxl111sf_table[10], NULL },
797 },
798 { "Hauppauge 117xxx ATSC+ (isoc)",
799 { NULL },
800 { &mxl111sf_table[11], &mxl111sf_table[14],
801 &mxl111sf_table[16], &mxl111sf_table[17],
802 &mxl111sf_table[32], &mxl111sf_table[33],
803 NULL },
804 },
805 { "Hauppauge Mercury (tp-isoc)",
806 { NULL },
807 { &mxl111sf_table[19], &mxl111sf_table[21],
808 &mxl111sf_table[23], &mxl111sf_table[25],
809 &mxl111sf_table[27], NULL },
810 },
811 { "Hauppauge WinTV-Aero-M (tp-isoc)",
812 { NULL },
813 { &mxl111sf_table[29], &mxl111sf_table[31],
814 NULL },
815 },
816 }
817};
818
819static struct usb_driver mxl111sf_driver = {
820 .name = "dvb_usb_mxl111sf",
821 .probe = mxl111sf_probe,
822 .disconnect = dvb_usb_device_exit,
823 .id_table = mxl111sf_table,
824};
825
826static int __init mxl111sf_module_init(void)
827{
828 int result = usb_register(&mxl111sf_driver);
829 if (result) {
830 err("usb_register failed. Error number %d", result);
831 return result;
832 }
833
834 return 0;
835}
836
837static void __exit mxl111sf_module_exit(void)
838{
839 usb_deregister(&mxl111sf_driver);
840}
841
842module_init(mxl111sf_module_init);
843module_exit(mxl111sf_module_exit);
844
845MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
846MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
847MODULE_VERSION("1.0");
848MODULE_LICENSE("GPL");
849
850/*
851 * Local variables:
852 * c-basic-offset: 8
853 * End:
854 */