Skip to content

Commit

Permalink
V4L/DVB (3934): Support new dvb-ttusb-budget boards with stv0297
Browse files Browse the repository at this point in the history
Added config switch to stv0297 to control i2c STOP during write behaviour.
Update frontend init in dvb-ttusb-budget.
Enable i2c STOP on other users of stv0297.

Signed-off-by: Thomas Kaiser <linux-dvb AT kaiser-linux.li>
Signed-off-by: Andrew de Quincey <adq_dvb@lidskialf.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
  • Loading branch information
Thomas Kaiser authored and Mauro Carvalho Chehab committed Jun 25, 2006
1 parent 21c2858 commit b8d4c23
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 18 deletions.
49 changes: 31 additions & 18 deletions drivers/media/dvb/frontends/stv0297.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,25 @@ static int stv0297_readreg(struct stv0297_state *state, u8 reg)
int ret;
u8 b0[] = { reg };
u8 b1[] = { 0 };
struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len =
1},
{.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
};
struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
{.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
};

// this device needs a STOP between the register and data
if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
return -1;
}
if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
return -1;
if (state->config->stop_during_read) {
if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
return -1;
}
if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
return -1;
}
} else {
if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
return -1;
}
}

return b1[0];
Expand All @@ -107,13 +113,20 @@ static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len
};

// this device needs a STOP between the register and data
if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
return -1;
}
if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
return -1;
if (state->config->stop_during_read) {
if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
return -1;
}
if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
return -1;
}
} else {
if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
return -1;
}
}

return 0;
Expand Down
3 changes: 3 additions & 0 deletions drivers/media/dvb/frontends/stv0297.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ struct stv0297_config

/* does the "inversion" need inverted? */
u8 invert:1;

/* set to 1 if the device requires an i2c STOP during reading */
u8 stop_during_read:1;
};

extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
Expand Down
1 change: 1 addition & 0 deletions drivers/media/dvb/ttpci/av7110.c
Original file line number Diff line number Diff line change
Expand Up @@ -1859,6 +1859,7 @@ static struct stv0297_config nexusca_stv0297_config = {
.demod_address = 0x1C,
.inittab = nexusca_stv0297_inittab,
.invert = 1,
.stop_during_read = 1,
};


Expand Down
1 change: 1 addition & 0 deletions drivers/media/dvb/ttpci/budget-ci.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,7 @@ static struct stv0297_config dvbc_philips_tdm1316l_config = {
.demod_address = 0x1c,
.inittab = dvbc_philips_tdm1316l_inittab,
.invert = 0,
.stop_during_read = 1,
};


Expand Down
1 change: 1 addition & 0 deletions drivers/media/dvb/ttusb-budget/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ config DVB_TTUSB_BUDGET
select DVB_VES1820
select DVB_TDA8083
select DVB_STV0299
select DVB_STV0297
select DVB_LNBP21
help
Support for external USB adapters designed by Technotrend and
Expand Down
175 changes: 175 additions & 0 deletions drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "tda1004x.h"
#include "stv0299.h"
#include "tda8083.h"
#include "stv0297.h"
#include "lnbp21.h"

#include <linux/dvb/frontend.h>
Expand Down Expand Up @@ -1380,6 +1381,174 @@ static u8 read_pwm(struct ttusb* ttusb)
}


static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
{
struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
u8 tuner_buf[5];
struct i2c_msg tuner_msg = {.addr = 0x60,
.flags = 0,
.buf = tuner_buf,
.len = sizeof(tuner_buf) };
int tuner_frequency = 0;
u8 band, cp, filter;

// determine charge pump
tuner_frequency = params->frequency;
if (tuner_frequency < 87000000) {return -EINVAL;}
else if (tuner_frequency < 130000000) {cp = 3; band = 1;}
else if (tuner_frequency < 160000000) {cp = 5; band = 1;}
else if (tuner_frequency < 200000000) {cp = 6; band = 1;}
else if (tuner_frequency < 290000000) {cp = 3; band = 2;}
else if (tuner_frequency < 420000000) {cp = 5; band = 2;}
else if (tuner_frequency < 480000000) {cp = 6; band = 2;}
else if (tuner_frequency < 620000000) {cp = 3; band = 4;}
else if (tuner_frequency < 830000000) {cp = 5; band = 4;}
else if (tuner_frequency < 895000000) {cp = 7; band = 4;}
else {return -EINVAL;}

// assume PLL filter should always be 8MHz for the moment.
filter = 1;

// calculate divisor
// (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
tuner_frequency = ((params->frequency + 36125000) / 62500);

// setup tuner buffer
tuner_buf[0] = tuner_frequency >> 8;
tuner_buf[1] = tuner_frequency & 0xff;
tuner_buf[2] = 0xc8;
tuner_buf[3] = (cp << 5) | (filter << 3) | band;
tuner_buf[4] = 0x80;

if (fe->ops->i2c_gate_ctrl)
fe->ops->i2c_gate_ctrl(fe, 1);
if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
return -EIO;
}

