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

📄 tda10048.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
		break;	case 3:		p->code_rate_LP = FEC_5_6;		break;	case 4:		p->code_rate_LP = FEC_7_8;		break;	}	val = tda10048_readreg(state, TDA10048_OUT_CONF1);	switch ((val & 0x0c) >> 2) {	case 0:		p->guard_interval = GUARD_INTERVAL_1_32;		break;	case 1:		p->guard_interval = GUARD_INTERVAL_1_16;		break;	case 2:		p->guard_interval =  GUARD_INTERVAL_1_8;		break;	case 3:		p->guard_interval =  GUARD_INTERVAL_1_4;		break;	}	switch (val & 0x02) {	case 0:		p->transmission_mode = TRANSMISSION_MODE_2K;		break;	case 1:		p->transmission_mode = TRANSMISSION_MODE_8K;		break;	}	return 0;}static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable){	struct tda10048_state *state = fe->demodulator_priv;	dprintk(1, "%s(%d)\n", __func__, enable);	if (enable)		return tda10048_writereg(state, TDA10048_CONF_C4_1,			tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02);	else		return tda10048_writereg(state, TDA10048_CONF_C4_1,			tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xfd);}static int tda10048_output_mode(struct dvb_frontend *fe, int serial){	struct tda10048_state *state = fe->demodulator_priv;	dprintk(1, "%s(%d)\n", __func__, serial);	/* Ensure pins are out of tri-state */	tda10048_writereg(state, TDA10048_CONF_TRISTATE1, 0x21);	tda10048_writereg(state, TDA10048_CONF_TRISTATE2, 0x00);	if (serial) {		tda10048_writereg(state, TDA10048_IC_MODE, 0x80 | 0x20);		tda10048_writereg(state, TDA10048_CONF_TS2, 0xc0);	} else {		tda10048_writereg(state, TDA10048_IC_MODE, 0x00);		tda10048_writereg(state, TDA10048_CONF_TS2, 0x01);	}	return 0;}/* Talk to the demod, set the FEC, GUARD, QAM settings etc *//* TODO: Support manual tuning with specific params */static int tda10048_set_frontend(struct dvb_frontend *fe,	struct dvb_frontend_parameters *p){	struct tda10048_state *state = fe->demodulator_priv;	dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency);	if (fe->ops.tuner_ops.set_params) {		if (fe->ops.i2c_gate_ctrl)			fe->ops.i2c_gate_ctrl(fe, 1);		fe->ops.tuner_ops.set_params(fe, p);		if (fe->ops.i2c_gate_ctrl)			fe->ops.i2c_gate_ctrl(fe, 0);	}	/* Enable demod TPS auto detection and begin acquisition */	tda10048_writereg(state, TDA10048_AUTO, 0x57);	return 0;}/* Establish sane defaults and load firmware. */static int tda10048_init(struct dvb_frontend *fe){	struct tda10048_state *state = fe->demodulator_priv;	int ret = 0, i;	dprintk(1, "%s()\n", __func__);	/* Apply register defaults */	for (i = 0; i < ARRAY_SIZE(init_tab); i++)		tda10048_writereg(state, init_tab[i].reg, init_tab[i].data);	if (state->fwloaded == 0)		ret = tda10048_firmware_upload(fe);	/* Set either serial or parallel */	tda10048_output_mode(fe, state->config->output_mode);	/* set inversion */	tda10048_set_inversion(fe, state->config->inversion);	/* Ensure we leave the gate closed */	tda10048_i2c_gate_ctrl(fe, 0);	return ret;}static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status){	struct tda10048_state *state = fe->demodulator_priv;	u8 reg;	*status = 0;	reg = tda10048_readreg(state, TDA10048_SYNC_STATUS);	dprintk(1, "%s() status =0x%02x\n", __func__, reg);	if (reg & 0x02)		*status |= FE_HAS_CARRIER;	if (reg & 0x04)		*status |= FE_HAS_SIGNAL;	if (reg & 0x08) {		*status |= FE_HAS_LOCK;		*status |= FE_HAS_VITERBI;		*status |= FE_HAS_SYNC;	}	return 0;}static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber){	struct tda10048_state *state = fe->demodulator_priv;	dprintk(1, "%s()\n", __func__);	/* TODO: A reset may be required here */	*ber = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 |		tda10048_readreg(state, TDA10048_CBER_LSB);	return 0;}static int tda10048_read_signal_strength(struct dvb_frontend *fe,	u16 *signal_strength){	struct tda10048_state *state = fe->demodulator_priv;	u8 v;	dprintk(1, "%s()\n", __func__);	*signal_strength = 65535;	v = tda10048_readreg(state, TDA10048_NP_OUT);	if (v > 0)		*signal_strength -= (v << 8) | v;	return 0;}/* SNR lookup table */static struct snr_tab {	u8 val;	u8 data;} snr_tab[] = {	{   0,   0 },	{   1, 246 },	{   2, 215 },	{   3, 198 },	{   4, 185 },	{   5, 176 },	{   6, 168 },	{   7, 161 },	{   8, 155 },	{   9, 150 },	{  10, 146 },	{  11, 141 },	{  12, 138 },	{  13, 134 },	{  14, 131 },	{  15, 128 },	{  16, 125 },	{  17, 122 },	{  18, 120 },	{  19, 118 },	{  20, 115 },	{  21, 113 },	{  22, 111 },	{  23, 109 },	{  24, 107 },	{  25, 106 },	{  26, 104 },	{  27, 102 },	{  28, 101 },	{  29,  99 },	{  30,  98 },	{  31,  96 },	{  32,  95 },	{  33,  94 },	{  34,  92 },	{  35,  91 },	{  36,  90 },	{  37,  89 },	{  38,  88 },	{  39,  86 },	{  40,  85 },	{  41,  84 },	{  42,  83 },	{  43,  82 },	{  44,  81 },	{  45,  80 },	{  46,  79 },	{  47,  78 },	{  48,  77 },	{  49,  76 },	{  50,  76 },	{  51,  75 },	{  52,  74 },	{  53,  73 },	{  54,  72 },	{  56,  71 },	{  57,  70 },	{  58,  69 },	{  60,  68 },	{  61,  67 },	{  63,  66 },	{  64,  65 },	{  66,  64 },	{  67,  63 },	{  68,  62 },	{  69,  62 },	{  70,  61 },	{  72,  60 },	{  74,  59 },	{  75,  58 },	{  77,  57 },	{  79,  56 },	{  81,  55 },	{  83,  54 },	{  85,  53 },	{  87,  52 },	{  89,  51 },	{  91,  50 },	{  93,  49 },	{  95,  48 },	{  97,  47 },	{ 100,  46 },	{ 102,  45 },	{ 104,  44 },	{ 107,  43 },	{ 109,  42 },	{ 112,  41 },	{ 114,  40 },	{ 117,  39 },	{ 120,  38 },	{ 123,  37 },	{ 125,  36 },	{ 128,  35 },	{ 131,  34 },	{ 134,  33 },	{ 138,  32 },	{ 141,  31 },	{ 144,  30 },	{ 147,  29 },	{ 151,  28 },	{ 154,  27 },	{ 158,  26 },	{ 162,  25 },	{ 165,  24 },	{ 169,  23 },	{ 173,  22 },	{ 177,  21 },	{ 181,  20 },	{ 186,  19 },	{ 190,  18 },	{ 194,  17 },	{ 199,  16 },	{ 204,  15 },	{ 208,  14 },	{ 213,  13 },	{ 218,  12 },	{ 223,  11 },	{ 229,  10 },	{ 234,   9 },	{ 239,   8 },	{ 245,   7 },	{ 251,   6 },	{ 255,   5 },};static int tda10048_read_snr(struct dvb_frontend *fe, u16 *snr){	struct tda10048_state *state = fe->demodulator_priv;	u8 v;	int i, ret = -EINVAL;	dprintk(1, "%s()\n", __func__);	v = tda10048_readreg(state, TDA10048_NP_OUT);	for (i = 0; i < ARRAY_SIZE(snr_tab); i++) {		if (v <= snr_tab[i].val) {			*snr = snr_tab[i].data;			ret = 0;			break;		}	}	return ret;}static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks){	struct tda10048_state *state = fe->demodulator_priv;	dprintk(1, "%s()\n", __func__);#if 0	/* Reset and begin counting */	tda10048_writereg(state, TDA10048_UNCOR_CTRL, 0x01);	msleep(10);#endif	*ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 |		tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB);	return 0;}static int tda10048_get_frontend(struct dvb_frontend *fe,	struct dvb_frontend_parameters *p){	struct tda10048_state *state = fe->demodulator_priv;	dprintk(1, "%s()\n", __func__);	p->inversion = tda10048_readreg(state, TDA10048_CONF_C1_1)		& 0x20 ? INVERSION_ON : INVERSION_OFF;	return tda10048_get_tps(state, &p->u.ofdm);}static int tda10048_get_tune_settings(struct dvb_frontend *fe,	struct dvb_frontend_tune_settings *tune){	tune->min_delay_ms = 1000;	return 0;}static void tda10048_release(struct dvb_frontend *fe){	struct tda10048_state *state = fe->demodulator_priv;	dprintk(1, "%s()\n", __func__);	kfree(state);}static struct dvb_frontend_ops tda10048_ops;struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,	struct i2c_adapter *i2c){	struct tda10048_state *state = NULL;	dprintk(1, "%s()\n", __func__);	/* allocate memory for the internal state */	state = kmalloc(sizeof(struct tda10048_state), GFP_KERNEL);	if (state == NULL)		goto error;	/* setup the state */	state->config = config;	state->i2c = i2c;	state->fwloaded = 0;	/* check if the demod is present */	if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048)		goto error;	/* create dvb_frontend */	memcpy(&state->frontend.ops, &tda10048_ops,		sizeof(struct dvb_frontend_ops));	state->frontend.demodulator_priv = state;	/* Leave the gate closed */	tda10048_i2c_gate_ctrl(&state->frontend, 0);	return &state->frontend;error:	kfree(state);	return NULL;}EXPORT_SYMBOL(tda10048_attach);static struct dvb_frontend_ops tda10048_ops = {	.info = {		.name			= "NXP TDA10048HN DVB-T",		.type			= FE_OFDM,		.frequency_min		= 177000000,		.frequency_max		= 858000000,		.frequency_stepsize	= 166666,		.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_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |		FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER	},	.release = tda10048_release,	.init = tda10048_init,	.i2c_gate_ctrl = tda10048_i2c_gate_ctrl,	.set_frontend = tda10048_set_frontend,	.get_frontend = tda10048_get_frontend,	.get_tune_settings = tda10048_get_tune_settings,	.read_status = tda10048_read_status,	.read_ber = tda10048_read_ber,	.read_signal_strength = tda10048_read_signal_strength,	.read_snr = tda10048_read_snr,	.read_ucblocks = tda10048_read_ucblocks,};module_param(debug, int, 0644);MODULE_PARM_DESC(debug, "Enable verbose debug messages");MODULE_DESCRIPTION("NXP TDA10048HN DVB-T Demodulator driver");MODULE_AUTHOR("Steven Toth");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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