static int tda18271_init(struct dvb_frontend *fe)
{
	struct tda18271_priv *priv = fe->tuner_priv;
	int ret;

	mutex_lock(&priv->lock);

	/* full power up */
	ret = tda18271_set_standby_mode(fe, 0, 0, 0);
	if (tda_fail(ret))
		goto fail;

	/* initialization */
	ret = tda18271_ir_cal_init(fe);
	if (tda_fail(ret))
		goto fail;

	if (priv->id == TDA18271HDC2)
		tda18271c2_rf_cal_init(fe);
fail:
	mutex_unlock(&priv->lock);

	return ret;
}
Exemple #2
0
struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
				     struct i2c_adapter *i2c,
				     struct tda18271_config *cfg)
{
	struct tda18271_priv *priv = NULL;
	int instance;

	mutex_lock(&tda18271_list_mutex);

	instance = hybrid_tuner_request_state(struct tda18271_priv, priv,
					      hybrid_tuner_instance_list,
					      i2c, addr, "tda18271");
	switch (instance) {
	case 0:
		goto fail;
	case 1:
	{
		
		int rf_cal_on_startup;

		priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
		priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
		priv->config = (cfg) ? cfg->config : 0;
		priv->small_i2c = (cfg) ? cfg->small_i2c : 0;
		priv->output_opt = (cfg) ?
			cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;

		
		if (tda18271_cal_on_startup == -1) {
			
			rf_cal_on_startup =
				((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0;
		} else {
			
			rf_cal_on_startup = tda18271_cal_on_startup;
		}

		priv->cal_initialized = false;
		mutex_init(&priv->lock);

		fe->tuner_priv = priv;

		if (tda_fail(tda18271_get_id(fe)))
			goto fail;

		if (tda_fail(tda18271_assign_map_layout(fe)))
			goto fail;

		mutex_lock(&priv->lock);
		tda18271_init_regs(fe);

		if ((rf_cal_on_startup) && (priv->id == TDA18271HDC2))
			tda18271c2_rf_cal_init(fe);

		mutex_unlock(&priv->lock);
		break;
	}
	default:
		
		fe->tuner_priv = priv;

		
		if (cfg) {
			if (cfg->gate != TDA18271_GATE_ANALOG)
				priv->gate = cfg->gate;
			if (cfg->role)
				priv->role = cfg->role;
			if (cfg->config)
				priv->config = cfg->config;
			if (cfg->small_i2c)
				priv->small_i2c = cfg->small_i2c;
			if (cfg->output_opt)
				priv->output_opt = cfg->output_opt;
		}
		break;
	}

	
	if ((cfg) && (cfg->std_map))
		tda18271_update_std_map(fe, cfg->std_map);

	mutex_unlock(&tda18271_list_mutex);

	memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops,
	       sizeof(struct dvb_tuner_ops));

	if (tda18271_debug & (DBG_MAP | DBG_ADV))
		tda18271_dump_std_map(fe);

	return fe;
fail:
	mutex_unlock(&tda18271_list_mutex);

	tda18271_release(fe);
	return NULL;
}
struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
				     struct i2c_adapter *i2c,
				     struct tda18271_config *cfg)
{
	struct tda18271_priv *priv = NULL;
	int instance, ret;

	mutex_lock(&tda18271_list_mutex);

	instance = hybrid_tuner_request_state(struct tda18271_priv, priv,
					      hybrid_tuner_instance_list,
					      i2c, addr, "tda18271");
	switch (instance) {
	case 0:
		goto fail;
	case 1:
		/* new tuner instance */
		fe->tuner_priv = priv;

		tda18271_setup_configuration(fe, cfg);

		priv->cal_initialized = false;
		mutex_init(&priv->lock);

		ret = tda18271_get_id(fe);
		if (tda_fail(ret))
			goto fail;

		ret = tda18271_assign_map_layout(fe);
		if (tda_fail(ret))
			goto fail;

		/* if delay_cal is set, delay IR & RF calibration until init()
		 * module option 'cal' overrides this delay */
		if ((cfg->delay_cal) && (!tda18271_need_cal_on_startup(cfg)))
			break;

		mutex_lock(&priv->lock);
		tda18271_init_regs(fe);

		if ((tda18271_need_cal_on_startup(cfg)) &&
		    (priv->id == TDA18271HDC2))
			tda18271c2_rf_cal_init(fe);

		/* enter standby mode, with required output features enabled */
		ret = tda18271_toggle_output(fe, 1);
		tda_fail(ret);

		mutex_unlock(&priv->lock);
		break;
	default:
		/* existing tuner instance */
		fe->tuner_priv = priv;

		/* allow dvb driver to override configuration settings */
		if (cfg) {
			if (cfg->gate != TDA18271_GATE_ANALOG)
				priv->gate = cfg->gate;
			if (cfg->role)
				priv->role = cfg->role;
			if (cfg->config)
				priv->config = cfg->config;
			if (cfg->small_i2c)
				priv->small_i2c = cfg->small_i2c;
			if (cfg->output_opt)
				priv->output_opt = cfg->output_opt;
			if (cfg->std_map)
				tda18271_update_std_map(fe, cfg->std_map);
		}
		if (tda18271_need_cal_on_startup(cfg))
			tda18271_init(fe);
		break;
	}

	/* override default std map with values in config struct */
	if ((cfg) && (cfg->std_map))
		tda18271_update_std_map(fe, cfg->std_map);

	mutex_unlock(&tda18271_list_mutex);

	memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops,
	       sizeof(struct dvb_tuner_ops));

	if (tda18271_debug & (DBG_MAP | DBG_ADV))
		tda18271_dump_std_map(fe);

	return fe;
fail:
	mutex_unlock(&tda18271_list_mutex);

	tda18271_release(fe);
	return NULL;
}
struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
				     struct i2c_adapter *i2c,
				     struct tda18271_config *cfg)
{
	struct tda18271_priv *priv = NULL;
	int instance, ret;

	mutex_lock(&tda18271_list_mutex);

	instance = hybrid_tuner_request_state(struct tda18271_priv, priv,
					      hybrid_tuner_instance_list,
					      i2c, addr, "tda18271");
	switch (instance) {
	case 0:
		goto fail;
	case 1:
		/*                    */
		fe->tuner_priv = priv;

		tda18271_setup_configuration(fe, cfg);

		priv->cal_initialized = false;
		mutex_init(&priv->lock);

		ret = tda18271_get_id(fe);
		if (tda_fail(ret))
			goto fail;

		ret = tda18271_assign_map_layout(fe);
		if (tda_fail(ret))
			goto fail;

		mutex_lock(&priv->lock);
		tda18271_init_regs(fe);

		if ((tda18271_need_cal_on_startup(cfg)) &&
		    (priv->id == TDA18271HDC2))
			tda18271c2_rf_cal_init(fe);

		mutex_unlock(&priv->lock);
		break;
	default:
		/*                         */
		fe->tuner_priv = priv;

		/*                                                     */
		if (cfg) {
			if (cfg->gate != TDA18271_GATE_ANALOG)
				priv->gate = cfg->gate;
			if (cfg->role)
				priv->role = cfg->role;
			if (cfg->config)
				priv->config = cfg->config;
			if (cfg->small_i2c)
				priv->small_i2c = cfg->small_i2c;
			if (cfg->output_opt)
				priv->output_opt = cfg->output_opt;
			if (cfg->std_map)
				tda18271_update_std_map(fe, cfg->std_map);
		}
		if (tda18271_need_cal_on_startup(cfg))
			tda18271_init(fe);
		break;
	}

	/*                                                       */
	if ((cfg) && (cfg->std_map))
		tda18271_update_std_map(fe, cfg->std_map);

	mutex_unlock(&tda18271_list_mutex);

	memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops,
	       sizeof(struct dvb_tuner_ops));

	if (tda18271_debug & (DBG_MAP | DBG_ADV))
		tda18271_dump_std_map(fe);

	return fe;
fail:
	mutex_unlock(&tda18271_list_mutex);

	tda18271_release(fe);
	return NULL;
}