On 07.05.2012 09:59, Antti Palosaari wrote: > Good morning! > Comments below. > > On 06.05.2012 15:46, Thomas Mair wrote: >> Hi everyone, >> >> this is the first complete version of the rtl2832 demod driver. I >> splitted the patches in three parts: >> 1. changes in the dvb-usb part (dvb_usb_rtl28xxu) >> 2. demod driver (rtl2832) >> 3. tuner driver (fc0012) >> >> - added tuner probing with log output >> - added callback for tuners to change UHF/VHF band >> - moved and renamed tuner enums to own header file >> - supported devices: >> - Terratec Cinergy T Stick Black >> - G-Tek Electronics Group Lifeview LV5TDLX DVB-T [RTL2832U] >> >> Signed-off-by: Thomas Mair<thomas.mai...@googlemail.com> >> --- >> drivers/media/dvb/dvb-usb/rtl28xxu.c | 604 >> ++++++++++++++++++++++----- >> drivers/media/dvb/dvb-usb/rtl28xxu.h | 19 - >> drivers/media/dvb/dvb-usb/rtl28xxu_tuners.h | 42 ++ >> 3 files changed, 544 insertions(+), 121 deletions(-) >> create mode 100644 drivers/media/dvb/dvb-usb/rtl28xxu_tuners.h >> >> diff --git a/drivers/media/dvb/dvb-usb/rtl28xxu.c >> b/drivers/media/dvb/dvb-usb/rtl28xxu.c >> index 8f4736a..00bd712 100644 >> --- a/drivers/media/dvb/dvb-usb/rtl28xxu.c >> +++ b/drivers/media/dvb/dvb-usb/rtl28xxu.c >> @@ -3,6 +3,7 @@ >> * >> * Copyright (C) 2009 Antti Palosaari<cr...@iki.fi> >> * Copyright (C) 2011 Antti Palosaari<cr...@iki.fi> >> + * Copyright (C) 2012 Thomas Mair<thomas.mai...@googlemail.com> >> * >> * This program is free software; you can redistribute it and/or modify >> * it under the terms of the GNU General Public License as published by >> @@ -20,17 +21,20 @@ >> */ >> >> #include "rtl28xxu.h" >> +#include "rtl28xxu_tuners.h" >> >> #include "rtl2830.h" >> +#include "rtl2832.h" >> >> #include "qt1010.h" >> #include "mt2060.h" >> #include "mxl5005s.h" >> +#include "fc0012.h" >> + >> >> -/* debug */ >> static int dvb_usb_rtl28xxu_debug; >> module_param_named(debug, dvb_usb_rtl28xxu_debug, int, 0644); >> -MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); >> +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); > Why you changed that at all? > And it is DVB USB driver, not frontend (demodulator), as it now says. Ok that was a bad idea. I'll revert that. >> DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); >> >> static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct >> rtl28xxu_req *req) >> @@ -76,11 +80,11 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device >> *d, struct rtl28xxu_req *req) >> >> return ret; >> err: >> - deb_info("%s: failed=%d\n", __func__, ret); >> + deb_info("%s: failed=%d", __func__, ret); > > Why you have removed new line from all the existing debugs? > >> return ret; >> } >> >> -static int rtl2831_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int >> len) >> +static int rtl28xx_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int >> len) > > That's renaming OK, my mistake originally... > >> { >> struct rtl28xxu_req req; >> >> @@ -98,7 +102,7 @@ static int rtl2831_wr_regs(struct dvb_usb_device >> *d, u16 reg, u8 *val, int len) >> return rtl28xxu_ctrl_msg(d,&req); >> } >> >> -static int rtl2831_rd_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int >> len) >> +static int rtl28xx_rd_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int >> len) >> { >> struct rtl28xxu_req req; >> >> @@ -116,14 +120,14 @@ static int rtl2831_rd_regs(struct dvb_usb_device >> *d, u16 reg, u8 *val, int len) >> return rtl28xxu_ctrl_msg(d,&req); >> } >> >> -static int rtl2831_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val) >> +static int rtl28xx_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val) >> { >> - return rtl2831_wr_regs(d, reg,&val, 1); >> + return rtl28xx_wr_regs(d, reg,&val, 1); >> } >> >> -static int rtl2831_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val) >> +static int rtl28xx_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val) >> { >> - return rtl2831_rd_regs(d, reg, val, 1); >> + return rtl28xx_rd_regs(d, reg, val, 1); >> } >> >> /* I2C */ >> @@ -297,7 +301,7 @@ static int rtl2831u_frontend_attach(struct >> dvb_usb_adapter *adap) >> /* for QT1010 tuner probe */ >> struct rtl28xxu_req req_qt1010 = { 0x0fc4, CMD_I2C_RD, 1, buf }; >> >> - deb_info("%s:\n", __func__); >> + deb_info("%s:", __func__); >> >> /* >> * RTL2831U GPIOs >> @@ -308,12 +312,13 @@ static int rtl2831u_frontend_attach(struct >> dvb_usb_adapter *adap) >> */ >> >> /* GPIO direction */ >> - ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a); >> + ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a); >> if (ret) >> goto err; >> >> + >> /* enable as output GPIO0, GPIO2, GPIO4 */ >> - ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15); >> + ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15); >> if (ret) >> goto err; >> >> @@ -330,12 +335,12 @@ static int rtl2831u_frontend_attach(struct >> dvb_usb_adapter *adap) >> /* check QT1010 ID(?) register; reg=0f val=2c */ >> ret = rtl28xxu_ctrl_msg(adap->dev,&req_qt1010); >> if (ret == 0&& buf[0] == 0x2c) { >> - priv->tuner = TUNER_RTL2830_QT1010; >> + priv->tuner = TUNER_RTL28XX_QT1010; > > The idea why I named it as a TUNER_RTL2830_QT1010 was to map RTL2830 and > given tuner. It could be nice to identify used demod/tuner combination in > some cases if there will even be such combination same tuner used for > multiple RTL28XXU chips. Ok. Should we use the TUNER_RTL2830/TUNER_RTL2832 approach or the RUNER_RTL28XX?
>> rtl2830_config =&rtl28xxu_rtl2830_qt1010_config; >> - deb_info("%s: QT1010\n", __func__); >> + deb_info("%s: QT1010", __func__); >> goto found; >> } else { >> - deb_info("%s: QT1010 probe failed=%d - %02x\n", >> + deb_info("%s: QT1010 probe failed=%d - %02x", >> __func__, ret, buf[0]); >> } >> >> @@ -347,20 +352,20 @@ static int rtl2831u_frontend_attach(struct >> dvb_usb_adapter *adap) >> /* check MT2060 ID register; reg=00 val=63 */ >> ret = rtl28xxu_ctrl_msg(adap->dev,&req_mt2060); >> if (ret == 0&& buf[0] == 0x63) { >> - priv->tuner = TUNER_RTL2830_MT2060; >> + priv->tuner = TUNER_RTL28XX_MT2060; >> rtl2830_config =&rtl28xxu_rtl2830_mt2060_config; >> - deb_info("%s: MT2060\n", __func__); >> + deb_info("%s: MT2060", __func__); >> goto found; >> } else { >> - deb_info("%s: MT2060 probe failed=%d - %02x\n", >> + deb_info("%s: MT2060 probe failed=%d - %02x", >> __func__, ret, buf[0]); >> } >> >> /* assume MXL5005S */ >> ret = 0; >> - priv->tuner = TUNER_RTL2830_MXL5005S; >> + priv->tuner = TUNER_RTL28XX_MXL5005S; >> rtl2830_config =&rtl28xxu_rtl2830_mxl5005s_config; >> - deb_info("%s: MXL5005S\n", __func__); >> + deb_info("%s: MXL5005S", __func__); >> goto found; >> >> found: >> @@ -374,37 +379,143 @@ found: >> >> return ret; >> err: >> - deb_info("%s: failed=%d\n", __func__, ret); >> + deb_info("%s: failed=%d", __func__, ret); >> + return ret; >> +} >> + >> +static struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = { >> + .i2c_addr = 0x10, /* 0x20 */ >> + .xtal = 28800000, >> + .if_dvbt = 0, >> + .tuner = TUNER_RTL28XX_FC0012 >> +}; >> + >> + >> +static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d, >> + int cmd, int arg) >> +{ >> + int ret; >> + u8 val; >> + >> + deb_info("%s cmd=%d arg=%d", __func__, cmd, arg); >> + switch (cmd) { >> + case FC0012_FE_CALLBACK_UHF_ENABLE: >> + /* set output values */ >> + >> + ret = rtl28xx_rd_reg(d, SYS_GPIO_DIR,&val); >> + if (ret) >> + goto err; >> + >> + val&= 0xbf; >> + >> + ret = rtl28xx_wr_reg(d, SYS_GPIO_DIR, val); >> + if (ret) >> + goto err; >> + >> + >> + ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_EN,&val); >> + if (ret) >> + goto err; >> + >> + val |= 0x40; >> + >> + ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, val); >> + if (ret) >> + goto err; >> + >> + >> + ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL,&val); >> + if (ret) >> + goto err; >> + >> + if (arg) >> + val&= 0xbf; /* set GPIO6 low */ >> + else >> + val |= 0x40; /* set GPIO6 high */ >> + >> + >> + ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val); >> + if (ret) >> + goto err; >> + break; >> + default: >> + ret = -EINVAL; >> + goto err; >> + } >> + return 0; >> + >> +err: >> + err("%s: failed=%d", __func__, ret); >> + >> return ret; >> } > > GPIOs are needed to configure only once. Put that configuration stuff to > frontend_attach() (or tuner_attach()) and switch only GPIO output (hi/lo) > here. Ack. >> +static int rtl2832u_tuner_callback(struct dvb_usb_device *d, int cmd, int >> arg) >> +{ >> + struct rtl28xxu_priv *priv = d->priv; >> + >> + switch (priv->tuner) { >> + case TUNER_RTL28XX_FC0012: >> + return rtl2832u_fc0012_tuner_callback(d, cmd, arg); >> + default: >> + break; >> + } >> + >> + return -ENODEV; >> +} >> + >> +static int rtl2832u_frontend_callback(void *adapter_priv, int component, >> + int cmd, int arg) >> +{ >> + struct i2c_adapter *adap = adapter_priv; >> + struct dvb_usb_device *d = i2c_get_adapdata(adap); >> + >> + switch (component) { >> + case DVB_FRONTEND_COMPONENT_TUNER: >> + return rtl2832u_tuner_callback(d, cmd, arg); >> + default: >> + break; >> + } >> + >> + return -EINVAL; >> +} >> + >> + >> + >> + >> static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) >> { >> int ret; >> struct rtl28xxu_priv *priv = adap->dev->priv; >> - u8 buf[1]; >> + struct rtl2832_config *rtl2832_config; >> + >> + u8 buf[2]; >> /* open RTL2832U/RTL2832 I2C gate */ >> struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"}; >> /* close RTL2832U/RTL2832 I2C gate */ >> struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"}; >> + /* for FC0012 tuner probe */ >> + struct rtl28xxu_req req_fc0012 = {0x00c6, CMD_I2C_RD, 1, buf}; >> + /* for FC0013 tuner probe */ >> + struct rtl28xxu_req req_fc0013 = {0x00c6, CMD_I2C_RD, 1, buf}; >> + /* for MT2266 tuner probe */ >> + struct rtl28xxu_req req_mt2266 = {0x00c0, CMD_I2C_RD, 1, buf}; >> /* for FC2580 tuner probe */ >> struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf}; >> - >> - deb_info("%s:\n", __func__); >> - >> - /* GPIO direction */ >> - ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a); >> - if (ret) >> - goto err; >> - >> - /* enable as output GPIO0, GPIO2, GPIO4 */ >> - ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15); >> - if (ret) >> - goto err; >> - >> - ret = rtl2831_wr_reg(adap->dev, SYS_DEMOD_CTL, 0xe8); >> - if (ret) >> - goto err; >> + /* for MT2063 tuner probe */ >> + struct rtl28xxu_req req_mt2063 = {0x00c0, CMD_I2C_RD, 1, buf}; >> + /* for MAX3543 tuner probe */ >> + struct rtl28xxu_req req_max3543 = {0x00c0, CMD_I2C_RD, 1, buf}; >> + /* for TUA9001 tuner probe */ >> + struct rtl28xxu_req req_tua9001 = {0x7ec0, CMD_I2C_RD, 2, buf}; >> + /* for MXL5007T tuner probe */ >> + struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf}; >> + /* for E4000 tuner probe */ >> + struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf}; >> + /* for TDA18272 tuner probe */ >> + struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; >> + >> + deb_info("%s:", __func__); >> >> /* >> * Probe used tuner. We need to know used tuner before demod attach >> @@ -416,15 +527,96 @@ static int rtl2832u_frontend_attach(struct >> dvb_usb_adapter *adap) >> if (ret) >> goto err; >> >> + priv->tuner = TUNER_NONE; >> + >> + /* check FC0012 ID register; reg=00 val=a1 */ >> + ret = rtl28xxu_ctrl_msg(adap->dev,&req_fc0012); >> + if (ret == 0&& buf[0] == 0xa1) { >> + priv->tuner = TUNER_RTL28XX_FC0012; >> + rtl2832_config =&rtl28xxu_rtl2832_fc0012_config; >> + info("%s: FC0012 tuner found", __func__); >> + goto found; >> + } >> + >> + /* check FC0013 ID register; reg=00 val=a3 */ >> + ret = rtl28xxu_ctrl_msg(adap->dev,&req_fc0013); >> + if (ret == 0&& buf[0] == 0xa3) { >> + priv->tuner = TUNER_RTL28XX_FC0013; >> + rtl2832_config =&rtl28xxu_rtl2832_fc0012_config; >> + info("%s: FC0013 tuner found", __func__); >> + goto found; >> + } >> + >> + /* check MT2266 ID register; reg=00 val=85 */ >> + ret = rtl28xxu_ctrl_msg(adap->dev,&req_mt2266); >> + if (ret == 0&& buf[0] == 0x85) { >> + priv->tuner = TUNER_RTL28XX_MT2266; >> + /* TODO implement tuner */ >> + info("%s: MT2266 tuner found", __func__); >> + goto found; >> + } >> + >> /* check FC2580 ID register; reg=01 val=56 */ >> ret = rtl28xxu_ctrl_msg(adap->dev,&req_fc2580); >> if (ret == 0&& buf[0] == 0x56) { >> - priv->tuner = TUNER_RTL2832_FC2580; >> - deb_info("%s: FC2580\n", __func__); >> + priv->tuner = TUNER_RTL28XX_FC2580; >> + /* TODO implement tuner */ >> + info("%s: FC2580 tuner found", __func__); >> + goto found; >> + } >> + >> + /* check MT2063 ID register; reg=00 val=9e || 9c */ >> + ret = rtl28xxu_ctrl_msg(adap->dev,&req_mt2063); >> + if (ret == 0&& (buf[0] == 0x9e || buf[0] == 0x9c)) { >> + priv->tuner = TUNER_RTL28XX_MT2063; >> + /* TODO implement tuner */ >> + info("%s: MT2063 tuner found", __func__); >> + goto found; >> + } >> + >> + /* check MAX3543 ID register; reg=00 val=38 */ >> + ret = rtl28xxu_ctrl_msg(adap->dev,&req_max3543); >> + if (ret == 0&& buf[0] == 0x38) { >> + priv->tuner = TUNER_RTL28XX_MAX3543; >> + /* TODO implement tuner */ >> + info("%s: MAX3534 tuner found", __func__); >> + goto found; >> + } >> + >> + /* check TUA9001 ID register; reg=7e val=2328 */ >> + ret = rtl28xxu_ctrl_msg(adap->dev,&req_tua9001); >> + if (ret == 0&& buf[0] == 0x23&& buf[1] == 0x28) { >> + priv->tuner = TUNER_RTL28XX_TUA9001; >> + /* TODO implement tuner */ >> + info("%s: TUA9001 tuner found", __func__); >> + goto found; >> + } >> + >> + /* check MXL5007R ID register; reg=d9 val=14 */ >> + ret = rtl28xxu_ctrl_msg(adap->dev,&req_mxl5007t); >> + if (ret == 0&& buf[0] == 0x14) { >> + priv->tuner = TUNER_RTL28XX_MXL5007T; >> + /* TODO implement tuner */ >> + info("%s: MXL5007T tuner found", __func__); >> + goto found; >> + } >> + >> + /* check E4000 ID register; reg=02 val=40 */ >> + ret = rtl28xxu_ctrl_msg(adap->dev,&req_e4000); >> + if (ret == 0&& buf[0] == 0x40) { >> + priv->tuner = TUNER_RTL28XX_E4000; >> + /* TODO implement tuner */ >> + info("%s: E4000 tuner found", __func__); >> + goto found; >> + } >> + >> + /* check TDA18272 ID register; reg=00 val=c760 */ >> + ret = rtl28xxu_ctrl_msg(adap->dev,&req_tda18272); >> + if (ret == 0&& (buf[0] == 0xc7 || buf[1] == 0x60)) { >> + priv->tuner = TUNER_RTL28XX_TDA18272; >> + /* TODO implement tuner */ >> + info("%s: TDA18272 tuner found", __func__); >> goto found; >> - } else { >> - deb_info("%s: FC2580 probe failed=%d - %02x\n", >> - __func__, ret, buf[0]); >> } >> >> /* close demod I2C gate */ >> @@ -432,7 +624,9 @@ static int rtl2832u_frontend_attach(struct >> dvb_usb_adapter *adap) >> if (ret) >> goto err; >> >> + >> /* tuner not found */ >> + deb_info("No compatible tuner found"); >> ret = -ENODEV; >> goto err; >> >> @@ -443,11 +637,20 @@ found: >> goto err; >> >> /* attach demodulator */ >> - /* TODO: */ >> + adap->fe_adap[0].fe = dvb_attach(rtl2832_attach, rtl2832_config, >> + &adap->dev->i2c_adap); >> + if (adap->fe_adap[0].fe == NULL) { >> + ret = -ENODEV; >> + goto err; >> + } >> + >> + /* set fe callbacks */ >> + adap->fe_adap[0].fe->callback = rtl2832u_frontend_callback; >> >> return ret; >> + >> err: >> - deb_info("%s: failed=%d\n", __func__, ret); >> + deb_info("%s: failed=%d", __func__, ret); >> return ret; >> } >> >> @@ -484,22 +687,22 @@ static int rtl2831u_tuner_attach(struct >> dvb_usb_adapter *adap) >> struct i2c_adapter *rtl2830_tuner_i2c; >> struct dvb_frontend *fe; >> >> - deb_info("%s:\n", __func__); >> + deb_info("%s:", __func__); >> >> /* use rtl2830 driver I2C adapter, for more info see rtl2830 driver */ >> rtl2830_tuner_i2c = rtl2830_get_tuner_i2c_adapter(adap->fe_adap[0].fe); >> >> switch (priv->tuner) { >> - case TUNER_RTL2830_QT1010: >> + case TUNER_RTL28XX_QT1010: >> fe = dvb_attach(qt1010_attach, adap->fe_adap[0].fe, >> rtl2830_tuner_i2c,&rtl28xxu_qt1010_config); >> break; >> - case TUNER_RTL2830_MT2060: >> + case TUNER_RTL28XX_MT2060: >> fe = dvb_attach(mt2060_attach, adap->fe_adap[0].fe, >> rtl2830_tuner_i2c,&rtl28xxu_mt2060_config, >> 1220); >> break; >> - case TUNER_RTL2830_MXL5005S: >> + case TUNER_RTL28XX_MXL5005S: >> fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, >> rtl2830_tuner_i2c,&rtl28xxu_mxl5005s_config); >> break; >> @@ -515,7 +718,7 @@ static int rtl2831u_tuner_attach(struct >> dvb_usb_adapter *adap) >> >> return 0; >> err: >> - deb_info("%s: failed=%d\n", __func__, ret); >> + deb_info("%s: failed=%d", __func__, ret); >> return ret; >> } >> >> @@ -525,12 +728,13 @@ static int rtl2832u_tuner_attach(struct >> dvb_usb_adapter *adap) >> struct rtl28xxu_priv *priv = adap->dev->priv; >> struct dvb_frontend *fe; >> >> - deb_info("%s:\n", __func__); >> + deb_info("%s:", __func__); >> >> switch (priv->tuner) { >> - case TUNER_RTL2832_FC2580: >> - /* TODO: */ >> - fe = NULL; >> + case TUNER_RTL28XX_FC0012: >> + fe = dvb_attach(fc0012_attach, adap->fe_adap[0].fe, >> + &adap->dev->i2c_adap, 0xc6>>1, FC_XTAL_28_8_MHZ); >> + return 0; >> break; >> default: >> fe = NULL; >> @@ -544,18 +748,18 @@ static int rtl2832u_tuner_attach(struct >> dvb_usb_adapter *adap) >> >> return 0; >> err: >> - deb_info("%s: failed=%d\n", __func__, ret); >> + deb_info("%s: failed=%d", __func__, ret); >> return ret; >> } >> >> -static int rtl28xxu_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff) >> +static int rtl2831u_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff) >> { >> int ret; >> u8 buf[2], gpio; >> >> - deb_info("%s: onoff=%d\n", __func__, onoff); >> + deb_info("%s: onoff=%d", __func__, onoff); >> >> - ret = rtl2831_rd_reg(adap->dev, SYS_GPIO_OUT_VAL,&gpio); >> + ret = rtl28xx_rd_reg(adap->dev, SYS_GPIO_OUT_VAL,&gpio); >> if (ret) >> goto err; >> >> @@ -569,43 +773,213 @@ static int rtl28xxu_streaming_ctrl(struct >> dvb_usb_adapter *adap , int onoff) >> gpio&= (~0x04); /* LED off */ >> } >> >> - ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_VAL, gpio); >> + ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_OUT_VAL, gpio); >> if (ret) >> goto err; >> >> - ret = rtl2831_wr_regs(adap->dev, USB_EPA_CTL, buf, 2); >> + ret = rtl28xx_wr_regs(adap->dev, USB_EPA_CTL, buf, 2); >> if (ret) >> goto err; >> >> return ret; >> err: >> - deb_info("%s: failed=%d\n", __func__, ret); >> + deb_info("%s: failed=%d", __func__, ret); >> return ret; >> } >> >> -static int rtl28xxu_power_ctrl(struct dvb_usb_device *d, int onoff) >> +static int rtl2832u_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff) >> +{ >> + int ret; >> + u8 buf[2]; >> + >> + deb_info("%s: onoff=%d", __func__, onoff); >> + >> + >> + if (onoff) { >> + buf[0] = 0x00; >> + buf[1] = 0x00; >> + } else { >> + buf[0] = 0x10; /* stall EPA */ >> + buf[1] = 0x02; /* reset EPA */ >> + } >> + >> + ret = rtl28xx_wr_regs(adap->dev, USB_EPA_CTL, buf, 2); >> + if (ret) >> + goto err; >> + >> + return ret; >> +err: >> + deb_info("%s: failed=%d", __func__, ret); >> + return ret; >> +} > > It is ~same function that existing one but without LED GPIO. Hmmm, dunno what > to do. Maybe it is OK still as switching "random" GPIOs during streaming > control is not good idea. I know. I had the same thougths and could not come up with a more elegant idea. Maybe here the TUNER_RTL2832 definition could be used. But that is too not the ideal solution I guess. >> + >> + >> +static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff) >> +{ >> + int ret; >> + struct rtl28xxu_req req; >> + u8 val; >> + >> + deb_info("%s: onoff=%d", __func__, onoff); >> + >> + if (onoff) { >> + /* set output values */ >> + ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL,&val); >> + if (ret) >> + goto err; >> + >> + val |= 0x08; >> + val&= 0xef; >> + >> + ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val); >> + if (ret) >> + goto err; >> + >> + /* enable as output GPIO3 */ >> + ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_EN,&val); >> + if (ret) >> + goto err; >> + >> + val |= 0x08; >> + >> + ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, val); >> + if (ret) >> + goto err; >> + >> + /* demod_ctl_1 */ >> + ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1,&val); >> + if (ret) >> + goto err; >> + >> + val&= 0xef; >> + >> + ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val); >> + if (ret) >> + goto err; >> + >> + /* demod control */ >> + /* PLL enable */ >> + ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL,&val); >> + if (ret) >> + goto err; >> + >> + /* bit 7 to 1 */ >> + val |= 0x80; >> + >> + ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val); >> + if (ret) >> + goto err; >> + >> + /* demod HW reset */ >> + ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL,&val); >> + if (ret) >> + goto err; >> + /* bit 5 to 0 */ >> + val&= 0xdf; >> + >> + ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val); >> + if (ret) >> + goto err; >> + >> + ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL,&val); >> + if (ret) >> + goto err; >> + >> + val |= 0x20; >> + >> + ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val); >> + if (ret) >> + goto err; >> + >> + /* set page cache to 0 */ >> + req.index = 0x0; >> + req.value = 0x20 + (1<<8); >> + req.data =&val; >> + req.size = 1; >> + ret = rtl28xxu_ctrl_msg(d,&req); >> + if (ret) >> + goto err; > > This looks weird as you write demod register. Is that really needed? > > If you has some problems I suspect those are coming from the fact page cached > by the driver isdifferent than page used by chip. Likely demod is reseted and > page is 0 after that. > > If you really have seen some problems then set page 0 in demod sleep. Or set > page directly to that driver priv. I'll check that. >> + >> + >> + mdelay(5); >> + >> + /*enable ADC_Q and ADC_I */ >> + ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL,&val); >> + if (ret) >> + goto err; >> + >> + val |= 0x48; >> + >> + ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val); >> + if (ret) >> + goto err; >> + >> + >> + } else { >> + /* demod_ctl_1 */ >> + ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1,&val); >> + if (ret) >> + goto err; >> + >> + val |= 0x0c; >> + >> + ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val); >> + if (ret) >> + goto err; >> + >> + /* set output values */ >> + ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL,&val); >> + if (ret) >> + goto err; >> + >> + val |= 0x10; >> + >> + ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val); >> + if (ret) >> + goto err; >> + >> + /* demod control */ >> + ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL,&val); >> + if (ret) >> + goto err; >> + >> + val&= 0x37; >> + >> + ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val); >> + if (ret) >> + goto err; >> + >> + } >> + >> + return ret; >> +err: >> + deb_info("%s: failed=%d", __func__, ret); >> + return ret; >> +} >> + >> +static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff) >> { >> int ret; >> u8 gpio, sys0; >> >> - deb_info("%s: onoff=%d\n", __func__, onoff); >> + deb_info("%s: onoff=%d", __func__, onoff); >> >> /* demod adc */ >> - ret = rtl2831_rd_reg(d, SYS_SYS0,&sys0); >> + ret = rtl28xx_rd_reg(d, SYS_SYS0,&sys0); >> if (ret) >> goto err; >> >> /* tuner power, read GPIOs */ >> - ret = rtl2831_rd_reg(d, SYS_GPIO_OUT_VAL,&gpio); >> + ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL,&gpio); >> if (ret) >> goto err; >> >> - deb_info("%s: RD SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio); >> + deb_info("%s: RD SYS0=%02x GPIO_OUT_VAL=%02x", __func__, sys0, gpio); >> >> if (onoff) { >> gpio |= 0x01; /* GPIO0 = 1 */ >> gpio&= (~0x10); /* GPIO4 = 0 */ >> - sys0 = sys0& 0x0f; >> + sys0 = sys0& 0x0f; /* enable demod adc */ >> sys0 |= 0xe0; >> } else { >> gpio&= (~0x01); /* GPIO0 = 0 */ >> @@ -613,21 +987,21 @@ static int rtl28xxu_power_ctrl(struct >> dvb_usb_device *d, int onoff) >> sys0 = sys0& (~0xc0); >> } >> >> - deb_info("%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio); >> + deb_info("%s: WR SYS0=%02x GPIO_OUT_VAL=%02x", __func__, sys0, gpio); >> >> /* demod adc */ >> - ret = rtl2831_wr_reg(d, SYS_SYS0, sys0); >> + ret = rtl28xx_wr_reg(d, SYS_SYS0, sys0); >> if (ret) >> goto err; >> >> /* tuner power, write GPIOs */ >> - ret = rtl2831_wr_reg(d, SYS_GPIO_OUT_VAL, gpio); >> + ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, gpio); >> if (ret) >> goto err; >> >> return ret; >> err: >> - deb_info("%s: failed=%d\n", __func__, ret); >> + deb_info("%s: failed=%d", __func__, ret); >> return ret; >> } >> >> @@ -657,7 +1031,7 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d) >> /* init remote controller */ >> if (!priv->rc_active) { >> for (i = 0; i< ARRAY_SIZE(rc_nec_tab); i++) { >> - ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg, >> + ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg, >> rc_nec_tab[i].val); >> if (ret) >> goto err; >> @@ -665,7 +1039,7 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d) >> priv->rc_active = true; >> } >> >> - ret = rtl2831_rd_regs(d, SYS_IRRC_RP, buf, 5); >> + ret = rtl28xx_rd_regs(d, SYS_IRRC_RP, buf, 5); >> if (ret) >> goto err; >> >> @@ -687,22 +1061,24 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d) >> >> rc_keydown(d->rc_dev, rc_code, 0); >> >> - ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1); >> + ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1); >> if (ret) >> goto err; >> >> /* repeated intentionally to avoid extra keypress */ >> - ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1); >> + ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1); >> if (ret) >> goto err; >> } >> >> return ret; >> err: >> - deb_info("%s: failed=%d\n", __func__, ret); >> + deb_info("%s: failed=%d", __func__, ret); >> return ret; >> } >> >> +/* unused for now */ >> +#if 0 >> static int rtl2832u_rc_query(struct dvb_usb_device *d) >> { >> int ret, i; >> @@ -729,7 +1105,7 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) >> /* init remote controller */ >> if (!priv->rc_active) { >> for (i = 0; i< ARRAY_SIZE(rc_nec_tab); i++) { >> - ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg, >> + ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg, >> rc_nec_tab[i].val); >> if (ret) >> goto err; >> @@ -737,37 +1113,40 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) >> priv->rc_active = true; >> } >> >> - ret = rtl2831_rd_reg(d, IR_RX_IF,&buf[0]); >> + ret = rtl28xx_rd_reg(d, IR_RX_IF,&buf[0]); >> if (ret) >> goto err; >> >> if (buf[0] != 0x83) >> goto exit; >> >> - ret = rtl2831_rd_reg(d, IR_RX_BC,&buf[0]); >> + ret = rtl28xx_rd_reg(d, IR_RX_BC,&buf[0]); >> if (ret) >> goto err; >> >> len = buf[0]; >> - ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len); >> + ret = rtl28xx_rd_regs(d, IR_RX_BUF, buf, len); >> >> /* TODO: pass raw IR to Kernel IR decoder */ >> >> - ret = rtl2831_wr_reg(d, IR_RX_IF, 0x03); >> - ret = rtl2831_wr_reg(d, IR_RX_BUF_CTRL, 0x80); >> - ret = rtl2831_wr_reg(d, IR_RX_CTRL, 0x80); >> + ret = rtl28xx_wr_reg(d, IR_RX_IF, 0x03); >> + ret = rtl28xx_wr_reg(d, IR_RX_BUF_CTRL, 0x80); >> + ret = rtl28xx_wr_reg(d, IR_RX_CTRL, 0x80); >> >> exit: >> return ret; >> err: >> - deb_info("%s: failed=%d\n", __func__, ret); >> + deb_info("%s: failed=%d", __func__, ret); >> return ret; >> } >> +#endif >> >> enum rtl28xxu_usb_table_entry { >> RTL2831U_0BDA_2831, >> RTL2831U_14AA_0160, >> RTL2831U_14AA_0161, >> + RTL2832U_0CCD_00A9, >> + RTL2832U_1F4D_B803, >> }; >> >> static struct usb_device_id rtl28xxu_table[] = { >> @@ -780,6 +1159,10 @@ static struct usb_device_id rtl28xxu_table[] = { >> USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2)}, >> >> /* RTL2832U */ >> + [RTL2832U_0CCD_00A9] = { >> + USB_DEVICE(USB_VID_TERRATEC, >> USB_PID_TERRATEC_CINERGY_T_STICK_BLACK)}, >> + [RTL2832U_1F4D_B803] = { >> + USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK)}, >> {} /* terminating entry */ >> }; >> >> @@ -802,7 +1185,7 @@ static struct dvb_usb_device_properties >> rtl28xxu_properties[] = { >> { >> .frontend_attach = rtl2831u_frontend_attach, >> .tuner_attach = rtl2831u_tuner_attach, >> - .streaming_ctrl = rtl28xxu_streaming_ctrl, >> + .streaming_ctrl = rtl2831u_streaming_ctrl, >> .stream = { >> .type = USB_BULK, >> .count = 6, >> @@ -818,7 +1201,7 @@ static struct dvb_usb_device_properties >> rtl28xxu_properties[] = { >> } >> }, >> >> - .power_ctrl = rtl28xxu_power_ctrl, >> + .power_ctrl = rtl2831u_power_ctrl, >> >> .rc.core = { >> .protocol = RC_TYPE_NEC, >> @@ -864,11 +1247,11 @@ static struct dvb_usb_device_properties >> rtl28xxu_properties[] = { >> { >> .frontend_attach = rtl2832u_frontend_attach, >> .tuner_attach = rtl2832u_tuner_attach, >> - .streaming_ctrl = rtl28xxu_streaming_ctrl, >> + .streaming_ctrl = rtl2832u_streaming_ctrl, >> .stream = { >> .type = USB_BULK, >> - .count = 6, >> - .endpoint = 0x81, >> + .count = 10, >> + .endpoint = 0x01, > > And what is reason behind that change? > EP 0x81 == 0x01. > Increasing buffers from 6 to 10 should not be needed for DVB-T stream (20 > Mbit/sec). If you set it too small you will see very soon erros in the > picture. Conviced ;) Will be reverted. >> .u = { >> .bulk = { >> .buffersize = 8*512, >> @@ -880,23 +1263,32 @@ static struct dvb_usb_device_properties >> rtl28xxu_properties[] = { >> } >> }, >> >> - .power_ctrl = rtl28xxu_power_ctrl, >> + .power_ctrl = rtl2832u_power_ctrl, >> >> - .rc.core = { >> + /*.rc.core = { >> .protocol = RC_TYPE_NEC, >> .module_name = "rtl28xxu", >> .rc_query = rtl2832u_rc_query, >> .rc_interval = 400, >> .allowed_protos = RC_TYPE_NEC, >> .rc_codes = RC_MAP_EMPTY, >> - }, >> + },*/ >> >> .i2c_algo =&rtl28xxu_i2c_algo, >> >> - .num_device_descs = 0, /* disabled as no support for RTL2832 */ >> + .num_device_descs = 2, >> .devices = { >> { >> - .name = "Realtek RTL2832U reference design", >> + .name = "Terratec Cinergy T Stick Black", >> + .warm_ids = { >> + &rtl28xxu_table[RTL2832U_0CCD_00A9], >> + }, >> + }, >> + { >> + .name = "G-Tek Electronics Group Lifeview LV5TDLX DVB-T >> [RTL2832U]", >> + .warm_ids = { >> + &rtl28xxu_table[RTL2832U_1F4D_B803], >> + }, >> }, >> } >> }, >> @@ -907,10 +1299,11 @@ static int rtl28xxu_probe(struct usb_interface *intf, >> const struct usb_device_id *id) >> { >> int ret, i; >> + u8 val; >> int properties_count = ARRAY_SIZE(rtl28xxu_properties); >> struct dvb_usb_device *d; >> >> - deb_info("%s: interface=%d\n", __func__, >> + deb_info("%s: interface=%d", __func__, >> intf->cur_altsetting->desc.bInterfaceNumber); >> >> if (intf->cur_altsetting->desc.bInterfaceNumber != 0) >> @@ -926,22 +1319,31 @@ static int rtl28xxu_probe(struct usb_interface *intf, >> if (ret) >> goto err; >> >> + >> /* init USB endpoints */ >> - ret = rtl2831_wr_reg(d, USB_SYSCTL_0, 0x09); >> + ret = rtl28xx_rd_reg(d, USB_SYSCTL_0,&val); >> + if (ret) >> + goto err; >> + >> + /* enable DMA and Full Packet Mode*/ >> + val |= 0x09; >> + ret = rtl28xx_wr_reg(d, USB_SYSCTL_0, val); >> if (ret) >> goto err; >> >> - ret = rtl2831_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4); >> + /* set EPA maximum packet size to 0x0200 */ >> + ret = rtl28xx_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4); >> if (ret) >> goto err; >> >> - ret = rtl2831_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4); >> + /* change EPA FIFO length */ >> + ret = rtl28xx_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4); >> if (ret) >> goto err; >> >> return ret; >> err: >> - deb_info("%s: failed=%d\n", __func__, ret); >> + deb_info("%s: failed=%d", __func__, ret); >> return ret; >> } >> >> @@ -957,8 +1359,6 @@ static int __init rtl28xxu_module_init(void) >> { >> int ret; >> >> - deb_info("%s:\n", __func__); >> - >> ret = usb_register(&rtl28xxu_driver); >> if (ret) >> err("usb_register failed=%d", ret); >> @@ -968,7 +1368,6 @@ static int __init rtl28xxu_module_init(void) >> >> static void __exit rtl28xxu_module_exit(void) >> { >> - deb_info("%s:\n", __func__); >> >> /* deregister this driver from the USB subsystem */ >> usb_deregister(&rtl28xxu_driver); >> @@ -979,4 +1378,5 @@ module_exit(rtl28xxu_module_exit); >> >> MODULE_DESCRIPTION("Realtek RTL28xxU DVB USB driver"); >> MODULE_AUTHOR("Antti Palosaari<cr...@iki.fi>"); >> +MODULE_AUTHOR("Thomas Mair<thomas.mai...@googlemail.com>"); >> MODULE_LICENSE("GPL"); >> diff --git a/drivers/media/dvb/dvb-usb/rtl28xxu.h >> b/drivers/media/dvb/dvb-usb/rtl28xxu.h >> index 90f3bb4..55f7c50 100644 >> --- a/drivers/media/dvb/dvb-usb/rtl28xxu.h >> +++ b/drivers/media/dvb/dvb-usb/rtl28xxu.h >> @@ -84,25 +84,6 @@ enum rtl28xxu_chip_id { >> CHIP_ID_RTL2832U, >> }; >> >> -enum rtl28xxu_tuner { >> - TUNER_NONE, >> - >> - TUNER_RTL2830_QT1010, >> - TUNER_RTL2830_MT2060, >> - TUNER_RTL2830_MXL5005S, >> - >> - TUNER_RTL2832_MT2266, >> - TUNER_RTL2832_FC2580, >> - TUNER_RTL2832_MT2063, >> - TUNER_RTL2832_MAX3543, >> - TUNER_RTL2832_TUA9001, >> - TUNER_RTL2832_MXL5007T, >> - TUNER_RTL2832_FC0012, >> - TUNER_RTL2832_E4000, >> - TUNER_RTL2832_TDA18272, >> - TUNER_RTL2832_FC0013, >> -}; >> - >> struct rtl28xxu_req { >> u16 value; >> u16 index; >> diff --git a/drivers/media/dvb/dvb-usb/rtl28xxu_tuners.h >> b/drivers/media/dvb/dvb-usb/rtl28xxu_tuners.h >> new file mode 100644 >> index 0000000..773e603 >> --- /dev/null >> +++ b/drivers/media/dvb/dvb-usb/rtl28xxu_tuners.h >> @@ -0,0 +1,42 @@ >> +/* >> + * Realtek RTL28xxU DVB USB driver >> + * >> + * Copyright (C) 2009 Antti Palosaari<cr...@iki.fi> >> + * Copyright (C) 2011 Antti Palosaari<cr...@iki.fi> >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License as published by >> + * the Free Software Foundation; either version 2 of the License, or >> + * (at your option) any later version. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + * >> + * You should have received a copy of the GNU General Public License >> along >> + * with this program; if not, write to the Free Software Foundation, >> Inc., >> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >> + */ >> + >> +#ifndef RTL28XXU_TUNERS_H >> +#define RTL28XXU_TUNERS_H >> + >> +enum rtl28xxu_tuner { >> + TUNER_NONE, >> + TUNER_RTL28XX_QT1010, >> + TUNER_RTL28XX_MT2060, >> + TUNER_RTL28XX_MT2266, >> + TUNER_RTL28XX_MT2063, >> + TUNER_RTL28XX_MAX3543, >> + TUNER_RTL28XX_TUA9001, >> + TUNER_RTL28XX_MXL5005S, >> + TUNER_RTL28XX_MXL5007T, >> + TUNER_RTL28XX_FC2580, >> + TUNER_RTL28XX_FC0012, >> + TUNER_RTL28XX_FC0013, >> + TUNER_RTL28XX_E4000, >> + TUNER_RTL28XX_TDA18272, >> +}; >> + >> +#endif > > I don't see it good idea to export tuners from the DVB-USB-driver to the > demodulator. Demod drivers should be independent. For the other direction it > is OK, I mean you can add tuners for demod config (rtl2832.h). Ok. So the definitions of the tuners would go into the rtl2830.h and rtl2832.h. > After all, you have done rather much changes. Even such changes that are not > relevant for the RTL2832 support. One patch per one change is the rule. Also > that patch serie is wrong order, it will break compilation for example very > bad when git bisect is taken. It should be done in order first tuner or demod > driver then DVB-USB-driver. Sorry for the inconsistent patches. I will go over my changes again and split them into smaller chunks, trying to keep the changes to a minimum. That includes to change the order of the patches to tuner, demod and finally dvb-usb driver. Thanks for all the comments. They really help me getting the driver nice and neat. I will probably not be able to do the changes before next weekend. > regards > Antti Regards Thomas -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html