From 449d1a0ad1732476d394fb2b885092a5c554f983 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 25 Jul 2011 20:25:21 -0300 Subject: [PATCH] [media] anysee: use multi-frontend (MFE) Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/anysee.c | 299 +++++++++++++++++++++++++------------ drivers/media/dvb/dvb-usb/anysee.h | 1 + 2 files changed, 206 insertions(+), 94 deletions(-) diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index 1ec88b6..d4d2420 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -446,6 +446,114 @@ static struct isl6423_config anysee_isl6423_config = { * IOE[5] STV0903 1=enabled */ +static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct anysee_state *state = adap->dev->priv; + int ret; + + deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff); + + /* no frontend sleep control */ + if (onoff == 0) + return 0; + + switch (state->hw) { + case ANYSEE_HW_507FA: /* 15 */ + /* E30 Combo Plus */ + /* E30 C Plus */ + + if ((fe->id ^ dvb_usb_anysee_delsys) == 0) { + /* disable DVB-T demod on IOD[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0), + 0x01); + if (ret) + goto error; + + /* enable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), + 0x20); + if (ret) + goto error; + + /* enable DVB-C tuner on IOE[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0), + 0x01); + if (ret) + goto error; + } else { + /* disable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), + 0x20); + if (ret) + goto error; + + /* enable DVB-T demod on IOD[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), + 0x01); + if (ret) + goto error; + + /* enable DVB-T tuner on IOE[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0), + 0x01); + if (ret) + goto error; + } + + break; + case ANYSEE_HW_508TC: /* 18 */ + case ANYSEE_HW_508PTC: /* 21 */ + /* E7 TC */ + /* E7 PTC */ + + if ((fe->id ^ dvb_usb_anysee_delsys) == 0) { + /* disable DVB-T demod on IOD[6] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), + 0x40); + if (ret) + goto error; + + /* enable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), + 0x20); + if (ret) + goto error; + + /* enable IF route on IOE[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0), + 0x01); + if (ret) + goto error; + } else { + /* disable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), + 0x20); + if (ret) + goto error; + + /* enable DVB-T demod on IOD[6] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6), + 0x40); + if (ret) + goto error; + + /* enable IF route on IOE[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0), + 0x01); + if (ret) + goto error; + } + + break; + default: + ret = 0; + } + +error: + return ret; +} + static int anysee_frontend_attach(struct dvb_usb_adapter *adap) { int ret; @@ -466,27 +574,37 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) } }; - /* Check which hardware we have. - * We must do this call two times to get reliable values (hw bug). - */ - ret = anysee_get_hw_info(adap->dev, hw_info); - if (ret) - goto error; + /* detect hardware only once */ + if (adap->fe[0] == NULL) { + /* Check which hardware we have. + * We must do this call two times to get reliable values (hw bug). + */ + ret = anysee_get_hw_info(adap->dev, hw_info); + if (ret) + goto error; - ret = anysee_get_hw_info(adap->dev, hw_info); - if (ret) - goto error; + ret = anysee_get_hw_info(adap->dev, hw_info); + if (ret) + goto error; + + /* Meaning of these info bytes are guessed. */ + info("firmware version:%d.%d hardware id:%d", + hw_info[1], hw_info[2], hw_info[0]); - /* Meaning of these info bytes are guessed. */ - info("firmware version:%d.%d hardware id:%d", - hw_info[1], hw_info[2], hw_info[0]); + state->hw = hw_info[0]; + } - state->hw = hw_info[0]; + /* set current frondend ID for devices having two frondends */ + if (adap->fe[0]) + state->fe_id++; switch (state->hw) { case ANYSEE_HW_507T: /* 2 */ /* E30 */ + if (state->fe_id) + break; + /* attach demod */ adap->fe[0] = dvb_attach(mt352_attach, &anysee_mt352_config, &adap->dev->i2c_adap); @@ -501,6 +619,9 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) case ANYSEE_HW_507CD: /* 6 */ /* E30 Plus */ + if (state->fe_id) + break; + /* enable DVB-T demod on IOD[0] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01); if (ret) @@ -512,26 +633,32 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config, - &adap->dev->i2c_adap); + adap->fe[0] = dvb_attach(zl10353_attach, + &anysee_zl10353_config, &adap->dev->i2c_adap); break; case ANYSEE_HW_507DC: /* 10 */ /* E30 C Plus */ + if (state->fe_id) + break; + /* enable DVB-C demod on IOD[0] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01); if (ret) goto error; /* attach demod */ - adap->fe[0] = dvb_attach(tda10023_attach, &anysee_tda10023_config, - &adap->dev->i2c_adap, 0x48); + adap->fe[0] = dvb_attach(tda10023_attach, + &anysee_tda10023_config, &adap->dev->i2c_adap, 0x48); break; case ANYSEE_HW_507SI: /* 11 */ /* E30 S2 Plus */ + if (state->fe_id) + break; + /* enable DVB-S/S2 demod on IOD[0] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01); if (ret) @@ -564,55 +691,59 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) if (ret) goto error; - if (dvb_usb_anysee_delsys) { - /* disable DVB-C demod on IOD[5] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), - 0x20); + if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) { + /* disable DVB-T demod on IOD[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0), + 0x01); if (ret) goto error; - /* enable DVB-T demod on IOD[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), - 0x01); + /* enable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), + 0x20); if (ret) goto error; /* attach demod */ if (tmp == 0xc7) { /* TDA18212 config */ - adap->fe[0] = dvb_attach(zl10353_attach, - &anysee_zl10353_tda18212_config2, - &adap->dev->i2c_adap); + adap->fe[state->fe_id] = dvb_attach( + tda10023_attach, + &anysee_tda10023_tda18212_config, + &adap->dev->i2c_adap, 0x48); } else { /* PLL config */ - adap->fe[0] = dvb_attach(zl10353_attach, - &anysee_zl10353_config, - &adap->dev->i2c_adap); + adap->fe[state->fe_id] = dvb_attach( + tda10023_attach, + &anysee_tda10023_config, + &adap->dev->i2c_adap, 0x48); } } else { - /* disable DVB-T demod on IOD[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0), - 0x01); + /* disable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), + 0x20); if (ret) goto error; - /* enable DVB-C demod on IOD[5] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), - 0x20); + /* enable DVB-T demod on IOD[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), + 0x01); if (ret) goto error; /* attach demod */ if (tmp == 0xc7) { /* TDA18212 config */ - adap->fe[0] = dvb_attach(tda10023_attach, - &anysee_tda10023_tda18212_config, - &adap->dev->i2c_adap, 0x48); + adap->fe[state->fe_id] = dvb_attach( + zl10353_attach, + &anysee_zl10353_tda18212_config2, + &adap->dev->i2c_adap); } else { /* PLL config */ - adap->fe[0] = dvb_attach(tda10023_attach, - &anysee_tda10023_config, - &adap->dev->i2c_adap, 0x48); + adap->fe[state->fe_id] = dvb_attach( + zl10353_attach, + &anysee_zl10353_config, + &adap->dev->i2c_adap); } } @@ -627,52 +758,40 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) if (ret) goto error; - if (dvb_usb_anysee_delsys) { - /* disable DVB-C demod on IOD[5] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), - 0x20); - if (ret) - goto error; - - /* enable DVB-T demod on IOD[6] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6), + if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) { + /* disable DVB-T demod on IOD[6] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), 0x40); if (ret) goto error; - /* enable IF route on IOE[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0), - 0x01); + /* enable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), + 0x20); if (ret) goto error; /* attach demod */ - adap->fe[0] = dvb_attach(zl10353_attach, - &anysee_zl10353_tda18212_config, - &adap->dev->i2c_adap); + adap->fe[state->fe_id] = dvb_attach(tda10023_attach, + &anysee_tda10023_tda18212_config, + &adap->dev->i2c_adap, 0x48); } else { - /* disable DVB-T demod on IOD[6] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), - 0x40); - if (ret) - goto error; - - /* enable DVB-C demod on IOD[5] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), + /* disable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), 0x20); if (ret) goto error; - /* enable IF route on IOE[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0), - 0x01); + /* enable DVB-T demod on IOD[6] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6), + 0x40); if (ret) goto error; /* attach demod */ - adap->fe[0] = dvb_attach(tda10023_attach, - &anysee_tda10023_tda18212_config, - &adap->dev->i2c_adap, 0x48); + adap->fe[state->fe_id] = dvb_attach(zl10353_attach, + &anysee_zl10353_tda18212_config, + &adap->dev->i2c_adap); } break; @@ -681,6 +800,9 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) /* E7 S2 */ /* E7 PS2 */ + if (state->fe_id) + break; + /* enable transport stream on IOA[7] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); if (ret) @@ -713,7 +835,7 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) struct anysee_state *state = adap->dev->priv; struct dvb_frontend *fe; int ret; - deb_info("%s:\n", __func__); + deb_info("%s: fe=%d\n", __func__, state->fe_id); switch (state->hw) { case ANYSEE_HW_507T: /* 2 */ @@ -744,28 +866,14 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* E30 S2 Plus */ /* attach LNB controller */ - fe = dvb_attach(isl6423_attach, adap->fe[0], &adap->dev->i2c_adap, - &anysee_isl6423_config); + fe = dvb_attach(isl6423_attach, adap->fe[0], + &adap->dev->i2c_adap, &anysee_isl6423_config); break; case ANYSEE_HW_507FA: /* 15 */ /* E30 Combo Plus */ /* E30 C Plus */ - if (dvb_usb_anysee_delsys) { - /* enable DVB-T tuner on IOE[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0), - 0x01); - if (ret) - goto error; - } else { - /* enable DVB-C tuner on IOE[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0), - 0x01); - if (ret) - goto error; - } - /* Try first attach TDA18212 silicon tuner on IOE[4], if that * fails attach old simple PLL. */ @@ -775,8 +883,8 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) goto error; /* attach tuner */ - fe = dvb_attach(tda18212_attach, adap->fe[0], &adap->dev->i2c_adap, - &anysee_tda18212_config); + fe = dvb_attach(tda18212_attach, adap->fe[state->fe_id], + &adap->dev->i2c_adap, &anysee_tda18212_config); if (fe) break; @@ -786,8 +894,9 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) goto error; /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1), - &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); + fe = dvb_attach(dvb_pll_attach, adap->fe[state->fe_id], + (0xc0 >> 1), &adap->dev->i2c_adap, + DVB_PLL_SAMSUNG_DTOS403IH102A); break; case ANYSEE_HW_508TC: /* 18 */ @@ -801,8 +910,8 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) goto error; /* attach tuner */ - fe = dvb_attach(tda18212_attach, adap->fe[0], &adap->dev->i2c_adap, - &anysee_tda18212_config); + fe = dvb_attach(tda18212_attach, adap->fe[state->fe_id], + &adap->dev->i2c_adap, &anysee_tda18212_config); break; case ANYSEE_HW_508S2: /* 19 */ @@ -918,6 +1027,8 @@ static struct dvb_usb_device_properties anysee_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 2, + .frontend_ctrl = anysee_frontend_ctrl, .streaming_ctrl = anysee_streaming_ctrl, .frontend_attach = anysee_frontend_attach, .tuner_attach = anysee_tuner_attach, diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h index ad6ccd1..57ee500 100644 --- a/drivers/media/dvb/dvb-usb/anysee.h +++ b/drivers/media/dvb/dvb-usb/anysee.h @@ -59,6 +59,7 @@ enum cmd { struct anysee_state { u8 hw; /* PCB ID */ u8 seq; + u8 fe_id:1; /* frondend ID */ }; #define ANYSEE_HW_507T 2 /* E30 */ -- 2.7.4