msleep(50);

if (fe->ops->i2c_gate_ctrl)
fe->ops->i2c_gate_ctrl(fe, 1);
if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
return -EIO;
}

msleep(1);

return 0;
}

static u8 dvbc_philips_tdm1316l_inittab[] = {
0x80, 0x21,
0x80, 0x20,
0x81, 0x01,
0x81, 0x00,
0x00, 0x09,
0x01, 0x69,
0x03, 0x00,
0x04, 0x00,
0x07, 0x00,
0x08, 0x00,
0x20, 0x00,
0x21, 0x40,
0x22, 0x00,
0x23, 0x00,
0x24, 0x40,
0x25, 0x88,
0x30, 0xff,
0x31, 0x00,
0x32, 0xff,
0x33, 0x00,
0x34, 0x50,
0x35, 0x7f,
0x36, 0x00,
0x37, 0x20,
0x38, 0x00,
0x40, 0x1c,
0x41, 0xff,
0x42, 0x29,
0x43, 0x20,
0x44, 0xff,
0x45, 0x00,
0x46, 0x00,
0x49, 0x04,
0x4a, 0xff,
0x4b, 0x7f,
0x52, 0x30,
0x55, 0xae,
0x56, 0x47,
0x57, 0xe1,
0x58, 0x3a,
0x5a, 0x1e,
0x5b, 0x34,
0x60, 0x00,
0x63, 0x00,
0x64, 0x00,
0x65, 0x00,
0x66, 0x00,
0x67, 0x00,
0x68, 0x00,
0x69, 0x00,
0x6a, 0x02,
0x6b, 0x00,
0x70, 0xff,
0x71, 0x00,
0x72, 0x00,
0x73, 0x00,
0x74, 0x0c,
0x80, 0x00,
0x81, 0x00,
0x82, 0x00,
0x83, 0x00,
0x84, 0x04,
0x85, 0x80,
0x86, 0x24,
0x87, 0x78,
0x88, 0x00,
0x89, 0x00,
0x90, 0x01,
0x91, 0x01,
0xa0, 0x00,
0xa1, 0x00,
0xa2, 0x00,
0xb0, 0x91,
0xb1, 0x0b,
0xc0, 0x4b,
0xc1, 0x00,
0xc2, 0x00,
0xd0, 0x00,
0xd1, 0x00,
0xd2, 0x00,
0xd3, 0x00,
0xd4, 0x00,
0xd5, 0x00,
0xde, 0x00,
0xdf, 0x00,
0x61, 0x38,
0x62, 0x0a,
0x53, 0x13,
0x59, 0x08,
0x55, 0x00,
0x56, 0x40,
0x57, 0x08,
0x58, 0x3d,
0x88, 0x10,
0xa0, 0x00,
0xa0, 0x00,
0xa0, 0x00,
0xa0, 0x04,
0xff, 0xff,
};

static struct stv0297_config dvbc_philips_tdm1316l_config = {
.demod_address = 0x1c,
.inittab = dvbc_philips_tdm1316l_inittab,
.invert = 0,
};

static void frontend_init(struct ttusb* ttusb)
{
switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
Expand Down Expand Up @@ -1413,6 +1582,12 @@ static void frontend_init(struct ttusb* ttusb)
ttusb->fe->ops->tuner_ops.set_params = alps_tdbe2_tuner_set_params;
break;
}

ttusb->fe = stv0297_attach(&dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
if (ttusb->fe != NULL) {
ttusb->fe->ops->tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
break;
}
break;

case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
Expand Down

0 comments on commit b8d4c23

Please sign in to comment.