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

📄 tda1004x.c

📁 linux_dvb的驱动程序:linuxtv-dvb-1.1.1.rar
💻 C
📖 第 1 页 / 共 4 页
字号:
  /*     Driver for Philips tda1004xh OFDM Frontend     (c) 2003, 2004 Andrew de Quincey & Robert Schlabbach     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 a copy of the DLL "ttlcdacc.dll" from the Haupauge or Technotrend    windows driver saved as '/usr/lib/hotplug/firmware/tda1004x.bin'.    You can also pass the complete file name with the module parameter 'tda1004x_firmware'.    Currently the DLL from v2.15a of the technotrend driver is supported. Other versions can    be added reasonably painlessly.    Windows driver URL: http://www.technotrend.de/ */#define __KERNEL_SYSCALLS__#include <linux/kernel.h>#include <linux/vmalloc.h>#include <linux/module.h>#include <linux/init.h>#include <linux/string.h>#include <linux/slab.h>#include <linux/fs.h>#include <linux/unistd.h>#include <linux/fcntl.h>#include <linux/errno.h>#include "dvb_frontend.h"#include "dvb_functions.h"#ifndef DVB_TDA1004X_FIRMWARE_FILE#define DVB_TDA1004X_FIRMWARE_FILE "/usr/lib/hotplug/firmware/tda1004x.bin"#endifstatic int tda1004x_debug = 0;static char *tda1004x_firmware = DVB_TDA1004X_FIRMWARE_FILE;#define MC44BC374_ADDRESS        0x65#define TDA1004X_CHIPID          0x00#define TDA1004X_AUTO            0x01#define TDA1004X_IN_CONF1        0x02#define TDA1004X_IN_CONF2        0x03#define TDA1004X_OUT_CONF1       0x04#define TDA1004X_OUT_CONF2       0x05#define TDA1004X_STATUS_CD       0x06#define TDA1004X_CONFC4          0x07#define TDA1004X_DSSPARE2        0x0C#define TDA10045H_CODE_IN        0x0D#define TDA10045H_FWPAGE         0x0E#define TDA1004X_SCAN_CPT        0x10#define TDA1004X_DSP_CMD         0x11#define TDA1004X_DSP_ARG         0x12#define TDA1004X_DSP_DATA1       0x13#define TDA1004X_DSP_DATA2       0x14#define TDA1004X_CONFADC1        0x15#define TDA1004X_CONFC1          0x16#define TDA10045H_S_AGC          0x1a#define TDA10046H_AGC_TUN_LEVEL  0x1a#define TDA1004X_SNR             0x1c#define TDA1004X_CONF_TS1        0x1e#define TDA1004X_CONF_TS2        0x1f#define TDA1004X_CBER_RESET      0x20#define TDA1004X_CBER_MSB        0x21#define TDA1004X_CBER_LSB        0x22#define TDA1004X_CVBER_LUT       0x23#define TDA1004X_VBER_MSB        0x24#define TDA1004X_VBER_MID        0x25#define TDA1004X_VBER_LSB        0x26#define TDA1004X_UNCOR           0x27#define TDA10045H_CONFPLL_P      0x2D#define TDA10045H_CONFPLL_M_MSB  0x2E#define TDA10045H_CONFPLL_M_LSB  0x2F#define TDA10045H_CONFPLL_N      0x30#define TDA10046H_CONFPLL1       0x2D#define TDA10046H_CONFPLL2       0x2F#define TDA10046H_CONFPLL3       0x30#define TDA10046H_TIME_WREF1     0x31#define TDA10046H_TIME_WREF2     0x32#define TDA10046H_TIME_WREF3     0x33#define TDA10046H_TIME_WREF4     0x34#define TDA10046H_TIME_WREF5     0x35#define TDA10045H_UNSURW_MSB     0x31#define TDA10045H_UNSURW_LSB     0x32#define TDA10045H_WREF_MSB       0x33#define TDA10045H_WREF_MID       0x34#define TDA10045H_WREF_LSB       0x35#define TDA10045H_MUXOUT         0x36#define TDA1004X_CONFADC2        0x37#define TDA10045H_IOFFSET        0x38#define TDA10046H_CONF_TRISTATE1 0x3B#define TDA10046H_CONF_TRISTATE2 0x3C#define TDA10046H_CONF_POLARITY  0x3D#define TDA10046H_FREQ_OFFSET    0x3E#define TDA10046H_GPIO_OUT_SEL   0x41#define TDA10046H_GPIO_SELECT    0x42#define TDA10046H_AGC_CONF       0x43#define TDA10046H_AGC_GAINS      0x46#define TDA10046H_AGC_TUN_MIN    0x47#define TDA10046H_AGC_TUN_MAX    0x48#define TDA10046H_AGC_IF_MIN     0x49#define TDA10046H_AGC_IF_MAX     0x4A#define TDA10046H_FREQ_PHY2_MSB  0x4D#define TDA10046H_FREQ_PHY2_LSB  0x4E#define TDA10046H_CVBER_CTRL     0x4F#define TDA10046H_AGC_IF_LEVEL   0x52#define TDA10046H_CODE_CPT       0x57#define TDA10046H_CODE_IN        0x58#define FE_TYPE_TDA10045H     0#define FE_TYPE_TDA10046H     1#define TUNER_TYPE_TD1344     0#define TUNER_TYPE_TD1316     1#define dprintk if (tda1004x_debug) printkstatic struct dvb_frontend_info tda10045h_info = {        .name = "Philips TDA10045H",        .type = FE_OFDM,        .frequency_min = 51000000,        .frequency_max = 858000000,        .frequency_stepsize = 166667,        .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_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO};static struct dvb_frontend_info tda10046h_info = {        .name = "Philips TDA10046H",        .type = FE_OFDM,        .frequency_min = 51000000,        .frequency_max = 858000000,        .frequency_stepsize = 166667,        .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_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO};#pragma pack(1)struct tda1004x_state {        u8 tda1004x_address;        u8 tuner_address;        u8 initialised:1;        u8 tuner_type:2;        u8 fe_type:2;};#pragma pack()struct fwinfo {        int file_size;        int fw_offset;        int fw_size;};static struct fwinfo tda10045h_fwinfo[] = { {.file_size = 286720,.fw_offset = 0x34cc5,.fw_size = 30555} };static int tda10045h_fwinfo_count = sizeof(tda10045h_fwinfo) / sizeof(struct fwinfo);static struct fwinfo tda10046h_fwinfo[] = { {.file_size = 286720,.fw_offset = 0x3c4f9,.fw_size = 24479} };static int tda10046h_fwinfo_count = sizeof(tda10046h_fwinfo) / sizeof(struct fwinfo);static int errno;static int tda1004x_write_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, int data){        int ret;        u8 buf[] = { reg, data };        struct i2c_msg msg = { .addr=0, .flags=0, .buf=buf, .len=2 };        dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data);        msg.addr = tda_state->tda1004x_address;        ret = i2c->xfer(i2c, &msg, 1);        if (ret != 1)                dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",                        __FUNCTION__, reg, data, ret);        dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,                reg, data, ret);        return (ret != 1) ? -1 : 0;}static int tda1004x_read_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg){        int ret;        u8 b0[] = { reg };        u8 b1[] = { 0 };        struct i2c_msg msg[] = {{ .addr=0, .flags=0, .buf=b0, .len=1},                                { .addr=0, .flags=I2C_M_RD, .buf=b1, .len = 1}};        dprintk("%s: reg=0x%x\n", __FUNCTION__, reg);        msg[0].addr = tda_state->tda1004x_address;        msg[1].addr = tda_state->tda1004x_address;        ret = i2c->xfer(i2c, msg, 2);        if (ret != 2) {                dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg,                        ret);                return -1;        }        dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,                reg, b1[0], ret);        return b1[0];}static int tda1004x_write_mask(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, int mask, int data){        int val;        dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __FUNCTION__, reg,                mask, data);        // read a byte and check        val = tda1004x_read_byte(i2c, tda_state, reg);        if (val < 0)                return val;        // mask if off        val = val & ~mask;        val |= data & 0xff;        // write it out again        return tda1004x_write_byte(i2c, tda_state, reg, val);}static int tda1004x_write_buf(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, unsigned char *buf, int len){        int i;        int result;        dprintk("%s: reg=0x%x, len=0x%x\n", __FUNCTION__, reg, len);        result = 0;        for (i = 0; i < len; i++) {                result = tda1004x_write_byte(i2c, tda_state, reg + i, buf[i]);                if (result != 0)                        break;        }        return result;}static int tda1004x_enable_tuner_i2c(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state){        int result;        dprintk("%s\n", __FUNCTION__);        result = tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 2, 2);        dvb_delay(1);        return result;}static int tda1004x_disable_tuner_i2c(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state){        dprintk("%s\n", __FUNCTION__);        return tda1004x_write_mask(i2c, tda_state, TDA1004X_CONFC4, 2, 0);}static int tda10045h_set_bandwidth(struct dvb_i2c_bus *i2c,                                   struct tda1004x_state *tda_state,                                   fe_bandwidth_t bandwidth){        static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f };        static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb };        static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 };        switch (bandwidth) {        case BANDWIDTH_6_MHZ:                tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0x14);                tda1004x_write_buf(i2c, tda_state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz));                break;        case BANDWIDTH_7_MHZ:                tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0x80);                tda1004x_write_buf(i2c, tda_state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz));                break;        case BANDWIDTH_8_MHZ:                tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0x14);                tda1004x_write_buf(i2c, tda_state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz));                break;        default:                return -EINVAL;        }        tda1004x_write_byte(i2c, tda_state, TDA10045H_IOFFSET, 0);        // done        return 0;}static int tda10046h_set_bandwidth(struct dvb_i2c_bus *i2c,                                   struct tda1004x_state *tda_state,                                   fe_bandwidth_t bandwidth){        static u8 bandwidth_6mhz[] = { 0x80, 0x15, 0xfe, 0xab, 0x8e };        static u8 bandwidth_7mhz[] = { 0x6e, 0x02, 0x53, 0xc8, 0x25 };        static u8 bandwidth_8mhz[] = { 0x60, 0x12, 0xa8, 0xe4, 0xbd };        switch (bandwidth) {        case BANDWIDTH_6_MHZ:                tda1004x_write_buf(i2c, tda_state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz));                tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0);                break;        case BANDWIDTH_7_MHZ:                tda1004x_write_buf(i2c, tda_state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz));                tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0);                break;        case BANDWIDTH_8_MHZ:                tda1004x_write_buf(i2c, tda_state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz));                tda1004x_write_byte(i2c, tda_state, TDA1004X_DSSPARE2, 0xFF);                break;        default:                return -EINVAL;        }        // done        return 0;}static int tda1004x_fwupload(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state){        u8 fw_buf[65];        struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = fw_buf,.len = 0 };        unsigned char *firmware = NULL;        int filesize;        int fd;        int fwinfo_idx;        int fw_size = 0;        int fw_pos, fw_offset;        int tx_size;        mm_segment_t fs = get_fs();        int dspCodeCounterReg=0, dspCodeInReg=0, dspVersion=0;        int fwInfoCount=0;

⌨️ 快捷键说明

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