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

Go to the documentation of this file.
00001 /*!********************************************************************************
00002 *! FILE NAME  : framepars.c
00003 *! DESCRIPTION: Handling of frame parameters, making use of FPGA i2c
00004 *! and command sequencer that accepts commands up to 6 frames ahead.
00005 *! This module includes parameter storage, code called from ISR,
00006 *! from other kernel drivers as well as from the user space
00007 *! Copyright (C) 2008 Elphel, Inc.
00008 *! -----------------------------------------------------------------------------**
00009 *!
00010 *!  This program is free software: you can redistribute it and/or modify
00011 *!  it under the terms of the GNU General Public License as published by
00012 *!  the Free Software Foundation, either version 3 of the License, or
00013 *!  (at your option) any later version.
00014 *!
00015 *!  This program is distributed in the hope that it will be useful,
00016 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 *!  GNU General Public License for more details.
00019 *!senssensor_common.hor_common.h
00020 *!  You should have received a copy of the GNU General Public License
00021 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00022 *! -----------------------------------------------------------------------------**
00023 *!  $Log: framepars.c,v $
00024 *!  Revision 1.1.1.1  2008/11/27 20:04:00  elphel
00025 *!
00026 *!
00027 *!  Revision 1.41  2008/11/17 06:42:37  elphel
00028 *!  added SETFRAMEREL - skipping specified number of frames from current (through lseek)
00029 *!
00030 *!  Revision 1.40  2008/11/14 07:09:48  elphel
00031 *!  additional test to prevent "JUST_THIS" parameters to be written to the future-most frame (otherwise it can get stuck)
00032 *!
00033 *!  Revision 1.39  2008/11/13 05:40:45  elphel
00034 *!  8.0.alpha16 - modified histogram storage, profiling
00035 *!
00036 *!  Revision 1.38  2008/11/05 02:01:25  elphel
00037 *!  Added bit field manipulation in parameters
00038 *!
00039 *!  Revision 1.37  2008/11/02 00:31:25  elphel
00040 *!  reduced required initialization steps
00041 *!
00042 *!  Revision 1.36  2008/10/29 04:18:28  elphel
00043 *!  v.8.0.alpha10 made a separate structure for global parameters (not related to particular frames in a frame queue)
00044 *!
00045 *!  Revision 1.35  2008/10/25 19:59:48  elphel
00046 *!  added lseek() calls to enable/disable daemons at events (compressed frame available, any frame available, histogram-Y and histograms-C available)
00047 *!
00048 *!  Revision 1.34  2008/10/23 18:25:40  elphel
00049 *!  removed unneeded test condition before calling wait_event_interruptible()
00050 *!
00051 *!  Revision 1.33  2008/10/23 08:03:38  elphel
00052 *!  cleanup
00053 *!
00054 *!  Revision 1.32  2008/10/21 21:28:26  elphel
00055 *!  minor bug fix
00056 *!
00057 *!  Revision 1.31  2008/10/20 18:46:36  elphel
00058 *!  all the functions for the same target frame are processed in the order regardless of latencies
00059 *!
00060 *!  Revision 1.30  2008/10/19 06:51:51  elphel
00061 *!  rearranged initialization, added frame number reset (to avoid unlikely integer overflow)
00062 *!
00063 *!  Revision 1.29  2008/10/17 05:44:48  elphel
00064 *!  fixing latencies
00065 *!
00066 *!  Revision 1.28  2008/10/15 22:28:56  elphel
00067 *!  snapshot 8.0.alpha2
00068 *!
00069 *!  Revision 1.27  2008/10/12 06:13:10  elphel
00070 *!  snapshot
00071 *!
00072 *!  Revision 1.26  2008/10/11 18:46:07  elphel
00073 *!  snapshot
00074 *!
00075 *!  Revision 1.25  2008/10/10 17:06:59  elphel
00076 *!  just a snapshot
00077 *!
00078 *!  Revision 1.24  2008/10/08 21:26:25  elphel
00079 *!  snapsot 7.2.0.pre4 - first images (actually - second)
00080 *!
00081 *!  Revision 1.23  2008/10/06 08:31:08  elphel
00082 *!  snapshot, first images
00083 *!
00084 *!  Revision 1.22  2008/10/05 05:13:33  elphel
00085 *!  snapshot003
00086 *!
00087 *!  Revision 1.21  2008/10/04 16:10:12  elphel
00088 *!  snapshot
00089 *!
00090 *!  Revision 1.20  2008/09/28 00:31:57  elphel
00091 *!  snapshot
00092 *!
00093 *!  Revision 1.19  2008/09/25 00:58:11  elphel
00094 *!  snapshot
00095 *!
00096 *!  Revision 1.18  2008/09/20 00:29:50  elphel
00097 *!  moved driver major/minor numbers to a single file - include/asm-cris/elphel/driver_numbers.h
00098 *!
00099 *!  Revision 1.17  2008/09/19 04:37:25  elphel
00100 *!  snapshot
00101 *!
00102 *!  Revision 1.16  2008/09/16 00:49:31  elphel
00103 *!  snapshot
00104 *!
00105 *!  Revision 1.15  2008/09/12 20:40:11  elphel
00106 *!  snapshot
00107 *!
00108 *!  Revision 1.14  2008/09/12 00:28:54  elphel
00109 *!  typo fixed
00110 *!
00111 *!  Revision 1.13  2008/09/12 00:23:59  elphel
00112 *!  removed cc353.c, cc353.h
00113 *!
00114 *!  Revision 1.12  2008/09/07 19:48:08  elphel
00115 *!  snapshot
00116 *!
00117 *!  Revision 1.11  2008/09/05 23:20:26  elphel
00118 *!  just a snapshot
00119 *!
00120 *!  Revision 1.10  2008/09/04 17:37:13  elphel
00121 *!  documenting
00122 *!
00123 *!  Revision 1.9  2008/09/02 21:01:06  elphel
00124 *!  just next...
00125 *!
00126 *!  Revision 1.8  2008/07/27 04:27:49  elphel
00127 *!  next snapshot
00128 *!
00129 *!  Revision 1.7  2008/06/24 00:43:44  elphel
00130 *!  just a snapshot
00131 *!
00132 *!  Revision 1.6  2008/06/20 03:54:19  elphel
00133 *!  another snapshot
00134 *!
00135 *!  Revision 1.5  2008/06/19 02:17:36  elphel
00136 *!  continuing work - just a snapshot
00137 *!
00138 *!  Revision 1.4  2008/06/16 06:51:21  elphel
00139 *!  work in progress, intermediate commit
00140 *!
00141 *!  Revision 1.3  2008/06/10 00:03:14  elphel
00142 *!  storing past frame data - subset of the frame parameters
00143 *!
00144 *!  Revision 1.2  2008/06/08 23:48:39  elphel
00145 *!  minor cleanup
00146 *!
00147 *!  Revision 1.1  2008/05/26 23:33:00  elphel
00148 *!  Added driver to handle multi-frame parameters
00149 *!
00150 *!
00151 */
00152 
00153 //copied from cxi2c.c - TODO:remove unneeded
00154 
00155 
00156 #include <linux/types.h> 
00157 #include <asm/div64.h>  
00158 
00159 
00160 #include <linux/module.h>
00161 #include <linux/mm.h>
00162 #include <linux/sched.h>
00163 #include <linux/slab.h>
00164 #include <linux/errno.h>
00165 #include <linux/kernel.h>
00166 #include <linux/fs.h>
00167 #include <linux/string.h>
00168 #include <linux/init.h>
00169 #include <linux/autoconf.h>
00170 #include <linux/vmalloc.h>
00171 
00172 #include <asm/system.h>
00173 #include <asm/byteorder.h> // endians
00174 #include <asm/io.h>
00175 
00176 #include <asm/irq.h>
00177 
00178 #include <asm/delay.h>
00179 #include <asm/uaccess.h>
00180 #include <asm/elphel/driver_numbers.h>
00181 #include <asm/elphel/c313a.h>
00182 #include <asm/elphel/exifa.h>
00183 #include "fpgactrl.h"  // defines port_csp0_adsensor_common.hdr, port_csp4_addr 
00184 //#include "cc3x3.h"
00185 #include "x3x3.h"           // hardware definitions
00186 
00187 
00188 #include "sensor_common.h"
00189 #include "framepars.h"
00190 #include "param_depend.h" // specifies what functions should be called for different parameters changed
00192 #include "cxdma.h" // x313_dma_init
00193 
00198 #if ELPHEL_DEBUG
00199  #define MDF(x) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;}
00200  #define MDF2(x) { if (GLOBALPARS(G_DEBUG) & (1 <<2)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;} }
00202  #define MDF5(x) { if (GLOBALPARS(G_DEBUG) & (1 <<5)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;} }
00203  #define   D5(x) { if (GLOBALPARS(G_DEBUG) & (1 <<5)) {x ;} }
00205  #define MDF6(x) { if (GLOBALPARS(G_DEBUG) & (1 <<6)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;} }
00206  #define   D6(x) { if (GLOBALPARS(G_DEBUG) & (1 <<6)) {x ;} }
00208  #define MDF7(x) { if (GLOBALPARS(G_DEBUG) & (1 <<7)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;} }
00209  #define   D7(x) { if (GLOBALPARS(G_DEBUG) & (1 <<7)) {x ;} }
00211  #define MDF8(x) { if (GLOBALPARS(G_DEBUG) & (1 <<8)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;} }
00212  #define   D8(x) { if (GLOBALPARS(G_DEBUG) & (1 <<8)) {x ;} }
00213  #define ELPHEL_DEBUG_THIS 0
00214 // #define ELPHEL_DEBUG_THIS 1
00215 #else
00216  #define MDF(x)
00217  #define MDF2(x)
00218  #define MDF5(x)
00219  #define D5(x)
00220  #define MDF6(x)
00221  #define D6(x)
00222  #define MDF7(x)
00223  #define D7(x)
00224  #define ELPHEL_DEBUG_THIS 0
00225 #endif
00226 
00227 
00228 #if ELPHEL_DEBUG_THIS
00229   #define MDD1(x) printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__); x ; udelay (ELPHEL_DEBUG_DELAY)
00230   #define MDF1(x) printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__); x
00231   #define D1(x) x
00232   #define D1I(x)
00233 
00234 #else
00235   #define MDD1(x)
00236   #define MDF1(x)
00237   #define D1(x)
00238   #define D1I(x) x
00239 #endif
00240 //#define ELP_KERR(x) printk("%s:%d:%s: ERROR ",__FILE__,__LINE__,__FUNCTION__); x
00241 
00246 #define  X3X3_FRAMEPARS_DRIVER_NAME "Elphel (R) Model 353 Frame Parameters device driver"
00247 
00248 static struct framepars_all_t sFrameParsAll __attribute__ ((aligned (PAGE_SIZE)));   
00249 unsigned long frameParsInitialized; 
00250 #define  thisFrameNumber GLOBALPARS(G_THIS_FRAME) // Current frame number (may lag from the hardware)
00251 #define  THISFRAMENUMBER GLOBALPARS(G_THIS_FRAME) // Current frame number (may lag from the hardware)
00252 
00253 struct framepars_all_t  *frameparsall=NULL; 
00254 struct framepars_t      *framepars=   NULL; 
00255 struct framepars_past_t *pastpars=    NULL; 
00256 unsigned long           *funcs2call=  NULL; 
00257 unsigned long           *globalPars=  NULL; 
00258 
00259 wait_queue_head_t framepars_wait_queue; 
00260 
00261 
00265 struct framepars_pd {
00266     int                minor; 
00267     struct wait_queue *framepars_wait_queue; 
00268 // something else to be added here?
00269 };
00270 
00271 
00272 
00276 void init_framepars_ptr(void) {
00277     frameparsall=&sFrameParsAll; 
00278     framepars = sFrameParsAll.framePars;
00279     pastpars =  sFrameParsAll.pastPars;
00280     funcs2call =sFrameParsAll.func2call.pars; 
00281     globalPars =sFrameParsAll.globalPars; 
00282 }
00283 
00284 int        framepars_open   (struct inode *inode, struct file *filp);
00285 int        framepars_release(struct inode *inode, struct file *filp);
00286 loff_t     framepars_lseek  (struct file * file, loff_t offset, int orig);
00287 ssize_t    framepars_write  (struct file * file, const char * buf, size_t count, loff_t *off);
00288 int        framepars_mmap   (struct file *file, struct vm_area_struct *vma);
00289 static int __init framepars_init(void);
00290 
00294 void initSequencers(void) {
00295   MDF2(printk ("\n"));
00296   X3X3_SEQ_RESET;
00297   X3X3_I2C_RESET_WAIT;
00298   initFramePars();
00299 }
00300 
00301 
00305 void resetFrameNumber(void) {
00306    int i;
00307    thisFrameNumber= X3X3_I2C_FRAME;
00308   MDF2(printk ("\n"));
00309 // write absolute frame numbers
00310    for (i=thisFrameNumber; i<(thisFrameNumber+PARS_FRAMES); i++) framepars[i & PARS_FRAMES_MASK].pars[P_FRAME]=i;
00312 }
00313 
00317 void initFramePars(void) {
00318    int i;
00319    memset(framepars, 0, sizeof(framepars));
00320    resetFrameNumber();
00322    for (i=0; i < (sizeof(param_depend_tab)/8); i++) funcs2call[param_depend_tab[2*i]]=param_depend_tab[2*i+1];
00323    for (i=0; i < P_SENSOR_NUMREGS; i++)    funcs2call[P_SENSOR_REGS+i] = ONCHANGE_SENSORREGS; 
00324    frameParsInitialized=1;
00325 }
00326 
00330 void initGlobalPars(void) {
00331    memset(globalPars, 0, sizeof(globalPars));
00332    MDF(GLOBALPARS(G_DEBUG) = ELPHEL_DEBUG_STARTUP; printk("GLOBALPARS(G_DEBUG)=%lx\n",GLOBALPARS(G_DEBUG)));
00333 }
00334 
00335 
00341 inline unsigned long get_imageParamsThis    (int n) {
00342    return framepars[thisFrameNumber & PARS_FRAMES_MASK].pars[n] ;
00343 }
00344 
00350 inline unsigned long get_imageParamsPrev    (int n) {
00351    return framepars[(thisFrameNumber-1) & PARS_FRAMES_MASK].pars[n] ;
00352 }
00353 
00361 inline void set_imageParamsThis    (int n,unsigned long d) {
00362    framepars[thisFrameNumber & PARS_FRAMES_MASK].pars[n]=d ;
00363 }
00364 
00370 inline unsigned long get_globalParam  (int n) {
00371    return GLOBALPARS(n) ;
00372 }
00379 inline void          set_globalParam   (int n, unsigned long d) {
00380   GLOBALPARS(n)=d;
00381 }
00382 
00389 inline void          set_imageParamsR_all(int n, unsigned long d) {
00390   int i;
00391   for (i=0; i < PARS_FRAMES; i++) framepars[i].pars[n]=d;
00392 }
00393 
00395 
00405 void updateFramePars(int frame8, struct interframe_params_t * interframe_pars) {
00406   int findex_this,findex_prev,findex_future,findex_next;
00407   int index,index32;
00408   unsigned long bmask, bmask32;
00409   int pastParsIndex;
00410   while ((frame8 ^ thisFrameNumber) & PARS_FRAMES_MASK) {
00416     findex_this=  thisFrameNumber  & PARS_FRAMES_MASK;
00417     findex_prev=  (findex_this-1)  & PARS_FRAMES_MASK;
00418     findex_future= (findex_this-2)  & PARS_FRAMES_MASK; // farthest in the future
00419     findex_next=  (findex_this+1)  & PARS_FRAMES_MASK;
00423 //    pastParsIndex= thisFrameNumber & PASTPARS_SAVE_ENTRIES_MASK;
00424     pastParsIndex= (thisFrameNumber-1) & PASTPARS_SAVE_ENTRIES_MASK; 
00425 //    memcpy (pastpars[pastParsIndex].past_pars, &framepars[findex_prev].pars[PARS_SAVE_FROM], sizeof(pastpars[0].past_pars));
00426     memcpy (pastpars[pastParsIndex].past_pars, &framepars[findex_prev].pars[PARS_SAVE_FROM], PARS_SAVE_COPY<<2);
00427 
00429     if (interframe_pars) { 
00430 #if 0
00431       memcpy (interframe_pars,  &framepars[findex_prev].pars[P_GTAB_R], 24); 
00432       interframe_pars->height=  framepars[findex_prev].pars[P_ACTUAL_HEIGHT]; 
00433       interframe_pars->color=   framepars[findex_prev].pars[P_COLOR];
00434       interframe_pars->byrshift=framepars[findex_prev].pars[P_COLOR];
00435 #endif
00437       memcpy (interframe_pars,  &framepars[findex_this].pars[P_GTAB_R], 24); 
00438       interframe_pars->height=  framepars[findex_this].pars[P_ACTUAL_HEIGHT]; 
00439       interframe_pars->color=   framepars[findex_this].pars[P_COLOR];
00440       interframe_pars->byrshift=framepars[findex_this].pars[P_COMPMOD_BYRSH];
00441     }
00443     if ((bmask32=framepars[findex_prev].modsince32)) {
00444      MDF7(printk("framepars[%d].modsince32=0x%lx\n",findex_prev,bmask32));
00445       for (index32=0; bmask32; index32++, bmask32 >>= 1) {
00446          if (bmask32 & 1) {
00447            for (index=(index32<<5),bmask=framepars[findex_prev].modsince[index32]; bmask; index++, bmask >>= 1)
00448              if (bmask & 1) {
00449                framepars[findex_prev].pars[index] = framepars[findex_future].pars[index];
00450      MDF7(printk("hw=%d framepars[%d].pars[%d]=framepars[%d].pars[%d]=0x%lx\n",frame8, findex_prev,index,findex_future,index,framepars[findex_future].pars[index]));
00451              }
00452            framepars[findex_prev].modsince[index32]=0; 
00453          }
00454       }
00455       framepars[findex_prev].modsince32=0;
00456     }
00458     if (framepars[findex_prev].mod32) memset(framepars[findex_prev].mod, 0, 32*4); 
00459     framepars[findex_prev].functions=0; 
00460     framepars[findex_prev].pars[P_FRAME]=thisFrameNumber+7; 
00461 
00462     if (framepars[findex_this].functions) { 
00463       if (!(get_globalParam(G_TASKLET_CTL) & (1 << TASKLET_CTL_IGNPAST))) {
00464         framepars[findex_next].functions |= framepars[findex_this].functions;
00465         if ((bmask32=framepars[findex_this].mod32)) {
00466           for (index32=0; bmask32; index32++, bmask32 >>= 1) {
00467             if (bmask32 & 1) {
00468               framepars[findex_next].mod[index32] |= framepars[findex_this].mod[index32];
00469             }
00470             framepars[findex_next].mod32 |= framepars[findex_this].mod32;
00471           }
00472         }
00473         MDF7(printk ("resubmitting past due functions = 0x%lx for frame=%ld (0x%x)\n",framepars[findex_this].functions,thisFrameNumber,findex_this));
00474       } else {
00475         MDF(printk ("Ignored past due functions = 0x%lx for frame=%ld (0x%x)\n",framepars[findex_this].functions,thisFrameNumber,findex_this));
00476       }
00477     }
00478     thisFrameNumber++;
00479   } 
00480 }
00481 
00482 
00489 inline void processParsASAP (struct sensorproc_t * sensorproc, int frame8) {
00490   unsigned long todo, mask , remain;
00491   int pars_ahead;  
00492   int frame_proc;   
00493   struct framepars_t * procpars;
00494   struct framepars_t * prevpars ; 
00495   unsigned long * p_nasap=& GLOBALPARS(G_CALLNASAP);
00496   int i;
00497   int rslt;
00498 #if ELPHEL_DEBUG
00499   unsigned long allfunctions=framepars[0].functions  | framepars[1].functions | framepars[2].functions | framepars[3].functions |
00500                              framepars[4].functions | framepars[5].functions | framepars[6].functions | framepars[7].functions;
00501   if (allfunctions)       MDF6(printk("frame8=%d, functions: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", frame8, framepars[0].functions,framepars[1].functions,framepars[2].functions,framepars[3].functions,framepars[4].functions,framepars[5].functions,framepars[6].functions,framepars[7].functions));
00502 
00503 #endif
00506   for (pars_ahead=0; pars_ahead <= 4;  pars_ahead++ ) {
00507     frame_proc=(frame8 + pars_ahead) & PARS_FRAMES_MASK;
00508     procpars  = &framepars[frame_proc];
00509     prevpars  = &framepars[(frame_proc-1) & PARS_FRAMES_MASK];
00510     i=0;
00511     mask=1;
00512     remain=0xffffffff;
00513     while ((todo=(pars_ahead)?
00514                    (p_nasap[pars_ahead] & (procpars->functions) & remain):
00515                    (procpars->functions & remain) )) { 
00516 
00517       while (!(todo & mask)) { 
00518         i++;
00519         mask   <<=1;
00520         remain <<=1;
00521       }
00523       MDF6(printk(" todo=0x%08lx (curr=0x%08lx) frame8=%d, pars_ahead=%d, frame_proc=%d i=%d, mask=0x%08lx\n", todo, procpars->functions, frame8,pars_ahead,frame_proc,i,mask));
00524 
00525       MDF6(printk(" %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", framepars[0].functions,framepars[1].functions,framepars[2].functions,framepars[3].functions,framepars[4].functions,framepars[5].functions,framepars[6].functions,framepars[7].functions));
00526 
00527       if (sensorproc->pgm_func[i]) {
00528         rslt=sensorproc->pgm_func[i]    ( &(sensorproc->sensor), procpars, prevpars, -1);
00529       } else rslt=0; 
00530       if ((rslt >= 0) && (sensorproc->pgm_func[i+32])) { 
00531         rslt=sensorproc->pgm_func[i+32] ( &(sensorproc->sensor), procpars, prevpars, -1);
00532       }
00534       if (rslt<0) printk("%s:%d:%s - error=%d",__FILE__,__LINE__,__FUNCTION__, rslt);
00535       procpars->functions &= ~mask;
00536       MDF6(printk(".functions=0x%08lx)\n", procpars->functions));
00537       i++;
00538       mask   <<=1;
00539       remain <<=1;
00540     }
00541   }
00542 }
00544 //#define G_CALLNASAP    119 // bitmask - what functions can be used not only in the current frame (ASAP) mode 
00545 //#define G_CALLNEXT1      120 // bitmask of actions to be one   or more frames ahead of the programmed one (OR-ed with G_CALLNEXT2..G_CALLNEXT4) 
00546 //#define G_CALLNEXT2      121 // bitmask of actions to be two   or more frames ahead of the programmed one (OR-ed with G_CALLNEXT3..G_CALLNEXT4)
00547 //#define G_CALLNEXT3      122 // bitmask of actions to be three or more frames ahead of the programmed one (OR-ed with G_CALLNEXT4)
00548 //#define G_CALLNEXT4      123 // bitmask of actions to be four  or more frames ahead of the programmed one
00549 
00550 
00551 inline void processParsSeq (struct sensorproc_t * sensorproc, int frame8, int maxahead) {
00552   unsigned long todo, mask , remain;
00553   int job_ahead;   
00554   int pars_ahead;  
00555   int frame_proc;   
00556   struct framepars_t * procpars;
00557   struct framepars_t * prevpars ; 
00558   unsigned long * p_nasap=& GLOBALPARS(G_CALLNASAP);
00559   int seq_frame;  
00560   int i;
00561   int rslt;
00562   int max_par_ahead;
00563   int this_ahead;
00564   if (maxahead > (PARS_FRAMES-3)) maxahead = PARS_FRAMES-3; 
00565 
00566 
00567 
00568 
00569   for (job_ahead=0; job_ahead <= maxahead; job_ahead++ ) {
00570     max_par_ahead=min(5,(PARS_FRAMES-3) -job_ahead); 
00571     for (pars_ahead=0; pars_ahead < max_par_ahead;  pars_ahead++ ) {
00572       frame_proc=(frame8 + job_ahead + pars_ahead +1) & PARS_FRAMES_MASK; 
00573       procpars  = &framepars[frame_proc];
00575       if (procpars->functions &
00576                    p_nasap[pars_ahead] &  
00577                    p_nasap[0]) {
00578         prevpars  = &framepars[(frame_proc-1) & PARS_FRAMES_MASK];
00579 //        seq_frame=  (frame8+job_ahead+1) & PARS_FRAMES_MASK;
00580         i=0;
00581         mask=1;
00582         remain=0xffffffff;
00583         while ((todo=procpars->functions &
00585                      p_nasap[0] & remain)) { 
00586           while (!(todo & mask)) { 
00587             i++;
00588             mask   <<=1;
00589             remain <<=1;
00590           }
00593           for (this_ahead=1; (p_nasap[this_ahead] & todo & mask) && (this_ahead <=4); this_ahead++); 
00594 //          seq_frame=  (frame8 + job_ahead + this_ahead) & PARS_FRAMES_MASK;
00595           seq_frame=  (frame_proc+1-this_ahead) & PARS_FRAMES_MASK;
00596 
00597           MDF6(printk(" todo=0x%08lx (curr=0x%08lx) frame8=%d, frame_proc=%d, seq_frame=%d, i=%d, mask=0x%08lx\n", todo, procpars->functions, frame8,frame_proc,seq_frame,i,mask));
00598           MDF6(printk(" %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", framepars[0].functions,framepars[1].functions,framepars[2].functions,framepars[3].functions,framepars[4].functions,framepars[5].functions,framepars[6].functions,framepars[7].functions));
00599 
00600           if (sensorproc->pgm_func[i]) {
00602             rslt=sensorproc->pgm_func[i]    ( &(sensorproc->sensor), procpars, prevpars, seq_frame); 
00603           } else rslt=0; 
00604           if ((rslt >= 0) && (sensorproc->pgm_func[i+32])) { 
00605             rslt=sensorproc->pgm_func[i+32] ( &(sensorproc->sensor), procpars, prevpars, seq_frame);
00606           }
00607           if (rslt >= 0) {
00608             procpars->functions &= ~mask; 
00609           } else {
00610             MDF6(printk("Error - function result was %d\n", rslt));
00611           }
00612           i++;
00613           mask   <<=1;
00614           remain <<=1;
00615         }
00616       }
00617     }
00618   }
00619 }
00620 
00629 //TODO: "Do it later" should be the only reason not to erase todo bit
00630 //#define P_CALLASAP       107 // bitmask - what functions work only in the current frame (ASAP) mode 
00631 
00632 void processPars (struct sensorproc_t * sensorproc, int frame8, int maxahead) {
00633    frame8 &= PARS_FRAMES_MASK;
00635 //   MDF6(printk("before first processParsASAP\n"));
00636    processParsASAP (sensorproc, frame8);
00639 //   MDF6(printk("before processParsSeq\n"));
00640    processParsSeq (sensorproc, frame8, maxahead);
00642 //   MDF6(printk("before second processParsASAP\n"));
00643    processParsASAP (sensorproc, frame8);
00644 }
00645 
00651 void schedule_pgm_func(int frame8, int func_num) {
00652    MDF1(printk(" frame8=%d, func_num=%d\n", frame8, func_num));
00653   framepars[frame8 & PARS_FRAMES_MASK].functions |= 1 << func_num;
00654 }
00655 
00661 void schedule_this_pgm_func(struct framepars_t * this_framepars, int func_num) {
00662   int frame8=this_framepars->pars[P_FRAME] & PARS_FRAMES_MASK;
00663    MDF1(printk(" frame8=%d, func_num=%d\n", frame8, func_num));
00664   framepars[frame8].functions |= 1 << func_num;
00665 }
00666 
00667 
00672 unsigned long getThisFrameNumber(void) { 
00673   return thisFrameNumber;
00674 }
00675 
00676 
00683 int setFrameParsStatic(int numPars, struct frameparspair_t * pars) { 
00684   int npar,nframe,index;
00685   for (npar=0; npar < numPars; npar++) {
00686     index=pars[npar].num;
00687     if (index > P_MAX_PAR) return -ERR_FRAMEPARS_BADINDEX;
00688     for (nframe=0; nframe < PARS_FRAMES; nframe++) {
00689       framepars[nframe].pars[index]=pars[npar].val;
00690     }
00691   }
00692   return 0;
00693 }
00694 
00704 
00705 int setFrameParsAtomic(unsigned long frameno, int maxLatency, int numPars, struct frameparspair_t * pars) {
00706   unsigned long flags;
00707   int npar,nframe;
00708   unsigned long val, bmask, bmask32;
00709   int index,bindex;
00710   if (!frameParsInitialized) {
00711      initSequencers(); 
00712   }
00713   int findex_this=  thisFrameNumber & PARS_FRAMES_MASK;
00714   int findex_prev= (findex_this-1)  & PARS_FRAMES_MASK;
00715   int findex_future=(findex_this-2)  & PARS_FRAMES_MASK; 
00716 //  int frame8=       frameno         & PARS_FRAMES_MASK;
00717   int frame8;
00718   MDF2(printk (": frameno=0x%lx, findex_this=%d maxLatency=%d, numPars=%d\n",frameno, findex_this, maxLatency, numPars));
00719   D1I(local_irq_save(flags));
00720   PROFILE_NOW(6);
00721   if (maxLatency>=0) {
00722     if      (frameno <= (thisFrameNumber+maxLatency)) {
00723       D1I(local_irq_restore(flags));
00724       return -ERR_FRAMEPARS_TOOLATE;
00725     }
00726     else if (frameno >= (thisFrameNumber+ (PARS_FRAMES-1))) {
00727       D1I(local_irq_restore(flags));
00728       return -ERR_FRAMEPARS_TOOEARLY;
00729     }
00730   }
00732   for (npar=0; npar < numPars; npar++) {
00733     D5(printk(" --pars[%d].num=0x%lx, pars[%d].val=0x%lx",npar,pars[npar].num, npar, pars[npar].val));
00734 //    frame8=      (pars[npar].num & FRAMEPAR_GLOBALS)? -1: (frameno  & PARS_FRAMES_MASK);
00735     frame8=      frameno  & PARS_FRAMES_MASK; 
00736     val=pars[npar].val;
00737     index= pars[npar].num & 0xffff;
00738     if (index> ((index >= FRAMEPAR_GLOBALS)? (P_MAX_GPAR+FRAMEPAR_GLOBALS): P_MAX_PAR)) {
00739       D1I(local_irq_restore(flags));
00740       return -ERR_FRAMEPARS_BADINDEX;
00741     }
00742     D5(printk(" index=0x%x, val=0x%lx",index, val));
00743     if (index >= FRAMEPAR_GLOBALS) { 
00744       if (pars[npar].num & FRAMEPAIR_MASK_BYTES) { 
00745         val= FRAMEPAIR_FRAME_MASK_NEW(pars[npar].num, GLOBALPARS(index), val);
00746       }
00747       GLOBALPARS(index)=val;
00748       D5(printk(" set GLOBALPARS(0x%x)=0x%lx\n",index,val));
00749     } else if (pars[npar].num  & FRAMEPAIR_FRAME_FUNC) {
00750       funcs2call[index] = val;
00751       D5(printk(" set funcs2call[0x%x]=0x%lx\n",index,val));
00752 //    } else if ((frameno !=findex_prev) && (frameno != findex_future)) { /// do not write parameters in the future otherwise 
00753     } else if ((frame8 != findex_future) || ((pars[npar].num & FRAMEPAIR_JUST_THIS)==0)) { 
00754       if (pars[npar].num & FRAMEPAIR_MASK_BYTES) { 
00755         val= FRAMEPAIR_FRAME_MASK_NEW(pars[npar].num, framepars[frame8].pars[index], val);
00756       }
00757 //TODO: optimize to use mask several parameters together
00758       D5(printk(" frame8=0x%x\n",frame8));
00759       if ((framepars[frame8].pars[index]!= val) || (pars[npar].num & FRAMEPAIR_FORCE_NEW)){
00760         bmask=   1 << (index & 31);
00761         bindex = index >> 5;
00762         bmask32= 1 << bindex;
00764         framepars[frame8].pars[index]       = val;
00765         framepars[frame8].mod[bindex]      |= bmask;
00766         framepars[frame8].mod32            |= bmask32;
00767         framepars[frame8].functions        |= funcs2call[index]; 
00768         D5(printk(" bindex=0x%x, bmask=0x%08lx, bmask32=0x%08lx, functions=0x%08lx\n",bindex, bmask, bmask32, framepars[frame8].functions));
00770         if ((pars[npar].num & FRAMEPAIR_JUST_THIS)==0) {
00771           MDF5(printk (":        ---   setting next frames"));
00772           for (nframe=(frame8+1) & PARS_FRAMES_MASK; (nframe != findex_prev) && (!(framepars[nframe].mod[bindex] & bmask)); nframe=(nframe+1) & PARS_FRAMES_MASK) {
00773             framepars[nframe].pars[index] = val;
00774             D5(printk (" %d",nframe));
00775           }
00776           frame8=(frame8-1) & PARS_FRAMES_MASK;
00777           D5(printk ("\n"));
00778         }
00781         for (nframe=frame8; nframe != findex_future; nframe=(nframe-1) & PARS_FRAMES_MASK) { 
00782           framepars[nframe].modsince[bindex] |= bmask;
00783           framepars[nframe].modsince32       |= bmask32;
00784         }
00785       }
00786     } else { 
00787       D1I(local_irq_restore(flags));
00788       ELP_KERR(printk("Tried to write JUST_THIS parameter (0x%lx) too far in the future", pars[npar].num));
00789       return -ERR_FRAMEPARS_TOOEARLY;
00790     }
00791   }
00795   if (!(get_globalParam(G_TASKLET_CTL) & (1<< TASKLET_CTL_NOSAME))) {
00796 //    processParsSeq (sensorproc, thisFrameNumber & PARS_FRAMES_MASK, 0); ///maxahead=0, the rest will be processed after frame sync, from the tasklet
00797     MDF5(printk ("\n"));
00798     processPars (sensorproc, thisFrameNumber & PARS_FRAMES_MASK, 0); 
00799   }
00800   PROFILE_NOW(7);
00801   D1I(local_irq_restore(flags));
00802   return 0;
00803 }
00804 //#define FRAMEPAIR_JUST_THIS     0x40000 // write only to this frame, don't propagate
00805                                          // (like "single frame" - compressor, sensor) first write "stop", then - "single" with FRAMEPAIR_JUST_THIS
00814 int setFramePar(struct framepars_t * this_framepars, unsigned long mindex, unsigned long val) {
00815   int frame8=  (this_framepars->pars[P_FRAME]) & PARS_FRAMES_MASK;
00816   unsigned long flags;
00817   int nframe;
00818   unsigned long bmask, bmask32 , bindex;
00819   int findex_this=  thisFrameNumber & PARS_FRAMES_MASK;
00820   int findex_prev= (findex_this-1)  & PARS_FRAMES_MASK;
00821   int findex_future=(findex_this-2)  & PARS_FRAMES_MASK;
00822   int index=    mindex & 0xffff;
00823   MDF8(printk (": thisFrameNumber=0x%lx frame8=%d index= %d (0x%lx), val=0x%lx\n", thisFrameNumber, frame8, index, mindex, val));
00824   D1I(local_irq_save(flags));
00825 
00826 //  if (index > P_MAX_PAR) {
00827   if (index> ((index >= FRAMEPAR_GLOBALS)? (P_MAX_GPAR+FRAMEPAR_GLOBALS): P_MAX_PAR)) {
00828     D1I(local_irq_restore(flags));
00829     return -ERR_FRAMEPARS_BADINDEX;
00830   }
00831 //TODO: optimize to use mask several parameters together
00832   if (index >= FRAMEPAR_GLOBALS) { 
00833     if (mindex & FRAMEPAIR_MASK_BYTES) { 
00834       val= FRAMEPAIR_FRAME_MASK_NEW(mindex, GLOBALPARS(index), val);
00835     }
00836     GLOBALPARS(index)=val;
00837   } else if (mindex  & FRAMEPAIR_FRAME_FUNC) { 
00838     funcs2call[index] = val;
00839 //  } else {
00840 
00841   } else if ((frame8 != findex_future) || ((mindex & FRAMEPAIR_JUST_THIS)==0)) { 
00842     if (mindex & FRAMEPAIR_MASK_BYTES) { 
00843       val= FRAMEPAIR_FRAME_MASK_NEW(mindex, framepars[frame8].pars[index], val);
00844     }
00845     if ((framepars[frame8].pars[index]!= val) || (mindex & (FRAMEPAIR_FORCE_NEW | FRAMEPAIR_FORCE_PROC))){
00846       bmask=   1 << (index & 31);
00847       bindex = index >> 5;
00848       bmask32= 1 << bindex;
00850       framepars[frame8].pars[index]       = val;
00851       framepars[frame8].mod[bindex]      |= bmask;
00852       framepars[frame8].mod32            |= bmask32;
00853       if (mindex & FRAMEPAIR_FORCE_PROC){
00854         framepars[frame8].functions        |= funcs2call[index]; 
00855       }
00856       MDF8(printk(" bindex=0x%lx, bmask=0x%08lx, bmask32=0x%08lx, functions=0x%08lx\n",bindex, bmask, bmask32, framepars[frame8].functions)); 
00858       if ((mindex & FRAMEPAIR_JUST_THIS)==0) {
00859         MDF8(printk (":        ---   setting next frames"));
00860 //        for (nframe=(frame8+1) & PARS_FRAMES_MASK; (nframe != findex_prev) && (!(framepars[frame8].mod[bindex] & bmask)); nframe=(nframe+1) & PARS_FRAMES_MASK) {
00861         for (nframe=(frame8+1) & PARS_FRAMES_MASK; (nframe != findex_prev) && (!(framepars[nframe].mod[bindex] & bmask)); nframe=(nframe+1) & PARS_FRAMES_MASK) {
00862           framepars[nframe].pars[index] = val;
00863           D8(printk (" %d",nframe));
00864         }
00865         frame8=(frame8-1) & PARS_FRAMES_MASK;  
00866       }
00867 //      MDF1(printk("\n"));
00870       MDF8(printk (":        >>>   setting modsince"));
00871 //    for (nframe=(frame8-1) & PARS_FRAMES_MASK; nframe != findex_future; nframe=(nframe-1) & PARS_FRAMES_MASK) {
00872       for (nframe=frame8;                        nframe != findex_future; nframe=(nframe-1) & PARS_FRAMES_MASK) { 
00873         framepars[nframe].modsince[bindex] |= bmask;
00874         framepars[nframe].modsince32       |= bmask32;
00875         D8(printk (" %d",nframe));
00876       }
00877       D8(printk ("\n"));
00878     } else { 
00879       D1I(local_irq_restore(flags));
00880       ELP_KERR(printk("Tried to write JUST_THIS parameter (0x%lx) too far in the future", mindex));
00881       return -ERR_FRAMEPARS_TOOEARLY;
00882     }
00883   }
00884   D1I(local_irq_restore(flags));
00885   return 0;
00886 }
00895 int setFramePars(struct framepars_t * this_framepars, int numPars, struct frameparspair_t * pars) {
00896   int frame8;
00897   unsigned long flags;
00898   int npar,nframe;
00899   unsigned long val, bmask, bmask32;
00900   int index,bindex;
00901   int findex_this=  thisFrameNumber & PARS_FRAMES_MASK;
00902   int findex_prev= (findex_this-1)  & PARS_FRAMES_MASK;
00903   int findex_future=(findex_this-2)  & PARS_FRAMES_MASK;
00904   MDF8(printk (": this_framepars=0x%x numPars=%d\n",(int) this_framepars, numPars));
00905   D1I(local_irq_save(flags));
00906   for (npar=0; npar < numPars; npar++) {
00907     frame8= (this_framepars->pars[P_FRAME]) & PARS_FRAMES_MASK;
00908     val=pars[npar].val;
00909     index= pars[npar].num & 0xffff;
00910     MDF8(printk (":    ---   frame8=%d index=%d (0x%x) val=0x%x\n", frame8, index, (int) pars[npar].num, (int) val));
00911     if (index> ((index >= FRAMEPAR_GLOBALS)? (P_MAX_GPAR+FRAMEPAR_GLOBALS): P_MAX_PAR)) {
00912       D1I(local_irq_restore(flags));
00913       ELP_KERR(printk(" bad index=%d > %d\n", index, P_MAX_PAR));
00914       return -ERR_FRAMEPARS_BADINDEX;
00915     }
00916     if (index >= FRAMEPAR_GLOBALS) { 
00917        if (pars[npar].num & FRAMEPAIR_MASK_BYTES) { 
00918          val= FRAMEPAIR_FRAME_MASK_NEW(pars[npar].num, GLOBALPARS(index), val);
00919        }
00920        GLOBALPARS(index)=val;
00921     } else if (pars[npar].num  & FRAMEPAIR_FRAME_FUNC) {
00922         funcs2call[index] = val;
00923 //    } else {
00924     } else if ((frame8 != findex_future) || ((pars[npar].num & FRAMEPAIR_JUST_THIS)==0)) { 
00925        if (pars[npar].num & FRAMEPAIR_MASK_BYTES) { 
00926          val= FRAMEPAIR_FRAME_MASK_NEW(pars[npar].num, framepars[frame8].pars[index], val);
00927        }
00928 //TODO: optimize to use mask several parameters together
00929       if ((framepars[frame8].pars[index]!= val) || (pars[npar].num & (FRAMEPAIR_FORCE_NEW | FRAMEPAIR_FORCE_PROC))){
00930         bmask=   1 << (index & 31);
00931         bindex = index >> 5;
00932         bmask32= 1 << bindex;
00934         framepars[frame8].pars[index]       = val;
00935         framepars[frame8].mod[bindex]      |= bmask;
00936         framepars[frame8].mod32            |= bmask32;
00937         if (pars[npar].num & FRAMEPAIR_FORCE_PROC){
00938           framepars[frame8].functions        |= funcs2call[index]; 
00939         }
00941         if ((pars[npar].num & FRAMEPAIR_JUST_THIS)==0) {
00942         MDF8(printk (":        ---   setting next frames"));
00943           for (nframe=(frame8+1) & PARS_FRAMES_MASK; (nframe != findex_prev) && (!(framepars[nframe].mod[bindex] & bmask)); nframe=(nframe+1) & PARS_FRAMES_MASK) {
00944             D8(printk (" %d",nframe));
00945             framepars[nframe].pars[index] = val;
00946           }
00947           frame8=(frame8-1) & PARS_FRAMES_MASK; 
00948           D8(printk ("\n"));
00949         }
00952 //      for (nframe=(frame8-1) & PARS_FRAMES_MASK; nframe != findex_future; nframe=(nframe-1) & PARS_FRAMES_MASK) {
00953         for (nframe=frame8;                        nframe != findex_future; nframe=(nframe-1) & PARS_FRAMES_MASK) { 
00954           framepars[nframe].modsince[bindex] |= bmask;
00955           framepars[nframe].modsince32       |= bmask32;
00956         }
00957       }
00958     } else { 
00959       D1I(local_irq_restore(flags));
00960       ELP_KERR(printk("Tried to write JUST_THIS parameter (0x%lx) too far in the future", pars[npar].num));
00961       return -ERR_FRAMEPARS_TOOEARLY;
00962     }
00963   }
00964   D1I(local_irq_restore(flags));
00965   return 0;
00966 }
00967 
00981 
00982 static struct file_operations framepars_fops = {
00983    owner:    THIS_MODULE,
00984    llseek:   framepars_lseek,
00985    write:    framepars_write,
00986    open:     framepars_open,
00987    mmap:     framepars_mmap,
00988    release:  framepars_release
00989 };
00990 
00997 int framepars_open(struct inode *inode, struct file *filp) {
00998   int res;
00999   struct framepars_pd * privData;
01000   privData= (struct framepars_pd *) kmalloc(sizeof(struct framepars_pd),GFP_KERNEL);
01001   if (!privData) return -ENOMEM;
01002   filp->private_data = privData;
01003   privData-> minor=MINOR(inode->i_rdev);
01004   MDF1(printk(": minor=0x%x\n",privData-> minor));
01005   switch (privData-> minor) {
01006     case  CMOSCAM_MINOR_FRAMEPARS :
01007         inode->i_size = 0; //or return 8 - number of frame pages?
01008         return 0;
01009     default:
01010        kfree(filp->private_data); // already allocated
01011        return -EINVAL;
01012   }
01013   return res;
01014 }
01015 
01022 int framepars_release(struct inode *inode, struct file *filp) {
01023   int res=0;
01024   int p = MINOR(inode->i_rdev);
01025   MDF1(printk(": minor=0x%x\n",p));
01026   switch ( p ) {
01027     case  CMOSCAM_MINOR_FRAMEPARS :
01028         break;
01029     default:
01030         return -EINVAL; 
01031     }
01032   kfree(filp->private_data);
01033   return res;
01034 }
01035 
01049 loff_t framepars_lseek (struct file * file, loff_t offset, int orig) {
01050  unsigned long target_frame;
01051  MDF1(printk(" offset=0x%x, orig=0x%x\n",(int) offset, (int) orig));
01052    switch(orig) {
01053    case SEEK_SET:
01054      file->f_pos = offset;
01055      break;
01056    case SEEK_CUR:
01057      if (offset==0) return getThisFrameNumber(); 
01058      file->f_pos = getThisFrameNumber() + offset; 
01059      break;
01060    case SEEK_END:
01061      if (offset <= 0) {
01062         break;
01063      } else if (offset >= LSEEK_FRAME_WAIT_REL) {
01064        if (offset >=LSEEK_FRAME_WAIT_ABS) target_frame=offset-LSEEK_FRAME_WAIT_ABS;                     
01065        else                               target_frame=getThisFrameNumber()+offset-LSEEK_FRAME_WAIT_REL; 
01066        wait_event_interruptible (framepars_wait_queue,getThisFrameNumber()>=target_frame);
01067 //       if (getThisFrameNumber()<target_frame) wait_event_interruptible (framepars_wait_queue,getThisFrameNumber()>=target_frame);
01068        return getThisFrameNumber(); 
01069      } else { 
01070         switch (offset & ~0x1f) {
01071           case  LSEEK_DAEMON_FRAME:  
01072             wait_event_interruptible (framepars_wait_queue, get_imageParamsThis(P_DAEMON_EN) & (1<<(offset & 0x1f)));
01073             break;
01074           default:
01075             switch (offset) {
01076               case LSEEK_GET_FPGA_TIME:
01077                 X313_GET_FPGA_TIME( GLOBALPARS(G_SECONDS), GLOBALPARS(G_MICROSECONDS) );
01078                 MDF2(printk("X313_GET_FPGA_TIME\n"));
01079                 break;
01080               case LSEEK_SET_FPGA_TIME:    
01081                 X313_SET_FPGA_TIME( GLOBALPARS(G_SECONDS) , GLOBALPARS(G_MICROSECONDS) );
01082                 MDF2(printk("X313_SET_FPGA_TIME\n"));
01083                 break;
01084               case LSEEK_FRAMEPARS_INIT:   
01085                 MDF2(printk("LSEEK_FRAMEPARS_INIT\n"));
01086                 initGlobalPars();
01087                 initSequencers();
01088                 break;
01089               case LSEEK_FRAME_RESET:     
01090                 MDF2(printk("LSEEK_FRAME_RESET\n"));
01091                 resetFrameNumber();
01092                 break;
01093               case LSEEK_SENSORPROC:      
01094                 MDF2(printk("LSEEK_SENSORPROC: framepars[0].functions=0x%08lx\n",framepars[0].functions));
01095                 processPars (sensorproc, 0, 8);  
01096                 break;
01097               case LSEEK_DMA_INIT:         
01098                 MDF2(printk("LSEEK_DMA_INIT\n"));
01099                 x313_dma_init();
01100                 break;
01101               case LSEEK_DMA_STOP:         
01102                 MDF2(printk("LSEEK_DMA_STOP\n"));
01103                 x313_dma_stop();           
01104                 break;
01105               case LSEEK_DMA_START:        
01106                 MDF2(printk("LSEEK_DMA_START\n"));
01107                 x313_dma_start();          
01108                 break;
01109               case LSEEK_COMPRESSOR_RESET: 
01110                 MDF2(printk("LSEEK_COMPRESSOR_RESET\n"));
01111                 reset_compressor();
01112                 break;
01113               case LSEEK_INTERRUPT_OFF:    
01114                 MDF2(printk ("LSEEK_INTERRUPT_OFF\n"));
01115                 camera_interrupts (0);
01116                 break;
01117               case LSEEK_INTERRUPT_ON:     
01118                 MDF2(printk ("LSEEK_INTERRUPT_ON\n"));
01119                 camera_interrupts (1);
01120                 break;
01121             }
01122         }
01123         break;
01124      }
01125      break;
01126    default:
01127       return -EINVAL;
01128    }
01129    return  file->f_pos ;
01130 }
01131 
01141 ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff_t *off) {
01142    struct frameparspair_t   pars_static[256];
01143    struct frameparspair_t * pars = pars_static;
01144    struct framepars_pd * privData = (struct framepars_pd *) file->private_data;
01145    unsigned long frame=*off; 
01146    int           latency=-1;
01147    int           first=0;
01148    int           last;
01149    int           result;
01150    MDF1(printk(": file->f_pos=0x%x, *off=0x%x, count=0x%x\n", (int) file->f_pos, (int) *off, (int) count));
01151    count &= ~7; 
01152    switch (privData->minor) {
01153        case CMOSCAM_MINOR_FRAMEPARS :
01154          if (count>sizeof(pars_static)) 
01155             pars =     (struct frameparspair_t *) kmalloc(count, GFP_KERNEL);
01156          if (!pars) return -ENOMEM;
01157          count >>=3; 
01158          if(count) {
01159             if(copy_from_user((char *) pars, buf, count<<3)) {
01160               if (count>sizeof(pars_static)) kfree(pars);
01161               return -EFAULT;
01162            }
01163            while (first <count) {
01164              while ((first <count) && ((pars[first].num & 0xff00)==0xff00)) { // process special instructions
01165                switch (pars[first].num & 0xffff) {
01166                  case FRAMEPARS_SETFRAME:
01167                     frame= pars[first].val;
01168                     break;
01169                  case FRAMEPARS_SETFRAMEREL:
01170                     frame= pars[first].val+getThisFrameNumber();
01171                     break;
01172                  case FRAMEPARS_SETLATENCY:
01173                     latency= (pars[first].val & 0x80000000)? -1: pars[first].val;
01174                     break;
01175                  case FRAMEPARS_SETFPGATIME:  
01176                     X313_SET_FPGA_TIME( GLOBALPARS(G_SECONDS) , GLOBALPARS(G_MICROSECONDS) );
01177                     break;
01178                  case FRAMEPARS_GETFPGATIME:  
01179                     X313_GET_FPGA_TIME( GLOBALPARS(G_SECONDS) , GLOBALPARS(G_MICROSECONDS) );
01180                     break;
01181                  default:
01182                  printk("framepars_write: invalid special instruction: 0x%x\n", (int) pars[first].num);
01183                }
01184                first ++;
01185              }
01186              last=first+1;
01187              while ((last < count) && ((pars[last].num & 0xff00)!=0xff00)) last++; // skip to the end or next special instructions
01188              result=setFrameParsAtomic(frame, latency, last-first, &pars[first]);
01189              MDF1(printk("setFrameParsAtomic(%ld, %d, %d)\n", frame, latency, last-first));
01190              if (result <0) { 
01191                if (count>sizeof(pars_static)) kfree(pars);
01192                return -EFAULT;
01193              }
01194              first=last;
01195            }
01196          }
01197          if (count>sizeof(pars_static)) kfree(pars);
01198          return count<<3; 
01199        default: return -EINVAL;
01200   }
01201 }
01202 
01211 int framepars_mmap (struct file *file, struct vm_area_struct *vma) {
01212   int result;
01213   struct framepars_pd * privData = (struct framepars_pd *) file->private_data;
01214   MDF1(printk(": minor=0x%x\n",privData-> minor));
01215      switch (privData->minor) {
01216        case  CMOSCAM_MINOR_FRAMEPARS :
01217            result=remap_pfn_range(vma,
01218                     vma->vm_start,
01219                    ((unsigned long) virt_to_phys(frameparsall)) >> PAGE_SHIFT, // Should be page-aligned
01220                     vma->vm_end-vma->vm_start,
01221                     vma->vm_page_prot);
01222            MDF1(printk("remap_pfn_range returned=%x\r\n",result));
01223            if (result) return -EAGAIN;
01224            return 0;
01225        default: return -EINVAL;
01226   }
01227 }
01228 
01233 static int __init framepars_init(void) {
01234    int res;
01235    init_framepars_ptr();
01236    initGlobalPars(); 
01237    frameParsInitialized=0;
01238    res = register_chrdev(FRAMEPARS_MAJOR, "framepars_operations", &framepars_fops);
01239    if(res < 0) {
01240      printk(KERN_ERR "\nframepars_init: couldn't get a major number %d.\n",FRAMEPARS_MAJOR);
01241      return res;
01242    }
01243    init_waitqueue_head(&framepars_wait_queue);
01244    printk(X3X3_FRAMEPARS_DRIVER_NAME" - %d \n",FRAMEPARS_MAJOR);
01245    return 0;
01246 }
01247 
01248 
01249 module_init(framepars_init);
01250 MODULE_LICENSE("GPLv3.0");
01251 MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
01252 MODULE_DESCRIPTION(X3X3_FRAMEPARS_DRIVER_NAME);

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