📄 or51132.c
字号:
/* * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM * * 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/moduleparam.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/string.h>#include <linux/slab.h>#include <asm/byteorder.h>#include "dvb_frontend.h"#include "dvb-pll.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; struct dvb_frontend_ops ops; /* Configuration settings */ const struct or51132_config* config; struct dvb_frontend frontend; /* Demodulator private data */ fe_modulation_t current_modulation; /* Tuner private data */ u32 current_frequency;};static int i2c_writebytes (struct or51132_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 "or51132: i2c_writebytes error (addr %02x, err == %i)\n", reg, err); return -EREMOTEIO; } return 0;}static u8 i2c_readbytes (struct or51132_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 "or51132: i2c_readbytes error (addr %02x, err == %i)\n", reg, err); return -EREMOTEIO; } return 0;}static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw){ struct or51132_state* state = fe->demodulator_priv; static u8 run_buf[] = {0x7F,0x01}; static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; u8 rec_buf[14]; u8 cmd_buf[14]; 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(*((u32*)fw->data)); dprintk("FirmwareA is %i bytes\n",firmwareAsize); firmwareBsize = le32_to_cpu(*((u32*)(fw->data+4))); dprintk("FirmwareB is %i bytes\n",firmwareBsize); /* Upload firmware */ if ((ret = i2c_writebytes(state,state->config->demod_address, &fw->data[8],firmwareAsize))) { printk(KERN_WARNING "or51132: load_firmware error 1\n"); return ret; } msleep(1); /* 1ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, &fw->data[8+firmwareAsize],firmwareBsize))) { printk(KERN_WARNING "or51132: load_firmware error 2\n"); return ret; } msleep(1); /* 1ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, run_buf,2))) { printk(KERN_WARNING "or51132: load_firmware error 3\n"); return ret; } /* Wait at least 5 msec */ msleep(20); /* 10ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, 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 */ cmd_buf[0] = 0x10; cmd_buf[1] = 0x10; cmd_buf[2] = 0x00; cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,3))) { printk(KERN_WARNING "or51132: load_firmware error a\n"); return ret; } cmd_buf[0] = 0x04; cmd_buf[1] = 0x17; cmd_buf[2] = 0x00; cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,2))) { printk(KERN_WARNING "or51132: load_firmware error b\n"); return ret; } cmd_buf[0] = 0x00; cmd_buf[1] = 0x00; cmd_buf[2] = 0x00; cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,2))) { printk(KERN_WARNING "or51132: load_firmware error c\n"); return ret; } for(i=0;i<4;i++) { msleep(20); /* 20ms */ get_ver_buf[4] = i+1; if ((ret = i2c_readbytes(state,state->config->demod_address, &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); cmd_buf[0] = 0x10; cmd_buf[1] = 0x00; cmd_buf[2] = 0x00; cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if ((ret = i2c_writebytes(state,state->config->demod_address, cmd_buf,3))) { 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; unsigned char cmd_buf[4]; dprintk("setmode %d\n",(int)state->current_modulation); /* set operation mode in Receiver 1 register; */ cmd_buf[0] = 0x04; cmd_buf[1] = 0x01; switch (state->current_modulation) { case QAM_256: case QAM_64: case QAM_AUTO: /* Auto-deinterleave; MPEG ser, MPEG2tr, phase noise-high*/ cmd_buf[2] = 0x5F; break; case VSB_8: /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high*/ cmd_buf[2] = 0x50; break; default: printk("setmode:Modulation set to unsupported value\n"); }; cmd_buf[3] = 0x00; if (i2c_writebytes(state,state->config->demod_address, cmd_buf,3)) { printk(KERN_WARNING "or51132: set_mode error 1\n"); return -1; } dprintk("or51132: set #1 to %02x\n", cmd_buf[2]); /* Set operation mode in Receiver 6 register */ cmd_buf[0] = 0x1C; switch (state->current_modulation) { case QAM_AUTO: /* REC MODE Normal Carrier Lock */ cmd_buf[1] = 0x00; /* Channel MODE Auto QAM64/256 */ cmd_buf[2] = 0x4f; break; case QAM_256: /* REC MODE Normal Carrier Lock */ cmd_buf[1] = 0x00; /* Channel MODE QAM256 */ cmd_buf[2] = 0x45; break; case QAM_64: /* REC MODE Normal Carrier Lock */ cmd_buf[1] = 0x00; /* Channel MODE QAM64 */ cmd_buf[2] = 0x43; break; case VSB_8: /* REC MODE inv IF spectrum, Normal */ cmd_buf[1] = 0x03; /* Channel MODE ATSC/VSB8 */ cmd_buf[2] = 0x06; break; default: printk("setmode: Modulation set to unsupported value\n"); }; cmd_buf[3] = 0x00; msleep(20); /* 20ms */ if (i2c_writebytes(state,state->config->demod_address, cmd_buf,3)) { printk(KERN_WARNING "or51132: set_mode error 2\n"); return -1; } dprintk("or51132: set #6 to 0x%02x%02x\n", cmd_buf[1], cmd_buf[2]); return 0;}static int or51132_set_parameters(struct dvb_frontend* fe,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -