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

📄 stv0297.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* set a dummy symbol rate */        stv0297_set_symbolrate(state, 6900);	/* invert AGC1 polarity */        stv0297_writereg_mask(state, 0x88, 0x10, 0x10);	/* setup bit error counting */        stv0297_writereg_mask(state, 0xA0, 0x80, 0x00);        stv0297_writereg_mask(state, 0xA0, 0x10, 0x00);        stv0297_writereg_mask(state, 0xA0, 0x08, 0x00);        stv0297_writereg_mask(state, 0xA0, 0x07, 0x04);	/* min + max PWM */        stv0297_writereg(state, 0x4a, 0x00);        stv0297_writereg(state, 0x4b, state->pwm);        msleep(200);	if (state->config->pll_init)		state->config->pll_init(fe);        return 0;}static int stv0297_sleep(struct dvb_frontend *fe){	struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv;	stv0297_writereg_mask(state, 0x80, 1, 1);	return 0;}static int stv0297_read_status(struct dvb_frontend* fe, fe_status_t* status){        struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv;        u8 sync = stv0297_readreg (state, 0xDF);        *status = 0;        if (sync & 0x80)		*status |=			FE_HAS_SYNC | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK;        return 0;}static int stv0297_read_ber(struct dvb_frontend* fe, u32* ber){        struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv;        u8 BER[3];        stv0297_writereg (state, 0xA0, 0x80);	// Start Counting bit errors for 4096 Bytes        mdelay(25);				// Hopefully got 4096 Bytes        stv0297_readregs (state, 0xA0, BER, 3);        mdelay(25);        *ber = (BER[2] << 8 | BER[1]) / ( 8 * 4096);        return 0;}static int stv0297_read_signal_strength(struct dvb_frontend* fe, u16* strength){        struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv;        u8 STRENGTH[2];        stv0297_readregs (state, 0x41, STRENGTH, 2);        *strength = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0];        return 0;}static int stv0297_read_snr(struct dvb_frontend* fe, u16* snr){        struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv;        u8 SNR[2];        stv0297_readregs (state, 0x07, SNR, 2);        *snr = SNR[1] << 8 | SNR[0];        return 0;}static int stv0297_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks){        struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv;        *ucblocks = (stv0297_readreg (state, 0xD5) << 8)                   | stv0297_readreg (state, 0xD4);        return 0;}static int stv0297_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p){        struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv;        int u_threshold;        int initial_u;        int blind_u;        int delay;        int sweeprate;        int carrieroffset;        unsigned long starttime;        unsigned long timeout;	fe_spectral_inversion_t inversion;        switch(p->u.qam.modulation) {        case QAM_16:        case QAM_32:        case QAM_64:          delay = 100;          sweeprate = 1500;          break;        case QAM_128:          delay = 150;          sweeprate = 1000;          break;        case QAM_256:          delay = 200;          sweeprate = 500;          break;        default:          return -EINVAL;        }        // determine inversion dependant parameters	inversion = p->inversion;	if (state->config->invert)		inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;        carrieroffset = -330;	switch (inversion) {        case INVERSION_OFF:          break;        case INVERSION_ON:          sweeprate = -sweeprate;          carrieroffset = -carrieroffset;          break;        default:          return -EINVAL;        }	stv0297_init(fe);        state->config->pll_set(fe, p);	/* clear software interrupts */	stv0297_writereg(state, 0x82, 0x0);	/* set initial demodulation frequency */	stv0297_set_initialdemodfreq(state, 7250);	/* setup AGC */        stv0297_writereg_mask(state, 0x43, 0x10, 0x00);        stv0297_writereg(state, 0x41, 0x00);        stv0297_writereg_mask(state, 0x42, 0x03, 0x01);        stv0297_writereg_mask(state, 0x36, 0x60, 0x00);        stv0297_writereg_mask(state, 0x36, 0x18, 0x00);        stv0297_writereg_mask(state, 0x71, 0x80, 0x80);        stv0297_writereg(state, 0x72, 0x00);        stv0297_writereg(state, 0x73, 0x00);        stv0297_writereg_mask(state, 0x74, 0x0F, 0x00);        stv0297_writereg_mask(state, 0x43, 0x08, 0x00);        stv0297_writereg_mask(state, 0x71, 0x80, 0x00);	/* setup STL */        stv0297_writereg_mask(state, 0x5a, 0x20, 0x20);        stv0297_writereg_mask(state, 0x5b, 0x02, 0x02);        stv0297_writereg_mask(state, 0x5b, 0x02, 0x00);        stv0297_writereg_mask(state, 0x5b, 0x01, 0x00);        stv0297_writereg_mask(state, 0x5a, 0x40, 0x40);	/* disable frequency sweep */        stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);	/* reset deinterleaver */        stv0297_writereg_mask(state, 0x81, 0x01, 0x01);        stv0297_writereg_mask(state, 0x81, 0x01, 0x00);	/* ??? */        stv0297_writereg_mask(state, 0x83, 0x20, 0x20);        stv0297_writereg_mask(state, 0x83, 0x20, 0x00);	/* reset equaliser */        u_threshold = stv0297_readreg(state, 0x00) & 0xf;        initial_u = stv0297_readreg(state, 0x01) >> 4;        blind_u = stv0297_readreg(state, 0x01) & 0xf;        stv0297_writereg_mask(state, 0x84, 0x01, 0x01);        stv0297_writereg_mask(state, 0x84, 0x01, 0x00);        stv0297_writereg_mask(state, 0x00, 0x0f, u_threshold);        stv0297_writereg_mask(state, 0x01, 0xf0, initial_u << 4);        stv0297_writereg_mask(state, 0x01, 0x0f, blind_u);	/* data comes from internal A/D */        stv0297_writereg_mask(state, 0x87, 0x80, 0x00);	/* clear phase registers */        stv0297_writereg(state, 0x63, 0x00);        stv0297_writereg(state, 0x64, 0x00);        stv0297_writereg(state, 0x65, 0x00);        stv0297_writereg(state, 0x66, 0x00);        stv0297_writereg(state, 0x67, 0x00);        stv0297_writereg(state, 0x68, 0x00);        stv0297_writereg_mask(state, 0x69, 0x0f, 0x00);	/* set parameters */        stv0297_set_qam(state, p->u.qam.modulation);        stv0297_set_symbolrate(state, p->u.qam.symbol_rate/1000);	stv0297_set_sweeprate(state, sweeprate, p->u.qam.symbol_rate / 1000);        stv0297_set_carrieroffset(state, carrieroffset);	stv0297_set_inversion(state, inversion);	/* kick off lock */        stv0297_writereg_mask(state, 0x88, 0x08, 0x08);        stv0297_writereg_mask(state, 0x5a, 0x20, 0x00);        stv0297_writereg_mask(state, 0x6a, 0x01, 0x01);        stv0297_writereg_mask(state, 0x43, 0x40, 0x40);        stv0297_writereg_mask(state, 0x5b, 0x30, 0x00);        stv0297_writereg_mask(state, 0x03, 0x0c, 0x0c);        stv0297_writereg_mask(state, 0x03, 0x03, 0x03);        stv0297_writereg_mask(state, 0x43, 0x10, 0x10);	/* wait for WGAGC lock */        starttime = jiffies;        timeout = jiffies + (200*HZ)/1000;        while(time_before(jiffies, timeout)) {                msleep(10);		if (stv0297_readreg(state, 0x43) & 0x08)			break;        }        if (time_after(jiffies, timeout)) {                goto timeout;        }        msleep(20);	/* wait for equaliser partial convergence */        timeout = jiffies + (50*HZ)/1000;        while(time_before(jiffies, timeout)) {                msleep(10);                if (stv0297_readreg(state, 0x82) & 0x04) {			break;                }        }	if (time_after(jiffies, timeout)) {                goto timeout;        }	/* wait for equaliser full convergence */        timeout = jiffies + (delay*HZ)/1000;        while(time_before(jiffies, timeout)) {                msleep(10);                if (stv0297_readreg(state, 0x82) & 0x08) {                        break;                }        }        if (time_after(jiffies, timeout)) {                goto timeout;        }	/* disable sweep */        stv0297_writereg_mask(state, 0x6a, 1, 0);        stv0297_writereg_mask(state, 0x88, 8, 0);	/* wait for main lock */        timeout = jiffies + (20*HZ)/1000;        while(time_before(jiffies, timeout)) {                msleep(10);                if (stv0297_readreg(state, 0xDF) & 0x80) {                        break;                }        }        if (time_after(jiffies, timeout)) {                goto timeout;        }        msleep(100);	/* is it still locked after that delay? */        if (!(stv0297_readreg(state, 0xDF) & 0x80)) {                goto timeout;        }	/* success!! */        stv0297_writereg_mask(state, 0x5a, 0x40, 0x00);        state->base_freq = p->frequency;        return 0;timeout:        stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);        return 0;}static int stv0297_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p){        struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv;        int reg_00, reg_83;        reg_00 = stv0297_readreg(state, 0x00);        reg_83 = stv0297_readreg(state, 0x83);	p->frequency = state->base_freq;        p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF;	if (state->config->invert)		p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;	p->u.qam.symbol_rate = stv0297_get_symbolrate(state) * 1000;	p->u.qam.fec_inner = FEC_NONE;        switch((reg_00 >> 4) & 0x7) {	case 0:		p->u.qam.modulation = QAM_16;		break;	case 1:		p->u.qam.modulation = QAM_32;		break;	case 2:		p->u.qam.modulation = QAM_128;		break;	case 3:		p->u.qam.modulation = QAM_256;		break;	case 4:		p->u.qam.modulation = QAM_64;		break;        }        return 0;}static void stv0297_release(struct dvb_frontend* fe){        struct stv0297_state* state = (struct stv0297_state*) fe->demodulator_priv;        kfree(state);}static struct dvb_frontend_ops stv0297_ops;struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,				    struct i2c_adapter *i2c, int pwm){        struct stv0297_state* state = NULL;        /* allocate memory for the internal state */        state = (struct stv0297_state*) kmalloc(sizeof(struct stv0297_state), GFP_KERNEL);	if (state == NULL)		goto error;        /* setup the state */        state->config = config;        state->i2c = i2c;        memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));        state->base_freq = 0;        state->pwm = pwm;        /* check if the demod is there */	if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20)		goto error;        /* create dvb_frontend */        state->frontend.ops = &state->ops;        state->frontend.demodulator_priv = state;        return &state->frontend;error:	if (state)		kfree(state);        return NULL;}static struct dvb_frontend_ops stv0297_ops = {        .info = {                .name			= "ST STV0297 DVB-C",                .type			= FE_QAM,                .frequency_min		= 64000000,                .frequency_max		= 1300000000,                .frequency_stepsize	= 62500,                .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 = stv0297_release,        .init = stv0297_init,	.sleep = stv0297_sleep,        .set_frontend = stv0297_set_frontend,        .get_frontend = stv0297_get_frontend,        .read_status = stv0297_read_status,        .read_ber = stv0297_read_ber,        .read_signal_strength = stv0297_read_signal_strength,        .read_snr = stv0297_read_snr,        .read_ucblocks = stv0297_read_ucblocks,};MODULE_DESCRIPTION("ST STV0297 DVB-C Demodulator driver");MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey");MODULE_LICENSE("GPL");EXPORT_SYMBOL(stv0297_attach);EXPORT_SYMBOL(stv0297_enable_plli2c);

⌨️ 快捷键说明

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