⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 af9013.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
			signal_strength = 0xffff;		state->signal_strength = signal_strength;	}error:	return ret;}static int af9013_update_statistics(struct dvb_frontend *fe){	struct af9013_state *state = fe->demodulator_priv;	int ret;	if (time_before(jiffies, state->next_statistics_check))		return 0;	/* set minimum statistic update interval */	state->next_statistics_check = jiffies + msecs_to_jiffies(1200);	ret = af9013_update_signal_strength(fe);	if (ret)		goto error;	ret = af9013_update_snr(fe);	if (ret)		goto error;	ret = af9013_update_ber_unc(fe);	if (ret)		goto error;error:	return ret;}static int af9013_get_tune_settings(struct dvb_frontend *fe,	struct dvb_frontend_tune_settings *fesettings){	fesettings->min_delay_ms = 800;	fesettings->step_size = 0;	fesettings->max_drift = 0;	return 0;}static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status){	struct af9013_state *state = fe->demodulator_priv;	int ret = 0;	u8 tmp;	*status = 0;	/* TPS lock */	ret = af9013_read_reg_bits(state, 0xd330, 3, 1, &tmp);	if (ret)		goto error;	if (tmp)		*status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;	/* MPEG2 lock */	ret = af9013_read_reg_bits(state, 0xd507, 6, 1, &tmp);	if (ret)		goto error;	if (tmp)		*status |= FE_HAS_SYNC | FE_HAS_LOCK;	if (!*status & FE_HAS_SIGNAL) {		/* AGC lock */		ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp);		if (ret)			goto error;		if (tmp)			*status |= FE_HAS_SIGNAL;	}	if (!*status & FE_HAS_CARRIER) {		/* CFO lock */		ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp);		if (ret)			goto error;		if (tmp)			*status |= FE_HAS_CARRIER;	}	if (!*status & FE_HAS_CARRIER) {		/* SFOE lock */		ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp);		if (ret)			goto error;		if (tmp)			*status |= FE_HAS_CARRIER;	}	ret = af9013_update_statistics(fe);error:	return ret;}static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber){	struct af9013_state *state = fe->demodulator_priv;	int ret;	ret = af9013_update_statistics(fe);	*ber = state->ber;	return ret;}static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength){	struct af9013_state *state = fe->demodulator_priv;	int ret;	ret = af9013_update_statistics(fe);	*strength = state->signal_strength;	return ret;}static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr){	struct af9013_state *state = fe->demodulator_priv;	int ret;	ret = af9013_update_statistics(fe);	*snr = state->snr;	return ret;}static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks){	struct af9013_state *state = fe->demodulator_priv;	int ret;	ret = af9013_update_statistics(fe);	*ucblocks = state->ucblocks;	return ret;}static int af9013_sleep(struct dvb_frontend *fe){	struct af9013_state *state = fe->demodulator_priv;	int ret;	deb_info("%s\n", __func__);	ret = af9013_lock_led(state, 0);	if (ret)		goto error;	ret = af9013_power_ctrl(state, 0);error:	return ret;}static int af9013_init(struct dvb_frontend *fe){	struct af9013_state *state = fe->demodulator_priv;	int ret, i, len;	u8 tmp0, tmp1;	struct regdesc *init;	deb_info("%s\n", __func__);	/* reset OFDM */	ret = af9013_reset(state, 0);	if (ret)		goto error;	/* power on */	ret = af9013_power_ctrl(state, 1);	if (ret)		goto error;	/* enable ADC */	ret = af9013_write_reg(state, 0xd73a, 0xa4);	if (ret)		goto error;	/* write API version to firmware */	for (i = 0; i < sizeof(state->config.api_version); i++) {		ret = af9013_write_reg(state, 0x9bf2 + i,			state->config.api_version[i]);		if (ret)			goto error;	}	/* program ADC control */	ret = af9013_set_adc_ctrl(state);	if (ret)		goto error;	/* set I2C master clock */	ret = af9013_write_reg(state, 0xd416, 0x14);	if (ret)		goto error;	/* set 16 embx */	ret = af9013_write_reg_bits(state, 0xd700, 1, 1, 1);	if (ret)		goto error;	/* set no trigger */	ret = af9013_write_reg_bits(state, 0xd700, 2, 1, 0);	if (ret)		goto error;	/* set read-update bit for constellation */	ret = af9013_write_reg_bits(state, 0xd371, 1, 1, 1);	if (ret)		goto error;	/* enable FEC monitor */	ret = af9013_write_reg_bits(state, 0xd392, 1, 1, 1);	if (ret)		goto error;	/* load OFSM settings */	deb_info("%s: load ofsm settings\n", __func__);	len = ARRAY_SIZE(ofsm_init);	init = ofsm_init;	for (i = 0; i < len; i++) {		ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos,			init[i].len, init[i].val);		if (ret)			goto error;	}	/* load tuner specific settings */	deb_info("%s: load tuner specific settings\n", __func__);	switch (state->config.tuner) {	case AF9013_TUNER_MXL5003D:		len = ARRAY_SIZE(tuner_init_mxl5003d);		init = tuner_init_mxl5003d;		break;	case AF9013_TUNER_MXL5005D:	case AF9013_TUNER_MXL5005R:		len = ARRAY_SIZE(tuner_init_mxl5005);		init = tuner_init_mxl5005;		break;	case AF9013_TUNER_ENV77H11D5:		len = ARRAY_SIZE(tuner_init_env77h11d5);		init = tuner_init_env77h11d5;		break;	case AF9013_TUNER_MT2060:		len = ARRAY_SIZE(tuner_init_mt2060);		init = tuner_init_mt2060;		break;	case AF9013_TUNER_MC44S803:		len = ARRAY_SIZE(tuner_init_mc44s803);		init = tuner_init_mc44s803;		break;	case AF9013_TUNER_QT1010:	case AF9013_TUNER_QT1010A:		len = ARRAY_SIZE(tuner_init_qt1010);		init = tuner_init_qt1010;		break;	case AF9013_TUNER_MT2060_2:		len = ARRAY_SIZE(tuner_init_mt2060_2);		init = tuner_init_mt2060_2;		break;	case AF9013_TUNER_TDA18271:		len = ARRAY_SIZE(tuner_init_tda18271);		init = tuner_init_tda18271;		break;	case AF9013_TUNER_UNKNOWN:	default:		len = ARRAY_SIZE(tuner_init_unknown);		init = tuner_init_unknown;		break;	}	for (i = 0; i < len; i++) {		ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos,			init[i].len, init[i].val);		if (ret)			goto error;	}	/* set TS mode */	deb_info("%s: setting ts mode\n", __func__);	tmp0 = 0; /* parallel mode */	tmp1 = 0; /* serial mode */	switch (state->config.output_mode) {	case AF9013_OUTPUT_MODE_PARALLEL:		tmp0 = 1;		break;	case AF9013_OUTPUT_MODE_SERIAL:		tmp1 = 1;		break;	case AF9013_OUTPUT_MODE_USB:		/* usb mode for AF9015 */	default:		break;	}	ret = af9013_write_reg_bits(state, 0xd500, 1, 1, tmp0); /* parallel */	if (ret)		goto error;	ret = af9013_write_reg_bits(state, 0xd500, 2, 1, tmp1); /* serial */	if (ret)		goto error;	/* enable lock led */	ret = af9013_lock_led(state, 1);	if (ret)		goto error;error:	return ret;}static struct dvb_frontend_ops af9013_ops;static int af9013_download_firmware(struct af9013_state *state){	int i, len, packets, remainder, ret;	const struct firmware *fw;	u16 addr = 0x5100; /* firmware start address */	u16 checksum = 0;	u8 val;	u8 fw_params[4];	u8 *data;	u8 *fw_file = AF9013_DEFAULT_FIRMWARE;	msleep(100);	/* check whether firmware is already running */	ret = af9013_read_reg(state, 0x98be, &val);	if (ret)		goto error;	else		deb_info("%s: firmware status:%02x\n", __func__, val);	if (val == 0x0c) /* fw is running, no need for download */		goto exit;	info("found a '%s' in cold state, will try to load a firmware",		af9013_ops.info.name);	/* request the firmware, this will block and timeout */	ret = request_firmware(&fw, fw_file,  &state->i2c->dev);	if (ret) {		err("did not find the firmware file. (%s) "			"Please see linux/Documentation/dvb/ for more details" \			" on firmware-problems. (%d)",			fw_file, ret);		goto error;	}	info("downloading firmware from file '%s'", fw_file);	/* calc checksum */	for (i = 0; i < fw->size; i++)		checksum += fw->data[i];	fw_params[0] = checksum >> 8;	fw_params[1] = checksum & 0xff;	fw_params[2] = fw->size >> 8;	fw_params[3] = fw->size & 0xff;	/* write fw checksum & size */	ret = af9013_write_ofsm_regs(state, 0x50fc,		fw_params, sizeof(fw_params));	if (ret)		goto error_release;	#define FW_PACKET_MAX_DATA  16	packets = fw->size / FW_PACKET_MAX_DATA;	remainder = fw->size % FW_PACKET_MAX_DATA;	len = FW_PACKET_MAX_DATA;	for (i = 0; i <= packets; i++) {		if (i == packets)  /* set size of the last packet */			len = remainder;		data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);		ret = af9013_write_ofsm_regs(state, addr, data, len);		addr += FW_PACKET_MAX_DATA;		if (ret) {			err("firmware download failed at %d with %d", i, ret);			goto error_release;		}	}	/* request boot firmware */	ret = af9013_write_reg(state, 0xe205, 1);	if (ret)		goto error_release;	for (i = 0; i < 15; i++) {		msleep(100);		/* check firmware status */		ret = af9013_read_reg(state, 0x98be, &val);		if (ret)			goto error_release;		deb_info("%s: firmware status:%02x\n", __func__, val);		if (val == 0x0c || val == 0x04) /* success or fail */			break;	}	if (val == 0x04) {		err("firmware did not run");		ret = -1;	} else if (val != 0x0c) {		err("firmware boot timeout");		ret = -1;	}error_release:	release_firmware(fw);error:exit:	if (!ret)		info("found a '%s' in warm state.", af9013_ops.info.name);	return ret;}static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable){	int ret;	struct af9013_state *state = fe->demodulator_priv;	deb_info("%s: enable:%d\n", __func__, enable);	if (state->config.output_mode == AF9013_OUTPUT_MODE_USB)		ret = af9013_write_reg_bits(state, 0xd417, 3, 1, enable);	else		ret = af9013_write_reg_bits(state, 0xd607, 2, 1, enable);	return ret;}static void af9013_release(struct dvb_frontend *fe){	struct af9013_state *state = fe->demodulator_priv;	kfree(state);}static struct dvb_frontend_ops af9013_ops;struct dvb_frontend *af9013_attach(const struct af9013_config *config,	struct i2c_adapter *i2c){	int ret;	struct af9013_state *state = NULL;	u8 buf[3], i;	/* allocate memory for the internal state */	state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL);	if (state == NULL)		goto error;	/* setup the state */	state->i2c = i2c;	memcpy(&state->config, config, sizeof(struct af9013_config));	/* chip version */	ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]);	if (ret)		goto error;	/* ROM version */	for (i = 0; i < 2; i++) {		ret = af9013_read_reg(state, 0x116b + i, &buf[i]);		if (ret)			goto error;	}	deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__,		buf[2], buf[0], buf[1]);	/* download firmware */	if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) {		ret = af9013_download_firmware(state);		if (ret)			goto error;	}	/* firmware version */	for (i = 0; i < 3; i++) {		ret = af9013_read_reg(state, 0x5103 + i, &buf[i]);		if (ret)			goto error;	}	info("firmware version:%d.%d.%d", buf[0], buf[1], buf[2]);	/* settings for mp2if */	if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) {		/* AF9015 split PSB to 1.5k + 0.5k */		ret = af9013_write_reg_bits(state, 0xd50b, 2, 1, 1);	} else {		/* AF9013 change the output bit to data7 */		ret = af9013_write_reg_bits(state, 0xd500, 3, 1, 1);		if (ret)			goto error;		/* AF9013 set mpeg to full speed */		ret = af9013_write_reg_bits(state, 0xd502, 4, 1, 1);	}	if (ret)		goto error;	ret = af9013_write_reg_bits(state, 0xd520, 4, 1, 1);	if (ret)		goto error;	/* set GPIOs */	for (i = 0; i < sizeof(state->config.gpio); i++) {		ret = af9013_set_gpio(state, i, state->config.gpio[i]);		if (ret)			goto error;	}	/* create dvb_frontend */	memcpy(&state->frontend.ops, &af9013_ops,		sizeof(struct dvb_frontend_ops));	state->frontend.demodulator_priv = state;	return &state->frontend;error:	kfree(state);	return NULL;}EXPORT_SYMBOL(af9013_attach);static struct dvb_frontend_ops af9013_ops = {	.info = {		.name = "Afatech AF9013 DVB-T",		.type = FE_OFDM,		.frequency_min = 174000000,		.frequency_max = 862000000,		.frequency_stepsize = 250000,		.frequency_tolerance = 0,		.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 | FE_CAN_FEC_AUTO |			FE_CAN_QPSK | FE_CAN_QAM_16 |			FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |			FE_CAN_TRANSMISSION_MODE_AUTO |			FE_CAN_GUARD_INTERVAL_AUTO |			FE_CAN_HIERARCHY_AUTO |			FE_CAN_RECOVER |			FE_CAN_MUTE_TS	},	.release = af9013_release,	.init = af9013_init,	.sleep = af9013_sleep,	.i2c_gate_ctrl = af9013_i2c_gate_ctrl,	.set_frontend = af9013_set_frontend,	.get_frontend = af9013_get_frontend,	.get_tune_settings = af9013_get_tune_settings,	.read_status = af9013_read_status,	.read_ber = af9013_read_ber,	.read_signal_strength = af9013_read_signal_strength,	.read_snr = af9013_read_snr,	.read_ucblocks = af9013_read_ucblocks,};module_param_named(debug, af9013_debug, int, 0644);MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -