os/linux-2.6-tag--devboard-R2_10-4/arch/cris/arch-v32/drivers/elphel/stream.c

Go to the documentation of this file.
00001 /*
00002  * stream faked device for some io controls
00003  *
00004  *  This program is free software: you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation, either version 3 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  *
00017  * Copyright (C) 2005-2008 Elphel, Inc
00018  *
00019  * Author: Mykhailo Malyshko <spectr@gmail.com>
00020  *
00021  */
00022 
00023 
00024 
00025 
00026 #include <linux/kernel.h>
00027 #include <linux/sched.h>
00028 #include <linux/mm.h>
00029 //#include <linux/tqueue.h>
00030 #include <linux/wait.h>
00031 
00032 #include <asm/unistd.h>
00033 #include <asm/semaphore.h>
00034 //#include <asm/smplock.h>
00035 #include <asm/atomic.h>
00036 
00037 #include <linux/module.h>
00038 #include <linux/slab.h>
00039 #include <linux/errno.h>
00040 #include <linux/fs.h>
00041 #include <linux/string.h>
00042 #include <linux/init.h>
00043 #include <linux/mm.h>
00044 //#include <linux/iobuf.h>
00045 //#include <linux/compatmac.h>
00046 #include <linux/vmalloc.h>
00047 #include <linux/rwsem.h>
00048 
00049 #include <linux/netdevice.h>
00050 #include <linux/skbuff.h>
00051 #include <linux/time.h>
00052 #include <linux/wait.h>
00053 #include <asm/io.h>
00054 #include <asm/atomic.h>
00055 #include <asm/page.h>
00056 //#include <linux/wrapper.h>
00057 
00058 
00059 #include <asm/elphel/driver_numbers.h>
00060 #include <asm/elphel/c313a.h>
00061 #include <asm/elphel/hist.h>
00062 #include <asm/elphel/autoexp.h>
00063 
00064 #include "fpgactrl.h"  // defines port_csp0_addr, port_csp4_addr // just for the FPGA time
00065 #include "quantization_tables.h" // get_gtables()
00066 
00067 //#include "cc3x3.h"
00068 #include "framepars.h"
00069 #include "cxdma.h"
00070 #include "jpeghead.h"
00071 #include "x3x3.h"
00072 //#include "hist.h"
00073 #include "fpga_io.h"
00074 
00075 //#include "helper.h"
00076 
00077 
00078 #if ELPHEL_DEBUG
00079  #define MD1(x) printk("%s:%d:",__FILE__,__LINE__);x
00080   //#define MD1(x)
00081 #else
00082   #define MD1(x)
00083 #endif
00084 
00085 
00086 
00087 /*******************************************************************************
00088  *
00089  * "stream" - faked device, for controlling instances of streamer, and running status
00090  *
00091  */
00092 
00093 DECLARE_MUTEX(stream_lock);
00094 static int stream__open(struct inode *inode, struct file *filp);
00095 static int stream__ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
00096 static int stream__release(struct inode *inode, struct file *filp);
00097 
00098 static struct file_operations stream__fops = {
00099         owner:          THIS_MODULE,
00100         open:           stream__open,
00101         ioctl:          stream__ioctl,
00102         release:        stream__release,
00103 };
00104 
00105 struct stream_ctx_t {
00106         int fps_flag;
00107         unsigned long p_fp1000slim;
00108         unsigned long p_fpsflags;
00109 };
00110 
00111 int stream__open(struct inode *inode, struct file *filp) {
00112         filp->private_data = NULL;
00113         if(down_trylock(&stream_lock)) {
00114 //              printk("/dev/stream: open() - fail, busy\r\n");
00115                 return -EBUSY;
00116         }
00117 //      printk("/dev/stream: open()\r\n");
00118         // init context
00119         filp->private_data = (struct stream_ctx_t *)kmalloc(sizeof(struct stream_ctx_t), GFP_ATOMIC);
00120         struct stream_ctx_t *ctx = (struct stream_ctx_t *)filp->private_data;
00121         ctx->fps_flag = 0;
00122         return 0;
00123 }
00124 
00125 static int stream__ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) {
00126 //      unsigned char *qtable[128];
00127         struct stream_ctx_t *ctx = (struct stream_ctx_t *)filp->private_data;
00128         unsigned long get_time_rez[4];
00129         struct timeval sys_1, sys_2;
00130 
00131         switch(_IOC_TYPE(cmd)) {
00132         case IOC_STREAM_SET_FPS:
00133                 ctx->fps_flag = 1;
00134                 ctx->p_fp1000slim = get_imageParamsThis(P_FP1000SLIM);
00135                 ctx->p_fpsflags = get_imageParamsThis(P_FPSFLAGS);
00136                setFramePar(&framepars[getThisFrameNumber() & PARS_FRAMES_MASK], P_FP1000SLIM,  arg);
00137                setFramePar(&framepars[getThisFrameNumber() & PARS_FRAMES_MASK], P_FPSFLAGS,  3); 
00138 
00139                 break;
00140 
00141 
00143         case IOC_STREAM_GET_TIME:
00144                 do_gettimeofday(&sys_1);
00145                 // read FPGA time
00146                 X313_GET_FPGA_TIME(get_time_rez[2], get_time_rez[3] );
00147 
00148                 do_gettimeofday(&sys_2);
00149                 unsigned long delta;
00150                 if(sys_2.tv_sec != sys_1.tv_sec)
00151                         sys_2.tv_usec += 1000000;
00152                 delta = sys_2.tv_usec - sys_1.tv_usec;
00153                 sys_1.tv_usec += delta / 2;
00154                 if(sys_1.tv_usec >= 1000000) {
00155                         sys_1.tv_usec -= 1000000;
00156                         sys_1.tv_sec -= 1;
00157                 }
00158                 get_time_rez[0] = sys_1.tv_sec;
00159                 get_time_rez[1] = sys_1.tv_usec;
00160                 copy_to_user((void *)arg, (void *)&get_time_rez[0], 4 * sizeof(unsigned long));
00161                 break;
00162         }
00163         return 0;
00164 }
00165 
00166 int stream__release(struct inode *inode, struct file *filp) {
00167         if(filp->private_data != NULL) {
00168                 struct stream_ctx_t *ctx = (struct stream_ctx_t *)filp->private_data;
00169                 // release context
00170                 if(ctx->fps_flag) {
00171                    setFramePar(&framepars[getThisFrameNumber() & PARS_FRAMES_MASK], P_FP1000SLIM,  ctx->p_fp1000slim);
00172                    setFramePar(&framepars[getThisFrameNumber() & PARS_FRAMES_MASK], P_FPSFLAGS,  ctx->p_fpsflags);
00173 
00174                 }
00175                 kfree(filp->private_data);
00176         }
00177 //      printk("/dev/stream: release()\r\n");
00178         up(&stream_lock);
00179         return 0;
00180 }
00181 
00182 
00183 /*******************************************************************************
00184  *
00185  * init
00186  */
00187 
00188 static int __init stream__init(void) {
00189         int res = register_chrdev(STREAM_MAJOR, "stream", &stream__fops);
00190         return res;
00191 }
00192 
00193 static void __exit stream__exit(void) {
00194         unregister_chrdev(STREAM_MAJOR, "stream");
00195 }
00196 
00197 module_init(stream__init);
00198 module_exit(stream__exit);

Generated on Fri Nov 28 00:06:23 2008 for elphel by  doxygen 1.5.1