1467 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2010-2014 Michael Krufky (mkrufky@linuxtv.org)4 *5 * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information6 */7 8#include <linux/vmalloc.h>9#include <linux/i2c.h>10#include <media/tuner.h>11 12#include "mxl111sf.h"13#include "mxl111sf-reg.h"14#include "mxl111sf-phy.h"15#include "mxl111sf-i2c.h"16#include "mxl111sf-gpio.h"17 18#include "mxl111sf-demod.h"19#include "mxl111sf-tuner.h"20 21#include "lgdt3305.h"22#include "lg2160.h"23 24int dvb_usb_mxl111sf_debug;25module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);26MODULE_PARM_DESC(debug, "set debugging level (1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");27 28static int dvb_usb_mxl111sf_isoc;29module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);30MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");31 32static int dvb_usb_mxl111sf_spi;33module_param_named(spi, dvb_usb_mxl111sf_spi, int, 0644);34MODULE_PARM_DESC(spi, "use spi rather than tp for data xfer (0=tp, 1=spi).");35 36#define ANT_PATH_AUTO 037#define ANT_PATH_EXTERNAL 138#define ANT_PATH_INTERNAL 239 40static int dvb_usb_mxl111sf_rfswitch =41#if 042 ANT_PATH_AUTO;43#else44 ANT_PATH_EXTERNAL;45#endif46 47module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);48MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");49 50DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);51 52int mxl111sf_ctrl_msg(struct mxl111sf_state *state,53 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)54{55 struct dvb_usb_device *d = state->d;56 int wo = (rbuf == NULL || rlen == 0); /* write-only */57 int ret;58 59 if (1 + wlen > MXL_MAX_XFER_SIZE) {60 pr_warn("%s: len=%d is too big!\n", __func__, wlen);61 return -EOPNOTSUPP;62 }63 64 pr_debug("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);65 66 mutex_lock(&state->msg_lock);67 memset(state->sndbuf, 0, 1+wlen);68 memset(state->rcvbuf, 0, rlen);69 70 state->sndbuf[0] = cmd;71 memcpy(&state->sndbuf[1], wbuf, wlen);72 73 ret = (wo) ? dvb_usbv2_generic_write(d, state->sndbuf, 1+wlen) :74 dvb_usbv2_generic_rw(d, state->sndbuf, 1+wlen, state->rcvbuf,75 rlen);76 77 if (rbuf)78 memcpy(rbuf, state->rcvbuf, rlen);79 80 mutex_unlock(&state->msg_lock);81 82 mxl_fail(ret);83 84 return ret;85}86 87/* ------------------------------------------------------------------------ */88 89#define MXL_CMD_REG_READ 0xaa90#define MXL_CMD_REG_WRITE 0x5591 92int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data)93{94 u8 buf[2];95 int ret;96 97 ret = mxl111sf_ctrl_msg(state, MXL_CMD_REG_READ, &addr, 1, buf, 2);98 if (mxl_fail(ret)) {99 mxl_debug("error reading reg: 0x%02x", addr);100 goto fail;101 }102 103 if (buf[0] == addr)104 *data = buf[1];105 else {106 pr_err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",107 addr, buf[0], buf[1]);108 ret = -EINVAL;109 }110 111 pr_debug("R: (0x%02x, 0x%02x)\n", addr, buf[1]);112fail:113 return ret;114}115 116int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)117{118 u8 buf[] = { addr, data };119 int ret;120 121 pr_debug("W: (0x%02x, 0x%02x)\n", addr, data);122 123 ret = mxl111sf_ctrl_msg(state, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);124 if (mxl_fail(ret))125 pr_err("error writing reg: 0x%02x, val: 0x%02x", addr, data);126 return ret;127}128 129/* ------------------------------------------------------------------------ */130 131int mxl111sf_write_reg_mask(struct mxl111sf_state *state,132 u8 addr, u8 mask, u8 data)133{134 int ret;135 u8 val = 0;136 137 if (mask != 0xff) {138 ret = mxl111sf_read_reg(state, addr, &val);139#if 1140 /* don't know why this usually errors out on the first try */141 if (mxl_fail(ret))142 pr_err("error writing addr: 0x%02x, mask: 0x%02x, data: 0x%02x, retrying...",143 addr, mask, data);144 145 ret = mxl111sf_read_reg(state, addr, &val);146#endif147 if (mxl_fail(ret))148 goto fail;149 }150 val &= ~mask;151 val |= data;152 153 ret = mxl111sf_write_reg(state, addr, val);154 mxl_fail(ret);155fail:156 return ret;157}158 159/* ------------------------------------------------------------------------ */160 161int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,162 struct mxl111sf_reg_ctrl_info *ctrl_reg_info)163{164 int i, ret = 0;165 166 for (i = 0; ctrl_reg_info[i].addr |167 ctrl_reg_info[i].mask |168 ctrl_reg_info[i].data; i++) {169 170 ret = mxl111sf_write_reg_mask(state,171 ctrl_reg_info[i].addr,172 ctrl_reg_info[i].mask,173 ctrl_reg_info[i].data);174 if (mxl_fail(ret)) {175 pr_err("failed on reg #%d (0x%02x)", i,176 ctrl_reg_info[i].addr);177 break;178 }179 }180 return ret;181}182 183/* ------------------------------------------------------------------------ */184 185static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)186{187 int ret;188 u8 id, ver;189 char *mxl_chip, *mxl_rev;190 191 if ((state->chip_id) && (state->chip_ver))192 return 0;193 194 ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);195 if (mxl_fail(ret))196 goto fail;197 state->chip_id = id;198 199 ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);200 if (mxl_fail(ret))201 goto fail;202 state->chip_ver = ver;203 204 switch (id) {205 case 0x61:206 mxl_chip = "MxL101SF";207 break;208 case 0x63:209 mxl_chip = "MxL111SF";210 break;211 default:212 mxl_chip = "UNKNOWN MxL1X1";213 break;214 }215 switch (ver) {216 case 0x36:217 state->chip_rev = MXL111SF_V6;218 mxl_rev = "v6";219 break;220 case 0x08:221 state->chip_rev = MXL111SF_V8_100;222 mxl_rev = "v8_100";223 break;224 case 0x18:225 state->chip_rev = MXL111SF_V8_200;226 mxl_rev = "v8_200";227 break;228 default:229 state->chip_rev = 0;230 mxl_rev = "UNKNOWN REVISION";231 break;232 }233 pr_info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);234fail:235 return ret;236}237 238#define get_chip_info(state) \239({ \240 int ___ret; \241 ___ret = mxl1x1sf_get_chip_info(state); \242 if (mxl_fail(___ret)) { \243 mxl_debug("failed to get chip info" \244 " on first probe attempt"); \245 ___ret = mxl1x1sf_get_chip_info(state); \246 if (mxl_fail(___ret)) \247 pr_err("failed to get chip info during probe"); \248 else \249 mxl_debug("probe needed a retry " \250 "in order to succeed."); \251 } \252 ___ret; \253})254 255/* ------------------------------------------------------------------------ */256#if 0257static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff)258{259 /* power control depends on which adapter is being woken:260 * save this for init, instead, via mxl111sf_adap_fe_init */261 return 0;262}263#endif264 265static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)266{267 struct dvb_usb_device *d = fe_to_d(fe);268 struct mxl111sf_state *state = fe_to_priv(fe);269 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];270 int err;271 272 /* exit if we didn't initialize the driver yet */273 if (!state->chip_id) {274 mxl_debug("driver not yet initialized, exit.");275 goto fail;276 }277 278 pr_debug("%s()\n", __func__);279 280 mutex_lock(&state->fe_lock);281 282 state->alt_mode = adap_state->alt_mode;283 284 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)285 pr_err("set interface failed");286 287 err = mxl1x1sf_soft_reset(state);288 mxl_fail(err);289 err = mxl111sf_init_tuner_demod(state);290 mxl_fail(err);291 err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);292 293 mxl_fail(err);294 err = mxl111sf_enable_usb_output(state);295 mxl_fail(err);296 err = mxl1x1sf_top_master_ctrl(state, 1);297 mxl_fail(err);298 299 if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) &&300 (state->chip_rev > MXL111SF_V6)) {301 mxl111sf_config_pin_mux_modes(state,302 PIN_MUX_TS_SPI_IN_MODE_1);303 mxl_fail(err);304 }305 err = mxl111sf_init_port_expander(state);306 if (!mxl_fail(err)) {307 state->gpio_mode = adap_state->gpio_mode;308 err = mxl111sf_gpio_mode_switch(state, state->gpio_mode);309 mxl_fail(err);310#if 0311 err = fe->ops.init(fe);312#endif313 msleep(100); /* add short delay after enabling314 * the demod before touching it */315 }316 317 return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0;318fail:319 return -ENODEV;320}321 322static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)323{324 struct mxl111sf_state *state = fe_to_priv(fe);325 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];326 int err;327 328 /* exit if we didn't initialize the driver yet */329 if (!state->chip_id) {330 mxl_debug("driver not yet initialized, exit.");331 goto fail;332 }333 334 pr_debug("%s()\n", __func__);335 336 err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;337 338 mutex_unlock(&state->fe_lock);339 340 return err;341fail:342 return -ENODEV;343}344 345 346static int mxl111sf_ep6_streaming_ctrl(struct dvb_frontend *fe, int onoff)347{348 struct mxl111sf_state *state = fe_to_priv(fe);349 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];350 int ret = 0;351 352 pr_debug("%s(%d)\n", __func__, onoff);353 354 if (onoff) {355 ret = mxl111sf_enable_usb_output(state);356 mxl_fail(ret);357 ret = mxl111sf_config_mpeg_in(state, 1, 1,358 adap_state->ep6_clockphase,359 0, 0);360 mxl_fail(ret);361#if 0362 } else {363 ret = mxl111sf_disable_656_port(state);364 mxl_fail(ret);365#endif366 }367 368 return ret;369}370 371static int mxl111sf_ep5_streaming_ctrl(struct dvb_frontend *fe, int onoff)372{373 struct mxl111sf_state *state = fe_to_priv(fe);374 int ret = 0;375 376 pr_debug("%s(%d)\n", __func__, onoff);377 378 if (onoff) {379 ret = mxl111sf_enable_usb_output(state);380 mxl_fail(ret);381 382 ret = mxl111sf_init_i2s_port(state, 200);383 mxl_fail(ret);384 ret = mxl111sf_config_i2s(state, 0, 15);385 mxl_fail(ret);386 } else {387 ret = mxl111sf_disable_i2s_port(state);388 mxl_fail(ret);389 }390 if (state->chip_rev > MXL111SF_V6)391 ret = mxl111sf_config_spi(state, onoff);392 mxl_fail(ret);393 394 return ret;395}396 397static int mxl111sf_ep4_streaming_ctrl(struct dvb_frontend *fe, int onoff)398{399 struct mxl111sf_state *state = fe_to_priv(fe);400 int ret = 0;401 402 pr_debug("%s(%d)\n", __func__, onoff);403 404 if (onoff) {405 ret = mxl111sf_enable_usb_output(state);406 mxl_fail(ret);407 }408 409 return ret;410}411 412/* ------------------------------------------------------------------------ */413 414static struct lgdt3305_config hauppauge_lgdt3305_config = {415 .i2c_addr = 0xb2 >> 1,416 .mpeg_mode = LGDT3305_MPEG_SERIAL,417 .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,418 .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,419 .deny_i2c_rptr = 1,420 .spectral_inversion = 0,421 .qam_if_khz = 6000,422 .vsb_if_khz = 6000,423};424 425static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)426{427 struct dvb_usb_device *d = adap_to_d(adap);428 struct mxl111sf_state *state = d_to_priv(d);429 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];430 int ret;431 432 pr_debug("%s()\n", __func__);433 434 /* save a pointer to the dvb_usb_device in device state */435 state->d = d;436 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;437 state->alt_mode = adap_state->alt_mode;438 439 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)440 pr_err("set interface failed");441 442 state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;443 adap_state->gpio_mode = state->gpio_mode;444 adap_state->device_mode = MXL_TUNER_MODE;445 adap_state->ep6_clockphase = 1;446 447 ret = mxl1x1sf_soft_reset(state);448 if (mxl_fail(ret))449 goto fail;450 ret = mxl111sf_init_tuner_demod(state);451 if (mxl_fail(ret))452 goto fail;453 454 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);455 if (mxl_fail(ret))456 goto fail;457 458 ret = mxl111sf_enable_usb_output(state);459 if (mxl_fail(ret))460 goto fail;461 ret = mxl1x1sf_top_master_ctrl(state, 1);462 if (mxl_fail(ret))463 goto fail;464 465 ret = mxl111sf_init_port_expander(state);466 if (mxl_fail(ret))467 goto fail;468 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);469 if (mxl_fail(ret))470 goto fail;471 472 adap->fe[fe_id] = dvb_attach(lgdt3305_attach,473 &hauppauge_lgdt3305_config,474 &d->i2c_adap);475 if (adap->fe[fe_id]) {476 state->num_frontends++;477 adap_state->fe_init = adap->fe[fe_id]->ops.init;478 adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;479 adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;480 adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;481 return 0;482 }483 ret = -EIO;484fail:485 return ret;486}487 488static struct lg2160_config hauppauge_lg2160_config = {489 .lg_chip = LG2160,490 .i2c_addr = 0x1c >> 1,491 .deny_i2c_rptr = 1,492 .spectral_inversion = 0,493 .if_khz = 6000,494};495 496static int mxl111sf_lg2160_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)497{498 struct dvb_usb_device *d = adap_to_d(adap);499 struct mxl111sf_state *state = d_to_priv(d);500 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];501 int ret;502 503 pr_debug("%s()\n", __func__);504 505 /* save a pointer to the dvb_usb_device in device state */506 state->d = d;507 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;508 state->alt_mode = adap_state->alt_mode;509 510 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)511 pr_err("set interface failed");512 513 state->gpio_mode = MXL111SF_GPIO_MOD_MH;514 adap_state->gpio_mode = state->gpio_mode;515 adap_state->device_mode = MXL_TUNER_MODE;516 adap_state->ep6_clockphase = 1;517 518 ret = mxl1x1sf_soft_reset(state);519 if (mxl_fail(ret))520 goto fail;521 ret = mxl111sf_init_tuner_demod(state);522 if (mxl_fail(ret))523 goto fail;524 525 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);526 if (mxl_fail(ret))527 goto fail;528 529 ret = mxl111sf_enable_usb_output(state);530 if (mxl_fail(ret))531 goto fail;532 ret = mxl1x1sf_top_master_ctrl(state, 1);533 if (mxl_fail(ret))534 goto fail;535 536 ret = mxl111sf_init_port_expander(state);537 if (mxl_fail(ret))538 goto fail;539 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);540 if (mxl_fail(ret))541 goto fail;542 543 ret = get_chip_info(state);544 if (mxl_fail(ret))545 goto fail;546 547 adap->fe[fe_id] = dvb_attach(lg2160_attach,548 &hauppauge_lg2160_config,549 &d->i2c_adap);550 if (adap->fe[fe_id]) {551 state->num_frontends++;552 adap_state->fe_init = adap->fe[fe_id]->ops.init;553 adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;554 adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;555 adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;556 return 0;557 }558 ret = -EIO;559fail:560 return ret;561}562 563static struct lg2160_config hauppauge_lg2161_1019_config = {564 .lg_chip = LG2161_1019,565 .i2c_addr = 0x1c >> 1,566 .deny_i2c_rptr = 1,567 .spectral_inversion = 0,568 .if_khz = 6000,569 .output_if = 2, /* LG2161_OIF_SPI_MAS */570};571 572static struct lg2160_config hauppauge_lg2161_1040_config = {573 .lg_chip = LG2161_1040,574 .i2c_addr = 0x1c >> 1,575 .deny_i2c_rptr = 1,576 .spectral_inversion = 0,577 .if_khz = 6000,578 .output_if = 4, /* LG2161_OIF_SPI_MAS */579};580 581static int mxl111sf_lg2161_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)582{583 struct dvb_usb_device *d = adap_to_d(adap);584 struct mxl111sf_state *state = d_to_priv(d);585 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];586 int ret;587 588 pr_debug("%s()\n", __func__);589 590 /* save a pointer to the dvb_usb_device in device state */591 state->d = d;592 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;593 state->alt_mode = adap_state->alt_mode;594 595 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)596 pr_err("set interface failed");597 598 state->gpio_mode = MXL111SF_GPIO_MOD_MH;599 adap_state->gpio_mode = state->gpio_mode;600 adap_state->device_mode = MXL_TUNER_MODE;601 adap_state->ep6_clockphase = 1;602 603 ret = mxl1x1sf_soft_reset(state);604 if (mxl_fail(ret))605 goto fail;606 ret = mxl111sf_init_tuner_demod(state);607 if (mxl_fail(ret))608 goto fail;609 610 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);611 if (mxl_fail(ret))612 goto fail;613 614 ret = mxl111sf_enable_usb_output(state);615 if (mxl_fail(ret))616 goto fail;617 ret = mxl1x1sf_top_master_ctrl(state, 1);618 if (mxl_fail(ret))619 goto fail;620 621 ret = mxl111sf_init_port_expander(state);622 if (mxl_fail(ret))623 goto fail;624 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);625 if (mxl_fail(ret))626 goto fail;627 628 ret = get_chip_info(state);629 if (mxl_fail(ret))630 goto fail;631 632 adap->fe[fe_id] = dvb_attach(lg2160_attach,633 (MXL111SF_V8_200 == state->chip_rev) ?634 &hauppauge_lg2161_1040_config :635 &hauppauge_lg2161_1019_config,636 &d->i2c_adap);637 if (adap->fe[fe_id]) {638 state->num_frontends++;639 adap_state->fe_init = adap->fe[fe_id]->ops.init;640 adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;641 adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;642 adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;643 return 0;644 }645 ret = -EIO;646fail:647 return ret;648}649 650static struct lg2160_config hauppauge_lg2161_1019_ep6_config = {651 .lg_chip = LG2161_1019,652 .i2c_addr = 0x1c >> 1,653 .deny_i2c_rptr = 1,654 .spectral_inversion = 0,655 .if_khz = 6000,656 .output_if = 1, /* LG2161_OIF_SERIAL_TS */657};658 659static struct lg2160_config hauppauge_lg2161_1040_ep6_config = {660 .lg_chip = LG2161_1040,661 .i2c_addr = 0x1c >> 1,662 .deny_i2c_rptr = 1,663 .spectral_inversion = 0,664 .if_khz = 6000,665 .output_if = 7, /* LG2161_OIF_SERIAL_TS */666};667 668static int mxl111sf_lg2161_ep6_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)669{670 struct dvb_usb_device *d = adap_to_d(adap);671 struct mxl111sf_state *state = d_to_priv(d);672 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];673 int ret;674 675 pr_debug("%s()\n", __func__);676 677 /* save a pointer to the dvb_usb_device in device state */678 state->d = d;679 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;680 state->alt_mode = adap_state->alt_mode;681 682 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)683 pr_err("set interface failed");684 685 state->gpio_mode = MXL111SF_GPIO_MOD_MH;686 adap_state->gpio_mode = state->gpio_mode;687 adap_state->device_mode = MXL_TUNER_MODE;688 adap_state->ep6_clockphase = 0;689 690 ret = mxl1x1sf_soft_reset(state);691 if (mxl_fail(ret))692 goto fail;693 ret = mxl111sf_init_tuner_demod(state);694 if (mxl_fail(ret))695 goto fail;696 697 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);698 if (mxl_fail(ret))699 goto fail;700 701 ret = mxl111sf_enable_usb_output(state);702 if (mxl_fail(ret))703 goto fail;704 ret = mxl1x1sf_top_master_ctrl(state, 1);705 if (mxl_fail(ret))706 goto fail;707 708 ret = mxl111sf_init_port_expander(state);709 if (mxl_fail(ret))710 goto fail;711 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);712 if (mxl_fail(ret))713 goto fail;714 715 ret = get_chip_info(state);716 if (mxl_fail(ret))717 goto fail;718 719 adap->fe[fe_id] = dvb_attach(lg2160_attach,720 (MXL111SF_V8_200 == state->chip_rev) ?721 &hauppauge_lg2161_1040_ep6_config :722 &hauppauge_lg2161_1019_ep6_config,723 &d->i2c_adap);724 if (adap->fe[fe_id]) {725 state->num_frontends++;726 adap_state->fe_init = adap->fe[fe_id]->ops.init;727 adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;728 adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;729 adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;730 return 0;731 }732 ret = -EIO;733fail:734 return ret;735}736 737static const struct mxl111sf_demod_config mxl_demod_config = {738 .read_reg = mxl111sf_read_reg,739 .write_reg = mxl111sf_write_reg,740 .program_regs = mxl111sf_ctrl_program_regs,741};742 743static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap, u8 fe_id)744{745 struct dvb_usb_device *d = adap_to_d(adap);746 struct mxl111sf_state *state = d_to_priv(d);747 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];748 int ret;749 750 pr_debug("%s()\n", __func__);751 752 /* save a pointer to the dvb_usb_device in device state */753 state->d = d;754 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;755 state->alt_mode = adap_state->alt_mode;756 757 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)758 pr_err("set interface failed");759 760 state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;761 adap_state->gpio_mode = state->gpio_mode;762 adap_state->device_mode = MXL_SOC_MODE;763 adap_state->ep6_clockphase = 1;764 765 ret = mxl1x1sf_soft_reset(state);766 if (mxl_fail(ret))767 goto fail;768 ret = mxl111sf_init_tuner_demod(state);769 if (mxl_fail(ret))770 goto fail;771 772 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);773 if (mxl_fail(ret))774 goto fail;775 776 ret = mxl111sf_enable_usb_output(state);777 if (mxl_fail(ret))778 goto fail;779 ret = mxl1x1sf_top_master_ctrl(state, 1);780 if (mxl_fail(ret))781 goto fail;782 783 /* don't care if this fails */784 mxl111sf_init_port_expander(state);785 786 adap->fe[fe_id] = dvb_attach(mxl111sf_demod_attach, state,787 &mxl_demod_config);788 if (adap->fe[fe_id]) {789 state->num_frontends++;790 adap_state->fe_init = adap->fe[fe_id]->ops.init;791 adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;792 adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;793 adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;794 return 0;795 }796 ret = -EIO;797fail:798 return ret;799}800 801static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,802 int antpath)803{804 return mxl111sf_idac_config(state, 1, 1,805 (antpath == ANT_PATH_INTERNAL) ?806 0x3f : 0x00, 0);807}808 809#define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \810 pr_err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \811 __func__, __LINE__, \812 (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \813 pwr0, pwr1, pwr2, pwr3)814 815#define ANT_HUNT_SLEEP 90816#define ANT_EXT_TWEAK 0817 818static int mxl111sf_ant_hunt(struct dvb_frontend *fe)819{820 struct mxl111sf_state *state = fe_to_priv(fe);821 int antctrl = dvb_usb_mxl111sf_rfswitch;822 823 u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;824 825 /* FIXME: must force EXTERNAL for QAM - done elsewhere */826 mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?827 ANT_PATH_EXTERNAL : antctrl);828 829 if (antctrl == ANT_PATH_AUTO) {830#if 0831 msleep(ANT_HUNT_SLEEP);832#endif833 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);834 835 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);836 msleep(ANT_HUNT_SLEEP);837 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);838 839 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);840 msleep(ANT_HUNT_SLEEP);841 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);842 843 mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);844 msleep(ANT_HUNT_SLEEP);845 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);846 847 if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {848 /* return with EXTERNAL enabled */849 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);850 DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,851 rxPwr0, rxPwr1, rxPwr2);852 } else {853 /* return with INTERNAL enabled */854 DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,855 rxPwr0, rxPwr1, rxPwr2);856 }857 }858 return 0;859}860 861static const struct mxl111sf_tuner_config mxl_tuner_config = {862 .if_freq = MXL_IF_6_0, /* applies to external IF output, only */863 .invert_spectrum = 0,864 .read_reg = mxl111sf_read_reg,865 .write_reg = mxl111sf_write_reg,866 .program_regs = mxl111sf_ctrl_program_regs,867 .top_master_ctrl = mxl1x1sf_top_master_ctrl,868 .ant_hunt = mxl111sf_ant_hunt,869};870 871static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)872{873 struct mxl111sf_state *state = adap_to_priv(adap);874#ifdef CONFIG_MEDIA_CONTROLLER_DVB875 struct media_device *mdev = dvb_get_media_controller(&adap->dvb_adap);876 int ret;877#endif878 int i;879 880 pr_debug("%s()\n", __func__);881 882 for (i = 0; i < state->num_frontends; i++) {883 if (dvb_attach(mxl111sf_tuner_attach, adap->fe[i], state,884 &mxl_tuner_config) == NULL)885 return -EIO;886 adap->fe[i]->ops.read_signal_strength = adap->fe[i]->ops.tuner_ops.get_rf_strength;887 }888 889#ifdef CONFIG_MEDIA_CONTROLLER_DVB890 state->tuner.function = MEDIA_ENT_F_TUNER;891 state->tuner.name = "mxl111sf tuner";892 state->tuner_pads[MXL111SF_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;893 state->tuner_pads[MXL111SF_PAD_RF_INPUT].sig_type = PAD_SIGNAL_ANALOG;894 state->tuner_pads[MXL111SF_PAD_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;895 state->tuner_pads[MXL111SF_PAD_OUTPUT].sig_type = PAD_SIGNAL_ANALOG;896 897 ret = media_entity_pads_init(&state->tuner,898 MXL111SF_NUM_PADS, state->tuner_pads);899 if (ret)900 return ret;901 902 ret = media_device_register_entity(mdev, &state->tuner);903 if (ret)904 return ret;905#endif906 return 0;907}908 909static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)910{911 return I2C_FUNC_I2C;912}913 914static struct i2c_algorithm mxl111sf_i2c_algo = {915 .master_xfer = mxl111sf_i2c_xfer,916 .functionality = mxl111sf_i2c_func,917#ifdef NEED_ALGO_CONTROL918 .algo_control = dummy_algo_control,919#endif920};921 922static int mxl111sf_init(struct dvb_usb_device *d)923{924 struct mxl111sf_state *state = d_to_priv(d);925 int ret;926 static u8 eeprom[256];927 u8 reg = 0;928 struct i2c_msg msg[2] = {929 { .addr = 0xa0 >> 1, .len = 1, .buf = ® },930 { .addr = 0xa0 >> 1, .flags = I2C_M_RD,931 .len = sizeof(eeprom), .buf = eeprom },932 };933 934 ret = get_chip_info(state);935 if (mxl_fail(ret))936 pr_err("failed to get chip info during probe");937 938 mutex_init(&state->fe_lock);939 940 if (state->chip_rev > MXL111SF_V6)941 mxl111sf_config_pin_mux_modes(state, PIN_MUX_TS_SPI_IN_MODE_1);942 943 ret = i2c_transfer(&d->i2c_adap, msg, 2);944 if (mxl_fail(ret))945 return 0;946 tveeprom_hauppauge_analog(&state->tv, (0x84 == eeprom[0xa0]) ?947 eeprom + 0xa0 : eeprom + 0x80);948#if 0949 switch (state->tv.model) {950 case 117001:951 case 126001:952 case 138001:953 break;954 default:955 printk(KERN_WARNING "%s: warning: unknown hauppauge model #%d\n",956 __func__, state->tv.model);957 }958#endif959 return 0;960}961 962static int mxl111sf_frontend_attach_dvbt(struct dvb_usb_adapter *adap)963{964 return mxl111sf_attach_demod(adap, 0);965}966 967static int mxl111sf_frontend_attach_atsc(struct dvb_usb_adapter *adap)968{969 return mxl111sf_lgdt3305_frontend_attach(adap, 0);970}971 972static int mxl111sf_frontend_attach_mh(struct dvb_usb_adapter *adap)973{974 return mxl111sf_lg2160_frontend_attach(adap, 0);975}976 977static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap)978{979 int ret;980 pr_debug("%s\n", __func__);981 982 ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);983 if (ret < 0)984 return ret;985 986 ret = mxl111sf_attach_demod(adap, 1);987 if (ret < 0)988 return ret;989 990 ret = mxl111sf_lg2160_frontend_attach(adap, 2);991 if (ret < 0)992 return ret;993 994 return ret;995}996 997static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)998{999 int ret;1000 pr_debug("%s\n", __func__);1001 1002 ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);1003 if (ret < 0)1004 return ret;1005 1006 ret = mxl111sf_attach_demod(adap, 1);1007 if (ret < 0)1008 return ret;1009 1010 ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 2);1011 if (ret < 0)1012 return ret;1013 1014 return ret;1015}1016 1017static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)1018{1019 int ret;1020 pr_debug("%s\n", __func__);1021 1022 ret = mxl111sf_attach_demod(adap, 0);1023 if (ret < 0)1024 return ret;1025 1026 if (dvb_usb_mxl111sf_spi)1027 ret = mxl111sf_lg2161_frontend_attach(adap, 1);1028 else1029 ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 1);1030 1031 return ret;1032}1033 1034static void mxl111sf_stream_config_bulk(struct usb_data_stream_properties *stream, u8 endpoint)1035{1036 pr_debug("%s: endpoint=%d size=8192\n", __func__, endpoint);1037 stream->type = USB_BULK;1038 stream->count = 5;1039 stream->endpoint = endpoint;1040 stream->u.bulk.buffersize = 8192;1041}1042 1043static void mxl111sf_stream_config_isoc(struct usb_data_stream_properties *stream,1044 u8 endpoint, int framesperurb, int framesize)1045{1046 pr_debug("%s: endpoint=%d size=%d\n", __func__, endpoint,1047 framesperurb * framesize);1048 stream->type = USB_ISOC;1049 stream->count = 5;1050 stream->endpoint = endpoint;1051 stream->u.isoc.framesperurb = framesperurb;1052 stream->u.isoc.framesize = framesize;1053 stream->u.isoc.interval = 1;1054}1055 1056/* DVB USB Driver stuff */1057 1058/* dvbt mxl111sf1059 * bulk EP4/BULK/5/81921060 * isoc EP4/ISOC/5/96/5641061 */1062static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe,1063 u8 *ts_type, struct usb_data_stream_properties *stream)1064{1065 pr_debug("%s: fe=%d\n", __func__, fe->id);1066 1067 *ts_type = DVB_USB_FE_TS_TYPE_188;1068 if (dvb_usb_mxl111sf_isoc)1069 mxl111sf_stream_config_isoc(stream, 4, 96, 564);1070 else1071 mxl111sf_stream_config_bulk(stream, 4);1072 return 0;1073}1074 1075static int mxl111sf_probe(struct dvb_usb_device *dev)1076{1077 struct mxl111sf_state *state = d_to_priv(dev);1078 1079 mutex_init(&state->msg_lock);1080 return 0;1081}1082 1083static struct dvb_usb_device_properties mxl111sf_props_dvbt = {1084 .driver_name = KBUILD_MODNAME,1085 .owner = THIS_MODULE,1086 .adapter_nr = adapter_nr,1087 .size_of_priv = sizeof(struct mxl111sf_state),1088 1089 .generic_bulk_ctrl_endpoint = 0x02,1090 .generic_bulk_ctrl_endpoint_response = 0x81,1091 1092 .probe = mxl111sf_probe,1093 .i2c_algo = &mxl111sf_i2c_algo,1094 .frontend_attach = mxl111sf_frontend_attach_dvbt,1095 .tuner_attach = mxl111sf_attach_tuner,1096 .init = mxl111sf_init,1097 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl,1098 .get_stream_config = mxl111sf_get_stream_config_dvbt,1099 1100 .num_adapters = 1,1101 .adapter = {1102 {1103 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),1104 }1105 }1106};1107 1108/* atsc lgdt33051109 * bulk EP6/BULK/5/81921110 * isoc EP6/ISOC/5/24/30721111 */1112static int mxl111sf_get_stream_config_atsc(struct dvb_frontend *fe,1113 u8 *ts_type, struct usb_data_stream_properties *stream)1114{1115 pr_debug("%s: fe=%d\n", __func__, fe->id);1116 1117 *ts_type = DVB_USB_FE_TS_TYPE_188;1118 if (dvb_usb_mxl111sf_isoc)1119 mxl111sf_stream_config_isoc(stream, 6, 24, 3072);1120 else1121 mxl111sf_stream_config_bulk(stream, 6);1122 return 0;1123}1124 1125static struct dvb_usb_device_properties mxl111sf_props_atsc = {1126 .driver_name = KBUILD_MODNAME,1127 .owner = THIS_MODULE,1128 .adapter_nr = adapter_nr,1129 .size_of_priv = sizeof(struct mxl111sf_state),1130 1131 .generic_bulk_ctrl_endpoint = 0x02,1132 .generic_bulk_ctrl_endpoint_response = 0x81,1133 1134 .probe = mxl111sf_probe,1135 .i2c_algo = &mxl111sf_i2c_algo,1136 .frontend_attach = mxl111sf_frontend_attach_atsc,1137 .tuner_attach = mxl111sf_attach_tuner,1138 .init = mxl111sf_init,1139 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl,1140 .get_stream_config = mxl111sf_get_stream_config_atsc,1141 1142 .num_adapters = 1,1143 .adapter = {1144 {1145 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),1146 }1147 }1148};1149 1150/* mh lg21601151 * bulk EP5/BULK/5/8192/RAW1152 * isoc EP5/ISOC/5/96/200/RAW1153 */1154static int mxl111sf_get_stream_config_mh(struct dvb_frontend *fe,1155 u8 *ts_type, struct usb_data_stream_properties *stream)1156{1157 pr_debug("%s: fe=%d\n", __func__, fe->id);1158 1159 *ts_type = DVB_USB_FE_TS_TYPE_RAW;1160 if (dvb_usb_mxl111sf_isoc)1161 mxl111sf_stream_config_isoc(stream, 5, 96, 200);1162 else1163 mxl111sf_stream_config_bulk(stream, 5);1164 return 0;1165}1166 1167static struct dvb_usb_device_properties mxl111sf_props_mh = {1168 .driver_name = KBUILD_MODNAME,1169 .owner = THIS_MODULE,1170 .adapter_nr = adapter_nr,1171 .size_of_priv = sizeof(struct mxl111sf_state),1172 1173 .generic_bulk_ctrl_endpoint = 0x02,1174 .generic_bulk_ctrl_endpoint_response = 0x81,1175 1176 .probe = mxl111sf_probe,1177 .i2c_algo = &mxl111sf_i2c_algo,1178 .frontend_attach = mxl111sf_frontend_attach_mh,1179 .tuner_attach = mxl111sf_attach_tuner,1180 .init = mxl111sf_init,1181 .streaming_ctrl = mxl111sf_ep5_streaming_ctrl,1182 .get_stream_config = mxl111sf_get_stream_config_mh,1183 1184 .num_adapters = 1,1185 .adapter = {1186 {1187 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),1188 }1189 }1190};1191 1192/* atsc mh lgdt3305 mxl111sf lg21601193 * bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP5/BULK/5/8192/RAW1194 * isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW1195 */1196static int mxl111sf_get_stream_config_atsc_mh(struct dvb_frontend *fe,1197 u8 *ts_type, struct usb_data_stream_properties *stream)1198{1199 pr_debug("%s: fe=%d\n", __func__, fe->id);1200 1201 if (fe->id == 0) {1202 *ts_type = DVB_USB_FE_TS_TYPE_188;1203 if (dvb_usb_mxl111sf_isoc)1204 mxl111sf_stream_config_isoc(stream, 6, 24, 3072);1205 else1206 mxl111sf_stream_config_bulk(stream, 6);1207 } else if (fe->id == 1) {1208 *ts_type = DVB_USB_FE_TS_TYPE_188;1209 if (dvb_usb_mxl111sf_isoc)1210 mxl111sf_stream_config_isoc(stream, 4, 96, 564);1211 else1212 mxl111sf_stream_config_bulk(stream, 4);1213 } else if (fe->id == 2) {1214 *ts_type = DVB_USB_FE_TS_TYPE_RAW;1215 if (dvb_usb_mxl111sf_isoc)1216 mxl111sf_stream_config_isoc(stream, 5, 96, 200);1217 else1218 mxl111sf_stream_config_bulk(stream, 5);1219 }1220 return 0;1221}1222 1223static int mxl111sf_streaming_ctrl_atsc_mh(struct dvb_frontend *fe, int onoff)1224{1225 pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);1226 1227 if (fe->id == 0)1228 return mxl111sf_ep6_streaming_ctrl(fe, onoff);1229 else if (fe->id == 1)1230 return mxl111sf_ep4_streaming_ctrl(fe, onoff);1231 else if (fe->id == 2)1232 return mxl111sf_ep5_streaming_ctrl(fe, onoff);1233 return 0;1234}1235 1236static struct dvb_usb_device_properties mxl111sf_props_atsc_mh = {1237 .driver_name = KBUILD_MODNAME,1238 .owner = THIS_MODULE,1239 .adapter_nr = adapter_nr,1240 .size_of_priv = sizeof(struct mxl111sf_state),1241 1242 .generic_bulk_ctrl_endpoint = 0x02,1243 .generic_bulk_ctrl_endpoint_response = 0x81,1244 1245 .probe = mxl111sf_probe,1246 .i2c_algo = &mxl111sf_i2c_algo,1247 .frontend_attach = mxl111sf_frontend_attach_atsc_mh,1248 .tuner_attach = mxl111sf_attach_tuner,1249 .init = mxl111sf_init,1250 .streaming_ctrl = mxl111sf_streaming_ctrl_atsc_mh,1251 .get_stream_config = mxl111sf_get_stream_config_atsc_mh,1252 1253 .num_adapters = 1,1254 .adapter = {1255 {1256 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),1257 }1258 }1259};1260 1261/* mercury lgdt3305 mxl111sf lg21611262 * tp bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP6/BULK/5/8192/RAW1263 * tp isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW1264 * spi bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP5/BULK/5/8192/RAW1265 * spi isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW1266 */1267static int mxl111sf_get_stream_config_mercury(struct dvb_frontend *fe,1268 u8 *ts_type, struct usb_data_stream_properties *stream)1269{1270 pr_debug("%s: fe=%d\n", __func__, fe->id);1271 1272 if (fe->id == 0) {1273 *ts_type = DVB_USB_FE_TS_TYPE_188;1274 if (dvb_usb_mxl111sf_isoc)1275 mxl111sf_stream_config_isoc(stream, 6, 24, 3072);1276 else1277 mxl111sf_stream_config_bulk(stream, 6);1278 } else if (fe->id == 1) {1279 *ts_type = DVB_USB_FE_TS_TYPE_188;1280 if (dvb_usb_mxl111sf_isoc)1281 mxl111sf_stream_config_isoc(stream, 4, 96, 564);1282 else1283 mxl111sf_stream_config_bulk(stream, 4);1284 } else if (fe->id == 2 && dvb_usb_mxl111sf_spi) {1285 *ts_type = DVB_USB_FE_TS_TYPE_RAW;1286 if (dvb_usb_mxl111sf_isoc)1287 mxl111sf_stream_config_isoc(stream, 5, 96, 200);1288 else1289 mxl111sf_stream_config_bulk(stream, 5);1290 } else if (fe->id == 2 && !dvb_usb_mxl111sf_spi) {1291 *ts_type = DVB_USB_FE_TS_TYPE_RAW;1292 if (dvb_usb_mxl111sf_isoc)1293 mxl111sf_stream_config_isoc(stream, 6, 24, 3072);1294 else1295 mxl111sf_stream_config_bulk(stream, 6);1296 }1297 return 0;1298}1299 1300static int mxl111sf_streaming_ctrl_mercury(struct dvb_frontend *fe, int onoff)1301{1302 pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);1303 1304 if (fe->id == 0)1305 return mxl111sf_ep6_streaming_ctrl(fe, onoff);1306 else if (fe->id == 1)1307 return mxl111sf_ep4_streaming_ctrl(fe, onoff);1308 else if (fe->id == 2 && dvb_usb_mxl111sf_spi)1309 return mxl111sf_ep5_streaming_ctrl(fe, onoff);1310 else if (fe->id == 2 && !dvb_usb_mxl111sf_spi)1311 return mxl111sf_ep6_streaming_ctrl(fe, onoff);1312 return 0;1313}1314 1315static struct dvb_usb_device_properties mxl111sf_props_mercury = {1316 .driver_name = KBUILD_MODNAME,1317 .owner = THIS_MODULE,1318 .adapter_nr = adapter_nr,1319 .size_of_priv = sizeof(struct mxl111sf_state),1320 1321 .generic_bulk_ctrl_endpoint = 0x02,1322 .generic_bulk_ctrl_endpoint_response = 0x81,1323 1324 .probe = mxl111sf_probe,1325 .i2c_algo = &mxl111sf_i2c_algo,1326 .frontend_attach = mxl111sf_frontend_attach_mercury,1327 .tuner_attach = mxl111sf_attach_tuner,1328 .init = mxl111sf_init,1329 .streaming_ctrl = mxl111sf_streaming_ctrl_mercury,1330 .get_stream_config = mxl111sf_get_stream_config_mercury,1331 1332 .num_adapters = 1,1333 .adapter = {1334 {1335 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),1336 }1337 }1338};1339 1340/* mercury mh mxl111sf lg21611341 * tp bulk EP4/BULK/5/8192 EP6/BULK/5/8192/RAW1342 * tp isoc EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW1343 * spi bulk EP4/BULK/5/8192 EP5/BULK/5/8192/RAW1344 * spi isoc EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW1345 */1346static int mxl111sf_get_stream_config_mercury_mh(struct dvb_frontend *fe,1347 u8 *ts_type, struct usb_data_stream_properties *stream)1348{1349 pr_debug("%s: fe=%d\n", __func__, fe->id);1350 1351 if (fe->id == 0) {1352 *ts_type = DVB_USB_FE_TS_TYPE_188;1353 if (dvb_usb_mxl111sf_isoc)1354 mxl111sf_stream_config_isoc(stream, 4, 96, 564);1355 else1356 mxl111sf_stream_config_bulk(stream, 4);1357 } else if (fe->id == 1 && dvb_usb_mxl111sf_spi) {1358 *ts_type = DVB_USB_FE_TS_TYPE_RAW;1359 if (dvb_usb_mxl111sf_isoc)1360 mxl111sf_stream_config_isoc(stream, 5, 96, 200);1361 else1362 mxl111sf_stream_config_bulk(stream, 5);1363 } else if (fe->id == 1 && !dvb_usb_mxl111sf_spi) {1364 *ts_type = DVB_USB_FE_TS_TYPE_RAW;1365 if (dvb_usb_mxl111sf_isoc)1366 mxl111sf_stream_config_isoc(stream, 6, 24, 3072);1367 else1368 mxl111sf_stream_config_bulk(stream, 6);1369 }1370 return 0;1371}1372 1373static int mxl111sf_streaming_ctrl_mercury_mh(struct dvb_frontend *fe, int onoff)1374{1375 pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);1376 1377 if (fe->id == 0)1378 return mxl111sf_ep4_streaming_ctrl(fe, onoff);1379 else if (fe->id == 1 && dvb_usb_mxl111sf_spi)1380 return mxl111sf_ep5_streaming_ctrl(fe, onoff);1381 else if (fe->id == 1 && !dvb_usb_mxl111sf_spi)1382 return mxl111sf_ep6_streaming_ctrl(fe, onoff);1383 return 0;1384}1385 1386static struct dvb_usb_device_properties mxl111sf_props_mercury_mh = {1387 .driver_name = KBUILD_MODNAME,1388 .owner = THIS_MODULE,1389 .adapter_nr = adapter_nr,1390 .size_of_priv = sizeof(struct mxl111sf_state),1391 1392 .generic_bulk_ctrl_endpoint = 0x02,1393 .generic_bulk_ctrl_endpoint_response = 0x81,1394 1395 .probe = mxl111sf_probe,1396 .i2c_algo = &mxl111sf_i2c_algo,1397 .frontend_attach = mxl111sf_frontend_attach_mercury_mh,1398 .tuner_attach = mxl111sf_attach_tuner,1399 .init = mxl111sf_init,1400 .streaming_ctrl = mxl111sf_streaming_ctrl_mercury_mh,1401 .get_stream_config = mxl111sf_get_stream_config_mercury_mh,1402 1403 .num_adapters = 1,1404 .adapter = {1405 {1406 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),1407 }1408 }1409};1410 1411static const struct usb_device_id mxl111sf_id_table[] = {1412 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },1413 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },1414 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602, &mxl111sf_props_mh, "HCW 126xxx", NULL) },1415 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },1416 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },1417 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },1418 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a, &mxl111sf_props_mh, "HCW 126xxx", NULL) },1419 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },1420 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },1421 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },1422 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },1423 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },1424 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },1425 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702, &mxl111sf_props_mh, "HCW 117xxx", NULL) },1426 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },1427 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },1428 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },1429 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },1430 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },1431 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },1432 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },1433 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },1434 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },1435 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },1436 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },1437 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },1438 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },1439 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },1440 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },1441 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },1442 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },1443 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },1444 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },1445 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },1446 { }1447};1448MODULE_DEVICE_TABLE(usb, mxl111sf_id_table);1449 1450static struct usb_driver mxl111sf_usb_driver = {1451 .name = KBUILD_MODNAME,1452 .id_table = mxl111sf_id_table,1453 .probe = dvb_usbv2_probe,1454 .disconnect = dvb_usbv2_disconnect,1455 .suspend = dvb_usbv2_suspend,1456 .resume = dvb_usbv2_resume,1457 .no_dynamic_id = 1,1458 .soft_unbind = 1,1459};1460 1461module_usb_driver(mxl111sf_usb_driver);1462 1463MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");1464MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");1465MODULE_VERSION("1.0");1466MODULE_LICENSE("GPL");1467