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

📄 or51132.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *    Support for OR51132 (pcHDTV HD-3000) - VSB/QAM * * *    Copyright (C) 2007 Trent Piepho <xyzzy@speakeasy.org> * *    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 two external firmware files. Please copy * "dvb-fe-or51132-vsb.fw" and "dvb-fe-or51132-qam.fw" to * /usr/lib/hotplug/firmware/ or /lib/firmware/ * (depending on configuration of firmware hotplug). */#define OR51132_VSB_FIRMWARE "dvb-fe-or51132-vsb.fw"#define OR51132_QAM_FIRMWARE "dvb-fe-or51132-qam.fw"#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/string.h>#include <linux/slab.h>#include <asm/byteorder.h>#include "dvb_math.h"#include "dvb_frontend.h"#include "or51132.h"static int debug;#define dprintk(args...) \	do { \		if (debug) printk(KERN_DEBUG "or51132: " args); \	} while (0)struct or51132_state{	struct i2c_adapter* i2c;	/* Configuration settings */	const struct or51132_config* config;	struct dvb_frontend frontend;	/* Demodulator private data */	fe_modulation_t current_modulation;	u32 snr; /* Result of last SNR calculation */	/* Tuner private data */	u32 current_frequency;};/* Write buffer to demod */static int or51132_writebuf(struct or51132_state *state, const u8 *buf, int len){	int err;	struct i2c_msg msg = { .addr = state->config->demod_address,			       .flags = 0, .buf = (u8*)buf, .len = len };	/* msleep(20); */ /* doesn't appear to be necessary */	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {		printk(KERN_WARNING "or51132: I2C write (addr 0x%02x len %d) error: %d\n",		       msg.addr, msg.len, err);		return -EREMOTEIO;	}	return 0;}/* Write constant bytes, e.g. or51132_writebytes(state, 0x04, 0x42, 0x00);   Less code and more efficient that loading a buffer on the stack with   the bytes to send and then calling or51132_writebuf() on that. */#define or51132_writebytes(state, data...)  \	({ static const u8 _data[] = {data}; \	or51132_writebuf(state, _data, sizeof(_data)); })/* Read data from demod into buffer.  Returns 0 on success. */static int or51132_readbuf(struct or51132_state *state, u8 *buf, int len){	int err;	struct i2c_msg msg = { .addr = state->config->demod_address,			       .flags = I2C_M_RD, .buf = buf, .len = len };	/* msleep(20); */ /* doesn't appear to be necessary */	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {		printk(KERN_WARNING "or51132: I2C read (addr 0x%02x len %d) error: %d\n",		       msg.addr, msg.len, err);		return -EREMOTEIO;	}	return 0;}/* Reads a 16-bit demod register.  Returns <0 on error. */static int or51132_readreg(struct or51132_state *state, u8 reg){	u8 buf[2] = { 0x04, reg };	struct i2c_msg msg[2] = {		{.addr = state->config->demod_address, .flags = 0,		 .buf = buf, .len = 2 },		{.addr = state->config->demod_address, .flags = I2C_M_RD,		 .buf = buf, .len = 2 }};	int err;	if ((err = i2c_transfer(state->i2c, msg, 2)) != 2) {		printk(KERN_WARNING "or51132: I2C error reading register %d: %d\n",		       reg, err);		return -EREMOTEIO;	}	return buf[0] | (buf[1] << 8);}static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw){	struct or51132_state* state = fe->demodulator_priv;	static const u8 run_buf[] = {0x7F,0x01};	u8 rec_buf[8];	u32 firmwareAsize, firmwareBsize;	int i,ret;	dprintk("Firmware is %Zd bytes\n",fw->size);	/* Get size of firmware A and B */	firmwareAsize = le32_to_cpu(*((__le32*)fw->data));	dprintk("FirmwareA is %i bytes\n",firmwareAsize);	firmwareBsize = le32_to_cpu(*((__le32*)(fw->data+4)));	dprintk("FirmwareB is %i bytes\n",firmwareBsize);	/* Upload firmware */	if ((ret = or51132_writebuf(state, &fw->data[8], firmwareAsize))) {		printk(KERN_WARNING "or51132: load_firmware error 1\n");		return ret;	}	if ((ret = or51132_writebuf(state, &fw->data[8+firmwareAsize],				    firmwareBsize))) {		printk(KERN_WARNING "or51132: load_firmware error 2\n");		return ret;	}	if ((ret = or51132_writebuf(state, run_buf, 2))) {		printk(KERN_WARNING "or51132: load_firmware error 3\n");		return ret;	}	if ((ret = or51132_writebuf(state, run_buf, 2))) {		printk(KERN_WARNING "or51132: load_firmware error 4\n");		return ret;	}	/* 50ms for operation to begin */	msleep(50);	/* Read back ucode version to besure we loaded correctly and are really up and running */	/* Get uCode version */	if ((ret = or51132_writebytes(state, 0x10, 0x10, 0x00))) {		printk(KERN_WARNING "or51132: load_firmware error a\n");		return ret;	}	if ((ret = or51132_writebytes(state, 0x04, 0x17))) {		printk(KERN_WARNING "or51132: load_firmware error b\n");		return ret;	}	if ((ret = or51132_writebytes(state, 0x00, 0x00))) {		printk(KERN_WARNING "or51132: load_firmware error c\n");		return ret;	}	for (i=0;i<4;i++) {		/* Once upon a time, this command might have had something		   to do with getting the firmware version, but it's		   not used anymore:		   {0x04,0x00,0x30,0x00,i+1} */		/* Read 8 bytes, two bytes at a time */		if ((ret = or51132_readbuf(state, &rec_buf[i*2], 2))) {			printk(KERN_WARNING			       "or51132: load_firmware error d - %d\n",i);			return ret;		}	}	printk(KERN_WARNING	       "or51132: Version: %02X%02X%02X%02X-%02X%02X%02X%02X (%02X%01X-%01X-%02X%01X-%01X)\n",	       rec_buf[1],rec_buf[0],rec_buf[3],rec_buf[2],	       rec_buf[5],rec_buf[4],rec_buf[7],rec_buf[6],	       rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f,	       rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f);	if ((ret = or51132_writebytes(state, 0x10, 0x00, 0x00))) {		printk(KERN_WARNING "or51132: load_firmware error e\n");		return ret;	}	return 0;};static int or51132_init(struct dvb_frontend* fe){	return 0;}static int or51132_read_ber(struct dvb_frontend* fe, u32* ber){	*ber = 0;	return 0;}static int or51132_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks){	*ucblocks = 0;	return 0;}static int or51132_sleep(struct dvb_frontend* fe){	return 0;}static int or51132_setmode(struct dvb_frontend* fe){	struct or51132_state* state = fe->demodulator_priv;	u8 cmd_buf1[3] = {0x04, 0x01, 0x5f};	u8 cmd_buf2[3] = {0x1c, 0x00, 0 };	dprintk("setmode %d\n",(int)state->current_modulation);	switch (state->current_modulation) {	case VSB_8:		/* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high */		cmd_buf1[2] = 0x50;		/* REC MODE inv IF spectrum, Normal */		cmd_buf2[1] = 0x03;		/* Channel MODE ATSC/VSB8 */		cmd_buf2[2] = 0x06;		break;	/* All QAM modes are:	   Auto-deinterleave; MPEGser, MPEG2tr, phase noise-high	   REC MODE Normal Carrier Lock */	case QAM_AUTO:		/* Channel MODE Auto QAM64/256 */		cmd_buf2[2] = 0x4f;		break;	case QAM_256:		/* Channel MODE QAM256 */		cmd_buf2[2] = 0x45;		break;	case QAM_64:		/* Channel MODE QAM64 */		cmd_buf2[2] = 0x43;		break;	default:		printk(KERN_WARNING		       "or51132: setmode: Modulation set to unsupported value (%d)\n",		       state->current_modulation);		return -EINVAL;	}	/* Set Receiver 1 register */	if (or51132_writebuf(state, cmd_buf1, 3)) {		printk(KERN_WARNING "or51132: set_mode error 1\n");		return -EREMOTEIO;	}	dprintk("set #1 to %02x\n", cmd_buf1[2]);	/* Set operation mode in Receiver 6 register */	if (or51132_writebuf(state, cmd_buf2, 3)) {		printk(KERN_WARNING "or51132: set_mode error 2\n");		return -EREMOTEIO;	}	dprintk("set #6 to 0x%02x%02x\n", cmd_buf2[1], cmd_buf2[2]);	return 0;}/* Some modulations use the same firmware.  This classifies modulations   by the firmware they use. */#define MOD_FWCLASS_UNKNOWN	0#define MOD_FWCLASS_VSB		1#define MOD_FWCLASS_QAM		2static int modulation_fw_class(fe_modulation_t modulation){	switch(modulation) {	case VSB_8:		return MOD_FWCLASS_VSB;	case QAM_AUTO:	case QAM_64:	case QAM_256:		return MOD_FWCLASS_QAM;	default:		return MOD_FWCLASS_UNKNOWN;	}}static int or51132_set_parameters(struct dvb_frontend* fe,				  struct dvb_frontend_parameters *param){	int ret;	struct or51132_state* state = fe->demodulator_priv;

⌨️ 快捷键说明

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