Avoid beyond bounds copy while caching ACL
[zen-stable.git] / drivers / media / dvb / dvb-usb / mxl111sf.c
blob81305de2fea5ca10fb68d0f263aa44afd131cc3c
1 /*
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
9 */
11 #include <linux/vmalloc.h>
12 #include <linux/i2c.h>
14 #include "mxl111sf.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"
23 #include "lgdt3305.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 =
39 #if 0
40 ANT_PATH_AUTO;
41 #else
42 ANT_PATH_EXTERNAL;
43 #endif
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 */
58 int ret;
59 u8 sndbuf[1+wlen];
61 deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
63 memset(sndbuf, 0, 1+wlen);
65 sndbuf[0] = cmd;
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);
70 mxl_fail(ret);
72 return ret;
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)
82 u8 buf[2];
83 int ret;
85 ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
86 if (mxl_fail(ret)) {
87 mxl_debug("error reading reg: 0x%02x", addr);
88 goto fail;
91 if (buf[0] == addr)
92 *data = buf[1];
93 else {
94 err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
95 addr, buf[0], buf[1]);
96 ret = -EINVAL;
99 deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
100 fail:
101 return ret;
104 int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)
106 u8 buf[] = { addr, data };
107 int ret;
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);
112 if (mxl_fail(ret))
113 err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
114 return ret;
117 /* ------------------------------------------------------------------------ */
119 int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
120 u8 addr, u8 mask, u8 data)
122 int ret;
123 u8 val;
125 if (mask != 0xff) {
126 ret = mxl111sf_read_reg(state, addr, &val);
127 #if 1
128 /* dont know why this usually errors out on the first try */
129 if (mxl_fail(ret))
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);
134 #endif
135 if (mxl_fail(ret))
136 goto fail;
138 val &= ~mask;
139 val |= data;
141 ret = mxl111sf_write_reg(state, addr, val);
142 mxl_fail(ret);
143 fail:
144 return ret;
147 /* ------------------------------------------------------------------------ */
149 int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
150 struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
152 int i, ret = 0;
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);
162 if (mxl_fail(ret)) {
163 err("failed on reg #%d (0x%02x)", i,
164 ctrl_reg_info[i].addr);
165 break;
168 return ret;
171 /* ------------------------------------------------------------------------ */
173 static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)
175 int ret;
176 u8 id, ver;
177 char *mxl_chip, *mxl_rev;
179 if ((state->chip_id) && (state->chip_ver))
180 return 0;
182 ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);
183 if (mxl_fail(ret))
184 goto fail;
185 state->chip_id = id;
187 ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);
188 if (mxl_fail(ret))
189 goto fail;
190 state->chip_ver = ver;
192 switch (id) {
193 case 0x61:
194 mxl_chip = "MxL101SF";
195 break;
196 case 0x63:
197 mxl_chip = "MxL111SF";
198 break;
199 default:
200 mxl_chip = "UNKNOWN MxL1X1";
201 break;
203 switch (ver) {
204 case 0x36:
205 state->chip_rev = MXL111SF_V6;
206 mxl_rev = "v6";
207 break;
208 case 0x08:
209 state->chip_rev = MXL111SF_V8_100;
210 mxl_rev = "v8_100";
211 break;
212 case 0x18:
213 state->chip_rev = MXL111SF_V8_200;
214 mxl_rev = "v8_200";
215 break;
216 default:
217 state->chip_rev = 0;
218 mxl_rev = "UNKNOWN REVISION";
219 break;
221 info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
222 fail:
223 return ret;
226 #define get_chip_info(state) \
227 ({ \
228 int ___ret; \
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"); \
236 else \
237 mxl_debug("probe needed a retry " \
238 "in order to succeed."); \
240 ___ret; \
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 */
249 return 0;
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;
259 int err;
261 /* exit if we didnt initialize the driver yet */
262 if (!state->chip_id) {
263 mxl_debug("driver not yet initialized, exit.");
264 goto fail;
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);
277 mxl_fail(err);
278 err = mxl111sf_init_tuner_demod(state);
279 mxl_fail(err);
280 err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
282 mxl_fail(err);
283 mxl111sf_enable_usb_output(state);
284 mxl_fail(err);
285 mxl1x1sf_top_master_ctrl(state, 1);
286 mxl_fail(err);
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);
292 mxl_fail(err);
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);
298 mxl_fail(err);
299 #if 0
300 err = fe->ops.init(fe);
301 #endif
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;
307 fail:
308 return -ENODEV;
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;
317 int err;
319 /* exit if we didnt initialize the driver yet */
320 if (!state->chip_id) {
321 mxl_debug("driver not yet initialized, exit.");
322 goto fail;
325 deb_info("%s()\n", __func__);
327 err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
329 mutex_unlock(&state->fe_lock);
331 return err;
332 fail:
333 return -ENODEV;
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;
342 int ret = 0;
343 u8 tmp;
345 deb_info("%s(%d)\n", __func__, onoff);
347 if (onoff) {
348 ret = mxl111sf_enable_usb_output(state);
349 mxl_fail(ret);
350 ret = mxl111sf_config_mpeg_in(state, 1, 1,
351 adap_state->ep6_clockphase,
352 0, 0);
353 mxl_fail(ret);
354 #if 0
355 } else {
356 ret = mxl111sf_disable_656_port(state);
357 mxl_fail(ret);
358 #endif
361 return ret;
364 static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
366 struct dvb_usb_device *d = adap->dev;
367 struct mxl111sf_state *state = d->priv;
368 int ret = 0;
370 deb_info("%s(%d)\n", __func__, onoff);
372 if (onoff) {
373 ret = mxl111sf_enable_usb_output(state);
374 mxl_fail(ret);
377 return ret;
380 /* ------------------------------------------------------------------------ */
382 static struct lgdt3305_config hauppauge_lgdt3305_config = {
383 .i2c_addr = 0xb2 >> 1,
384 .mpeg_mode = LGDT3305_MPEG_SERIAL,
385 .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,
386 .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
387 .deny_i2c_rptr = 1,
388 .spectral_inversion = 0,
389 .qam_if_khz = 6000,
390 .vsb_if_khz = 6000,
393 static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
395 struct dvb_usb_device *d = adap->dev;
396 struct mxl111sf_state *state = d->priv;
397 int fe_id = adap->num_frontends_initialized;
398 struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
399 int ret;
401 deb_adv("%s()\n", __func__);
403 /* save a pointer to the dvb_usb_device in device state */
404 state->d = d;
405 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
406 state->alt_mode = adap_state->alt_mode;
408 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
409 err("set interface failed");
411 state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
412 adap_state->gpio_mode = state->gpio_mode;
413 adap_state->device_mode = MXL_TUNER_MODE;
414 adap_state->ep6_clockphase = 1;
416 ret = mxl1x1sf_soft_reset(state);
417 if (mxl_fail(ret))
418 goto fail;
419 ret = mxl111sf_init_tuner_demod(state);
420 if (mxl_fail(ret))
421 goto fail;
423 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
424 if (mxl_fail(ret))
425 goto fail;
427 ret = mxl111sf_enable_usb_output(state);
428 if (mxl_fail(ret))
429 goto fail;
430 ret = mxl1x1sf_top_master_ctrl(state, 1);
431 if (mxl_fail(ret))
432 goto fail;
434 ret = mxl111sf_init_port_expander(state);
435 if (mxl_fail(ret))
436 goto fail;
437 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
438 if (mxl_fail(ret))
439 goto fail;
441 adap->fe_adap[fe_id].fe = dvb_attach(lgdt3305_attach,
442 &hauppauge_lgdt3305_config,
443 &adap->dev->i2c_adap);
444 if (adap->fe_adap[fe_id].fe) {
445 adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
446 adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
447 adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
448 adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
449 return 0;
451 ret = -EIO;
452 fail:
453 return ret;
456 static struct mxl111sf_demod_config mxl_demod_config = {
457 .read_reg = mxl111sf_read_reg,
458 .write_reg = mxl111sf_write_reg,
459 .program_regs = mxl111sf_ctrl_program_regs,
462 static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap)
464 struct dvb_usb_device *d = adap->dev;
465 struct mxl111sf_state *state = d->priv;
466 int fe_id = adap->num_frontends_initialized;
467 struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
468 int ret;
470 deb_adv("%s()\n", __func__);
472 /* save a pointer to the dvb_usb_device in device state */
473 state->d = d;
474 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
475 state->alt_mode = adap_state->alt_mode;
477 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
478 err("set interface failed");
480 state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
481 adap_state->gpio_mode = state->gpio_mode;
482 adap_state->device_mode = MXL_SOC_MODE;
483 adap_state->ep6_clockphase = 1;
485 ret = mxl1x1sf_soft_reset(state);
486 if (mxl_fail(ret))
487 goto fail;
488 ret = mxl111sf_init_tuner_demod(state);
489 if (mxl_fail(ret))
490 goto fail;
492 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
493 if (mxl_fail(ret))
494 goto fail;
496 ret = mxl111sf_enable_usb_output(state);
497 if (mxl_fail(ret))
498 goto fail;
499 ret = mxl1x1sf_top_master_ctrl(state, 1);
500 if (mxl_fail(ret))
501 goto fail;
503 /* dont care if this fails */
504 mxl111sf_init_port_expander(state);
506 adap->fe_adap[fe_id].fe = dvb_attach(mxl111sf_demod_attach, state,
507 &mxl_demod_config);
508 if (adap->fe_adap[fe_id].fe) {
509 adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
510 adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
511 adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
512 adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
513 return 0;
515 ret = -EIO;
516 fail:
517 return ret;
520 static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
521 int antpath)
523 return mxl111sf_idac_config(state, 1, 1,
524 (antpath == ANT_PATH_INTERNAL) ?
525 0x3f : 0x00, 0);
528 #define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
529 err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
530 __func__, __LINE__, \
531 (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
532 pwr0, pwr1, pwr2, pwr3)
534 #define ANT_HUNT_SLEEP 90
535 #define ANT_EXT_TWEAK 0
537 static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
539 struct dvb_usb_adapter *adap = fe->dvb->priv;
540 struct dvb_usb_device *d = adap->dev;
541 struct mxl111sf_state *state = d->priv;
543 int antctrl = dvb_usb_mxl111sf_rfswitch;
545 u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
547 /* FIXME: must force EXTERNAL for QAM - done elsewhere */
548 mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
549 ANT_PATH_EXTERNAL : antctrl);
551 if (antctrl == ANT_PATH_AUTO) {
552 #if 0
553 msleep(ANT_HUNT_SLEEP);
554 #endif
555 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
557 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
558 msleep(ANT_HUNT_SLEEP);
559 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
561 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
562 msleep(ANT_HUNT_SLEEP);
563 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
565 mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
566 msleep(ANT_HUNT_SLEEP);
567 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
569 if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
570 /* return with EXTERNAL enabled */
571 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
572 DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
573 rxPwr0, rxPwr1, rxPwr2);
574 } else {
575 /* return with INTERNAL enabled */
576 DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
577 rxPwr0, rxPwr1, rxPwr2);
580 return 0;
583 static struct mxl111sf_tuner_config mxl_tuner_config = {
584 .if_freq = MXL_IF_6_0, /* applies to external IF output, only */
585 .invert_spectrum = 0,
586 .read_reg = mxl111sf_read_reg,
587 .write_reg = mxl111sf_write_reg,
588 .program_regs = mxl111sf_ctrl_program_regs,
589 .top_master_ctrl = mxl1x1sf_top_master_ctrl,
590 .ant_hunt = mxl111sf_ant_hunt,
593 static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
595 struct dvb_usb_device *d = adap->dev;
596 struct mxl111sf_state *state = d->priv;
597 int fe_id = adap->num_frontends_initialized;
599 deb_adv("%s()\n", __func__);
601 if (NULL != dvb_attach(mxl111sf_tuner_attach,
602 adap->fe_adap[fe_id].fe, state,
603 &mxl_tuner_config))
604 return 0;
606 return -EIO;
609 static int mxl111sf_fe_ioctl_override(struct dvb_frontend *fe,
610 unsigned int cmd, void *parg,
611 unsigned int stage)
613 int err = 0;
615 switch (stage) {
616 case DVB_FE_IOCTL_PRE:
618 switch (cmd) {
619 case FE_READ_SIGNAL_STRENGTH:
620 err = fe->ops.tuner_ops.get_rf_strength(fe, parg);
621 /* If no error occurs, prevent dvb-core from handling
622 * this IOCTL, otherwise return the error */
623 if (0 == err)
624 err = 1;
625 break;
627 break;
629 case DVB_FE_IOCTL_POST:
630 /* no post-ioctl handling required */
631 break;
633 return err;
636 static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
638 return I2C_FUNC_I2C;
641 struct i2c_algorithm mxl111sf_i2c_algo = {
642 .master_xfer = mxl111sf_i2c_xfer,
643 .functionality = mxl111sf_i2c_func,
644 #ifdef NEED_ALGO_CONTROL
645 .algo_control = dummy_algo_control,
646 #endif
649 static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
650 static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
651 static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
652 static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
654 static int mxl111sf_probe(struct usb_interface *intf,
655 const struct usb_device_id *id)
657 struct dvb_usb_device *d = NULL;
659 deb_adv("%s()\n", __func__);
661 if (((dvb_usb_mxl111sf_isoc) &&
662 (0 == dvb_usb_device_init(intf,
663 &mxl111sf_dvbt_isoc_properties,
664 THIS_MODULE, &d, adapter_nr) ||
665 0 == dvb_usb_device_init(intf,
666 &mxl111sf_atsc_isoc_properties,
667 THIS_MODULE, &d, adapter_nr))) ||
668 0 == dvb_usb_device_init(intf,
669 &mxl111sf_dvbt_bulk_properties,
670 THIS_MODULE, &d, adapter_nr) ||
671 0 == dvb_usb_device_init(intf,
672 &mxl111sf_atsc_bulk_properties,
673 THIS_MODULE, &d, adapter_nr) || 0) {
675 struct mxl111sf_state *state = d->priv;
676 static u8 eeprom[256];
677 struct i2c_client c;
678 int ret;
680 ret = get_chip_info(state);
681 if (mxl_fail(ret))
682 err("failed to get chip info during probe");
684 mutex_init(&state->fe_lock);
686 if (state->chip_rev > MXL111SF_V6)
687 mxl111sf_config_pin_mux_modes(state,
688 PIN_MUX_TS_SPI_IN_MODE_1);
690 c.adapter = &d->i2c_adap;
691 c.addr = 0xa0 >> 1;
693 ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
694 if (mxl_fail(ret))
695 return 0;
696 tveeprom_hauppauge_analog(&c, &state->tv,
697 (0x84 == eeprom[0xa0]) ?
698 eeprom + 0xa0 : eeprom + 0x80);
699 #if 0
700 switch (state->tv.model) {
701 case 117001:
702 case 126001:
703 case 138001:
704 break;
705 default:
706 printk(KERN_WARNING "%s: warning: "
707 "unknown hauppauge model #%d\n",
708 __func__, state->tv.model);
710 #endif
711 return 0;
713 err("Your device is not yet supported by this driver. "
714 "See kernellabs.com for more info");
715 return -EINVAL;
718 static struct usb_device_id mxl111sf_table[] = {
719 /* 0 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600) }, /* ATSC+ IR */
720 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601) }, /* ATSC */
721 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602) }, /* + */
722 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603) }, /* ATSC+ */
723 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604) }, /* DVBT */
724 /* 5 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609) }, /* ATSC IR */
725 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a) }, /* + IR */
726 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b) }, /* ATSC+ IR */
727 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c) }, /* DVBT IR */
728 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653) }, /* ATSC+ */
729 /*10 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b) }, /* ATSC+ IR */
730 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700) }, /* ATSC+ sw */
731 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701) }, /* ATSC sw */
732 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702) }, /* + sw */
733 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703) }, /* ATSC+ sw */
734 /*15 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704) }, /* DVBT sw */
735 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753) }, /* ATSC+ sw */
736 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763) }, /* ATSC+ no */
737 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764) }, /* DVBT no */
738 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853) }, /* ATSC+ sw */
739 /*20 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854) }, /* DVBT sw */
740 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863) }, /* ATSC+ no */
741 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864) }, /* DVBT no */
742 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3) }, /* ATSC+ sw */
743 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4) }, /* DVBT sw */
744 /*25 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3) }, /* ATSC+ no */
745 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4) }, /* DVBT no */
746 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff) }, /* ATSC+ */
747 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612) }, /* + */
748 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613) }, /* ATSC+ */
749 /*30 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a) }, /* + IR */
750 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b) }, /* ATSC+ IR */
751 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757) }, /* ATSC+DVBT sw */
752 { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767) }, /* ATSC+DVBT no */
753 {} /* Terminating entry */
755 MODULE_DEVICE_TABLE(usb, mxl111sf_table);
758 #define MXL111SF_EP4_BULK_STREAMING_CONFIG \
759 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
760 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
761 .stream = { \
762 .type = USB_BULK, \
763 .count = 5, \
764 .endpoint = 0x04, \
765 .u = { \
766 .bulk = { \
767 .buffersize = 8192, \
772 /* FIXME: works for v6 but not v8 silicon */
773 #define MXL111SF_EP4_ISOC_STREAMING_CONFIG \
774 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
775 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
776 .stream = { \
777 .type = USB_ISOC, \
778 .count = 5, \
779 .endpoint = 0x04, \
780 .u = { \
781 .isoc = { \
782 .framesperurb = 96, \
783 /* FIXME: v6 SILICON: */ \
784 .framesize = 564, \
785 .interval = 1, \
790 #define MXL111SF_EP6_BULK_STREAMING_CONFIG \
791 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
792 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
793 .stream = { \
794 .type = USB_BULK, \
795 .count = 5, \
796 .endpoint = 0x06, \
797 .u = { \
798 .bulk = { \
799 .buffersize = 8192, \
804 /* FIXME */
805 #define MXL111SF_EP6_ISOC_STREAMING_CONFIG \
806 .size_of_priv = sizeof(struct mxl111sf_adap_state), \
807 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
808 .stream = { \
809 .type = USB_ISOC, \
810 .count = 5, \
811 .endpoint = 0x06, \
812 .u = { \
813 .isoc = { \
814 .framesperurb = 24, \
815 .framesize = 3072, \
816 .interval = 1, \
821 #define MXL111SF_DEFAULT_DEVICE_PROPERTIES \
822 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
823 .usb_ctrl = DEVICE_SPECIFIC, \
824 /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t), \
825 EP6 BULK transfer (atsc/qam), \
826 use usb alt setting 2 for EP4 BULK transfer (dvb-t), \
827 EP6 ISOC transfer (atsc/qam), \
828 */ \
829 .power_ctrl = mxl111sf_power_ctrl, \
830 .i2c_algo = &mxl111sf_i2c_algo, \
831 .generic_bulk_ctrl_endpoint = MXL_EP2_REG_WRITE, \
832 .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \
833 .size_of_priv = sizeof(struct mxl111sf_state)
835 static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
836 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
838 .num_adapters = 1,
839 .adapter = {
841 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
842 .num_frontends = 1,
843 .fe = {{
844 .frontend_attach = mxl111sf_attach_demod,
845 .tuner_attach = mxl111sf_attach_tuner,
847 MXL111SF_EP4_BULK_STREAMING_CONFIG,
848 } },
851 .num_device_descs = 4,
852 .devices = {
853 { "Hauppauge 126xxx DVBT (bulk)",
854 { NULL },
855 { &mxl111sf_table[4], &mxl111sf_table[8],
856 NULL },
858 { "Hauppauge 117xxx DVBT (bulk)",
859 { NULL },
860 { &mxl111sf_table[15], &mxl111sf_table[18],
861 NULL },
863 { "Hauppauge 138xxx DVBT (bulk)",
864 { NULL },
865 { &mxl111sf_table[20], &mxl111sf_table[22],
866 &mxl111sf_table[24], &mxl111sf_table[26],
867 NULL },
869 { "Hauppauge 126xxx (tp-bulk)",
870 { NULL },
871 { &mxl111sf_table[28], &mxl111sf_table[30],
872 NULL },
877 static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = {
878 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
880 .num_adapters = 1,
881 .adapter = {
883 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
884 .num_frontends = 1,
885 .fe = {{
886 .frontend_attach = mxl111sf_attach_demod,
887 .tuner_attach = mxl111sf_attach_tuner,
889 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
890 } },
893 .num_device_descs = 4,
894 .devices = {
895 { "Hauppauge 126xxx DVBT (isoc)",
896 { NULL },
897 { &mxl111sf_table[4], &mxl111sf_table[8],
898 NULL },
900 { "Hauppauge 117xxx DVBT (isoc)",
901 { NULL },
902 { &mxl111sf_table[15], &mxl111sf_table[18],
903 NULL },
905 { "Hauppauge 138xxx DVBT (isoc)",
906 { NULL },
907 { &mxl111sf_table[20], &mxl111sf_table[22],
908 &mxl111sf_table[24], &mxl111sf_table[26],
909 NULL },
911 { "Hauppauge 126xxx (tp-isoc)",
912 { NULL },
913 { &mxl111sf_table[28], &mxl111sf_table[30],
914 NULL },
919 static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
920 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
922 .num_adapters = 1,
923 .adapter = {
925 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
926 .num_frontends = 2,
927 .fe = {{
928 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
929 .tuner_attach = mxl111sf_attach_tuner,
931 MXL111SF_EP6_BULK_STREAMING_CONFIG,
934 .frontend_attach = mxl111sf_attach_demod,
935 .tuner_attach = mxl111sf_attach_tuner,
937 MXL111SF_EP4_BULK_STREAMING_CONFIG,
941 .num_device_descs = 6,
942 .devices = {
943 { "Hauppauge 126xxx ATSC (bulk)",
944 { NULL },
945 { &mxl111sf_table[1], &mxl111sf_table[5],
946 NULL },
948 { "Hauppauge 117xxx ATSC (bulk)",
949 { NULL },
950 { &mxl111sf_table[12],
951 NULL },
953 { "Hauppauge 126xxx ATSC+ (bulk)",
954 { NULL },
955 { &mxl111sf_table[0], &mxl111sf_table[3],
956 &mxl111sf_table[7], &mxl111sf_table[9],
957 &mxl111sf_table[10], NULL },
959 { "Hauppauge 117xxx ATSC+ (bulk)",
960 { NULL },
961 { &mxl111sf_table[11], &mxl111sf_table[14],
962 &mxl111sf_table[16], &mxl111sf_table[17],
963 &mxl111sf_table[32], &mxl111sf_table[33],
964 NULL },
966 { "Hauppauge Mercury (tp-bulk)",
967 { NULL },
968 { &mxl111sf_table[19], &mxl111sf_table[21],
969 &mxl111sf_table[23], &mxl111sf_table[25],
970 &mxl111sf_table[27], NULL },
972 { "Hauppauge WinTV-Aero-M",
973 { NULL },
974 { &mxl111sf_table[29], &mxl111sf_table[31],
975 NULL },
980 static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
981 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
983 .num_adapters = 1,
984 .adapter = {
986 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
987 .num_frontends = 2,
988 .fe = {{
989 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
990 .tuner_attach = mxl111sf_attach_tuner,
992 MXL111SF_EP6_ISOC_STREAMING_CONFIG,
995 .frontend_attach = mxl111sf_attach_demod,
996 .tuner_attach = mxl111sf_attach_tuner,
998 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
1002 .num_device_descs = 6,
1003 .devices = {
1004 { "Hauppauge 126xxx ATSC (isoc)",
1005 { NULL },
1006 { &mxl111sf_table[1], &mxl111sf_table[5],
1007 NULL },
1009 { "Hauppauge 117xxx ATSC (isoc)",
1010 { NULL },
1011 { &mxl111sf_table[12],
1012 NULL },
1014 { "Hauppauge 126xxx ATSC+ (isoc)",
1015 { NULL },
1016 { &mxl111sf_table[0], &mxl111sf_table[3],
1017 &mxl111sf_table[7], &mxl111sf_table[9],
1018 &mxl111sf_table[10], NULL },
1020 { "Hauppauge 117xxx ATSC+ (isoc)",
1021 { NULL },
1022 { &mxl111sf_table[11], &mxl111sf_table[14],
1023 &mxl111sf_table[16], &mxl111sf_table[17],
1024 &mxl111sf_table[32], &mxl111sf_table[33],
1025 NULL },
1027 { "Hauppauge Mercury (tp-isoc)",
1028 { NULL },
1029 { &mxl111sf_table[19], &mxl111sf_table[21],
1030 &mxl111sf_table[23], &mxl111sf_table[25],
1031 &mxl111sf_table[27], NULL },
1033 { "Hauppauge WinTV-Aero-M (tp-isoc)",
1034 { NULL },
1035 { &mxl111sf_table[29], &mxl111sf_table[31],
1036 NULL },
1041 static struct usb_driver mxl111sf_driver = {
1042 .name = "dvb_usb_mxl111sf",
1043 .probe = mxl111sf_probe,
1044 .disconnect = dvb_usb_device_exit,
1045 .id_table = mxl111sf_table,
1048 module_usb_driver(mxl111sf_driver);
1050 MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
1051 MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
1052 MODULE_VERSION("1.0");
1053 MODULE_LICENSE("GPL");
1056 * Local variables:
1057 * c-basic-offset: 8
1058 * End: