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 25int dvb_usb_mxl111sf_debug; 26module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644); 27MODULE_PARM_DESC(debug, "set debugging level " 28 "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able))."); 29 30int dvb_usb_mxl111sf_isoc; 31module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644); 32MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc)."); 33 34#define ANT_PATH_AUTO 0 35#define ANT_PATH_EXTERNAL 1 36#define ANT_PATH_INTERNAL 2 37 38int dvb_usb_mxl111sf_rfswitch = 39#if 0 40 ANT_PATH_AUTO; 41#else 42 ANT_PATH_EXTERNAL; 43#endif 44 45module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644); 46MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int)."); 47 48DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 49 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) 53 54int mxl111sf_ctrl_msg(struct dvb_usb_device *d, 55 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) 56{ 57 int wo = (rbuf == NULL || rlen == 0); /* write-only */ 58 int ret; 59 u8 sndbuf[1+wlen]; 60 61 deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen); 62 63 memset(sndbuf, 0, 1+wlen); 64 65 sndbuf[0] = cmd; 66 memcpy(&sndbuf[1], wbuf, wlen); 67 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); 71 72 return ret; 73} 74 75/* ------------------------------------------------------------------------ */ 76 77#define MXL_CMD_REG_READ 0xaa 78#define MXL_CMD_REG_WRITE 0x55 79 80int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data) 81{ 82 u8 buf[2]; 83 int ret; 84 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; 89 } 90 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; 97 } 98 99 deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data); 100fail: 101 return ret; 102} 103 104int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data) 105{ 106 u8 buf[] = { addr, data }; 107 int ret; 108 109 deb_reg("W: (0x%02x, 0x%02x)\n", addr, data); 110 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; 115} 116 117/* ------------------------------------------------------------------------ */ 118 119int mxl111sf_write_reg_mask(struct mxl111sf_state *state, 120 u8 addr, u8 mask, u8 data) 121{ 122 int ret; 123 u8 val; 124 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); 132 133 ret = mxl111sf_read_reg(state, addr, &val); 134#endif 135 if (mxl_fail(ret)) 136 goto fail; 137 } 138 val &= ~mask; 139 val |= data; 140 141 ret = mxl111sf_write_reg(state, addr, val); 142 mxl_fail(ret); 143fail: 144 return ret; 145} 146 147/* ------------------------------------------------------------------------ */ 148 149int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state, 150 struct mxl111sf_reg_ctrl_info *ctrl_reg_info) 151{ 152 int i, ret = 0; 153 154 for (i = 0; ctrl_reg_info[i].addr | 155 ctrl_reg_info[i].mask | 156 ctrl_reg_info[i].data; i++) { 157 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; 166 } 167 } 168 return ret; 169} 170 171/* ------------------------------------------------------------------------ */ 172 173static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state) 174{ 175 int ret; 176 u8 id, ver; 177 char *mxl_chip, *mxl_rev; 178 179 if ((state->chip_id) && (state->chip_ver)) 180 return 0; 181 182 ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id); 183 if (mxl_fail(ret)) 184 goto fail; 185 state->chip_id = id; 186 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; 191 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; 202 } 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; 220 } 221 info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver); 222fail: 223 return ret; 224} 225 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."); \ 239 } \ 240 ___ret; \ 241}) 242 243/* ------------------------------------------------------------------------ */ 244 245static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff) 246{ 247 /* power control depends on which adapter is being woken: 248 * save this for init, instead, via mxl111sf_adap_fe_init */ 249 return 0; 250} 251 252static int mxl111sf_adap_fe_init(struct dvb_frontend *fe) 253{ 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; 258 259 int err; 260 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; 265 } 266 267 deb_info("%s()\n", __func__); 268 269 mutex_lock(&state->fe_lock); 270 271 state->alt_mode = adap_state->alt_mode; 272 273 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0) 274 err("set interface failed"); 275 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); 281 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); 287 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); 293 } 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 */ 304 } 305 306 return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0; 307fail: 308 return -ENODEV; 309} 310 311static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe) 312{ 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; 318 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; 323 } 324 325 deb_info("%s()\n", __func__); 326 327 err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0; 328 329 mutex_unlock(&state->fe_lock); 330 331 return err; 332fail: 333 return -ENODEV; 334} 335 336 337static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 338{ 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; 344 345 deb_info("%s(%d)\n", __func__, onoff); 346 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 359 } 360 361 return ret; 362} 363 364static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 365{ 366 struct dvb_usb_device *d = adap->dev; 367 struct mxl111sf_state *state = d->priv; 368 int ret = 0; 369 370 deb_info("%s(%d)\n", __func__, onoff); 371 372 if (onoff) { 373 ret = mxl111sf_enable_usb_output(state); 374 mxl_fail(ret); 375 } 376 377 return ret; 378} 379 380/* ------------------------------------------------------------------------ */ 381 382static 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, 391}; 392 393static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap) 394{ 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; 400 401 deb_adv("%s()\n", __func__); 402 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; 407 408 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0) 409 err("set interface failed"); 410 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; 415 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; 422 423 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode); 424 if (mxl_fail(ret)) 425 goto fail; 426 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; 433 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; 440 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; 450 } 451 ret = -EIO; 452fail: 453 return ret; 454} 455 456static 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, 460}; 461 462static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap) 463{ 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; 469 470 deb_adv("%s()\n", __func__); 471 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; 476 477 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0) 478 err("set interface failed"); 479 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; 484 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; 491 492 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode); 493 if (mxl_fail(ret)) 494 goto fail; 495 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; 502 503 /* dont care if this fails */ 504 mxl111sf_init_port_expander(state); 505 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; 514 } 515 ret = -EIO; 516fail: 517 return ret; 518} 519 520static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state, 521 int antpath) 522{ 523 return mxl111sf_idac_config(state, 1, 1, 524 (antpath == ANT_PATH_INTERNAL) ? 525 0x3f : 0x00, 0); 526} 527 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) 533 534#define ANT_HUNT_SLEEP 90 535#define ANT_EXT_TWEAK 0 536 537static int mxl111sf_ant_hunt(struct dvb_frontend *fe) 538{ 539 struct dvb_usb_adapter *adap = fe->dvb->priv; 540 struct dvb_usb_device *d = adap->dev; 541 struct mxl111sf_state *state = d->priv; 542 543 int antctrl = dvb_usb_mxl111sf_rfswitch; 544 545 u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2; 546 547 /* FIXME: must force EXTERNAL for QAM - done elsewhere */ 548 mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ? 549 ANT_PATH_EXTERNAL : antctrl); 550 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); 556 557 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL); 558 msleep(ANT_HUNT_SLEEP); 559 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0); 560 561 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL); 562 msleep(ANT_HUNT_SLEEP); 563 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1); 564 565 mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL); 566 msleep(ANT_HUNT_SLEEP); 567 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2); 568 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); 578 } 579 } 580 return 0; 581} 582 583static 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, 591}; 592 593static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap) 594{ 595 struct dvb_usb_device *d = adap->dev; 596 struct mxl111sf_state *state = d->priv; 597 int fe_id = adap->num_frontends_initialized; 598 599 deb_adv("%s()\n", __func__); 600 601 if (NULL != dvb_attach(mxl111sf_tuner_attach, 602 adap->fe_adap[fe_id].fe, state, 603 &mxl_tuner_config)) 604 return 0; 605 606 return -EIO; 607} 608 609static int mxl111sf_fe_ioctl_override(struct dvb_frontend *fe, 610 unsigned int cmd, void *parg, 611 unsigned int stage) 612{ 613 int err = 0; 614 615 switch (stage) { 616 case DVB_FE_IOCTL_PRE: 617 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; 626 } 627 break; 628 629 case DVB_FE_IOCTL_POST: 630 /* no post-ioctl handling required */ 631 break; 632 } 633 return err; 634}; 635 636static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter) 637{ 638 return I2C_FUNC_I2C; 639} 640 641struct 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 647}; 648 649static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties; 650static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties; 651static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties; 652static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties; 653 654static int mxl111sf_probe(struct usb_interface *intf, 655 const struct usb_device_id *id) 656{ 657 struct dvb_usb_device *d = NULL; 658 659 deb_adv("%s()\n", __func__); 660 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) { 674 675 struct mxl111sf_state *state = d->priv; 676 static u8 eeprom[256]; 677 struct i2c_client c; 678 int ret; 679 680 ret = get_chip_info(state); 681 if (mxl_fail(ret)) 682 err("failed to get chip info during probe"); 683 684 mutex_init(&state->fe_lock); 685 686 if (state->chip_rev > MXL111SF_V6) 687 mxl111sf_config_pin_mux_modes(state, 688 PIN_MUX_TS_SPI_IN_MODE_1); 689 690 c.adapter = &d->i2c_adap; 691 c.addr = 0xa0 >> 1; 692 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); 709 } 710#endif 711 return 0; 712 } 713 err("Your device is not yet supported by this driver. " 714 "See kernellabs.com for more info"); 715 return -EINVAL; 716} 717 718static 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 */ 754}; 755MODULE_DEVICE_TABLE(usb, mxl111sf_table); 756 757 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, \ 768 } \ 769 } \ 770 } 771 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, \ 786 } \ 787 } \ 788 } 789 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, \ 800 } \ 801 } \ 802 } 803 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, \ 817 } \ 818 } \ 819 } 820 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) 834 835static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = { 836 MXL111SF_DEFAULT_DEVICE_PROPERTIES, 837 838 .num_adapters = 1, 839 .adapter = { 840 { 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, 846 847 MXL111SF_EP4_BULK_STREAMING_CONFIG, 848 } }, 849 }, 850 }, 851 .num_device_descs = 4, 852 .devices = { 853 { "Hauppauge 126xxx DVBT (bulk)", 854 { NULL }, 855 { &mxl111sf_table[4], &mxl111sf_table[8], 856 NULL }, 857 }, 858 { "Hauppauge 117xxx DVBT (bulk)", 859 { NULL }, 860 { &mxl111sf_table[15], &mxl111sf_table[18], 861 NULL }, 862 }, 863 { "Hauppauge 138xxx DVBT (bulk)", 864 { NULL }, 865 { &mxl111sf_table[20], &mxl111sf_table[22], 866 &mxl111sf_table[24], &mxl111sf_table[26], 867 NULL }, 868 }, 869 { "Hauppauge 126xxx (tp-bulk)", 870 { NULL }, 871 { &mxl111sf_table[28], &mxl111sf_table[30], 872 NULL }, 873 }, 874 } 875}; 876 877static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = { 878 MXL111SF_DEFAULT_DEVICE_PROPERTIES, 879 880 .num_adapters = 1, 881 .adapter = { 882 { 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, 888 889 MXL111SF_EP4_ISOC_STREAMING_CONFIG, 890 } }, 891 }, 892 }, 893 .num_device_descs = 4, 894 .devices = { 895 { "Hauppauge 126xxx DVBT (isoc)", 896 { NULL }, 897 { &mxl111sf_table[4], &mxl111sf_table[8], 898 NULL }, 899 }, 900 { "Hauppauge 117xxx DVBT (isoc)", 901 { NULL }, 902 { &mxl111sf_table[15], &mxl111sf_table[18], 903 NULL }, 904 }, 905 { "Hauppauge 138xxx DVBT (isoc)", 906 { NULL }, 907 { &mxl111sf_table[20], &mxl111sf_table[22], 908 &mxl111sf_table[24], &mxl111sf_table[26], 909 NULL }, 910 }, 911 { "Hauppauge 126xxx (tp-isoc)", 912 { NULL }, 913 { &mxl111sf_table[28], &mxl111sf_table[30], 914 NULL }, 915 }, 916 } 917}; 918 919static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = { 920 MXL111SF_DEFAULT_DEVICE_PROPERTIES, 921 922 .num_adapters = 1, 923 .adapter = { 924 { 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, 930 931 MXL111SF_EP6_BULK_STREAMING_CONFIG, 932 }, 933 { 934 .frontend_attach = mxl111sf_attach_demod, 935 .tuner_attach = mxl111sf_attach_tuner, 936 937 MXL111SF_EP4_BULK_STREAMING_CONFIG, 938 }}, 939 }, 940 }, 941 .num_device_descs = 6, 942 .devices = { 943 { "Hauppauge 126xxx ATSC (bulk)", 944 { NULL }, 945 { &mxl111sf_table[1], &mxl111sf_table[5], 946 NULL }, 947 }, 948 { "Hauppauge 117xxx ATSC (bulk)", 949 { NULL }, 950 { &mxl111sf_table[12], 951 NULL }, 952 }, 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 }, 958 }, 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 }, 965 }, 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 }, 971 }, 972 { "Hauppauge WinTV-Aero-M", 973 { NULL }, 974 { &mxl111sf_table[29], &mxl111sf_table[31], 975 NULL }, 976 }, 977 } 978}; 979 980static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = { 981 MXL111SF_DEFAULT_DEVICE_PROPERTIES, 982 983 .num_adapters = 1, 984 .adapter = { 985 { 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, 991 992 MXL111SF_EP6_ISOC_STREAMING_CONFIG, 993 }, 994 { 995 .frontend_attach = mxl111sf_attach_demod, 996 .tuner_attach = mxl111sf_attach_tuner, 997 998 MXL111SF_EP4_ISOC_STREAMING_CONFIG, 999 }}, 1000 }, 1001 }, 1002 .num_device_descs = 6, 1003 .devices = { 1004 { "Hauppauge 126xxx ATSC (isoc)", 1005 { NULL }, 1006 { &mxl111sf_table[1], &mxl111sf_table[5], 1007 NULL }, 1008 }, 1009 { "Hauppauge 117xxx ATSC (isoc)", 1010 { NULL }, 1011 { &mxl111sf_table[12], 1012 NULL }, 1013 }, 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 }, 1019 }, 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 }, 1026 }, 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 }, 1032 }, 1033 { "Hauppauge WinTV-Aero-M (tp-isoc)", 1034 { NULL }, 1035 { &mxl111sf_table[29], &mxl111sf_table[31], 1036 NULL }, 1037 }, 1038 } 1039}; 1040 1041static 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, 1046}; 1047 1048module_usb_driver(mxl111sf_driver); 1049 1050MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>"); 1051MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF"); 1052MODULE_VERSION("1.0"); 1053MODULE_LICENSE("GPL"); 1054 1055/* 1056 * Local variables: 1057 * c-basic-offset: 8 1058 * End: 1059 */ 1060