On Viernes, 22 de Julio de 2011 20:12:20 Jose Alberto Reguero escribió: > On Viernes, 22 de Julio de 2011 18:46:24 Antti Palosaari escribió: > > On 07/22/2011 07:25 PM, Jose Alberto Reguero wrote: > > > On Viernes, 22 de Julio de 2011 18:08:39 Antti Palosaari escribió: > > >> On 07/22/2011 07:02 PM, Jose Alberto Reguero wrote: > > >>> On Viernes, 22 de Julio de 2011 13:32:53 Antti Palosaari escribió: > > >>>> Have you had to time test these? > > >>>> > > >>>> And about I2C adapter, I don't see why changes are needed. As far as > > >>>> I understand it is already working with TDA10023 and you have done > > >>>> changes for TDA10048 support. I compared TDA10048 and TDA10023 I2C > > >>>> functions and those are ~similar. Both uses most typical access, > > >>>> for reg write {u8 REG, u8 VAL} and for reg read {u8 REG}/{u8 VAL}. > > >>>> > > >>>> regards > > >>>> Antti > > >>> > > >>> I just finish the testing. The changes to I2C are for the tuner > > >>> tda827x. The MFE fork fine. I need to change the code in tda10048 and > > >>> ttusb2. Attached is the patch for CT-3650 with your MFE patch. > > >> > > >> You still pass tda10023 fe pointer to tda10048 for I2C-gate control > > >> which is wrong. Could you send USB sniff I can look what there really > > >> happens. If you have raw SniffUSB2 logs I wish to check those, other > > >> logs are welcome too if no raw SniffUSB2 available. > > > > > > Youre chnage don't work. You need to change the function i2c gate of > > > tda1048 for the one of tda1023, but the parameter of this function must > > > be the fe pointer of tda1023. If this is a problem, I can duplicate > > > tda1023 i2c gate in ttusb2 code and pass it to the tda10048. It is done > > > this way in the first patch of this thread. > > > > Yes I now see why it cannot work - since FE is given as a parameter to > > i2c_gate_ctrl it does not see correct priv and used I2C addr is read > > from priv. You must implement own i2c_gate_ctrl in ttusb2 driver. > > Implement own ct3650_i2c_gate_ctrl and override tda10048 i2c_gate_ctrl > > using that. Then call tda10023 i2c_gate_ctrl but instead of tda10048 FE > > use td10023 FE. Something like > > > > static int ct3650_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) > > { > > > > return adap->mfe[0]->ops.i2c_gate_ctrl(POINTER_TO_TDA10023_FE, enable); > > > > } > > > > /* tuner is behind TDA10023 I2C-gate */ > > adap->mfe[1]->ops.i2c_gate_ctrl = ct3650_i2c_gate_ctrl; > > > > > > Could you still send USB logs? I don't see it correct behaviour you need > > to change I2C-adaper when same tuner is used for DVB-T because it was > > already working in DVB-C mode. > > > > regards > > Antti > > Thanks, I try to implement that. I attach a processed log. It prints the > first line of a usb command and the first line of the returned byes. If > you want the full log I can upload it where you want. > > Jose Alberto New version with Antti's sugestion. Signed-off-by: Jose Alberto Reguero <jareguero@xxxxxxxxxxxxxx> Jose Alberto
diff -ur linux/drivers/media/dvb/dvb-usb/ttusb2.c linux.new/drivers/media/dvb/dvb-usb/ttusb2.c --- linux/drivers/media/dvb/dvb-usb/ttusb2.c 2011-01-10 16:24:45.000000000 +0100 +++ linux.new/drivers/media/dvb/dvb-usb/ttusb2.c 2011-07-22 22:15:20.483271578 +0200 @@ -30,6 +30,7 @@ #include "tda826x.h" #include "tda10086.h" #include "tda1002x.h" +#include "tda10048.h" #include "tda827x.h" #include "lnbp21.h" @@ -82,7 +83,7 @@ { struct dvb_usb_device *d = i2c_get_adapdata(adap); static u8 obuf[60], ibuf[60]; - int i,read; + int i, read1, read2; if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; @@ -91,27 +92,33 @@ warn("more than 2 i2c messages at a time is not handled yet. TODO."); for (i = 0; i < num; i++) { - read = i+1 < num && (msg[i+1].flags & I2C_M_RD); + read1 = i+1 < num && (msg[i+1].flags & I2C_M_RD); + read2 = msg[i].flags & I2C_M_RD; - obuf[0] = (msg[i].addr << 1) | read; + obuf[0] = (msg[i].addr << 1) | (read1 | read2); obuf[1] = msg[i].len; /* read request */ - if (read) + if (read1) obuf[2] = msg[i+1].len; + else if (read2) + obuf[2] = msg[i].len; else obuf[2] = 0; - memcpy(&obuf[3],msg[i].buf,msg[i].len); + memcpy(&obuf[3], msg[i].buf, msg[i].len); if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) { err("i2c transfer failed."); break; } - if (read) { - memcpy(msg[i+1].buf,&ibuf[3],msg[i+1].len); - i++; + if (read1 || read2) { + if (read1) { + memcpy(msg[i+1].buf, &ibuf[3], msg[i+1].len); + i++; + } else if (read2) + memcpy(msg[i].buf, &ibuf[3], msg[i].len); } } @@ -190,6 +197,21 @@ .deltaf = 0xa511, }; +static struct tda10048_config tda10048_config = { + .demod_address = 0x10 >> 1, + .output_mode = TDA10048_PARALLEL_OUTPUT, + .inversion = TDA10048_INVERSION_ON, + .dtv6_if_freq_khz = TDA10048_IF_4000, + .dtv7_if_freq_khz = TDA10048_IF_4500, + .dtv8_if_freq_khz = TDA10048_IF_5000, + .clk_freq_khz = TDA10048_CLK_16000, + .no_firmware = 1, +}; + +static struct tda827x_config tda827x_config = { + .config = 0, +}; + static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap) { if (usb_set_interface(adap->dev->udev,0,3) < 0) @@ -203,23 +225,60 @@ return 0; } +static int ct3650_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + + return adap->mfe[0]->ops.i2c_gate_ctrl(adap->mfe[0], enable); +} + static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap) { if (usb_set_interface(adap->dev->udev, 0, 3) < 0) err("set interface to alts=3 failed"); - if ((adap->fe = dvb_attach(tda10023_attach, &tda10023_config, &adap->dev->i2c_adap, 0x48)) == NULL) { - deb_info("TDA10023 attach failed\n"); - return -ENODEV; + + if (adap->mfe[0] == NULL) { + /* FE 0 DVB-C */ + adap->mfe[0] = dvb_attach(tda10023_attach, + &tda10023_config, &adap->dev->i2c_adap, 0x48); + + if (adap->mfe[0] == NULL) { + deb_info("TDA10023 attach failed\n"); + return -ENODEV; + } + } else { + adap->mfe[1] = dvb_attach(tda10048_attach, + &tda10048_config, &adap->dev->i2c_adap); + + if (adap->mfe[1] == NULL) { + deb_info("TDA10048 attach failed\n"); + return -ENODEV; + } + + /* tuner is behind TDA10023 I2C-gate */ + adap->mfe[1]->ops.i2c_gate_ctrl = ct3650_i2c_gate_ctrl; + } + return 0; } static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap) { - if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) { + struct dvb_frontend *fe; + + /* MFE: select correct FE to attach tuner since that's called twice */ + if (adap->mfe[1] == NULL) + fe = adap->mfe[0]; + else + fe = adap->mfe[1]; + + /* attach tuner */ + if (dvb_attach(tda827x_attach, fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) { printk(KERN_ERR "%s: No tda827x found!\n", __func__); return -ENODEV; } + return 0; } @@ -383,8 +442,7 @@ .num_adapters = 1, .adapter = { { - .streaming_ctrl = NULL, - + .num_frontends = 2, .frontend_attach = ttusb2_frontend_tda10023_attach, .tuner_attach = ttusb2_tuner_tda827x_attach, diff -ur linux/drivers/media/dvb/frontends/tda10048.c linux.new/drivers/media/dvb/frontends/tda10048.c --- linux/drivers/media/dvb/frontends/tda10048.c 2010-10-25 01:34:58.000000000 +0200 +++ linux.new/drivers/media/dvb/frontends/tda10048.c 2011-07-22 22:35:32.014271650 +0200 @@ -214,6 +214,8 @@ { TDA10048_CLK_16000, TDA10048_IF_3800, 10, 3, 0 }, { TDA10048_CLK_16000, TDA10048_IF_4000, 10, 3, 0 }, { TDA10048_CLK_16000, TDA10048_IF_4300, 10, 3, 0 }, + { TDA10048_CLK_16000, TDA10048_IF_4500, 5, 3, 0 }, + { TDA10048_CLK_16000, TDA10048_IF_5000, 5, 3, 0 }, { TDA10048_CLK_16000, TDA10048_IF_36130, 10, 3, 0 }, }; @@ -478,6 +480,11 @@ dprintk(1, "- pll_nfactor = %d\n", state->pll_nfactor); dprintk(1, "- pll_pfactor = %d\n", state->pll_pfactor); + /* Set the pll registers */ + tda10048_writereg(state, TDA10048_CONF_PLL1, 0x0f); + tda10048_writereg(state, TDA10048_CONF_PLL2, (u8)(state->pll_mfactor)); + tda10048_writereg(state, TDA10048_CONF_PLL3, tda10048_readreg(state, TDA10048_CONF_PLL3) | ((u8)(state->pll_nfactor) | 0x40)); + /* Calculate the sample frequency */ state->sample_freq = state->xtal_hz * (state->pll_mfactor + 45); state->sample_freq /= (state->pll_nfactor + 1); @@ -1123,7 +1130,7 @@ /* setup the state and clone the config */ memcpy(&state->config, config, sizeof(*config)); state->i2c = i2c; - state->fwloaded = 0; + state->fwloaded = config->no_firmware; state->bandwidth = BANDWIDTH_8_MHZ; /* check if the demod is present */ diff -ur linux/drivers/media/dvb/frontends/tda10048.h linux.new/drivers/media/dvb/frontends/tda10048.h --- linux/drivers/media/dvb/frontends/tda10048.h 2010-07-03 23:22:08.000000000 +0200 +++ linux.new/drivers/media/dvb/frontends/tda10048.h 2011-07-22 22:15:33.841271580 +0200 @@ -51,6 +51,7 @@ #define TDA10048_IF_4300 4300 #define TDA10048_IF_4500 4500 #define TDA10048_IF_4750 4750 +#define TDA10048_IF_5000 5000 #define TDA10048_IF_36130 36130 u16 dtv6_if_freq_khz; u16 dtv7_if_freq_khz; @@ -62,6 +63,8 @@ /* Disable I2C gate access */ u8 disable_gate_access; + + bool no_firmware; };