📄 saa7113_prp.c.bak
字号:
}/* Initialize SCCB signal, simulation SCCB timing by GPIO */SINT32 sccb_init(){ /* * PA15 : SDA * PA16 : SCL */ _reg_GPIO_GIUS(GPIOE) |= 0x00000018; _reg_GPIO_OCR1(GPIOE) |= 0x000003C0; _reg_GPIO_DDIR(GPIOE) |= 0x00000018; set_sda_value(1); set_scl_high(); return 0;} int sccb_write_check(UINT8 reg, UINT8 data){ UINT8 ret = 0; sccb_write(reg,data); sccb_read(reg,&ret); if(ret != data) printk("I2C write error!\n"); return 0;}int pwdn_saa7113(int flag){ if(flag) _reg_GPIO_DR(GPIOF) |= 0x00200000; else _reg_GPIO_DR(GPIOF) &= ~(0x00200000); return 0;}static void saa7113h_hard_reset(void){ unsigned short i; pwdn_saa7113(0); for(i=0;i<1000;i++) delay10us(); pwdn_saa7113(1); for(i=0;i<1000;i++) delay10us(); return;}/*** Test on I2C channel* Read / write one of the register* compare and verify if the data is correct*/static int saa7113h_i2c_test(void){ unsigned char chip_ver; //silicon ID unsigned char rdata, wdata; unsigned int error = 0; printk("I2C Test...\n"); saa7113h_hard_reset(); //read silicon ID sccb_read(0x00, &chip_ver); printk("Chip version = 0x%02X\n", chip_ver); for(wdata = 0x1; wdata < 0x3F; wdata ++) { //register read write test sccb_write(0x0D, wdata); //test on reg 0x0D sccb_read(0x0D, &rdata); if(rdata != wdata) error = 1; } if(error) printk("saa7113h: i2c test failed\n"); else printk("saa7113h: i2c test ok\n"); saa7113h_hard_reset(); return error;}/*** SAA7113 Basic Init* Composite/S-Video Input** - Accept composite or s-video video from input A11* - Automatic field detection, PAL or NTSC expected* - Standard CCIR656 output enable* - VBI-data slicer disable* - VSYNC & HSYNC out enable* - ITU recommended contrast, brightness & saturation control* - Chrominance processin with nominal BW (800kHz)** @param type SAA7113H_INPUT_COMPOSITE Accept composite video* SAA7113H_INPUT_SVIDEO Accept s-video video*/static int saa7113h_init(void){// unsigned int chipVer; unsigned char status; unsigned int reg,i;//hard reset saa7113h_hard_reset();//recommended startup settings sccb_write_check(0x01, 0x08); //increment delay sccb_write_check(0x02, 0xC0); //analog input control 1 sccb_write_check(0x03, 0x33); //analog input control 2 sccb_write_check(0x04, 0x00); //analog input control 3 sccb_write_check(0x05, 0x00); //analog input control 4 sccb_write_check(0x06, 0xE9); //HSYNC start sccb_write_check(0x07, 0x0D); //HSYNC stop sccb_write_check(0x08, 0x98); //SYNC control sccb_write_check(0x09, 0x01); //luminance control sccb_write_check(0x0A, 0x80); //luminance brightness sccb_write_check(0x0B, 0x47); //luminance contrast sccb_write_check(0x0C, 0x40); //chrom sat sccb_write_check(0x0D, 0x00); //chrom hue sccb_write_check(0x0E, 0x01); //chrom control //sccb_write_check(0x0F, 0x2A); //chrom gain control sccb_write_check(0x0F, 0x2A); //format / delay control sccb_write_check(0x10, 0x00); //format / delay control sccb_write_check(0x11, 0x0C); //output control 1// sccb_write_check(0x11, 0x0D); //output control 1 (color kill disable) sccb_write_check(0x12, 0x7B); //output control 2 sccb_write_check(0x13, 0x00); //output control 3 sccb_write_check(0x15, 0x00); //VGATE start sccb_write_check(0x16, 0x00); //VGATE stop sccb_write_check(0x17, 0x00); //MSBs for VGATE control sccb_write_check(0x40, 0x02); //silcer control 1 for(reg = 0x41; reg <= 0x57; reg ++) sccb_write_check(reg, 0xFF); //line control register 2 to 24 sccb_write_check(0x58, 0x00); //framing code sccb_write_check(0x59, 0x54); //horizontal offset for slicer sccb_write_check(0x5A, 0x07); //vertical offset for slicer sccb_write_check(0x5B, 0x83); //field offset and SBs for H & V offset sccb_write_check(0x5E, 0x00); //silced data ID code for(i=0;i<100;i++) delay10us();//read out status sccb_read(0x1F, &status); if(status & 0x20) { printk("NTSC\n"); return 60; //60Hz => NTSC } else{ printk("PAL\n"); return 50; //50Hz => PAL }} SINT32 init_control_signal(void){ /* PWDN: PF21(~CS4), RESET:PF22(~CS5) */ /* Set GPIO functionality */ _reg_GPIO_GIUS(GPIOF) |= 0x00600000; /* Set output configure register */ _reg_GPIO_OCR2(GPIOF) |= 0x00003C00; /* Set direction configure register,output */ _reg_GPIO_DDIR(GPIOF) |= 0x00600000; return 0;}static int csi_prp_open(struct inode *inode, struct file *filp){ MOD_INC_USE_COUNT; return 0;}static int csi_prp_release(struct inode *inode, struct file *filp){ MOD_DEC_USE_COUNT; return 0;}static ssize_t csi_prp_read(struct file *filp, char *buf, size_t size, loff_t *l){ //printk("status = 0x%x\n",_reg_EMMA_PRP_INTRSTATUS); printk("cntl = 0x%x\n",(*((volatile unsigned long *)(MX2_IO_ADDRESS(EMMA_PRP_BASE+0x80))))); if(_reg_EMMA_PRP_CNTL & 0x20000000) return -1; copy_to_user(buf, pDstYAddr, Y_BUFFER_SIZE); copy_to_user(buf+Y_BUFFER_SIZE, pDstUAddr, Y_BUFFER_SIZE/4); copy_to_user(buf+Y_BUFFER_SIZE+Y_BUFFER_SIZE/4, pDstVAddr, Y_BUFFER_SIZE/4); _reg_EMMA_PRP_CNTL |= 0x60000000; return size;}static ssize_t csi_prp_write(struct file *filp, const char *buf, size_t size, loff_t *l){ return 0;}static int csi_prp_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ return 0;}SINT32 csi_init(){ //disable_sof_interrupt(); _reg_CRM_PCDR1 &= 0xc0ffffff; _reg_CRM_PCDR1 |= 0x02000000; //PerClk4 = MPLL/3 _reg_CRM_PCCR0 |= 0x80000000; _reg_CRM_PCCR0 |= 0x00400000; _reg_GPIO_GIUS(GPIOB) &= ~0x3FFC00; //disable GPIO _reg_GPIO_GPR(GPIOB) &= ~0x3FFC00; _reg_CSI_CSICR1=0; //module reset _reg_CSI_CSICR1 |= 0x2; //latch on rising edge _reg_CSI_CSICR1 |= 0x10; //gated clock mode _reg_CSI_CSICR1 |= 0x800; //hsync active mode _reg_CSI_CSICR1 |= 0x100; //sync FIFO clear _reg_CSI_CSICR1 |= 0x1200; //MCLK = PerCLK4/4 _reg_CSI_CSICR1 |= 0x40000000; //SOF rising edge _reg_CSI_CSICR1 |= 0x20000; //SOF rising edge _reg_CSI_CSICR1 |= 0x10000000; //Enable csi-prp; _reg_CSI_CSICR1 |= 0x80000; //RXFF level =8; _reg_CSI_CSICR1 |= 0x10000; //SOF INT _reg_CSI_CSICR1 |= 0x08000000; //Interlace _reg_CSI_CSICR1 |= 0x400; //CCIR mode return 0;}static void prp_intr_handler(){ //_reg_EMMA_PRP_CNTL &= ~0x60000000; //wake_up_interruptible(&gDctWaitQueue); return;}static int mx21_prp_init(){ int i; pDstYAddr = NULL; pDstUAddr = NULL; pDstVAddr = NULL; /* Alloc memory for inout and output buffer */ pDstYAddr = consistent_alloc(GFP_KERNEL|GFP_DMA,Y_BUFFER_SIZE+1024,&phyDestYAddr); pDstUAddr = consistent_alloc(GFP_KERNEL|GFP_DMA,Y_BUFFER_SIZE/4+1024,&phyDestUAddr); pDstVAddr = consistent_alloc(GFP_KERNEL|GFP_DMA,Y_BUFFER_SIZE/4+1024,&phyDestVAddr); pDstYAddr2 = consistent_alloc(GFP_KERNEL|GFP_DMA,Y_BUFFER_SIZE+1024,&phyDestYAddr2); pDstUAddr2 = consistent_alloc(GFP_KERNEL|GFP_DMA,Y_BUFFER_SIZE/4+1024,&phyDestUAddr2); pDstVAddr2 = consistent_alloc(GFP_KERNEL|GFP_DMA,Y_BUFFER_SIZE/4+1024,&phyDestVAddr2); _reg_CRM_PCCR0 |= 0x08008000; /*reset the PRP module */ _reg_EMMA_PRP_CNTL |= 0x1000; for(i=0;i<2000;i++); _reg_EMMA_PRP_CNTL = 0xE8008E2C; _reg_EMMA_PRP_CNTL |= (1 << 14); //Enable window control _reg_EMMA_PRP_DY_PTR = phyDestYAddr; _reg_EMMA_PRP_DCB_PTR = phyDestUAddr; _reg_EMMA_PRP_DCR_PTR = phyDestVAddr; _reg_EMMA_PRP_SY_PTR = phyDestYAddr2; _reg_EMMA_PRP_SCB_PTR = phyDestUAddr2; _reg_EMMA_PRP_SCR_PTR = phyDestVAddr2; _reg_EMMA_PRP_SFRM_SIZE = IN_Y_WIDTH_SIZE; _reg_EMMA_PRP_SFRM_SIZE = (_reg_EMMA_PRP_SFRM_SIZE << 16 | IN_Y_HIGHT_SIZE); _reg_EMMA_PRP_SPIX_FMT = 0x01180888; _reg_EMMA_PRP_DISIZE_CH2 = OUT_Y_WIDTH_SIZE; _reg_EMMA_PRP_DISIZE_CH2 = (_reg_EMMA_PRP_DISIZE_CH2 << 16 | OUT_Y_HIGHT_SIZE); //_reg_EMMA_PRP_RSIZE_CTRL = 0x40; //_reg_EMMA_PRP_INTRCTRL = 0x20; //Enable interupt _reg_EMMA_PRP_CNTL |= 0x2; //Enable PRP ch2 return 0;}static devfs_handle_t devfs_handle;MODULE_PARM(mode, "i");int init_module(){ int result,i; switch(mode) { case 0: IN_Y_WIDTH_SIZE = 720; IN_Y_HIGHT_SIZE = 576; OUT_Y_WIDTH_SIZE = 352; OUT_Y_HIGHT_SIZE = 288; Y_BUFFER_SIZE = OUT_Y_WIDTH_SIZE*OUT_Y_HIGHT_SIZE; break; case 1: IN_Y_WIDTH_SIZE = 720; IN_Y_HIGHT_SIZE = 576; OUT_Y_WIDTH_SIZE = 352; OUT_Y_HIGHT_SIZE = 288; Y_BUFFER_SIZE = OUT_Y_WIDTH_SIZE*OUT_Y_HIGHT_SIZE; break; default: printk("unsupported image size!\n"); break; } /* register our character device */ result = devfs_register_chrdev(0, "csi_prp", &csi_prp_fops); if ( result < 0 ) { printk("csi_prp driver: Unable to register driver\n"); return -ENODEV; } devfs_handle = devfs_register(NULL, "csi_prp", DEVFS_FL_DEFAULT, result, 0, S_IFCHR | S_IRUSR | S_IWUSR, &csi_prp_fops, NULL); printk("make node for csi_prp with 'mknod csi_prp c %d 0'\n", result); gMajor = result; //if (request_irq(EMMA_PRP_IRQ, prp_intr_handler, SA_INTERRUPT, "PRP", NULL)) // printk("*** Cannot register interrupt handler for PRP ! ***\n"); //else // printk("PRP interrupt handler registered\n"); init_control_signal(); sccb_init(); csi_init(); saa7113h_i2c_test(); saa7113h_init(); delay10us(); mx21_prp_init(); return 0;}void cleanup_module(){ if (gMajor > 0){ devfs_unregister_chrdev(gMajor, "csi_prp"); devfs_unregister(devfs_handle); } //free_irq(EMMA_PRP_IRQ, 0); printk("Say goodbye to csi_prp\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -