2 * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com)
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.
8 * see Documentation/dvb/README.dvb-usb for more information
11 #include <linux/vmalloc.h>
12 #include <linux/i2c.h>
15 #include "mxl111sf-reg.h"
16 #include "mxl111sf-phy.h"
17 #include "mxl111sf-i2c.h"
18 #include "mxl111sf-gpio.h"
20 #include "mxl111sf-demod.h"
21 #include "mxl111sf-tuner.h"
25 int dvb_usb_mxl111sf_debug
;
26 module_param_named(debug
, dvb_usb_mxl111sf_debug
, int, 0644);
27 MODULE_PARM_DESC(debug
, "set debugging level "
28 "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
30 int dvb_usb_mxl111sf_isoc
;
31 module_param_named(isoc
, dvb_usb_mxl111sf_isoc
, int, 0644);
32 MODULE_PARM_DESC(isoc
, "enable usb isoc xfer (0=bulk, 1=isoc).");
34 #define ANT_PATH_AUTO 0
35 #define ANT_PATH_EXTERNAL 1
36 #define ANT_PATH_INTERNAL 2
38 int dvb_usb_mxl111sf_rfswitch
=
45 module_param_named(rfswitch
, dvb_usb_mxl111sf_rfswitch
, int, 0644);
46 MODULE_PARM_DESC(rfswitch
, "force rf switch position (0=auto, 1=ext, 2=int).");
48 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr
);
50 #define deb_info(args...) dprintk(dvb_usb_mxl111sf_debug, 0x13, args)
51 #define deb_reg(args...) dprintk(dvb_usb_mxl111sf_debug, 0x08, args)
52 #define deb_adv(args...) dprintk(dvb_usb_mxl111sf_debug, MXL_ADV_DBG, args)
54 int mxl111sf_ctrl_msg(struct dvb_usb_device
*d
,
55 u8 cmd
, u8
*wbuf
, int wlen
, u8
*rbuf
, int rlen
)
57 int wo
= (rbuf
== NULL
|| rlen
== 0); /* write-only */
61 deb_adv("%s(wlen = %d, rlen = %d)\n", __func__
, wlen
, rlen
);
63 memset(sndbuf
, 0, 1+wlen
);
66 memcpy(&sndbuf
[1], wbuf
, wlen
);
68 ret
= (wo
) ? dvb_usb_generic_write(d
, sndbuf
, 1+wlen
) :
69 dvb_usb_generic_rw(d
, sndbuf
, 1+wlen
, rbuf
, rlen
, 0);
75 /* ------------------------------------------------------------------------ */
77 #define MXL_CMD_REG_READ 0xaa
78 #define MXL_CMD_REG_WRITE 0x55
80 int mxl111sf_read_reg(struct mxl111sf_state
*state
, u8 addr
, u8
*data
)
85 ret
= mxl111sf_ctrl_msg(state
->d
, MXL_CMD_REG_READ
, &addr
, 1, buf
, 2);
87 mxl_debug("error reading reg: 0x%02x", addr
);
94 err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
95 addr
, buf
[0], buf
[1]);
99 deb_reg("R: (0x%02x, 0x%02x)\n", addr
, *data
);
104 int mxl111sf_write_reg(struct mxl111sf_state
*state
, u8 addr
, u8 data
)
106 u8 buf
[] = { addr
, data
};
109 deb_reg("W: (0x%02x, 0x%02x)\n", addr
, data
);
111 ret
= mxl111sf_ctrl_msg(state
->d
, MXL_CMD_REG_WRITE
, buf
, 2, NULL
, 0);
113 err("error writing reg: 0x%02x, val: 0x%02x", addr
, data
);
117 /* ------------------------------------------------------------------------ */
119 int mxl111sf_write_reg_mask(struct mxl111sf_state
*state
,
120 u8 addr
, u8 mask
, u8 data
)
126 ret
= mxl111sf_read_reg(state
, addr
, &val
);
128 /* dont know why this usually errors out on the first try */
130 err("error writing addr: 0x%02x, mask: 0x%02x, "
131 "data: 0x%02x, retrying...", addr
, mask
, data
);
133 ret
= mxl111sf_read_reg(state
, addr
, &val
);
141 ret
= mxl111sf_write_reg(state
, addr
, val
);
147 /* ------------------------------------------------------------------------ */
149 int mxl111sf_ctrl_program_regs(struct mxl111sf_state
*state
,
150 struct mxl111sf_reg_ctrl_info
*ctrl_reg_info
)
154 for (i
= 0; ctrl_reg_info
[i
].addr
|
155 ctrl_reg_info
[i
].mask
|
156 ctrl_reg_info
[i
].data
; i
++) {
158 ret
= mxl111sf_write_reg_mask(state
,
159 ctrl_reg_info
[i
].addr
,
160 ctrl_reg_info
[i
].mask
,
161 ctrl_reg_info
[i
].data
);
163 err("failed on reg #%d (0x%02x)", i
,
164 ctrl_reg_info
[i
].addr
);
171 /* ------------------------------------------------------------------------ */
173 static int mxl1x1sf_get_chip_info(struct mxl111sf_state
*state
)
177 char *mxl_chip
, *mxl_rev
;
179 if ((state
->chip_id
) && (state
->chip_ver
))
182 ret
= mxl111sf_read_reg(state
, CHIP_ID_REG
, &id
);
187 ret
= mxl111sf_read_reg(state
, TOP_CHIP_REV_ID_REG
, &ver
);
190 state
->chip_ver
= ver
;
194 mxl_chip
= "MxL101SF";
197 mxl_chip
= "MxL111SF";
200 mxl_chip
= "UNKNOWN MxL1X1";
205 state
->chip_rev
= MXL111SF_V6
;
209 state
->chip_rev
= MXL111SF_V8_100
;
213 state
->chip_rev
= MXL111SF_V8_200
;
218 mxl_rev
= "UNKNOWN REVISION";
221 info("%s detected, %s (0x%x)", mxl_chip
, mxl_rev
, ver
);
226 #define get_chip_info(state) \
229 ___ret = mxl1x1sf_get_chip_info(state); \
230 if (mxl_fail(___ret)) { \
231 mxl_debug("failed to get chip info" \
232 " on first probe attempt"); \
233 ___ret = mxl1x1sf_get_chip_info(state); \
234 if (mxl_fail(___ret)) \
235 err("failed to get chip info during probe"); \
237 mxl_debug("probe needed a retry " \
238 "in order to succeed."); \
243 /* ------------------------------------------------------------------------ */
245 static int mxl111sf_power_ctrl(struct dvb_usb_device
*d
, int onoff
)
247 /* power control depends on which adapter is being woken:
248 * save this for init, instead, via mxl111sf_adap_fe_init */
252 static int mxl111sf_adap_fe_init(struct dvb_frontend
*fe
)
254 struct dvb_usb_adapter
*adap
= fe
->dvb
->priv
;
255 struct dvb_usb_device
*d
= adap
->dev
;
256 struct mxl111sf_state
*state
= d
->priv
;
257 struct mxl111sf_adap_state
*adap_state
= adap
->fe_adap
[fe
->id
].priv
;
261 /* exit if we didnt initialize the driver yet */
262 if (!state
->chip_id
) {
263 mxl_debug("driver not yet initialized, exit.");
267 deb_info("%s()\n", __func__
);
269 mutex_lock(&state
->fe_lock
);
271 state
->alt_mode
= adap_state
->alt_mode
;
273 if (usb_set_interface(adap
->dev
->udev
, 0, state
->alt_mode
) < 0)
274 err("set interface failed");
276 err
= mxl1x1sf_soft_reset(state
);
278 err
= mxl111sf_init_tuner_demod(state
);
280 err
= mxl1x1sf_set_device_mode(state
, adap_state
->device_mode
);
283 mxl111sf_enable_usb_output(state
);
285 mxl1x1sf_top_master_ctrl(state
, 1);
288 if ((MXL111SF_GPIO_MOD_DVBT
!= adap_state
->gpio_mode
) &&
289 (state
->chip_rev
> MXL111SF_V6
)) {
290 mxl111sf_config_pin_mux_modes(state
,
291 PIN_MUX_TS_SPI_IN_MODE_1
);
294 err
= mxl111sf_init_port_expander(state
);
295 if (!mxl_fail(err
)) {
296 state
->gpio_mode
= adap_state
->gpio_mode
;
297 err
= mxl111sf_gpio_mode_switch(state
, state
->gpio_mode
);
300 err
= fe
->ops
.init(fe
);
302 msleep(100); /* add short delay after enabling
303 * the demod before touching it */
306 return (adap_state
->fe_init
) ? adap_state
->fe_init(fe
) : 0;
311 static int mxl111sf_adap_fe_sleep(struct dvb_frontend
*fe
)
313 struct dvb_usb_adapter
*adap
= fe
->dvb
->priv
;
314 struct dvb_usb_device
*d
= adap
->dev
;
315 struct mxl111sf_state
*state
= d
->priv
;
316 struct mxl111sf_adap_state
*adap_state
= adap
->fe_adap
[fe
->id
].priv
;
319 /* exit if we didnt initialize the driver yet */
320 if (!state
->chip_id
) {
321 mxl_debug("driver not yet initialized, exit.");
325 deb_info("%s()\n", __func__
);
327 err
= (adap_state
->fe_sleep
) ? adap_state
->fe_sleep(fe
) : 0;
329 mutex_unlock(&state
->fe_lock
);
337 static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter
*adap
, int onoff
)
339 struct dvb_usb_device
*d
= adap
->dev
;
340 struct mxl111sf_state
*state
= d
->priv
;
341 struct mxl111sf_adap_state
*adap_state
= adap
->fe_adap
[adap
->active_fe
].priv
;
345 deb_info("%s(%d)\n", __func__
, onoff
);
348 ret
= mxl111sf_enable_usb_output(state
);
350 ret
= mxl111sf_config_mpeg_in(state
, 1, 1,
351 adap_state
->ep6_clockphase
,
355 ret
= mxl111sf_disable_656_port(state
);
359 mxl111sf_read_reg(state
, 0x12, &tmp
);
361 mxl111sf_write_reg(state
, 0x12, tmp
);
366 static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter
*adap
, int onoff
)
368 struct dvb_usb_device
*d
= adap
->dev
;
369 struct mxl111sf_state
*state
= d
->priv
;
372 deb_info("%s(%d)\n", __func__
, onoff
);
375 ret
= mxl111sf_enable_usb_output(state
);
382 /* ------------------------------------------------------------------------ */
384 static struct lgdt3305_config hauppauge_lgdt3305_config
= {
385 .i2c_addr
= 0xb2 >> 1,
386 .mpeg_mode
= LGDT3305_MPEG_SERIAL
,
387 .tpclk_edge
= LGDT3305_TPCLK_RISING_EDGE
,
388 .tpvalid_polarity
= LGDT3305_TP_VALID_HIGH
,
390 .spectral_inversion
= 0,
395 static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter
*adap
)
397 struct dvb_usb_device
*d
= adap
->dev
;
398 struct mxl111sf_state
*state
= d
->priv
;
399 int fe_id
= adap
->num_frontends_initialized
;
400 struct mxl111sf_adap_state
*adap_state
= adap
->fe_adap
[fe_id
].priv
;
403 deb_adv("%s()\n", __func__
);
405 /* save a pointer to the dvb_usb_device in device state */
407 adap_state
->alt_mode
= (dvb_usb_mxl111sf_isoc
) ? 2 : 1;
408 state
->alt_mode
= adap_state
->alt_mode
;
410 if (usb_set_interface(adap
->dev
->udev
, 0, state
->alt_mode
) < 0)
411 err("set interface failed");
413 state
->gpio_mode
= MXL111SF_GPIO_MOD_ATSC
;
414 adap_state
->gpio_mode
= state
->gpio_mode
;
415 adap_state
->device_mode
= MXL_TUNER_MODE
;
416 adap_state
->ep6_clockphase
= 1;
418 ret
= mxl1x1sf_soft_reset(state
);
421 ret
= mxl111sf_init_tuner_demod(state
);
425 ret
= mxl1x1sf_set_device_mode(state
, adap_state
->device_mode
);
429 ret
= mxl111sf_enable_usb_output(state
);
432 ret
= mxl1x1sf_top_master_ctrl(state
, 1);
436 ret
= mxl111sf_init_port_expander(state
);
439 ret
= mxl111sf_gpio_mode_switch(state
, state
->gpio_mode
);
443 adap
->fe_adap
[fe_id
].fe
= dvb_attach(lgdt3305_attach
,
444 &hauppauge_lgdt3305_config
,
445 &adap
->dev
->i2c_adap
);
446 if (adap
->fe_adap
[fe_id
].fe
) {
447 adap_state
->fe_init
= adap
->fe_adap
[fe_id
].fe
->ops
.init
;
448 adap
->fe_adap
[fe_id
].fe
->ops
.init
= mxl111sf_adap_fe_init
;
449 adap_state
->fe_sleep
= adap
->fe_adap
[fe_id
].fe
->ops
.sleep
;
450 adap
->fe_adap
[fe_id
].fe
->ops
.sleep
= mxl111sf_adap_fe_sleep
;
458 static struct mxl111sf_demod_config mxl_demod_config
= {
459 .read_reg
= mxl111sf_read_reg
,
460 .write_reg
= mxl111sf_write_reg
,
461 .program_regs
= mxl111sf_ctrl_program_regs
,
464 static int mxl111sf_attach_demod(struct dvb_usb_adapter
*adap
)
466 struct dvb_usb_device
*d
= adap
->dev
;
467 struct mxl111sf_state
*state
= d
->priv
;
468 int fe_id
= adap
->num_frontends_initialized
;
469 struct mxl111sf_adap_state
*adap_state
= adap
->fe_adap
[fe_id
].priv
;
472 deb_adv("%s()\n", __func__
);
474 /* save a pointer to the dvb_usb_device in device state */
476 adap_state
->alt_mode
= (dvb_usb_mxl111sf_isoc
) ? 1 : 2;
477 state
->alt_mode
= adap_state
->alt_mode
;
479 if (usb_set_interface(adap
->dev
->udev
, 0, state
->alt_mode
) < 0)
480 err("set interface failed");
482 state
->gpio_mode
= MXL111SF_GPIO_MOD_DVBT
;
483 adap_state
->gpio_mode
= state
->gpio_mode
;
484 adap_state
->device_mode
= MXL_SOC_MODE
;
485 adap_state
->ep6_clockphase
= 1;
487 ret
= mxl1x1sf_soft_reset(state
);
490 ret
= mxl111sf_init_tuner_demod(state
);
494 ret
= mxl1x1sf_set_device_mode(state
, adap_state
->device_mode
);
498 ret
= mxl111sf_enable_usb_output(state
);
501 ret
= mxl1x1sf_top_master_ctrl(state
, 1);
505 /* dont care if this fails */
506 mxl111sf_init_port_expander(state
);
508 adap
->fe_adap
[fe_id
].fe
= dvb_attach(mxl111sf_demod_attach
, state
,
510 if (adap
->fe_adap
[fe_id
].fe
) {
511 adap_state
->fe_init
= adap
->fe_adap
[fe_id
].fe
->ops
.init
;
512 adap
->fe_adap
[fe_id
].fe
->ops
.init
= mxl111sf_adap_fe_init
;
513 adap_state
->fe_sleep
= adap
->fe_adap
[fe_id
].fe
->ops
.sleep
;
514 adap
->fe_adap
[fe_id
].fe
->ops
.sleep
= mxl111sf_adap_fe_sleep
;
522 static inline int mxl111sf_set_ant_path(struct mxl111sf_state
*state
,
525 return mxl111sf_idac_config(state
, 1, 1,
526 (antpath
== ANT_PATH_INTERNAL
) ?
530 #define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
531 err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
532 __func__, __LINE__, \
533 (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
534 pwr0, pwr1, pwr2, pwr3)
536 #define ANT_HUNT_SLEEP 90
537 #define ANT_EXT_TWEAK 0
539 static int mxl111sf_ant_hunt(struct dvb_frontend
*fe
)
541 struct dvb_usb_adapter
*adap
= fe
->dvb
->priv
;
542 struct dvb_usb_device
*d
= adap
->dev
;
543 struct mxl111sf_state
*state
= d
->priv
;
545 int antctrl
= dvb_usb_mxl111sf_rfswitch
;
547 u16 rxPwrA
, rxPwr0
, rxPwr1
, rxPwr2
;
549 /* FIXME: must force EXTERNAL for QAM - done elsewhere */
550 mxl111sf_set_ant_path(state
, antctrl
== ANT_PATH_AUTO
?
551 ANT_PATH_EXTERNAL
: antctrl
);
553 if (antctrl
== ANT_PATH_AUTO
) {
555 msleep(ANT_HUNT_SLEEP
);
557 fe
->ops
.tuner_ops
.get_rf_strength(fe
, &rxPwrA
);
559 mxl111sf_set_ant_path(state
, ANT_PATH_EXTERNAL
);
560 msleep(ANT_HUNT_SLEEP
);
561 fe
->ops
.tuner_ops
.get_rf_strength(fe
, &rxPwr0
);
563 mxl111sf_set_ant_path(state
, ANT_PATH_EXTERNAL
);
564 msleep(ANT_HUNT_SLEEP
);
565 fe
->ops
.tuner_ops
.get_rf_strength(fe
, &rxPwr1
);
567 mxl111sf_set_ant_path(state
, ANT_PATH_INTERNAL
);
568 msleep(ANT_HUNT_SLEEP
);
569 fe
->ops
.tuner_ops
.get_rf_strength(fe
, &rxPwr2
);
571 if (rxPwr1
+ANT_EXT_TWEAK
>= rxPwr2
) {
572 /* return with EXTERNAL enabled */
573 mxl111sf_set_ant_path(state
, ANT_PATH_EXTERNAL
);
574 DbgAntHunt(ANT_PATH_EXTERNAL
, rxPwrA
,
575 rxPwr0
, rxPwr1
, rxPwr2
);
577 /* return with INTERNAL enabled */
578 DbgAntHunt(ANT_PATH_INTERNAL
, rxPwrA
,
579 rxPwr0
, rxPwr1
, rxPwr2
);
585 static struct mxl111sf_tuner_config mxl_tuner_config
= {
586 .if_freq
= MXL_IF_6_0
, /* applies to external IF output, only */
587 .invert_spectrum
= 0,
588 .read_reg
= mxl111sf_read_reg
,
589 .write_reg
= mxl111sf_write_reg
,
590 .program_regs
= mxl111sf_ctrl_program_regs
,
591 .top_master_ctrl
= mxl1x1sf_top_master_ctrl
,
592 .ant_hunt
= mxl111sf_ant_hunt
,
595 static int mxl111sf_attach_tuner(struct dvb_usb_adapter
*adap
)
597 struct dvb_usb_device
*d
= adap
->dev
;
598 struct mxl111sf_state
*state
= d
->priv
;
599 int fe_id
= adap
->num_frontends_initialized
;
601 deb_adv("%s()\n", __func__
);
603 if (NULL
!= dvb_attach(mxl111sf_tuner_attach
,
604 adap
->fe_adap
[fe_id
].fe
, state
,
611 static int mxl111sf_fe_ioctl_override(struct dvb_frontend
*fe
,
612 unsigned int cmd
, void *parg
,
618 case DVB_FE_IOCTL_PRE
:
621 case FE_READ_SIGNAL_STRENGTH
:
622 err
= fe
->ops
.tuner_ops
.get_rf_strength(fe
, parg
);
623 /* If no error occurs, prevent dvb-core from handling
624 * this IOCTL, otherwise return the error */
631 case DVB_FE_IOCTL_POST
:
632 /* no post-ioctl handling required */
638 static u32
mxl111sf_i2c_func(struct i2c_adapter
*adapter
)
643 struct i2c_algorithm mxl111sf_i2c_algo
= {
644 .master_xfer
= mxl111sf_i2c_xfer
,
645 .functionality
= mxl111sf_i2c_func
,
646 #ifdef NEED_ALGO_CONTROL
647 .algo_control
= dummy_algo_control
,
651 static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties
;
652 static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties
;
653 static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties
;
654 static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties
;
656 static int mxl111sf_probe(struct usb_interface
*intf
,
657 const struct usb_device_id
*id
)
659 struct dvb_usb_device
*d
= NULL
;
661 deb_adv("%s()\n", __func__
);
663 if (((dvb_usb_mxl111sf_isoc
) &&
664 (0 == dvb_usb_device_init(intf
,
665 &mxl111sf_dvbt_isoc_properties
,
666 THIS_MODULE
, &d
, adapter_nr
) ||
667 0 == dvb_usb_device_init(intf
,
668 &mxl111sf_atsc_isoc_properties
,
669 THIS_MODULE
, &d
, adapter_nr
))) ||
670 0 == dvb_usb_device_init(intf
,
671 &mxl111sf_dvbt_bulk_properties
,
672 THIS_MODULE
, &d
, adapter_nr
) ||
673 0 == dvb_usb_device_init(intf
,
674 &mxl111sf_atsc_bulk_properties
,
675 THIS_MODULE
, &d
, adapter_nr
) || 0) {
677 struct mxl111sf_state
*state
= d
->priv
;
678 static u8 eeprom
[256];
682 ret
= get_chip_info(state
);
684 err("failed to get chip info during probe");
686 mutex_init(&state
->fe_lock
);
688 if (state
->chip_rev
> MXL111SF_V6
)
689 mxl111sf_config_pin_mux_modes(state
,
690 PIN_MUX_TS_SPI_IN_MODE_1
);
692 c
.adapter
= &d
->i2c_adap
;
695 ret
= tveeprom_read(&c
, eeprom
, sizeof(eeprom
));
698 tveeprom_hauppauge_analog(&c
, &state
->tv
,
699 (0x84 == eeprom
[0xa0]) ?
700 eeprom
+ 0xa0 : eeprom
+ 0x80);
702 switch (state
->tv
.model
) {
708 printk(KERN_WARNING
"%s: warning: "
709 "unknown hauppauge model #%d\n",
710 __func__
, state
->tv
.model
);
715 err("Your device is not yet supported by this driver. "
716 "See kernellabs.com for more info");
720 static struct usb_device_id mxl111sf_table
[] = {
721 /* 0 */ { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc600) }, /* ATSC+ IR */
722 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc601) }, /* ATSC */
723 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc602) }, /* + */
724 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc603) }, /* ATSC+ */
725 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc604) }, /* DVBT */
726 /* 5 */ { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc609) }, /* ATSC IR */
727 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc60a) }, /* + IR */
728 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc60b) }, /* ATSC+ IR */
729 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc60c) }, /* DVBT IR */
730 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc653) }, /* ATSC+ */
731 /*10 */ { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc65b) }, /* ATSC+ IR */
732 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xb700) }, /* ATSC+ sw */
733 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xb701) }, /* ATSC sw */
734 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xb702) }, /* + sw */
735 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xb703) }, /* ATSC+ sw */
736 /*15 */ { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xb704) }, /* DVBT sw */
737 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xb753) }, /* ATSC+ sw */
738 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xb763) }, /* ATSC+ no */
739 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xb764) }, /* DVBT no */
740 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xd853) }, /* ATSC+ sw */
741 /*20 */ { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xd854) }, /* DVBT sw */
742 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xd863) }, /* ATSC+ no */
743 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xd864) }, /* DVBT no */
744 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xd8d3) }, /* ATSC+ sw */
745 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xd8d4) }, /* DVBT sw */
746 /*25 */ { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xd8e3) }, /* ATSC+ no */
747 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xd8e4) }, /* DVBT no */
748 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xd8ff) }, /* ATSC+ */
749 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc612) }, /* + */
750 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc613) }, /* ATSC+ */
751 /*30 */ { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc61a) }, /* + IR */
752 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xc61b) }, /* ATSC+ IR */
753 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xb757) }, /* ATSC+DVBT sw */
754 { USB_DEVICE(USB_VID_HAUPPAUGE
, 0xb767) }, /* ATSC+DVBT no */
755 {} /* Terminating entry */
757 MODULE_DEVICE_TABLE(usb
, mxl111sf_table
);
760 #define MXL111SF_EP4_BULK_STREAMING_CONFIG \
761 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
762 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
769 .buffersize = 8192, \
774 /* FIXME: works for v6 but not v8 silicon */
775 #define MXL111SF_EP4_ISOC_STREAMING_CONFIG \
776 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
777 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
784 .framesperurb = 96, \
785 /* FIXME: v6 SILICON: */ \
792 #define MXL111SF_EP6_BULK_STREAMING_CONFIG \
793 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
794 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
801 .buffersize = 8192, \
807 #define MXL111SF_EP6_ISOC_STREAMING_CONFIG \
808 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
809 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
816 .framesperurb = 24, \
823 #define MXL111SF_DEFAULT_DEVICE_PROPERTIES \
824 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
825 .usb_ctrl = DEVICE_SPECIFIC, \
826 /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t), \
827 EP6 BULK transfer (atsc/qam), \
828 use usb alt setting 2 for EP4 BULK transfer (dvb-t), \
829 EP6 ISOC transfer (atsc/qam), \
831 .power_ctrl = mxl111sf_power_ctrl, \
832 .i2c_algo = &mxl111sf_i2c_algo, \
833 .generic_bulk_ctrl_endpoint = MXL_EP2_REG_WRITE, \
834 .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \
835 .size_of_priv = sizeof(struct mxl111sf_state)
837 static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties
= {
838 MXL111SF_DEFAULT_DEVICE_PROPERTIES
,
843 .fe_ioctl_override
= mxl111sf_fe_ioctl_override
,
846 .frontend_attach
= mxl111sf_attach_demod
,
847 .tuner_attach
= mxl111sf_attach_tuner
,
849 MXL111SF_EP4_BULK_STREAMING_CONFIG
,
853 .num_device_descs
= 4,
855 { "Hauppauge 126xxx DVBT (bulk)",
857 { &mxl111sf_table
[4], &mxl111sf_table
[8],
860 { "Hauppauge 117xxx DVBT (bulk)",
862 { &mxl111sf_table
[15], &mxl111sf_table
[18],
865 { "Hauppauge 138xxx DVBT (bulk)",
867 { &mxl111sf_table
[20], &mxl111sf_table
[22],
868 &mxl111sf_table
[24], &mxl111sf_table
[26],
871 { "Hauppauge 126xxx (tp-bulk)",
873 { &mxl111sf_table
[28], &mxl111sf_table
[30],
879 static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties
= {
880 MXL111SF_DEFAULT_DEVICE_PROPERTIES
,
885 .fe_ioctl_override
= mxl111sf_fe_ioctl_override
,
888 .frontend_attach
= mxl111sf_attach_demod
,
889 .tuner_attach
= mxl111sf_attach_tuner
,
891 MXL111SF_EP4_ISOC_STREAMING_CONFIG
,
895 .num_device_descs
= 4,
897 { "Hauppauge 126xxx DVBT (isoc)",
899 { &mxl111sf_table
[4], &mxl111sf_table
[8],
902 { "Hauppauge 117xxx DVBT (isoc)",
904 { &mxl111sf_table
[15], &mxl111sf_table
[18],
907 { "Hauppauge 138xxx DVBT (isoc)",
909 { &mxl111sf_table
[20], &mxl111sf_table
[22],
910 &mxl111sf_table
[24], &mxl111sf_table
[26],
913 { "Hauppauge 126xxx (tp-isoc)",
915 { &mxl111sf_table
[28], &mxl111sf_table
[30],
921 static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties
= {
922 MXL111SF_DEFAULT_DEVICE_PROPERTIES
,
927 .fe_ioctl_override
= mxl111sf_fe_ioctl_override
,
930 .frontend_attach
= mxl111sf_lgdt3305_frontend_attach
,
931 .tuner_attach
= mxl111sf_attach_tuner
,
933 MXL111SF_EP6_BULK_STREAMING_CONFIG
,
936 .frontend_attach
= mxl111sf_attach_demod
,
937 .tuner_attach
= mxl111sf_attach_tuner
,
939 MXL111SF_EP4_BULK_STREAMING_CONFIG
,
943 .num_device_descs
= 6,
945 { "Hauppauge 126xxx ATSC (bulk)",
947 { &mxl111sf_table
[1], &mxl111sf_table
[5],
950 { "Hauppauge 117xxx ATSC (bulk)",
952 { &mxl111sf_table
[12],
955 { "Hauppauge 126xxx ATSC+ (bulk)",
957 { &mxl111sf_table
[0], &mxl111sf_table
[3],
958 &mxl111sf_table
[7], &mxl111sf_table
[9],
959 &mxl111sf_table
[10], NULL
},
961 { "Hauppauge 117xxx ATSC+ (bulk)",
963 { &mxl111sf_table
[11], &mxl111sf_table
[14],
964 &mxl111sf_table
[16], &mxl111sf_table
[17],
965 &mxl111sf_table
[32], &mxl111sf_table
[33],
968 { "Hauppauge Mercury (tp-bulk)",
970 { &mxl111sf_table
[19], &mxl111sf_table
[21],
971 &mxl111sf_table
[23], &mxl111sf_table
[25],
972 &mxl111sf_table
[27], NULL
},
974 { "Hauppauge WinTV-Aero-M",
976 { &mxl111sf_table
[29], &mxl111sf_table
[31],
982 static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties
= {
983 MXL111SF_DEFAULT_DEVICE_PROPERTIES
,
988 .fe_ioctl_override
= mxl111sf_fe_ioctl_override
,
991 .frontend_attach
= mxl111sf_lgdt3305_frontend_attach
,
992 .tuner_attach
= mxl111sf_attach_tuner
,
994 MXL111SF_EP6_ISOC_STREAMING_CONFIG
,
997 .frontend_attach
= mxl111sf_attach_demod
,
998 .tuner_attach
= mxl111sf_attach_tuner
,
1000 MXL111SF_EP4_ISOC_STREAMING_CONFIG
,
1004 .num_device_descs
= 6,
1006 { "Hauppauge 126xxx ATSC (isoc)",
1008 { &mxl111sf_table
[1], &mxl111sf_table
[5],
1011 { "Hauppauge 117xxx ATSC (isoc)",
1013 { &mxl111sf_table
[12],
1016 { "Hauppauge 126xxx ATSC+ (isoc)",
1018 { &mxl111sf_table
[0], &mxl111sf_table
[3],
1019 &mxl111sf_table
[7], &mxl111sf_table
[9],
1020 &mxl111sf_table
[10], NULL
},
1022 { "Hauppauge 117xxx ATSC+ (isoc)",
1024 { &mxl111sf_table
[11], &mxl111sf_table
[14],
1025 &mxl111sf_table
[16], &mxl111sf_table
[17],
1026 &mxl111sf_table
[32], &mxl111sf_table
[33],
1029 { "Hauppauge Mercury (tp-isoc)",
1031 { &mxl111sf_table
[19], &mxl111sf_table
[21],
1032 &mxl111sf_table
[23], &mxl111sf_table
[25],
1033 &mxl111sf_table
[27], NULL
},
1035 { "Hauppauge WinTV-Aero-M (tp-isoc)",
1037 { &mxl111sf_table
[29], &mxl111sf_table
[31],
1043 static struct usb_driver mxl111sf_driver
= {
1044 .name
= "dvb_usb_mxl111sf",
1045 .probe
= mxl111sf_probe
,
1046 .disconnect
= dvb_usb_device_exit
,
1047 .id_table
= mxl111sf_table
,
1050 module_usb_driver(mxl111sf_driver
);
1052 MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
1053 MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
1054 MODULE_VERSION("1.0");
1055 MODULE_LICENSE("GPL");