Commit fa4b2a17 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

[media] drxk: create only one frontend for both DVB-C and DVB-T

Instead of creating two DVB frontend entries for the same device,
create just one entry, and fill the delivery_system according with
the supported standards.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 9348393a
...@@ -580,7 +580,7 @@ static int demod_attach_drxk(struct ddb_input *input) ...@@ -580,7 +580,7 @@ static int demod_attach_drxk(struct ddb_input *input)
memset(&config, 0, sizeof(config)); memset(&config, 0, sizeof(config));
config.adr = 0x29 + (input->nr & 1); config.adr = 0x29 + (input->nr & 1);
fe = input->fe = dvb_attach(drxk_attach, &config, i2c, &input->fe2); fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
if (!input->fe) { if (!input->fe) {
printk(KERN_ERR "No DRXK found!\n"); printk(KERN_ERR "No DRXK found!\n");
return -ENODEV; return -ENODEV;
......
...@@ -37,12 +37,10 @@ struct drxk_config { ...@@ -37,12 +37,10 @@ struct drxk_config {
#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \ #if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \
&& defined(MODULE)) && defined(MODULE))
extern struct dvb_frontend *drxk_attach(const struct drxk_config *config, extern struct dvb_frontend *drxk_attach(const struct drxk_config *config,
struct i2c_adapter *i2c, struct i2c_adapter *i2c);
struct dvb_frontend **fe_t);
#else #else
static inline struct dvb_frontend *drxk_attach(const struct drxk_config *config, static inline struct dvb_frontend *drxk_attach(const struct drxk_config *config,
struct i2c_adapter *i2c, struct i2c_adapter *i2c)
struct dvb_frontend **fe_t)
{ {
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL; return NULL;
......
...@@ -6174,7 +6174,7 @@ static int init_drxk(struct drxk_state *state) ...@@ -6174,7 +6174,7 @@ static int init_drxk(struct drxk_state *state)
return status; return status;
} }
static void drxk_c_release(struct dvb_frontend *fe) static void drxk_release(struct dvb_frontend *fe)
{ {
struct drxk_state *state = fe->demodulator_priv; struct drxk_state *state = fe->demodulator_priv;
...@@ -6182,21 +6182,7 @@ static void drxk_c_release(struct dvb_frontend *fe) ...@@ -6182,21 +6182,7 @@ static void drxk_c_release(struct dvb_frontend *fe)
kfree(state); kfree(state);
} }
static int drxk_c_init(struct dvb_frontend *fe) static int drxk_sleep(struct dvb_frontend *fe)
{
struct drxk_state *state = fe->demodulator_priv;
dprintk(1, "\n");
if (mutex_trylock(&state->ctlock) == 0)
return -EBUSY;
if (state->m_itut_annex_c)
SetOperationMode(state, OM_QAM_ITU_C);
else
SetOperationMode(state, OM_QAM_ITU_A);
return 0;
}
static int drxk_c_sleep(struct dvb_frontend *fe)
{ {
struct drxk_state *state = fe->demodulator_priv; struct drxk_state *state = fe->demodulator_priv;
...@@ -6229,24 +6215,36 @@ static int drxk_set_parameters(struct dvb_frontend *fe) ...@@ -6229,24 +6215,36 @@ static int drxk_set_parameters(struct dvb_frontend *fe)
return -EINVAL; return -EINVAL;
} }
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if (fe->ops.tuner_ops.set_params)
fe->ops.tuner_ops.set_params(fe);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
state->props = *p;
switch (delsys) { switch (delsys) {
case SYS_DVBC_ANNEX_A: case SYS_DVBC_ANNEX_A:
state->m_itut_annex_c = false;
break;
case SYS_DVBC_ANNEX_C: case SYS_DVBC_ANNEX_C:
if (!state->m_hasDVBC)
return -EINVAL;
state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
if (state->m_itut_annex_c)
SetOperationMode(state, OM_QAM_ITU_C);
else
SetOperationMode(state, OM_QAM_ITU_A);
break;
state->m_itut_annex_c = true; state->m_itut_annex_c = true;
break; break;
case SYS_DVBT:
if (!state->m_hasDVBT)
return -EINVAL;
SetOperationMode(state, OM_DVBT);
break;
default: default:
return -EINVAL; return -EINVAL;
} }
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if (fe->ops.tuner_ops.set_params)
fe->ops.tuner_ops.set_params(fe);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
state->props = *p;
fe->ops.tuner_ops.get_if_frequency(fe, &IF); fe->ops.tuner_ops.get_if_frequency(fe, &IF);
Start(state, 0, IF); Start(state, 0, IF);
...@@ -6314,91 +6312,54 @@ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ...@@ -6314,91 +6312,54 @@ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
return 0; return 0;
} }
static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
*sets) *sets)
{ {
dprintk(1, "\n"); struct dtv_frontend_properties *p = &fe->dtv_property_cache;
sets->min_delay_ms = 3000;
sets->max_drift = 0;
sets->step_size = 0;
return 0;
}
static void drxk_t_release(struct dvb_frontend *fe)
{
/*
* There's nothing to release here, as the state struct
* is already freed by drxk_c_release.
*/
}
static int drxk_t_init(struct dvb_frontend *fe)
{
struct drxk_state *state = fe->demodulator_priv;
dprintk(1, "\n");
if (mutex_trylock(&state->ctlock) == 0)
return -EBUSY;
SetOperationMode(state, OM_DVBT);
return 0;
}
static int drxk_t_sleep(struct dvb_frontend *fe)
{
struct drxk_state *state = fe->demodulator_priv;
dprintk(1, "\n"); dprintk(1, "\n");
mutex_unlock(&state->ctlock); switch (p->delivery_system) {
return 0; case SYS_DVBC_ANNEX_A:
case SYS_DVBC_ANNEX_C:
sets->min_delay_ms = 3000;
sets->max_drift = 0;
sets->step_size = 0;
return 0;
default:
/*
* For DVB-T, let it use the default DVB core way, that is:
* fepriv->step_size = fe->ops.info.frequency_stepsize * 2
*/
return -EINVAL;
}
} }
static struct dvb_frontend_ops drxk_c_ops = { static struct dvb_frontend_ops drxk_ops = {
.delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C }, /* .delsys will be filled dynamically */
.info = {
.name = "DRXK DVB-C",
.frequency_min = 47000000,
.frequency_max = 862000000,
.symbol_rate_min = 870000,
.symbol_rate_max = 11700000,
.caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
.release = drxk_c_release,
.init = drxk_c_init,
.sleep = drxk_c_sleep,
.i2c_gate_ctrl = drxk_gate_ctrl,
.set_frontend = drxk_set_parameters,
.get_tune_settings = drxk_c_get_tune_settings,
.read_status = drxk_read_status,
.read_ber = drxk_read_ber,
.read_signal_strength = drxk_read_signal_strength,
.read_snr = drxk_read_snr,
.read_ucblocks = drxk_read_ucblocks,
};
static struct dvb_frontend_ops drxk_t_ops = {
.delsys = { SYS_DVBT },
.info = { .info = {
.name = "DRXK DVB-T", .name = "DRXK",
.frequency_min = 47125000, .frequency_min = 47000000,
.frequency_max = 865000000, .frequency_max = 865000000,
.frequency_stepsize = 166667, /* For DVB-C */
.frequency_tolerance = 0, .symbol_rate_min = 870000,
.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | .symbol_rate_max = 11700000,
FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | /* For DVB-T */
FE_CAN_FEC_AUTO | .frequency_stepsize = 166667,
FE_CAN_QAM_16 | FE_CAN_QAM_64 |
FE_CAN_QAM_AUTO | .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS}, FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_MUTE_TS |
.release = drxk_t_release, FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
.init = drxk_t_init, FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO
.sleep = drxk_t_sleep, },
.release = drxk_release,
.sleep = drxk_sleep,
.i2c_gate_ctrl = drxk_gate_ctrl, .i2c_gate_ctrl = drxk_gate_ctrl,
.set_frontend = drxk_set_parameters, .set_frontend = drxk_set_parameters,
.get_tune_settings = drxk_get_tune_settings,
.read_status = drxk_read_status, .read_status = drxk_read_status,
.read_ber = drxk_read_ber, .read_ber = drxk_read_ber,
...@@ -6408,9 +6369,10 @@ static struct dvb_frontend_ops drxk_t_ops = { ...@@ -6408,9 +6369,10 @@ static struct dvb_frontend_ops drxk_t_ops = {
}; };
struct dvb_frontend *drxk_attach(const struct drxk_config *config, struct dvb_frontend *drxk_attach(const struct drxk_config *config,
struct i2c_adapter *i2c, struct i2c_adapter *i2c)
struct dvb_frontend **fe_t)
{ {
int n;
struct drxk_state *state = NULL; struct drxk_state *state = NULL;
u8 adr = config->adr; u8 adr = config->adr;
...@@ -6445,21 +6407,29 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, ...@@ -6445,21 +6407,29 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
mutex_init(&state->mutex); mutex_init(&state->mutex);
mutex_init(&state->ctlock); mutex_init(&state->ctlock);
memcpy(&state->c_frontend.ops, &drxk_c_ops, memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops));
sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state;
memcpy(&state->t_frontend.ops, &drxk_t_ops,
sizeof(struct dvb_frontend_ops));
state->c_frontend.demodulator_priv = state;
state->t_frontend.demodulator_priv = state;
init_state(state); init_state(state);
if (init_drxk(state) < 0) if (init_drxk(state) < 0)
goto error; goto error;
*fe_t = &state->t_frontend;
printk(KERN_INFO "drxk: frontend initialized.\n"); /* Initialize the supported delivery systems */
n = 0;
if (state->m_hasDVBC) {
state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
strlcat(state->frontend.ops.info.name, " DVB-C",
sizeof(state->frontend.ops.info.name));
}
if (state->m_hasDVBT) {
state->frontend.ops.delsys[n++] = SYS_DVBT;
strlcat(state->frontend.ops.info.name, " DVB-T",
sizeof(state->frontend.ops.info.name));
}
return &state->c_frontend; printk(KERN_INFO "drxk: frontend initialized.\n");
return &state->frontend;
error: error:
printk(KERN_ERR "drxk: not found\n"); printk(KERN_ERR "drxk: not found\n");
......
...@@ -195,8 +195,7 @@ struct DRXKOfdmScCmd_t { ...@@ -195,8 +195,7 @@ struct DRXKOfdmScCmd_t {
}; };
struct drxk_state { struct drxk_state {
struct dvb_frontend c_frontend; struct dvb_frontend frontend;
struct dvb_frontend t_frontend;
struct dtv_frontend_properties props; struct dtv_frontend_properties props;
struct device *dev; struct device *dev;
......
...@@ -218,7 +218,7 @@ static int demod_attach_drxk(struct ngene_channel *chan, ...@@ -218,7 +218,7 @@ static int demod_attach_drxk(struct ngene_channel *chan,
memset(&config, 0, sizeof(config)); memset(&config, 0, sizeof(config));
config.adr = 0x29 + (chan->number ^ 2); config.adr = 0x29 + (chan->number ^ 2);
chan->fe = dvb_attach(drxk_attach, &config, i2c, &chan->fe2); chan->fe = dvb_attach(drxk_attach, &config, i2c);
if (!chan->fe) { if (!chan->fe) {
printk(KERN_ERR "No DRXK found!\n"); printk(KERN_ERR "No DRXK found!\n");
return -ENODEV; return -ENODEV;
......
...@@ -874,11 +874,8 @@ static int em28xx_dvb_init(struct em28xx *dev) ...@@ -874,11 +874,8 @@ static int em28xx_dvb_init(struct em28xx *dev)
struct xc5000_config cfg; struct xc5000_config cfg;
hauppauge_hvr930c_init(dev); hauppauge_hvr930c_init(dev);
dvb->dont_attach_fe1 = 1;
dvb->fe[0] = dvb_attach(drxk_attach, dvb->fe[0] = dvb_attach(drxk_attach,
&hauppauge_930c_drxk, &dev->i2c_adap, &hauppauge_930c_drxk, &dev->i2c_adap);
&dvb->fe[1]);
if (!dvb->fe[0]) { if (!dvb->fe[0]) {
result = -EINVAL; result = -EINVAL;
goto out_free; goto out_free;
...@@ -888,7 +885,6 @@ static int em28xx_dvb_init(struct em28xx *dev) ...@@ -888,7 +885,6 @@ static int em28xx_dvb_init(struct em28xx *dev)
sema_init(&dvb->pll_mutex, 1); sema_init(&dvb->pll_mutex, 1);
dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
dvb->fe[1]->id = 1;
/* Attach xc5000 */ /* Attach xc5000 */
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
...@@ -902,27 +898,16 @@ static int em28xx_dvb_init(struct em28xx *dev) ...@@ -902,27 +898,16 @@ static int em28xx_dvb_init(struct em28xx *dev)
result = -EINVAL; result = -EINVAL;
goto out_free; goto out_free;
} }
if (dvb->fe[0]->ops.i2c_gate_ctrl) if (dvb->fe[0]->ops.i2c_gate_ctrl)
dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);
/* Hack - needed by drxk/tda18271c2dd */
dvb->fe[1]->tuner_priv = dvb->fe[0]->tuner_priv;
memcpy(&dvb->fe[1]->ops.tuner_ops,
&dvb->fe[0]->ops.tuner_ops,
sizeof(dvb->fe[0]->ops.tuner_ops));
mfe_shared = 1;
break; break;
} }
case EM2884_BOARD_TERRATEC_H5: case EM2884_BOARD_TERRATEC_H5:
case EM2884_BOARD_CINERGY_HTC_STICK: case EM2884_BOARD_CINERGY_HTC_STICK:
terratec_h5_init(dev); terratec_h5_init(dev);
dvb->dont_attach_fe1 = 1; dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap);
dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap, &dvb->fe[1]);
if (!dvb->fe[0]) { if (!dvb->fe[0]) {
result = -EINVAL; result = -EINVAL;
goto out_free; goto out_free;
...@@ -932,7 +917,6 @@ static int em28xx_dvb_init(struct em28xx *dev) ...@@ -932,7 +917,6 @@ static int em28xx_dvb_init(struct em28xx *dev)
sema_init(&dvb->pll_mutex, 1); sema_init(&dvb->pll_mutex, 1);
dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
dvb->fe[1]->id = 1;
/* Attach tda18271 to DVB-C frontend */ /* Attach tda18271 to DVB-C frontend */
if (dvb->fe[0]->ops.i2c_gate_ctrl) if (dvb->fe[0]->ops.i2c_gate_ctrl)
...@@ -944,14 +928,6 @@ static int em28xx_dvb_init(struct em28xx *dev) ...@@ -944,14 +928,6 @@ static int em28xx_dvb_init(struct em28xx *dev)
if (dvb->fe[0]->ops.i2c_gate_ctrl) if (dvb->fe[0]->ops.i2c_gate_ctrl)
dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);
/* Hack - needed by drxk/tda18271c2dd */
dvb->fe[1]->tuner_priv = dvb->fe[0]->tuner_priv;
memcpy(&dvb->fe[1]->ops.tuner_ops,
&dvb->fe[0]->ops.tuner_ops,
sizeof(dvb->fe[0]->ops.tuner_ops));
mfe_shared = 1;
break; break;
case EM28174_BOARD_PCTV_460E: case EM28174_BOARD_PCTV_460E:
/* attach demod */ /* attach demod */
......
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