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

📄 grundig_29504-401.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		break;	case 1:		param->u.ofdm.code_rate_HP = FEC_2_3;		break;	case 2:		param->u.ofdm.code_rate_HP = FEC_3_4;		break;	case 3:		param->u.ofdm.code_rate_HP = FEC_5_6;		break;	case 4:		param->u.ofdm.code_rate_HP = FEC_7_8;		break;	default:		printk("Unexpected value for code_rate_HP\n");	}	switch((tmp >> 3) & 7) {	case 0: 		param->u.ofdm.code_rate_LP = FEC_1_2;		break;	case 1:		param->u.ofdm.code_rate_LP = FEC_2_3;		break;	case 2:		param->u.ofdm.code_rate_LP = FEC_3_4;		break;	case 3:		param->u.ofdm.code_rate_LP = FEC_5_6;		break;	case 4:		param->u.ofdm.code_rate_LP = FEC_7_8;		break;	default:		printk("Unexpected value for code_rate_LP\n");	}			tmp = l64781_readreg(i2c, 0x06);	switch(tmp & 3) {	case 0: 		param->u.ofdm.constellation = QPSK;		break;	case 1:		param->u.ofdm.constellation = QAM_16;		break;	case 2:		param->u.ofdm.constellation = QAM_64;		break;	default:		printk("Unexpected value for constellation\n");	}	switch((tmp >> 2) & 7) {	case 0: 		param->u.ofdm.hierarchy_information = HIERARCHY_NONE;		break;	case 1:		param->u.ofdm.hierarchy_information = HIERARCHY_1;		break;	case 2:		param->u.ofdm.hierarchy_information = HIERARCHY_2;		break;	case 3:		param->u.ofdm.hierarchy_information = HIERARCHY_4;		break;	default:		printk("Unexpected value for hierarchy\n");	}	tmp = l64781_readreg (i2c, 0x1d);	param->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF;	tmp = (int) (l64781_readreg (i2c, 0x08) | 		     (l64781_readreg (i2c, 0x09) << 8) |		     (l64781_readreg (i2c, 0x0a) << 16));	param->frequency += tmp;	return 0;}static int init (struct dvb_i2c_bus *i2c){        reset_and_configure (i2c);	/* Power up */	l64781_writereg (i2c, 0x3e, 0xa5);	/* Reset hard */	l64781_writereg (i2c, 0x2a, 0x04);	l64781_writereg (i2c, 0x2a, 0x00);	/* Set tuner specific things */	/* AFC_POL, set also in reset_afc */	l64781_writereg (i2c, 0x07, 0x8e);	/* Use internal ADC */	l64781_writereg (i2c, 0x0b, 0x81);	/* AGC loop gain, and polarity is positive */	l64781_writereg (i2c, 0x0c, 0x84);	/* Internal ADC outputs two's complement */	l64781_writereg (i2c, 0x0d, 0x8c);	/* With ppm=8000, it seems the DTR_SENSITIVITY will result in           value of 2 with all possible bandwidths and guard           intervals, which is the initial value anyway. */        /*l64781_writereg (i2c, 0x19, 0x92);*/	/* Everything is two's complement, soft bit and CSI_OUT too */	l64781_writereg (i2c, 0x1e, 0x09);	return 0;}static int grundig_29504_401_ioctl (struct dvb_frontend *fe,			     unsigned int cmd, void *arg){	struct dvb_i2c_bus *i2c = fe->i2c;	int res;	struct grundig_state* state = (struct grundig_state*) fe->data;        switch (cmd) {        case FE_GET_INFO:		memcpy (arg, &grundig_29504_401_info,			sizeof(struct dvb_frontend_info));                break;	case FE_READ_STATUS:	{		fe_status_t *status = (fe_status_t *) arg;		int sync = l64781_readreg (i2c, 0x32);		int gain = l64781_readreg (i2c, 0x0e);		l64781_readreg (i2c, 0x00);  /*  clear interrupt registers... */		l64781_readreg (i2c, 0x01);  /*  dto. */		*status = 0;		if (gain > 5)			*status |= FE_HAS_SIGNAL;		if (sync & 0x02) /* VCXO locked, this criteria should be ok */			*status |= FE_HAS_CARRIER;		if (sync & 0x20)			*status |= FE_HAS_VITERBI;		if (sync & 0x40)			*status |= FE_HAS_SYNC;		if (sync == 0x7f)			*status |= FE_HAS_LOCK;		break;	}        case FE_READ_BER:	{		/*   XXX FIXME: set up counting period (reg 0x26...0x28)		 */		u32 *ber = (u32 *) arg;		*ber = l64781_readreg (i2c, 0x39)		    | (l64781_readreg (i2c, 0x3a) << 8);		break;	}        case FE_READ_SIGNAL_STRENGTH:	{		u8 gain = l64781_readreg (i2c, 0x0e);		*(u16 *) arg = (gain << 8) | gain;		break;	}        case FE_READ_SNR:	{		u16 *snr = (u16 *) arg;		u8 avg_quality = 0xff - l64781_readreg (i2c, 0x33);		*snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/ 		break;	}	case FE_READ_UNCORRECTED_BLOCKS: 	{		u32 *ub = (u32 *) arg;		*ub = l64781_readreg (i2c, 0x37)		   | (l64781_readreg (i2c, 0x38) << 8);		break;	}        case FE_SET_FRONTEND:	{		struct dvb_frontend_parameters *p = arg;		tsa5060_set_tv_freq (i2c, p->frequency);		return apply_frontend_param (i2c, p);	}        case FE_GET_FRONTEND:	{		struct dvb_frontend_parameters *p = arg;		return get_frontend(i2c, p);	}	case FE_SLEEP:		/* Power down */		return l64781_writereg (i2c, 0x3e, 0x5a);	case FE_INIT:		res = init (i2c);		if ((res == 0) && (state->first)) {			state->first = 0;			dvb_delay(200);		}		return res;	case FE_GET_TUNE_SETTINGS:	{	        struct dvb_frontend_tune_settings* fesettings = (struct dvb_frontend_tune_settings*) arg;	        fesettings->min_delay_ms = 200;	        fesettings->step_size = 166667;	        fesettings->max_drift = 166667*2;	        return 0;	}        default:		dprintk ("%s: unknown command !!!\n", __FUNCTION__);		return -EINVAL;        };                return 0;} static int l64781_attach (struct dvb_i2c_bus *i2c, void **data){	u8 reg0x3e;	u8 b0 [] = { 0x1a };	u8 b1 [] = { 0x00 };	struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 },			   { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } };	struct grundig_state* state;	/**	 *  the L64781 won't show up before we send the reset_and_configure()	 *  broadcast. If nothing responds there is no L64781 on the bus...	 */	if (reset_and_configure(i2c) < 0) {		dprintk("no response on reset_and_configure() broadcast, bailing out...\n");		return -ENODEV;	}	/* The chip always responds to reads */	if (i2c->xfer(i2c, msg, 2) != 2) {  	        dprintk("no response to read on I2C bus\n");		return -ENODEV;	}	/* Save current register contents for bailout */	reg0x3e = l64781_readreg(i2c, 0x3e);	/* Reading the POWER_DOWN register always returns 0 */	if (reg0x3e != 0) {	        dprintk("Device doesn't look like L64781\n");		return -ENODEV;	}	/* Turn the chip off */	l64781_writereg (i2c, 0x3e, 0x5a);	/* Responds to all reads with 0 */	if (l64781_readreg(i2c, 0x1a) != 0) { 	        dprintk("Read 1 returned unexpcted value\n");	        goto bailout;	}	  	/* Turn the chip on */	l64781_writereg (i2c, 0x3e, 0xa5);		/* Responds with register default value */	if (l64781_readreg(i2c, 0x1a) != 0xa1) {  	        dprintk("Read 2 returned unexpcted value\n");	        goto bailout;	}	state = kmalloc(sizeof(struct grundig_state), GFP_KERNEL);	if (state == NULL) goto bailout;	*data = state;	state->first = 1;	return dvb_register_frontend (grundig_29504_401_ioctl, i2c, state,			       &grundig_29504_401_info); bailout:	l64781_writereg (i2c, 0x3e, reg0x3e);  /* restore reg 0x3e */	return -ENODEV;}static void l64781_detach (struct dvb_i2c_bus *i2c, void *data){	kfree(data);	dvb_unregister_frontend (grundig_29504_401_ioctl, i2c);}static int __init init_grundig_29504_401 (void){	return dvb_register_i2c_device (THIS_MODULE,					l64781_attach, l64781_detach);}static void __exit exit_grundig_29504_401 (void){	dvb_unregister_i2c_device (l64781_attach);}module_init(init_grundig_29504_401);module_exit(exit_grundig_29504_401);MODULE_PARM(debug,"i");MODULE_PARM_DESC(debug, "enable verbose debug messages");MODULE_DESCRIPTION("Grundig 29504-401 DVB-T Frontend");MODULE_AUTHOR("Holger Waechtler, Marko Kohtala");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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