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

📄 or51211.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *    Support for OR51211 (pcHDTV HD-2000) - VSB * *    Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> * *    Based on code from Jack Kelliher (kelliher@xmission.com) *                           Copyright (C) 2002 & pcHDTV, inc. * *    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. **//* * This driver needs external firmware. Please use the command * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to * download/extract it, and then copy it to /usr/lib/hotplug/firmware * or /lib/firmware (depending on configuration of firmware hotplug). */#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw"#include <linux/kernel.h>#include <linux/module.h>#include <linux/device.h>#include <linux/firmware.h>#include <linux/string.h>#include <linux/slab.h>#include <asm/byteorder.h>#include "dvb_math.h"#include "dvb_frontend.h"#include "or51211.h"static int debug;#define dprintk(args...) \	do { \		if (debug) printk(KERN_DEBUG "or51211: " args); \	} while (0)static u8 run_buf[] = {0x7f,0x01};static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSCstruct or51211_state {	struct i2c_adapter* i2c;	/* Configuration settings */	const struct or51211_config* config;	struct dvb_frontend frontend;	struct bt878* bt;	/* Demodulator private data */	u8 initialized:1;	u32 snr; /* Result of last SNR claculation */	/* Tuner private data */	u32 current_frequency;};static int i2c_writebytes (struct or51211_state* state, u8 reg, u8 *buf,			   int len){	int err;	struct i2c_msg msg;	msg.addr	= reg;	msg.flags	= 0;	msg.len		= len;	msg.buf		= buf;	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {		printk(KERN_WARNING "or51211: i2c_writebytes error "		       "(addr %02x, err == %i)\n", reg, err);		return -EREMOTEIO;	}	return 0;}static u8 i2c_readbytes (struct or51211_state* state, u8 reg, u8* buf, int len){	int err;	struct i2c_msg msg;	msg.addr	= reg;	msg.flags	= I2C_M_RD;	msg.len		= len;	msg.buf		= buf;	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {		printk(KERN_WARNING "or51211: i2c_readbytes error "		       "(addr %02x, err == %i)\n", reg, err);		return -EREMOTEIO;	}	return 0;}static int or51211_load_firmware (struct dvb_frontend* fe,				  const struct firmware *fw){	struct or51211_state* state = fe->demodulator_priv;	u8 tudata[585];	int i;	dprintk("Firmware is %zd bytes\n",fw->size);	/* Get eprom data */	tudata[0] = 17;	if (i2c_writebytes(state,0x50,tudata,1)) {		printk(KERN_WARNING "or51211:load_firmware error eprom addr\n");		return -1;	}	if (i2c_readbytes(state,0x50,&tudata[145],192)) {		printk(KERN_WARNING "or51211: load_firmware error eprom\n");		return -1;	}	/* Create firmware buffer */	for (i = 0; i < 145; i++)		tudata[i] = fw->data[i];	for (i = 0; i < 248; i++)		tudata[i+337] = fw->data[145+i];	state->config->reset(fe);	if (i2c_writebytes(state,state->config->demod_address,tudata,585)) {		printk(KERN_WARNING "or51211: load_firmware error 1\n");		return -1;	}	msleep(1);	if (i2c_writebytes(state,state->config->demod_address,			   &fw->data[393],8125)) {		printk(KERN_WARNING "or51211: load_firmware error 2\n");		return -1;	}	msleep(1);	if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {		printk(KERN_WARNING "or51211: load_firmware error 3\n");		return -1;	}	/* Wait at least 5 msec */	msleep(10);	if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {		printk(KERN_WARNING "or51211: load_firmware error 4\n");		return -1;	}	msleep(10);	printk("or51211: Done.\n");	return 0;};static int or51211_setmode(struct dvb_frontend* fe, int mode){	struct or51211_state* state = fe->demodulator_priv;	u8 rec_buf[14];	state->config->setmode(fe, mode);	if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {		printk(KERN_WARNING "or51211: setmode error 1\n");		return -1;	}	/* Wait at least 5 msec */	msleep(10);	if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {		printk(KERN_WARNING "or51211: setmode error 2\n");		return -1;	}	msleep(10);	/* Set operation mode in Receiver 1 register;	 * type 1:	 * data 0x50h  Automatic sets receiver channel conditions	 *             Automatic NTSC rejection filter	 *             Enable  MPEG serial data output	 *             MPEG2tr	 *             High tuner phase noise	 *             normal +/-150kHz Carrier acquisition range	 */	if (i2c_writebytes(state,state->config->demod_address,cmd_buf,3)) {		printk(KERN_WARNING "or51211: setmode error 3\n");		return -1;	}	rec_buf[0] = 0x04;	rec_buf[1] = 0x00;	rec_buf[2] = 0x03;	rec_buf[3] = 0x00;	msleep(20);	if (i2c_writebytes(state,state->config->demod_address,rec_buf,3)) {		printk(KERN_WARNING "or51211: setmode error 5\n");	}	msleep(3);	if (i2c_readbytes(state,state->config->demod_address,&rec_buf[10],2)) {		printk(KERN_WARNING "or51211: setmode error 6");		return -1;	}	dprintk("setmode rec status %02x %02x\n",rec_buf[10],rec_buf[11]);	return 0;}static int or51211_set_parameters(struct dvb_frontend* fe,				  struct dvb_frontend_parameters *param){	struct or51211_state* state = fe->demodulator_priv;	/* Change only if we are actually changing the channel */	if (state->current_frequency != param->frequency) {		if (fe->ops.tuner_ops.set_params) {			fe->ops.tuner_ops.set_params(fe, param);			if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);		}		/* Set to ATSC mode */		or51211_setmode(fe,0);		/* Update current frequency */		state->current_frequency = param->frequency;	}	return 0;}static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status){	struct or51211_state* state = fe->demodulator_priv;	unsigned char rec_buf[2];	unsigned char snd_buf[] = {0x04,0x00,0x03,0x00};	*status = 0;	/* Receiver Status */	if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {		printk(KERN_WARNING "or51132: read_status write error\n");		return -1;	}	msleep(3);	if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {		printk(KERN_WARNING "or51132: read_status read error\n");		return -1;	}	dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);	if (rec_buf[0] &  0x01) { /* Receiver Lock */		*status |= FE_HAS_SIGNAL;		*status |= FE_HAS_CARRIER;		*status |= FE_HAS_VITERBI;		*status |= FE_HAS_SYNC;		*status |= FE_HAS_LOCK;	}	return 0;}/* Calculate SNR estimation (scaled by 2^24)   8-VSB SNR equation from Oren datasheets   For 8-VSB:     SNR[dB] = 10 * log10(219037.9454 / MSE^2 )   We re-write the snr equation as:     SNR * 2^24 = 10*(c - 2*intlog10(MSE))   Where for 8-VSB, c = log10(219037.9454) * 2^24 */static u32 calculate_snr(u32 mse, u32 c){	if (mse == 0) /* No signal */		return 0;	mse = 2*intlog10(mse);	if (mse > c) {		/* Negative SNR, which is possible, but realisticly the		demod will lose lock before the signal gets this bad.  The		API only allows for unsigned values, so just return 0 */		return 0;	}	return 10*(c - mse);

⌨️ 快捷键说明

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