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 } else { 355 ret = mxl111sf_disable_656_port(state); 356 mxl_fail(ret); 357 } 358 359 mxl111sf_read_reg(state, 0x12, &tmp); 360 tmp &= ~0x04; 361 mxl111sf_write_reg(state, 0x12, tmp); 362 363 return ret; 364} 365 366static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 367{ 368 struct dvb_usb_device *d = adap->dev; 369 struct mxl111sf_state *state = d->priv; 370 int ret = 0; 371 372 deb_info("%s(%d)\n", __func__, onoff); 373 374 if (onoff) { 375 ret = mxl111sf_enable_usb_output(state); 376 mxl_fail(ret); 377 } 378 379 return ret; 380} 381 382/* ------------------------------------------------------------------------ */ 383 384static 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, 389 .deny_i2c_rptr = 1, 390 .spectral_inversion = 0, 391 .qam_if_khz = 6000, 392 .vsb_if_khz = 6000, 393}; 394 395static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap) 396{ 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; 401 int ret; 402 403 deb_adv("%s()\n", __func__); 404 405 /* save a pointer to the dvb_usb_device in device state */ 406 state->d = d; 407 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1; 408 state->alt_mode = adap_state->alt_mode; 409 410 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0) 411 err("set interface failed"); 412 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; 417 418 ret = mxl1x1sf_soft_reset(state); 419 if (mxl_fail(ret)) 420 goto fail; 421 ret = mxl111sf_init_tuner_demod(state); 422 if (mxl_fail(ret)) 423 goto fail; 424 425 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode); 426 if (mxl_fail(ret)) 427 goto fail; 428 429 ret = mxl111sf_enable_usb_output(state); 430 if (mxl_fail(ret)) 431 goto fail; 432 ret = mxl1x1sf_top_master_ctrl(state, 1); 433 if (mxl_fail(ret)) 434 goto fail; 435 436 ret = mxl111sf_init_port_expander(state); 437 if (mxl_fail(ret)) 438 goto fail; 439 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode); 440 if (mxl_fail(ret)) 441 goto fail; 442 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; 451 return 0; 452 } 453 ret = -EIO; 454fail: 455 return ret; 456} 457 458static 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, 462}; 463 464static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap) 465{ 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; 470 int ret; 471 472 deb_adv("%s()\n", __func__); 473 474 /* save a pointer to the dvb_usb_device in device state */ 475 state->d = d; 476 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2; 477 state->alt_mode = adap_state->alt_mode; 478 479 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0) 480 err("set interface failed"); 481 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; 486 487 ret = mxl1x1sf_soft_reset(state); 488 if (mxl_fail(ret)) 489 goto fail; 490 ret = mxl111sf_init_tuner_demod(state); 491 if (mxl_fail(ret)) 492 goto fail; 493 494 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode); 495 if (mxl_fail(ret)) 496 goto fail; 497 498 ret = mxl111sf_enable_usb_output(state); 499 if (mxl_fail(ret)) 500 goto fail; 501 ret = mxl1x1sf_top_master_ctrl(state, 1); 502 if (mxl_fail(ret)) 503 goto fail; 504 505 /* dont care if this fails */ 506 mxl111sf_init_port_expander(state); 507 508 adap->fe_adap[fe_id].fe = dvb_attach(mxl111sf_demod_attach, state, 509 &mxl_demod_config); 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; 515 return 0; 516 } 517 ret = -EIO; 518fail: 519 return ret; 520} 521 522static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state, 523 int antpath) 524{ 525 return mxl111sf_idac_config(state, 1, 1, 526 (antpath == ANT_PATH_INTERNAL) ? 527 0x3f : 0x00, 0); 528} 529 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) 535 536#define ANT_HUNT_SLEEP 90 537#define ANT_EXT_TWEAK 0 538 539static int mxl111sf_ant_hunt(struct dvb_frontend *fe) 540{ 541 struct dvb_usb_adapter *adap = fe->dvb->priv; 542 struct dvb_usb_device *d = adap->dev; 543 struct mxl111sf_state *state = d->priv; 544 545 int antctrl = dvb_usb_mxl111sf_rfswitch; 546 547 u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2; 548 549 /* FIXME: must force EXTERNAL for QAM - done elsewhere */ 550 mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ? 551 ANT_PATH_EXTERNAL : antctrl); 552 553 if (antctrl == ANT_PATH_AUTO) { 554#if 0 555 msleep(ANT_HUNT_SLEEP); 556#endif 557 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA); 558 559 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL); 560 msleep(ANT_HUNT_SLEEP); 561 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0); 562 563 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL); 564 msleep(ANT_HUNT_SLEEP); 565 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1); 566 567 mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL); 568 msleep(ANT_HUNT_SLEEP); 569 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2); 570 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); 576 } else { 577 /* return with INTERNAL enabled */ 578 DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA, 579 rxPwr0, rxPwr1, rxPwr2); 580 } 581 } 582 return 0; 583} 584 585static 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, 593}; 594 595static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap) 596{ 597 struct dvb_usb_device *d = adap->dev; 598 struct mxl111sf_state *state = d->priv; 599 int fe_id = adap->num_frontends_initialized; 600 601 deb_adv("%s()\n", __func__); 602 603 if (NULL != dvb_attach(mxl111sf_tuner_attach, 604 adap->fe_adap[fe_id].fe, state, 605 &mxl_tuner_config)) 606 return 0; 607 608 return -EIO; 609} 610 611static int mxl111sf_fe_ioctl_override(struct dvb_frontend *fe, 612 unsigned int cmd, void *parg, 613 unsigned int stage) 614{ 615 int err = 0; 616 617 switch (stage) { 618 case DVB_FE_IOCTL_PRE: 619 620 switch (cmd) { 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 */ 625 if (0 == err) 626 err = 1; 627 break; 628 } 629 break; 630 631 case DVB_FE_IOCTL_POST: 632 /* no post-ioctl handling required */ 633 break; 634 } 635 return err; 636}; 637 638static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter) 639{ 640 return I2C_FUNC_I2C; 641} 642 643struct 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, 648#endif 649}; 650 651static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties; 652static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties; 653static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties; 654static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties; 655 656static int mxl111sf_probe(struct usb_interface *intf, 657 const struct usb_device_id *id) 658{ 659 struct dvb_usb_device *d = NULL; 660 661 deb_adv("%s()\n", __func__); 662 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) { 676 677 struct mxl111sf_state *state = d->priv; 678 static u8 eeprom[256]; 679 struct i2c_client c; 680 int ret; 681 682 ret = get_chip_info(state); 683 if (mxl_fail(ret)) 684 err("failed to get chip info during probe"); 685 686 mutex_init(&state->fe_lock); 687 688 if (state->chip_rev > MXL111SF_V6) 689 mxl111sf_config_pin_mux_modes(state, 690 PIN_MUX_TS_SPI_IN_MODE_1); 691 692 c.adapter = &d->i2c_adap; 693 c.addr = 0xa0 >> 1; 694 695 ret = tveeprom_read(&c, eeprom, sizeof(eeprom)); 696 if (mxl_fail(ret)) 697 return 0; 698 tveeprom_hauppauge_analog(&c, &state->tv, 699 (0x84 == eeprom[0xa0]) ? 700 eeprom + 0xa0 : eeprom + 0x80); 701#if 0 702 switch (state->tv.model) { 703 case 117001: 704 case 126001: 705 case 138001: 706 break; 707 default: 708 printk(KERN_WARNING "%s: warning: " 709 "unknown hauppauge model #%d\n", 710 __func__, state->tv.model); 711 } 712#endif 713 return 0; 714 } 715 err("Your device is not yet supported by this driver. " 716 "See kernellabs.com for more info"); 717 return -EINVAL; 718} 719 720static 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 */ 756}; 757MODULE_DEVICE_TABLE(usb, mxl111sf_table); 758 759 760#define MXL111SF_EP4_BULK_STREAMING_CONFIG \ 761 .size_of_priv = sizeof(struct mxl111sf_adap_state), \ 762 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \ 763 .stream = { \ 764 .type = USB_BULK, \ 765 .count = 5, \ 766 .endpoint = 0x04, \ 767 .u = { \ 768 .bulk = { \ 769 .buffersize = 8192, \ 770 } \ 771 } \ 772 } 773 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, \ 778 .stream = { \ 779 .type = USB_ISOC, \ 780 .count = 5, \ 781 .endpoint = 0x04, \ 782 .u = { \ 783 .isoc = { \ 784 .framesperurb = 96, \ 785 /* FIXME: v6 SILICON: */ \ 786 .framesize = 564, \ 787 .interval = 1, \ 788 } \ 789 } \ 790 } 791 792#define MXL111SF_EP6_BULK_STREAMING_CONFIG \ 793 .size_of_priv = sizeof(struct mxl111sf_adap_state), \ 794 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ 795 .stream = { \ 796 .type = USB_BULK, \ 797 .count = 5, \ 798 .endpoint = 0x06, \ 799 .u = { \ 800 .bulk = { \ 801 .buffersize = 8192, \ 802 } \ 803 } \ 804 } 805 806/* FIXME */ 807#define MXL111SF_EP6_ISOC_STREAMING_CONFIG \ 808 .size_of_priv = sizeof(struct mxl111sf_adap_state), \ 809 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ 810 .stream = { \ 811 .type = USB_ISOC, \ 812 .count = 5, \ 813 .endpoint = 0x06, \ 814 .u = { \ 815 .isoc = { \ 816 .framesperurb = 24, \ 817 .framesize = 3072, \ 818 .interval = 1, \ 819 } \ 820 } \ 821 } 822 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), \ 830 */ \ 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) 836 837static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = { 838 MXL111SF_DEFAULT_DEVICE_PROPERTIES, 839 840 .num_adapters = 1, 841 .adapter = { 842 { 843 .fe_ioctl_override = mxl111sf_fe_ioctl_override, 844 .num_frontends = 1, 845 .fe = {{ 846 .frontend_attach = mxl111sf_attach_demod, 847 .tuner_attach = mxl111sf_attach_tuner, 848 849 MXL111SF_EP4_BULK_STREAMING_CONFIG, 850 } }, 851 }, 852 }, 853 .num_device_descs = 4, 854 .devices = { 855 { "Hauppauge 126xxx DVBT (bulk)", 856 { NULL }, 857 { &mxl111sf_table[4], &mxl111sf_table[8], 858 NULL }, 859 }, 860 { "Hauppauge 117xxx DVBT (bulk)", 861 { NULL }, 862 { &mxl111sf_table[15], &mxl111sf_table[18], 863 NULL }, 864 }, 865 { "Hauppauge 138xxx DVBT (bulk)", 866 { NULL }, 867 { &mxl111sf_table[20], &mxl111sf_table[22], 868 &mxl111sf_table[24], &mxl111sf_table[26], 869 NULL }, 870 }, 871 { "Hauppauge 126xxx (tp-bulk)", 872 { NULL }, 873 { &mxl111sf_table[28], &mxl111sf_table[30], 874 NULL }, 875 }, 876 } 877}; 878 879static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = { 880 MXL111SF_DEFAULT_DEVICE_PROPERTIES, 881 882 .num_adapters = 1, 883 .adapter = { 884 { 885 .fe_ioctl_override = mxl111sf_fe_ioctl_override, 886 .num_frontends = 1, 887 .fe = {{ 888 .frontend_attach = mxl111sf_attach_demod, 889 .tuner_attach = mxl111sf_attach_tuner, 890 891 MXL111SF_EP4_ISOC_STREAMING_CONFIG, 892 } }, 893 }, 894 }, 895 .num_device_descs = 4, 896 .devices = { 897 { "Hauppauge 126xxx DVBT (isoc)", 898 { NULL }, 899 { &mxl111sf_table[4], &mxl111sf_table[8], 900 NULL }, 901 }, 902 { "Hauppauge 117xxx DVBT (isoc)", 903 { NULL }, 904 { &mxl111sf_table[15], &mxl111sf_table[18], 905 NULL }, 906 }, 907 { "Hauppauge 138xxx DVBT (isoc)", 908 { NULL }, 909 { &mxl111sf_table[20], &mxl111sf_table[22], 910 &mxl111sf_table[24], &mxl111sf_table[26], 911 NULL }, 912 }, 913 { "Hauppauge 126xxx (tp-isoc)", 914 { NULL }, 915 { &mxl111sf_table[28], &mxl111sf_table[30], 916 NULL }, 917 }, 918 } 919}; 920 921static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = { 922 MXL111SF_DEFAULT_DEVICE_PROPERTIES, 923 924 .num_adapters = 1, 925 .adapter = { 926 { 927 .fe_ioctl_override = mxl111sf_fe_ioctl_override, 928 .num_frontends = 2, 929 .fe = {{ 930 .frontend_attach = mxl111sf_lgdt3305_frontend_attach, 931 .tuner_attach = mxl111sf_attach_tuner, 932 933 MXL111SF_EP6_BULK_STREAMING_CONFIG, 934 }, 935 { 936 .frontend_attach = mxl111sf_attach_demod, 937 .tuner_attach = mxl111sf_attach_tuner, 938 939 MXL111SF_EP4_BULK_STREAMING_CONFIG, 940 }}, 941 }, 942 }, 943 .num_device_descs = 6, 944 .devices = { 945 { "Hauppauge 126xxx ATSC (bulk)", 946 { NULL }, 947 { &mxl111sf_table[1], &mxl111sf_table[5], 948 NULL }, 949 }, 950 { "Hauppauge 117xxx ATSC (bulk)", 951 { NULL }, 952 { &mxl111sf_table[12], 953 NULL }, 954 }, 955 { "Hauppauge 126xxx ATSC+ (bulk)", 956 { NULL }, 957 { &mxl111sf_table[0], &mxl111sf_table[3], 958 &mxl111sf_table[7], &mxl111sf_table[9], 959 &mxl111sf_table[10], NULL }, 960 }, 961 { "Hauppauge 117xxx ATSC+ (bulk)", 962 { NULL }, 963 { &mxl111sf_table[11], &mxl111sf_table[14], 964 &mxl111sf_table[16], &mxl111sf_table[17], 965 &mxl111sf_table[32], &mxl111sf_table[33], 966 NULL }, 967 }, 968 { "Hauppauge Mercury (tp-bulk)", 969 { NULL }, 970 { &mxl111sf_table[19], &mxl111sf_table[21], 971 &mxl111sf_table[23], &mxl111sf_table[25], 972 &mxl111sf_table[27], NULL }, 973 }, 974 { "Hauppauge WinTV-Aero-M", 975 { NULL }, 976 { &mxl111sf_table[29], &mxl111sf_table[31], 977 NULL }, 978 }, 979 } 980}; 981 982static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = { 983 MXL111SF_DEFAULT_DEVICE_PROPERTIES, 984 985 .num_adapters = 1, 986 .adapter = { 987 { 988 .fe_ioctl_override = mxl111sf_fe_ioctl_override, 989 .num_frontends = 2, 990 .fe = {{ 991 .frontend_attach = mxl111sf_lgdt3305_frontend_attach, 992 .tuner_attach = mxl111sf_attach_tuner, 993 994 MXL111SF_EP6_ISOC_STREAMING_CONFIG, 995 }, 996 { 997 .frontend_attach = mxl111sf_attach_demod, 998 .tuner_attach = mxl111sf_attach_tuner, 999 1000 MXL111SF_EP4_ISOC_STREAMING_CONFIG, 1001 }}, 1002 }, 1003 }, 1004 .num_device_descs = 6, 1005 .devices = { 1006 { "Hauppauge 126xxx ATSC (isoc)", 1007 { NULL }, 1008 { &mxl111sf_table[1], &mxl111sf_table[5], 1009 NULL }, 1010 }, 1011 { "Hauppauge 117xxx ATSC (isoc)", 1012 { NULL }, 1013 { &mxl111sf_table[12], 1014 NULL }, 1015 }, 1016 { "Hauppauge 126xxx ATSC+ (isoc)", 1017 { NULL }, 1018 { &mxl111sf_table[0], &mxl111sf_table[3], 1019 &mxl111sf_table[7], &mxl111sf_table[9], 1020 &mxl111sf_table[10], NULL }, 1021 }, 1022 { "Hauppauge 117xxx ATSC+ (isoc)", 1023 { NULL }, 1024 { &mxl111sf_table[11], &mxl111sf_table[14], 1025 &mxl111sf_table[16], &mxl111sf_table[17], 1026 &mxl111sf_table[32], &mxl111sf_table[33], 1027 NULL }, 1028 }, 1029 { "Hauppauge Mercury (tp-isoc)", 1030 { NULL }, 1031 { &mxl111sf_table[19], &mxl111sf_table[21], 1032 &mxl111sf_table[23], &mxl111sf_table[25], 1033 &mxl111sf_table[27], NULL }, 1034 }, 1035 { "Hauppauge WinTV-Aero-M (tp-isoc)", 1036 { NULL }, 1037 { &mxl111sf_table[29], &mxl111sf_table[31], 1038 NULL }, 1039 }, 1040 } 1041}; 1042 1043static 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, 1048}; 1049 1050module_usb_driver(mxl111sf_driver); 1051 1052MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>"); 1053MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF"); 1054MODULE_VERSION("1.0"); 1055MODULE_LICENSE("GPL"); 1056 1057/* 1058 * Local variables: 1059 * c-basic-offset: 8 1060 * End: 1061 */ 1062