📄 at2041_inf.c
字号:
/* * Copyright(C) 2004, Pentamicro Inc. All Right Reserved. * * Filename : at2041_inf.c * Description : Linux device driver of AT2041 * * Project : MPEG-4 4-channel SDVR * * Date : Apr., 20. 2004. * Company : Advanced Technology R&D Center * Pentamicro Inc. * * Linux version : */ /** ************************************************************************* ** ** includes ** ************************************************************************* **/#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/init.h>#include <linux/ioctl.h>#include <linux/major.h>#include <linux/delay.h>#include <asm/errno.h>#include <asm/irq.h>#include <asm/uaccess.h>#include <asm/io.h>#include <asm/delay.h>#include "at2041_inf.h"#include <asm/irq.h> /*HJT*/ #include <asm/arch/s3c2410.h> /*HJT*/#include <asm/arch/io.h>unsigned short * mux_buf[MAX_BUF_NUM];unsigned short * demux_buf[MAX_BUF_NUM];unsigned short * tx_buf[MAX_TXBUF_NUM];unsigned short * size_buf[MAX_BUF_NUM];unsigned int demux_size_buf[MAX_BUF_NUM];volatile unsigned short enc_txmsg_size = 4;volatile static unsigned short mux_ring_cnt = 0;volatile static unsigned short mux_rd_cnt = 0;volatile static unsigned short mux_wr_cnt = 0; volatile static unsigned short mux_full = 0;volatile static unsigned short demux_empty = 0;volatile static unsigned short demux_ring_cnt = 0;volatile static unsigned short demux_rd_cnt = 0;volatile static unsigned short demux_wr_cnt = 0; volatile static unsigned short txfifo_rd_cnt = 0;volatile static unsigned short txfifo_wr_cnt = 0;volatile static unsigned short txfifo_ring_cnt = 0;static struct semaphore muxfifo_read_sem;static struct semaphore demuxfifo_write_sem;//unsigned short *fifo_reg;unsigned int *fifo_reg;//void *fifo_reg;unsigned int ii;/** ************************************************************************* ** ** forward declarations ** ************************************************************************* **/static void do_mw32 ( _SET_REG_STR_ mw32_str) /*HJT*/{ unsigned int base_address = (unsigned int)fifo_reg; unsigned int reg_ad = (mw32_str.addr<<AT2041_ADD_SHIFT); unsigned int reg_val=0; unsigned int cmd_cnt=0; reg_ad += base_address; for (cmd_cnt=0;cmd_cnt<=mw32_str.cmd_num;cmd_cnt+=2) { reg_val = (mw32_str.value[cmd_cnt]|(mw32_str.value[cmd_cnt+1]<<AT2041_DAT_SHIFT)); *((unsigned int *)reg_ad) = reg_val;udelay(100); //printk ("do_mw32 : 0x%08x, 0x%08x\n", reg_ad, reg_val); /*HJT*/ } return ;}void at2041_ioctl_init() { _SET_REG_STR_ set_reg_st={0,0,{0,0,0,0,0,0}}; int count; unsigned short status, temp; /* check tx fifo empty */ printk("at2041_ioctl_init_0\n"); count = 0; do { status = *((unsigned short *)((unsigned int)fifo_reg + AT2041_STATUS_REG)); count ++; udelay(10); } while ((status & 0x100) && (count < 1000)); if (count == 1000) { printk("AT2041_STATUS_REG : 0x%x\n", status); } else { printk("AT2041_STATUS_REG : 0x%x\n", status); /* data read from Tx_FIFO of the AT2041 */ temp = *((unsigned short *)((unsigned int)fifo_reg + AT2041_TX_FIFO)); if (temp != 0x8003) { printk("AT2041_TX_FIFO : 0x%x\n", temp); return; } else { printk("AT2041_TX_FIFO : 0x%x\n", temp); } /* TxACK command */ //*((unsigned short *)((unsigned int)fifo_reg + AT2041_RX_FIFO_ADDR)) = 0x8003; //do_mw32(AT2041_RX_FIFO_ADDR, 0x8003); set_reg_st.cmd_num=0;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=0x8003; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); } printk("at2041_ioctl_init_1\n");}void pre_enc_config(void) // dec part(1) (set video output){ _SET_REG_STR_ set_reg_st={0,0,{0,0,0,0,0,0}}; unsigned short id_conf, clear_cnt; printk ("pre_enc_config started\n"); /*HJT*/ /*Global parameter */ id_conf= RxID(GID_GLOBAL, 0x00, 0x02, W_FLAG); set_reg_st.cmd_num=1; set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=2; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); id_conf= RxID(GID_GLOBAL, 0x00, 0x03, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=128; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); id_conf= RxID(GID_GLOBAL, 0x00, 0x05, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=1; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); id_conf= RxID(GID_GLOBAL, 0x00, 0x06, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=3; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); /* Normal embbedded sync */ id_conf= RxID(GID_ENC_VIDEO, 0x00, 0x03, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=0; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); /* maximum output data size */ id_conf = RxID(GID_ENCODER, 0, 0x05, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=512; // 512KBytes do_mw32 ( (_SET_REG_STR_ ) set_reg_st); /* Rate Control Mode : CBR ==> VBR */ id_conf = RxID(GID_ENC_VIDEO_CH, 0x00, 0x04, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; //set_reg_st.value[1]=0; //0:VBR 1~2:CBR //set_reg_st.value[1]=2; //0:VBR 1~2:CBR set_reg_st.value[1]=1; //0:VBR 1~2:CBR do_mw32 ( (_SET_REG_STR_ ) set_reg_st); id_conf = RxID(GID_ENC_VIDEO_CH, 0, 0x03, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=4; //MPEG4 do_mw32 ( (_SET_REG_STR_ ) set_reg_st); /* Rate Control Parameter Setting */ id_conf = RxID(GID_ENC_VIDEO_CH, 0x00, 0x06, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; //set_reg_st.value[1]=5; set_reg_st.value[1]=(1024/30); do_mw32 ( (_SET_REG_STR_ ) set_reg_st); /* Quality Setting */ id_conf = RxID(GID_ENC_VIDEO_CH, 0x00, 0x05, W_FLAG); // set channel 1 set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=5; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); /* GOP Structure : 0x07 */ id_conf = RxID(GID_ENC_VIDEO_CH, 0x00, 0x07, W_FLAG); set_reg_st.cmd_num=3;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=1; // closed gop set_reg_st.value[2]=6; // n/m //IPPPPP set_reg_st.value[3]=1; // m do_mw32 ( (_SET_REG_STR_ ) set_reg_st); /* Encoding Region Information : 0x23 */ id_conf = RxID(GID_ENC_VIDEO_CH,0x00, 0x23, W_FLAG); set_reg_st.cmd_num=4;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=0; // hor offset(must be 0) set_reg_st.value[2]=0;// ver offset(must be 0) set_reg_st.value[3]=(720>>4); // hor mb set_reg_st.value[4]=(480>>4); // ver mb do_mw32 ( (_SET_REG_STR_ ) set_reg_st); for (clear_cnt=0;clear_cnt<6;clear_cnt++) {set_reg_st.value[clear_cnt]=0;} /* Output video format NTSC */ id_conf = RxID(GID_DEC_VIDEO, 0x00, 0x01, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=NTSC; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); /* Input Video Format : 0x01 */ id_conf = RxID(GID_ENC_VIDEO, 0x00, 0x01, W_FLAG); set_reg_st.cmd_num=4;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=720; // hor_size set_reg_st.value[2]=480; // ver_size set_reg_st.value[3]=4; // video_input_rate // video_input_rate 30000/10001 set_reg_st.value[4]=0; // field_mode (d1=>interlaced '0') do_mw32 ( (_SET_REG_STR_ ) set_reg_st); for (clear_cnt=0;clear_cnt<6;clear_cnt++) {set_reg_st.value[clear_cnt]=0;} /*Encoding video size*/ id_conf = RxID(GID_ENC_VIDEO_CH, 0x00, 0x22, W_FLAG); set_reg_st.cmd_num=2;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=2; set_reg_st.value[1]=1; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); id_conf = RxID(GID_ENC_VIDEO_CH, 0x00, 0x23, W_FLAG); set_reg_st.cmd_num=4;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=0; set_reg_st.value[2]=0;set_reg_st.value[3]=22; set_reg_st.value[4]=15; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); for (clear_cnt=0;clear_cnt<6;clear_cnt++) {set_reg_st.value[clear_cnt]=0;} /* Display ON/OFF */ id_conf = RxID(GID_DEC_VIDEO_CH, 0, 0x04, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=4; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); /* Live ON/OFF */ id_conf = RxID(GID_DEC_VIDEO, 0, 0x1e, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=1; /*Not 2*/ do_mw32 ( (_SET_REG_STR_ ) set_reg_st); /* Zoom in */ id_conf = RxID(GID_DEC_VIDEO, 0, 0x10, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=3; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); #if 1 /*20041004_1*/ /*adds "reference picture selection" function for network camera application*/ /*GID=4,CID=0,PID=0x11*/ /*Data0[0]*/ /*0 : Last I/P-Picture Reference mode (default, ISO standard)*/ /*1 : I-Picture Reference mode (non ISO standard)*/ id_conf = RxID(GID_ENC_VIDEO, 0, 0x11, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=1; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); printk ("[I-Picture Reference mode]\n"); #endif printk ("pre_enc_config end\n"); /*HJT*/ udelay(100000);}static int PAL_NTSC=NTSC;typedef enum { RES_MODE_CIF, RES_MODE_DI} RES_MODE;//#define START_STOP_ENC 3 /*Video/Audio*/static void set_cbr (unsigned short cbr){ _SET_REG_STR_ set_reg_st={0,0,{0,0,0,0,0,0}}; unsigned short id_conf; unsigned short CBR_RATE=1024; #ifdef START_STOP_ENC id_conf = RxID(GID_ENCODER, 0x00, 0x03, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR;set_reg_st.value[0]=id_conf; set_reg_st.value[1]=START_STOP_ENC; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); #endif udelay(100000); //if (cbr>=1023) CBR_RATE=1023; if (cbr>=150) CBR_RATE=150; else if (cbr<=1) CBR_RATE=1; else CBR_RATE=cbr; id_conf = RxID(GID_ENC_VIDEO_CH, 0x00, 0x06, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; //set_reg_st.value[1]=(CBR_RATE/30); set_reg_st.value[1]=CBR_RATE; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); udelay(100000);#ifdef START_STOP_ENC id_conf = RxID(GID_ENCODER, 0x00, 0x02, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR;set_reg_st.value[0]=id_conf; set_reg_st.value[1]=START_STOP_ENC; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); #endif printk ("[CBR_RATE : %d Kbps]\n" , CBR_RATE*30); return ;}static void set_quality (unsigned short quality){ _SET_REG_STR_ set_reg_st={0,0,{0,0,0,0,0,0}}; unsigned short id_conf; unsigned short QUATLITY=5; #ifdef START_STOP_ENC id_conf = RxID(GID_ENCODER, 0x00, 0x03, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR;set_reg_st.value[0]=id_conf; set_reg_st.value[1]=START_STOP_ENC; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); #endif udelay(100000); if (quality>=31) QUATLITY=31; else if (quality<=3) QUATLITY=3; else QUATLITY=quality; id_conf = RxID(GID_ENC_VIDEO_CH, 0x00, 0x05, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=QUATLITY; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); udelay(100000);#ifdef START_STOP_ENC id_conf = RxID(GID_ENCODER, 0x00, 0x02, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR;set_reg_st.value[0]=id_conf; set_reg_st.value[1]=START_STOP_ENC; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); #endif printk ("[VBR_QUALITY : %d ]\n" , QUATLITY); return ;}#define MAX_FRAME_IPB 15static void set_enc_opt (unsigned short opt){ _SET_REG_STR_ set_reg_st={0,0,{0,0,0,0,0,0}}; unsigned short id_conf, clear_cnt; unsigned short OPT=1; #ifdef START_STOP_ENC id_conf = RxID(GID_ENCODER, 0x00, 0x03, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR;set_reg_st.value[0]=id_conf; set_reg_st.value[1]=START_STOP_ENC; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); #endif udelay(100000); /*20041004_1*/ /*adds "reference picture selection" function for network camera application*/ /*GID=4,CID=0,PID=0x11*/ /*Data0[0]*/ /*0 : Last I/P-Picture Reference mode (default, ISO standard)*/ /*1 : I-Picture Reference mode (non ISO standard)*/ if (opt<=0) { OPT=0; /* GOP Structure : 0x07 */ id_conf = RxID(GID_ENC_VIDEO_CH, 0x00, 0x07, W_FLAG); set_reg_st.cmd_num=3;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1] = 1; // closed gop set_reg_st.value[2] = MAX_FRAME_IPB; // n/m //IP set_reg_st.value[3] = 1; // m do_mw32 ( (_SET_REG_STR_ ) set_reg_st); printk ("[I-Picture Reference mode OFF]\n"); } else { OPT=1; /* GOP Structure : 0x07 */ id_conf = RxID(GID_ENC_VIDEO_CH, 0x00, 0x07, W_FLAG); set_reg_st.cmd_num=3;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1] = 1; // closed gop set_reg_st.value[2] = MAX_FRAME_IPB; // n/m set_reg_st.value[3] = 1; // m do_mw32 ( (_SET_REG_STR_ ) set_reg_st); printk ("[I-Picture Reference mode ON]\n"); } id_conf = RxID(GID_ENC_VIDEO, 0x00, 0x11, W_FLAG); set_reg_st.cmd_num=1;set_reg_st.addr=AT2041_RX_FIFO_ADDR; set_reg_st.value[0]=id_conf; set_reg_st.value[1]=OPT; do_mw32 ( (_SET_REG_STR_ ) set_reg_st); for (clear_cnt=0;clear_cnt<6;clear_cnt++) {set_reg_st.value[clear_cnt]=0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -