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

📄 mt312.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct mt312_state *state = fe->demodulator_priv;	const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };	if (v > SEC_VOLTAGE_OFF)		return -EINVAL;	return mt312_writereg(state, DISEQC_MODE, volt_tab[v]);}static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s){	struct mt312_state *state = fe->demodulator_priv;	int ret;	u8 status[3];	*s = 0;	if ((ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status))) < 0)		return ret;	dprintk(KERN_DEBUG "QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x, FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]);	if (status[0] & 0xc0)		*s |= FE_HAS_SIGNAL;	/* signal noise ratio */	if (status[0] & 0x04)		*s |= FE_HAS_CARRIER;	/* qpsk carrier lock */	if (status[2] & 0x02)		*s |= FE_HAS_VITERBI;	/* viterbi lock */	if (status[2] & 0x04)		*s |= FE_HAS_SYNC;	/* byte align lock */	if (status[0] & 0x01)		*s |= FE_HAS_LOCK;	/* qpsk lock */	return 0;}static int mt312_read_ber(struct dvb_frontend* fe, u32 *ber){	struct mt312_state *state = fe->demodulator_priv;	int ret;	u8 buf[3];	if ((ret = mt312_read(state, RS_BERCNT_H, buf, 3)) < 0)		return ret;	*ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64;	return 0;}static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_strength){	struct mt312_state *state = fe->demodulator_priv;	int ret;	u8 buf[3];	u16 agc;	s16 err_db;	if ((ret = mt312_read(state, AGC_H, buf, sizeof(buf))) < 0)		return ret;	agc = (buf[0] << 6) | (buf[1] >> 2);	err_db = (s16) (((buf[1] & 0x03) << 14) | buf[2] << 6) >> 6;	*signal_strength = agc;	dprintk(KERN_DEBUG "agc=%08x err_db=%hd\n", agc, err_db);	return 0;}static int mt312_read_snr(struct dvb_frontend* fe, u16 *snr){	struct mt312_state *state = fe->demodulator_priv;	int ret;	u8 buf[2];	if ((ret = mt312_read(state, M_SNR_H, &buf, sizeof(buf))) < 0)		return ret;	*snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1);	return 0;}static int mt312_read_ucblocks(struct dvb_frontend* fe, u32 *ubc){	struct mt312_state *state = fe->demodulator_priv;	int ret;	u8 buf[2];	if ((ret = mt312_read(state, RS_UBC_H, &buf, sizeof(buf))) < 0)		return ret;	*ubc = (buf[0] << 8) | buf[1];	return 0;}static int mt312_set_frontend(struct dvb_frontend* fe,			      struct dvb_frontend_parameters *p){	struct mt312_state *state = fe->demodulator_priv;	int ret;	u8 buf[5], config_val;	u16 sr;	const u8 fec_tab[10] =	    { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f };	const u8 inv_tab[3] = { 0x00, 0x40, 0x80 };	dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency);	if ((p->frequency < fe->ops->info.frequency_min)	    || (p->frequency > fe->ops->info.frequency_max))		return -EINVAL;	if ((p->inversion < INVERSION_OFF)	    || (p->inversion > INVERSION_ON))		return -EINVAL;	if ((p->u.qpsk.symbol_rate < fe->ops->info.symbol_rate_min)	    || (p->u.qpsk.symbol_rate > fe->ops->info.symbol_rate_max))		return -EINVAL;	if ((p->u.qpsk.fec_inner < FEC_NONE)	    || (p->u.qpsk.fec_inner > FEC_AUTO))		return -EINVAL;	if ((p->u.qpsk.fec_inner == FEC_4_5)	    || (p->u.qpsk.fec_inner == FEC_8_9))		return -EINVAL;	switch (state->id) {	case ID_VP310:	// For now we will do this only for the VP310.	// It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03		if ((ret = mt312_readreg(state, CONFIG, &config_val) < 0))			return ret;		if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz		{			if ((config_val & 0x0c) == 0x08) { //We are running 60MHz				state->frequency = 90;				if ((ret = mt312_initfe(fe)) < 0)					return ret;			}		}		else		{			if ((config_val & 0x0c) == 0x0C) { //We are running 90MHz				state->frequency = 60;				if ((ret = mt312_initfe(fe)) < 0)					return ret;			}		}		break;	case ID_MT312:		break;	default:		return -EINVAL;	}	mt312_writereg(state, GPP_CTRL, 0x40);	state->config->pll_set(fe, p);	mt312_writereg(state, GPP_CTRL, 0x00);	/* sr = (u16)(sr * 256.0 / 1000000.0) */	sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625);	/* SYM_RATE */	buf[0] = (sr >> 8) & 0x3f;	buf[1] = (sr >> 0) & 0xff;	/* VIT_MODE */	buf[2] = inv_tab[p->inversion] | fec_tab[p->u.qpsk.fec_inner];	/* QPSK_CTRL */	buf[3] = 0x40;		/* swap I and Q before QPSK demodulation */	if (p->u.qpsk.symbol_rate < 10000000)		buf[3] |= 0x04;	/* use afc mode */	/* GO */	buf[4] = 0x01;	if ((ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf))) < 0)		return ret;	mt312_reset(state, 0);	return 0;}static int mt312_get_frontend(struct dvb_frontend* fe,			      struct dvb_frontend_parameters *p){	struct mt312_state *state = fe->demodulator_priv;	int ret;	if ((ret = mt312_get_inversion(state, &p->inversion)) < 0)		return ret;	if ((ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate)) < 0)		return ret;	if ((ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner)) < 0)		return ret;	return 0;}static int mt312_sleep(struct dvb_frontend* fe){	struct mt312_state *state = fe->demodulator_priv;	int ret;	u8 config;	/* reset all registers to defaults */	if ((ret = mt312_reset(state, 1)) < 0)		return ret;	if ((ret = mt312_readreg(state, CONFIG, &config)) < 0)		return ret;	/* enter standby */	if ((ret = mt312_writereg(state, CONFIG, config & 0x7f)) < 0)		return ret;	return 0;}static int mt312_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings){	fesettings->min_delay_ms = 50;	fesettings->step_size = 0;	fesettings->max_drift = 0;	return 0;}static void mt312_release(struct dvb_frontend* fe){	struct mt312_state* state = fe->demodulator_priv;	kfree(state);}static struct dvb_frontend_ops vp310_mt312_ops;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 = 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 VP310 DVB-S");	/* check if the demod is there */	if (mt312_readreg(state, ID, &state->id) < 0)		goto error;	if (state->id != ID_VP310) {		goto error;	}	/* create dvb_frontend */	state->frequency = 90;	state->frontend.ops = &state->ops;	state->frontend.demodulator_priv = state;	return &state->frontend;error:	kfree(state);	return NULL;}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 = 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:	kfree(state);	return NULL;}static struct dvb_frontend_ops vp310_mt312_ops = {	.info = {		.name = "Zarlink ???? DVB-S",		.type = FE_QPSK,		.frequency_min = 950000,		.frequency_max = 2150000,		.frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,		.symbol_rate_min = MT312_SYS_CLK / 128,		.symbol_rate_max = MT312_SYS_CLK / 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 |		    FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS |		    FE_CAN_RECOVER	},	.release = mt312_release,	.init = mt312_initfe,	.sleep = mt312_sleep,	.set_frontend = mt312_set_frontend,	.get_frontend = mt312_get_frontend,	.get_tune_settings = mt312_get_tune_settings,	.read_status = mt312_read_status,	.read_ber = mt312_read_ber,	.read_signal_strength = mt312_read_signal_strength,	.read_snr = mt312_read_snr,	.read_ucblocks = mt312_read_ucblocks,	.diseqc_send_master_cmd = mt312_send_master_cmd,	.diseqc_send_burst = mt312_send_burst,	.set_tone = mt312_set_tone,	.set_voltage = mt312_set_voltage,};module_param(debug, int, 0644);MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver");MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");MODULE_LICENSE("GPL");EXPORT_SYMBOL(mt312_attach);EXPORT_SYMBOL(vp310_attach);

⌨️ 快捷键说明

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