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

📄 s5h1409.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Samsung S5H1409 VSB/QAM demodulator driver    Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>#include <linux/string.h>#include <linux/slab.h>#include <linux/delay.h>#include "dvb_frontend.h"#include "s5h1409.h"struct s5h1409_state {	struct i2c_adapter *i2c;	/* configuration settings */	const struct s5h1409_config *config;	struct dvb_frontend frontend;	/* previous uncorrected block counter */	fe_modulation_t current_modulation;	u32 current_frequency;	int if_freq;	u32 is_qam_locked;	u32 qam_state;};static int debug;module_param(debug, int, 0644);MODULE_PARM_DESC(debug, "Enable verbose debug messages");#define dprintk	if (debug) printk/* Register values to initialise the demod, this will set VSB by default */static struct init_tab {	u8	reg;	u16	data;} init_tab[] = {	{ 0x00, 0x0071, },	{ 0x01, 0x3213, },	{ 0x09, 0x0025, },	{ 0x1c, 0x001d, },	{ 0x1f, 0x002d, },	{ 0x20, 0x001d, },	{ 0x22, 0x0022, },	{ 0x23, 0x0020, },	{ 0x29, 0x110f, },	{ 0x2a, 0x10b4, },	{ 0x2b, 0x10ae, },	{ 0x2c, 0x0031, },	{ 0x31, 0x010d, },	{ 0x32, 0x0100, },	{ 0x44, 0x0510, },	{ 0x54, 0x0104, },	{ 0x58, 0x2222, },	{ 0x59, 0x1162, },	{ 0x5a, 0x3211, },	{ 0x5d, 0x0370, },	{ 0x5e, 0x0296, },	{ 0x61, 0x0010, },	{ 0x63, 0x4a00, },	{ 0x65, 0x0800, },	{ 0x71, 0x0003, },	{ 0x72, 0x0470, },	{ 0x81, 0x0002, },	{ 0x82, 0x0600, },	{ 0x86, 0x0002, },	{ 0x8a, 0x2c38, },	{ 0x8b, 0x2a37, },	{ 0x92, 0x302f, },	{ 0x93, 0x3332, },	{ 0x96, 0x000c, },	{ 0x99, 0x0101, },	{ 0x9c, 0x2e37, },	{ 0x9d, 0x2c37, },	{ 0x9e, 0x2c37, },	{ 0xab, 0x0100, },	{ 0xac, 0x1003, },	{ 0xad, 0x103f, },	{ 0xe2, 0x0100, },	{ 0xe3, 0x1000, },	{ 0x28, 0x1010, },	{ 0xb1, 0x000e, },};/* VSB SNR lookup table */static struct vsb_snr_tab {	u16	val;	u16	data;} vsb_snr_tab[] = {	{  924, 300, },	{  923, 300, },	{  918, 295, },	{  915, 290, },	{  911, 285, },	{  906, 280, },	{  901, 275, },	{  896, 270, },	{  891, 265, },	{  885, 260, },	{  879, 255, },	{  873, 250, },	{  864, 245, },	{  858, 240, },	{  850, 235, },	{  841, 230, },	{  832, 225, },	{  823, 220, },	{  812, 215, },	{  802, 210, },	{  788, 205, },	{  778, 200, },	{  767, 195, },	{  753, 190, },	{  740, 185, },	{  725, 180, },	{  707, 175, },	{  689, 170, },	{  671, 165, },	{  656, 160, },	{  637, 155, },	{  616, 150, },	{  542, 145, },	{  519, 140, },	{  507, 135, },	{  497, 130, },	{  492, 125, },	{  474, 120, },	{  300, 111, },	{    0,   0, },};/* QAM64 SNR lookup table */static struct qam64_snr_tab {	u16	val;	u16	data;} qam64_snr_tab[] = {	{    1,   0, },	{   12, 300, },	{   15, 290, },	{   18, 280, },	{   22, 270, },	{   23, 268, },	{   24, 266, },	{   25, 264, },	{   27, 262, },	{   28, 260, },	{   29, 258, },	{   30, 256, },	{   32, 254, },	{   33, 252, },	{   34, 250, },	{   35, 249, },	{   36, 248, },	{   37, 247, },	{   38, 246, },	{   39, 245, },	{   40, 244, },	{   41, 243, },	{   42, 241, },	{   43, 240, },	{   44, 239, },	{   45, 238, },	{   46, 237, },	{   47, 236, },	{   48, 235, },	{   49, 234, },	{   50, 233, },	{   51, 232, },	{   52, 231, },	{   53, 230, },	{   55, 229, },	{   56, 228, },	{   57, 227, },	{   58, 226, },	{   59, 225, },	{   60, 224, },	{   62, 223, },	{   63, 222, },	{   65, 221, },	{   66, 220, },	{   68, 219, },	{   69, 218, },	{   70, 217, },	{   72, 216, },	{   73, 215, },	{   75, 214, },	{   76, 213, },	{   78, 212, },	{   80, 211, },	{   81, 210, },	{   83, 209, },	{   84, 208, },	{   85, 207, },	{   87, 206, },	{   89, 205, },	{   91, 204, },	{   93, 203, },	{   95, 202, },	{   96, 201, },	{  104, 200, },	{  255,   0, },};/* QAM256 SNR lookup table */static struct qam256_snr_tab {	u16	val;	u16	data;} qam256_snr_tab[] = {	{    1,   0, },	{   12, 400, },	{   13, 390, },	{   15, 380, },	{   17, 360, },	{   19, 350, },	{   22, 348, },	{   23, 346, },	{   24, 344, },	{   25, 342, },	{   26, 340, },	{   27, 336, },	{   28, 334, },	{   29, 332, },	{   30, 330, },	{   31, 328, },	{   32, 326, },	{   33, 325, },	{   34, 322, },	{   35, 320, },	{   37, 318, },	{   39, 316, },	{   40, 314, },	{   41, 312, },	{   42, 310, },	{   43, 308, },	{   46, 306, },	{   47, 304, },	{   49, 302, },	{   51, 300, },	{   53, 298, },	{   54, 297, },	{   55, 296, },	{   56, 295, },	{   57, 294, },	{   59, 293, },	{   60, 292, },	{   61, 291, },	{   63, 290, },	{   64, 289, },	{   65, 288, },	{   66, 287, },	{   68, 286, },	{   69, 285, },	{   71, 284, },	{   72, 283, },	{   74, 282, },	{   75, 281, },	{   76, 280, },	{   77, 279, },	{   78, 278, },	{   81, 277, },	{   83, 276, },	{   84, 275, },	{   86, 274, },	{   87, 273, },	{   89, 272, },	{   90, 271, },	{   92, 270, },	{   93, 269, },	{   95, 268, },	{   96, 267, },	{   98, 266, },	{  100, 265, },	{  102, 264, },	{  104, 263, },	{  105, 262, },	{  106, 261, },	{  110, 260, },	{  255,   0, },};/* 8 bit registers, 16 bit values */static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data){	int ret;	u8 buf[] = { reg, data >> 8,  data & 0xff };	struct i2c_msg msg = { .addr = state->config->demod_address,			       .flags = 0, .buf = buf, .len = 3 };	ret = i2c_transfer(state->i2c, &msg, 1);	if (ret != 1)		printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, "		       "ret == %i)\n", __func__, reg, data, ret);	return (ret != 1) ? -1 : 0;}static u16 s5h1409_readreg(struct s5h1409_state *state, u8 reg){	int ret;	u8 b0[] = { reg };	u8 b1[] = { 0, 0 };	struct i2c_msg msg[] = {		{ .addr = state->config->demod_address, .flags = 0,		  .buf = b0, .len = 1 },		{ .addr = state->config->demod_address, .flags = I2C_M_RD,		  .buf = b1, .len = 2 } };	ret = i2c_transfer(state->i2c, msg, 2);	if (ret != 2)		printk("%s: readreg error (ret == %i)\n", __func__, ret);	return (b1[0] << 8) | b1[1];}static int s5h1409_softreset(struct dvb_frontend *fe){	struct s5h1409_state *state = fe->demodulator_priv;	dprintk("%s()\n", __func__);	s5h1409_writereg(state, 0xf5, 0);	s5h1409_writereg(state, 0xf5, 1);	state->is_qam_locked = 0;	state->qam_state = 0;	return 0;}#define S5H1409_VSB_IF_FREQ 5380#define S5H1409_QAM_IF_FREQ (state->config->qam_if)static int s5h1409_set_if_freq(struct dvb_frontend *fe, int KHz){	struct s5h1409_state *state = fe->demodulator_priv;	dprintk("%s(%d KHz)\n", __func__, KHz);	switch (KHz) {	case 4000:		s5h1409_writereg(state, 0x87, 0x014b);		s5h1409_writereg(state, 0x88, 0x0cb5);		s5h1409_writereg(state, 0x89, 0x03e2);		break;	case 5380:	case 44000:	default:		s5h1409_writereg(state, 0x87, 0x01be);		s5h1409_writereg(state, 0x88, 0x0436);		s5h1409_writereg(state, 0x89, 0x054d);		break;	}	state->if_freq = KHz;	return 0;}static int s5h1409_set_spectralinversion(struct dvb_frontend *fe, int inverted){	struct s5h1409_state *state = fe->demodulator_priv;	dprintk("%s(%d)\n", __func__, inverted);	if (inverted == 1)		return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */	else		return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */}static int s5h1409_enable_modulation(struct dvb_frontend *fe,				     fe_modulation_t m){	struct s5h1409_state *state = fe->demodulator_priv;	dprintk("%s(0x%08x)\n", __func__, m);	switch (m) {	case VSB_8:		dprintk("%s() VSB_8\n", __func__);		if (state->if_freq != S5H1409_VSB_IF_FREQ)			s5h1409_set_if_freq(fe, S5H1409_VSB_IF_FREQ);		s5h1409_writereg(state, 0xf4, 0);		break;	case QAM_64:	case QAM_256:	case QAM_AUTO:		dprintk("%s() QAM_AUTO (64/256)\n", __func__);		if (state->if_freq != S5H1409_QAM_IF_FREQ)			s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ);		s5h1409_writereg(state, 0xf4, 1);		s5h1409_writereg(state, 0x85, 0x110);		break;	default:		dprintk("%s() Invalid modulation\n", __func__);		return -EINVAL;	}	state->current_modulation = m;	s5h1409_softreset(fe);	return 0;}static int s5h1409_i2c_gate_ctrl(struct dvb_frontend *fe, int enable){	struct s5h1409_state *state = fe->demodulator_priv;	dprintk("%s(%d)\n", __func__, enable);	if (enable)

⌨️ 快捷键说明

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