📄 video-driver.c
字号:
/* Copyright (C) 2004 Samsung Electronics SW.LEE <hitchcar@sec.samsung.com> 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. ChangeLog 07.01.03 - 饭瘤胶磐 悸泼阑 困秦 #include <asm/arch/map.h> 甫 眠啊窃 by lovejin*/#include <linux/version.h>#include <linux/module.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/major.h>#include <linux/slab.h>#include <linux/poll.h>#include <linux/signal.h>#include <linux/ioport.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/interrupt.h>#include <linux/kmod.h>#include <linux/vmalloc.h>#include <linux/init.h>#include <asm/io.h>#include <asm/page.h>#include <asm/irq.h>#include <asm/semaphore.h>#include <linux/miscdevice.h>#include <asm/mach/irq.h>//#define SW_DEBUG //#include <asm/arch/s3c2410.h>//#include <asm/arch/s3c2440.h> /* Helios 2.4 目澄侩 by lovejin */#include <asm/arch/map.h> /* Helios 2.6 目澄侩 by lovejin */#include "heliosCam.h" // by lovejin#include "camif.h"#include "videodev.h"#include "miscdevice.h"#include "userapp.h"#include "i2c_decoder.h"/* Codec and Preview */#define CAMIF_NUM 2static camif_cfg_t fimc[CAMIF_NUM];static const char *driver_version = "$Id: video-driver.c,v 1.9 2004/06/02 03:10:36 swlee Exp $";extern const char *fimc_version;extern const char *fsm_version;static camif_gc_t default_data = {#if 1 /* ITU-R BT.656 */ itu_fmt: CAMIF_ITU656, //order422: CAMIF_CBYCRY, // something wrong //order422: CAMIF_YCRYCB, // no order422: CAMIF_CRYCBY, camclk: 27000000, //source_x: 648, //source_y: 486, //source_x: 648, //source_y: 243, source_x: 720, source_y: 240, win_hor_ofst: 1, win_ver_ofst: 1, polarity_pclk: 0, polarity_href: 0, reset_type: CAMIF_EX_RESET_AL, reset_udelay:2000,#else /* ITU-R BT.601 */ itu_fmt: CAMIF_ITU601, //order422: CAMIF_YCBYCR, order422: CAMIF_YCRYCB, //order422: CAMIF_CRYCBY, //order422: CAMIF_CBYCRY, camclk: 27000000, //source_x: 648, //source_y: 486, source_x: 640, // source input 康惑俊辑 磊甫 荐 乐促. source_y: 480, win_hor_ofst: 50, // 5老锭 拳搁捞 唱坷瘤 臼澜. win_ver_ofst: 10, polarity_pclk: 1, polarity_href: 1, reset_type: CAMIF_EX_RESET_AL, reset_udelay:2000,#endif};camif_cfg_t * get_camif(int nr){ camif_cfg_t *ret = NULL; switch(nr) { case CODEC_MINOR: ret = &fimc[0]; break; case PREVIEW_MINOR: ret = &fimc[1]; break; default: panic("Unknow Minor Number \n"); } return ret;}static int camif_codec_start(camif_cfg_t *cfg){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin int ret = 0; ret =camif_check_preview(cfg); switch(ret) { case 0: /* Play alone */ DPRINTK("Start Alone \n"); camif_4fsm_start(cfg); cfg->gc->status |= C_WORKING; break; case -ERESTARTSYS: /* Busy , retry */ //DPRINTK("Error \n"); printk("Error \n"); break; case 1: DPRINTK("need callback \n"); ret = camif_callback_start(cfg); if(ret < 0 ) { printk(KERN_INFO "Busy RESTART \n"); return ret; /* Busy, retry */ } break; } DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return ret;}ssize_t camif_write (struct file *f, const char *b, size_t c,loff_t *offset){ camif_cfg_t *cfg; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin c = 0; /* return value */ DPRINTK("\n"); cfg = get_camif(MINOR(f->f_dentry->d_inode->i_rdev)); //printk("Debug 0 \n"); //lovejin switch (*b) { case 'O': if (cfg->dma_type & CAMIF_PREVIEW) { if (cfg->gc->status & C_WORKING) { camif_start_c_with_p(cfg,get_camif(CODEC_MINOR)); } else { camif_4fsm_start(cfg); } } else{ c = camif_codec_start(cfg); if(c < 0) c = 1; /* Error and neet to retry */ } break; case 'X': camif_p_stop(cfg); break; default: panic("CAMERA:camif_write: Unexpected Param\n"); } DPRINTK("end\n"); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return c;}ssize_t camif_p_read(struct file *file, char *buf, size_t count, loff_t *pos){ camif_cfg_t *cfg = NULL; size_t end; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin cfg = get_camif(MINOR(file->f_dentry->d_inode->i_rdev)); cfg->status = CAMIF_STARTED; //printk("============= camif_p_read ===============\n"); //print_pregs(); //printk("PRIORITY = 0x%08x\n", rPRIORITY); //printk("RTCCON = 0x%08x\n", rRTCCON); //printk("TICNT = 0x%08x\n", rTICNT); //printk("CLKCON = 0x%08x\n", rCLKCON); if (wait_event_interruptible(cfg->waitq,cfg->status == CAMIF_INT_HAPPEN)) return -ERESTARTSYS; cfg->status = CAMIF_STOPPED; end = min_t(size_t, cfg->pp_totalsize /cfg->pp_num, count); if (copy_to_user(buf, camif_g_frame(cfg), end)) return -EFAULT; DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return end;}static ssize_t camif_c_read(struct file *file, char *buf, size_t count, loff_t *pos){ camif_cfg_t *cfg = NULL; size_t end; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin /* cfg = file->private_data; */ cfg = get_camif(MINOR(file->f_dentry->d_inode->i_rdev));#if 0 if(file->f_flags & O_NONBLOCK) { printk(KERN_ERR"Don't Support NON_BLOCK \n"); }#endif /* Change the below wait_event_interruptible func */ if (wait_event_interruptible(cfg->waitq,cfg->status == CAMIF_INT_HAPPEN)) return -ERESTARTSYS; cfg->status = CAMIF_STOPPED; end = min_t(size_t, cfg->pp_totalsize /cfg->pp_num, count); if (copy_to_user(buf, camif_g_frame(cfg), end)) return -EFAULT; DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return end;}static void camif_c_irq(int irq, void *dev_id, struct pt_regs *regs){ camif_cfg_t *cfg = (camif_cfg_t *)dev_id; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin DPRINTK("\n"); camif_g_fifo_status(cfg); camif_g_frame_num(cfg); if(camif_enter_c_4fsm(cfg) == INSTANT_SKIP) return; wake_up_interruptible(&cfg->waitq); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}//static void camif_p_irq(int irq, void *dev_id, struct pt_regs * regs)static int camif_p_irq(int irq, void *dev_id, struct pt_regs * regs){ camif_cfg_t *cfg = (camif_cfg_t *)dev_id; //DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin //DPRINTK("\n"); //printk("camif_p_irq() IRQ %d\n",irq); // lovejin camif_g_fifo_status(cfg); camif_g_frame_num(cfg); if(camif_enter_p_4fsm(cfg) == INSTANT_SKIP) return -1; wake_up_interruptible(&cfg->waitq);#if 0 if( (cfg->perf.frames % 5) == 0) DPRINTK("5\n");#endif //DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}static void camif_release_irq(camif_cfg_t *cfg){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin disable_irq(cfg->irq); free_irq(cfg->irq, cfg); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}static int camif_irq_request(camif_cfg_t *cfg){ int ret = 0; DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if (cfg->dma_type & CAMIF_CODEC) { DEBUG1("\tirq %d \n",cfg->irq); //lovejin if ((ret = request_irq(cfg->irq, camif_c_irq, SA_INTERRUPT,cfg->shortname, cfg))) { printk("request_irq(CAM_C) failed.\n"); } } //print_pregs(); if (cfg->dma_type & CAMIF_PREVIEW) { DEBUG1("\tirq %d \n",cfg->irq); //lovejin if ((ret = request_irq(cfg->irq, camif_p_irq, SA_INTERRUPT,cfg->shortname, cfg))) { printk("request_irq(CAM_P) failed. ret = %d\n", ret); } } DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}static void camif_init_sensor(camif_cfg_t *cfg){#if 0 camif_gc_t *gc = cfg->gc; if (!gc->decoder) panic("CAMERA:I2C Client(Img Sensor)Not registered\n"); if(!gc->init_sensor) { camif_reset(gc->reset_type, gc->reset_udelay); gc->sensor->driver->command(gc->sensor,SENSOR_INIT,NULL); gc->init_sensor = 1; /*sensor init done */ } gc->sensor->driver->command(gc->sensor, USER_ADD, NULL);#else DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin printk("camif_init_sensor: do nothing!!\n"); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin#endif}static int camif_open(struct inode *inode, struct file *file){ int err; camif_cfg_t * cfg = get_camif(MINOR(inode->i_rdev)); DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin if(cfg->dma_type & CAMIF_PREVIEW) { if(down_interruptible(&cfg->gc->lock)) return -ERESTARTSYS; if (cfg->dma_type & CAMIF_PREVIEW) { cfg->gc->status &= ~PNOTWORKING; } up(&cfg->gc->lock); } err = video_exclusive_open(inode,file); cfg->gc->user++; cfg->status = CAMIF_STOPPED; if (err < 0) return err; if (file->f_flags & O_NONCAP ) { printk("Don't Support Non-capturing open \n"); return 0; } file->private_data = cfg; camif_irq_request(cfg); camif_init_sensor(cfg); // additional setting for video setting // It setting GPIO, GPG7 to High //rGPGCON &= ~(11 << 14); //rGPGCON |= (1 << 14); //rGPGDAT |= (1 << 7 ); //printk("\tcamera if open GPG7 Setting --\n"); //printk("\tGPGCON is 0x%08x\n", rGPGCON); //printk("\tGPGDAT is 0x%08x\n", rGPGDAT); //printk("turn on camera of wallpad power - 1\n"); //rGPEDAT |= ( 1 << 11 ); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin return 0;}#if 1static void print_pregs(void){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin printk("\tCISRCFMT 0x%08X \n", rCISRCFMT); printk("\tCIWDOFST 0x%08X \n", rCIWDOFST); printk("\tCIGCTRL 0x%08X \n", rCIGCTRL); printk("\tCIPRTRGFMT 0x%08X \n", rCIPRTRGFMT); printk("\tCIPRCTRL 0x%08X \n", rCIPRCTRL); printk("\tCIPRSCPRERATIO 0x%08X \n", rCIPRSCPRERATIO); printk("\tCIPRSCPREDST 0x%08X \n", rCIPRSCPREDST); printk("\tCIPRSCCTRL 0x%08X \n", rCIPRSCCTRL); printk("\tCIPRTAREA 0x%08X \n", rCIPRTAREA); printk("\tCIPRSTATUS 0x%08X \n", rCIPRSTATUS); printk("\tCIIMGCPT 0x%08X \n", rCIIMGCPT); DEBUG0("[ %s() E ]\n",__FUNCTION__); // lovejin}static void print_cregs(void){ DEBUG0("[ %s() S ]\n",__FUNCTION__); // lovejin printk("\tCISRCFMT 0x%08X \n", rCISRCFMT); printk("\tCIWDOFST 0x%08X \n", rCIWDOFST); printk("\tCIGCTRL 0x%08X \n", rCIGCTRL); printk("\tCICOCTRL 0x%8X \n", rCICOCTRL); printk("\tCICOSCPRERATIO 0x%08X \n", rCICOSCPRERATIO); printk("\tCICOSCPREDST 0x%08X \n", rCICOSCPREDST); printk("\tCICOSCCTRL 0x%08X \n", rCICOSCCTRL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -