Commit 0e8a0d01 authored by Michael Hunold's avatar Michael Hunold Committed by Linus Torvalds

[PATCH] dvb: frontend update

- dib3000: support for dynamically i2c addresses of the demod

- tda1004x: fixed firmware upload problems, forgot to include tune_settings
  for tda1004x, added setting to allow inversion of OCLK, set
  fesettings->min_delay_ms = 800 as suggested by Peter Siering

- stv0297: code cleanup

- mt312: added vp310 support

- mt352: decrease verbosity
Signed-off-by: default avatarMichael Hunold <hunold@linuxtv.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 7b05de7e
......@@ -393,7 +393,7 @@ static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s)
{
struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv;
int ret;
u8 status[3], vit_mode;
u8 status[3];
*s = 0;
......@@ -413,17 +413,6 @@ static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s)
if (status[0] & 0x01)
*s |= FE_HAS_LOCK; /* qpsk lock */
// VP310 doesn't have AUTO, so we "implement it here" ACCJr
if ((state->id == ID_VP310) && !(status[0] & 0x01)) {
if ((ret = mt312_readreg(state, VIT_MODE, &vit_mode)) < 0)
return ret;
vit_mode ^= 0x40;
if ((ret = mt312_writereg(state, VIT_MODE, vit_mode)) < 0)
return ret;
if ((ret = mt312_writereg(state, GO, 0x01)) < 0)
return ret;
}
return 0;
}
......@@ -638,61 +627,88 @@ static void mt312_release(struct dvb_frontend* fe)
kfree(state);
}
static struct dvb_frontend_ops mt312_ops;
static struct dvb_frontend_ops vp310_mt312_ops;
struct dvb_frontend* mt312_attach(const struct mt312_config* config,
struct dvb_frontend* vp310_attach(const struct mt312_config* config,
struct i2c_adapter* i2c)
{
struct mt312_state* state = NULL;
/* allocate memory for the internal state */
state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
if (state == NULL) goto error;
if (state == NULL)
goto error;
/* setup the state */
state->config = config;
state->i2c = i2c;
memcpy(&state->ops, &mt312_ops, sizeof(struct dvb_frontend_ops));
memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
strcpy(state->ops.info.name, "Zarlink VP310 DVB-S");
/* check if the demod is there */
if (mt312_readreg(state, ID, &state->id) < 0) goto error;
switch(state->id) {
case ID_VP310:
if (mt312_readreg(state, ID, &state->id) < 0)
goto error;
if (state->id != ID_VP310) {
goto error;
}
/* create dvb_frontend */
state->frequency = 90;
printk("mt312: Detected Zarlink VP310\n");
break;
state->frontend.ops = &state->ops;
state->frontend.demodulator_priv = state;
return &state->frontend;
case ID_MT312:
state->frequency = 60;
printk("mt312: Detected Zarlink MT312\n");
break;
error:
if (state)
kfree(state);
return NULL;
}
default:
struct dvb_frontend* mt312_attach(const struct mt312_config* config,
struct i2c_adapter* i2c)
{
struct mt312_state* state = NULL;
/* allocate memory for the internal state */
state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
if (state == NULL)
goto error;
/* setup the state */
state->config = config;
state->i2c = i2c;
memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops));
strcpy(state->ops.info.name, "Zarlink MT312 DVB-S");
/* check if the demod is there */
if (mt312_readreg(state, ID, &state->id) < 0)
goto error;
if (state->id != ID_MT312) {
goto error;
}
/* create dvb_frontend */
state->frequency = 60;
state->frontend.ops = &state->ops;
state->frontend.demodulator_priv = state;
return &state->frontend;
error:
if (state) kfree(state);
if (state)
kfree(state);
return NULL;
}
static struct dvb_frontend_ops mt312_ops = {
static struct dvb_frontend_ops vp310_mt312_ops = {
.info = {
.name = "Zarlink VP310/MT312 DVB-S",
.name = "Zarlink ???? DVB-S",
.type = FE_QPSK,
.frequency_min = 950000,
.frequency_max = 2150000,
.frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
/*.frequency_tolerance = 29500, FIXME: binary compatibility waste? */
.symbol_rate_min = MT312_SYS_CLK / 128,
.symbol_rate_max = MT312_SYS_CLK / 2,
/*.symbol_rate_tolerance = 500, FIXME: binary compatibility waste? 2% */
.caps =
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
......@@ -729,3 +745,4 @@ MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(mt312_attach);
EXPORT_SYMBOL(vp310_attach);
......@@ -41,4 +41,7 @@ struct mt312_config
extern struct dvb_frontend* mt312_attach(const struct mt312_config* config,
struct i2c_adapter* i2c);
extern struct dvb_frontend* vp310_attach(const struct mt312_config* config,
struct i2c_adapter* i2c);
#endif // MT312_H
......@@ -65,8 +65,7 @@ int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
.buf = ibuf, .len = ilen };
int err = i2c_transfer(state->i2c, &msg, 1);
if (err != 1) {
printk(KERN_WARNING
"mt352_write() failed (err = %d)!\n", err);
dprintk("mt352_write() failed (err = %d)!\n", err);
return err;
}
......@@ -88,8 +87,7 @@ static u8 mt352_read_register(struct mt352_state* state, u8 reg)
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2)
printk(KERN_WARNING
"%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
return b1[0];
}
......
This diff is collapsed.
......@@ -393,6 +393,11 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
int ret;
const struct firmware *fw;
/* reset + wake up chip */
tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0);
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
msleep(100);
/* don't re-upload unless necessary */
if (tda1004x_check_upload_ok(state, 0x20) == 0) return 0;
......@@ -404,11 +409,6 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
return ret;
}
/* reset chip */
tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0);
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
msleep(10);
/* set parameters */
tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10);
tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0);
......@@ -533,6 +533,8 @@ static int tda10045_init(struct dvb_frontend* fe)
tda1004x_write_mask(state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity
tda1004x_write_byteI(state, TDA1004X_CONFADC1, 0x2e);
tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);
state->initialised = 1;
return 0;
}
......@@ -585,6 +587,8 @@ static int tda10046_init(struct dvb_frontend* fe)
tda1004x_write_mask(state, TDA10046H_GPIO_SELECT, 8, 8); // GPIO select
tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
state->initialised = 1;
return 0;
}
......@@ -616,12 +620,13 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
if (state->demod_type == TDA1004X_DEMOD_TDA10046)
tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 4);
// Hardcoded to use auto as much as possible
// The TDA10045 is very unreliable if AUTO mode is _not_ used. I have not
// yet tested the TDA10046 to see if this issue has been fixed
// Hardcoded to use auto as much as possible on the TDA10045 as it
// is very unreliable if AUTO mode is _not_ used.
if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
}
// Set standard params.. or put them to auto
if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) ||
......@@ -1170,6 +1175,7 @@ static struct dvb_frontend_ops tda10045_ops = {
.set_frontend = tda1004x_set_fe,
.get_frontend = tda1004x_get_fe,
.get_tune_settings = tda1004x_get_tune_settings,
.read_status = tda1004x_read_status,
.read_ber = tda1004x_read_ber,
......
......@@ -34,6 +34,9 @@ struct tda1004x_config
/* does the "inversion" need inverted? */
u8 invert:1;
/* Does the OCLK signal need inverted? */
u8 invert_oclk:1;
/* PLL maintenance */
int (*pll_init)(struct dvb_frontend* fe);
int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment