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; }