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 #include <linux/kernel.h>
00024 #include <linux/sched.h>
00025 #include <linux/mm.h>
00026 //#include <linux/tqueue.h>
00027 #include <linux/wait.h>
00028 
00029 #include <asm/unistd.h>
00030 #include <asm/semaphore.h>
00031 //#include <asm/smplock.h>
00032 #include <asm/atomic.h>
00033 
00034 #include <linux/module.h>
00035 #include <linux/slab.h>
00036 #include <linux/errno.h>
00037 #include <linux/fs.h>
00038 #include <linux/string.h>
00039 #include <linux/init.h>
00040 #include <linux/mm.h>
00041 //#include <linux/iobuf.h>
00042 //#include <linux/compatmac.h>
00043 #include <linux/vmalloc.h>
00044 #include <linux/rwsem.h>
00045 
00046 #include <linux/netdevice.h>
00047 #include <linux/skbuff.h>
00048 #include <linux/time.h>
00049 #include <linux/wait.h>
00050 #include <asm/io.h>
00051 #include <asm/atomic.h>
00052 #include <asm/page.h>
00053 //#include <linux/wrapper.h>
00054 
00055 #include "fpgactrl.h"  // defines port_csp0_addr, port_csp4_addr 
00056 
00057 #include <asm/elphel/c313a.h>
00058 #include <asm/elphel/hist.h>
00059 #include <asm/elphel/autoexp.h>
00060 
00061 #include "cc3x3.h"
00062 #include "cxdma.h"
00063 #include "x3x3.h"
00064 #include "hist.h"
00065 #include "fpga_io.h"
00066 
00067 //#include "helper.h"
00068 
00069 #define STREAM_MAJOR 127
00070 
00071 #if ELPHEL_DEBUG
00072  #define MD1(x) printk("%s:%d:",__FILE__,__LINE__);x
00073   //#define MD1(x)
00074 #else
00075   #define MD1(x)
00076 #endif
00077 
00078 
00079 
00080 /*******************************************************************************
00081  *
00082  * "stream" - faked device, for controlling instances of streamer, and running status
00083  *
00084  */
00085 
00086 DECLARE_MUTEX(stream_lock);
00087 static int stream__open(struct inode *inode, struct file *filp);
00088 static int stream__ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
00089 static int stream__release(struct inode *inode, struct file *filp);
00090 
00091 static struct file_operations stream__fops = {
00092         owner:          THIS_MODULE,
00093         open:           stream__open,
00094         ioctl:          stream__ioctl,
00095         release:        stream__release,
00096 };
00097 
00098 struct stream_ctx_t {
00099         int fps_flag;
00100         unsigned long p_fp100s;
00101         unsigned long p_fpslm;
00102 };
00103 
00104 int stream__open(struct inode *inode, struct file *filp) {
00105         filp->private_data = NULL;
00106         if(down_trylock(&stream_lock)) {
00107 //              printk("/dev/stream: open() - fail, busy\r\n");
00108                 return -EBUSY;
00109         }
00110 //      printk("/dev/stream: open()\r\n");
00111         // init context
00112         filp->private_data = (struct stream_ctx_t *)kmalloc(sizeof(struct stream_ctx_t), GFP_ATOMIC);
00113         struct stream_ctx_t *ctx = (struct stream_ctx_t *)filp->private_data;
00114         ctx->fps_flag = 0;
00115         return 0;
00116 }
00117 
00118 static int stream__ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) {
00119         unsigned char *qtable[128];
00120         struct stream_ctx_t *ctx = (struct stream_ctx_t *)filp->private_data;
00121         unsigned long get_time_rez[4];
00122         struct timeval sys_1, sys_2;
00123 
00124         switch(_IOC_TYPE(cmd)) {
00125         case IOC_STREAM_SET_FPS:
00126                 ctx->fps_flag = 1;
00127                 ctx->p_fp100s = get_imageParamsR(P_FP100S);
00128                 ctx->p_fpslm = get_imageParamsR(P_FPSLM);
00129 printk("P_FPSLM read == 0x%08lX\n", ctx->p_fpslm);
00130                 ctx->p_fpslm = get_imageParamsW(P_FPSLM);
00131 printk("P_FPSLM write == 0x%08lX\n", ctx->p_fpslm);
00132                 set_imageParamsW(P_FP100S, arg);
00133                 set_imageParamsW(P_FPSLM, 0x03);
00134                 set_imageParamsR(P_FP100S, arg);
00135                 set_imageParamsR(P_FPSLM, 0x03);
00136                 program_sensor_exposition_just();
00137 /*
00138 //              program_exposure_mt9x001();
00139                 int c = 0;
00140                 while(program_sensor_exposition() == -1) {
00141                         yield();
00142                         c++;
00143                         if(c > 256)
00144                                 break;
00145                 }
00146 */
00147                 break;
00148         case IOC_STREAM_GET_QTABLES:
00149                 jpeg_set_quality(_IOC_NR(cmd), QTABLES_TABLE, (void *)&qtable[0]);
00150                 copy_to_user((void *)arg, (void *)&qtable[0], 128);
00151                 break;
00152         case IOC_STREAM_GET_TIME:
00153                 do_gettimeofday(&sys_1);
00154                 // read FPGA time
00155                 port_csp0_addr[X313_WA_RTC_LATCH] = 0xFF;
00156                 get_time_rez[2] = port_csp0_addr[X313_RA_RTC_SEC];
00157                 get_time_rez[3] = port_csp0_addr[X313_RA_RTC_USEC];
00158                 do_gettimeofday(&sys_2);
00159                 unsigned long delta;
00160                 if(sys_2.tv_sec != sys_1.tv_sec)
00161                         sys_2.tv_usec += 1000000;
00162                 delta = sys_2.tv_usec - sys_1.tv_usec;
00163                 sys_1.tv_usec += delta / 2;
00164                 if(sys_1.tv_usec >= 1000000) {
00165                         sys_1.tv_usec -= 1000000;
00166                         sys_1.tv_sec -= 1;
00167                 }
00168                 get_time_rez[0] = sys_1.tv_sec;
00169                 get_time_rez[1] = sys_1.tv_usec;
00170                 copy_to_user((void *)arg, (void *)&get_time_rez[0], 4 * sizeof(unsigned long));
00171                 break;
00172         }
00173         return 0;
00174 }
00175 
00176 int stream__release(struct inode *inode, struct file *filp) {
00177         if(filp->private_data != NULL) {
00178                 struct stream_ctx_t *ctx = (struct stream_ctx_t *)filp->private_data;
00179                 // release context
00180                 if(ctx->fps_flag) {
00181                         set_imageParamsR(P_FP100S, ctx->p_fp100s);
00182                         set_imageParamsR(P_FPSLM, ctx->p_fpslm);
00183                 }
00184                 kfree(filp->private_data);
00185         }
00186 //      printk("/dev/stream: release()\r\n");
00187         up(&stream_lock);
00188         return 0;
00189 }
00190 
00191 
00192 /*******************************************************************************
00193  *
00194  * init
00195  */
00196 
00197 static int __init stream__init(void) {
00198         int res = register_chrdev(STREAM_MAJOR, "stream", &stream__fops);
00199         return res;
00200 }
00201 
00202 static void __exit stream__exit(void) {
00203         unregister_chrdev(STREAM_MAJOR, "stream");
00204 }
00205 
00206 module_init(stream__init);
00207 module_exit(stream__exit);

Generated on Thu Aug 7 16:19:00 2008 for elphel by  doxygen 1.5.1