00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
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>
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"
00184
00185 #include "x3x3.h"
00186
00187
00188 #include "sensor_common.h"
00189 #include "framepars.h"
00190 #include "param_depend.h"
00192 #include "cxdma.h"
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
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
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
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
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;
00419 findex_next= (findex_this+1) & PARS_FRAMES_MASK;
00423
00424 pastParsIndex= (thisFrameNumber-1) & PASTPARS_SAVE_ENTRIES_MASK;
00425
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
00545
00546
00547
00548
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
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
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
00630
00631
00632 void processPars (struct sensorproc_t * sensorproc, int frame8, int maxahead) {
00633 frame8 &= PARS_FRAMES_MASK;
00635
00636 processParsASAP (sensorproc, frame8);
00639
00640 processParsSeq (sensorproc, frame8, maxahead);
00642
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
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
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
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
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
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
00805
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
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
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
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
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
00870 MDF8(printk (": >>> setting modsince"));
00871
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
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
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
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;
01008 return 0;
01009 default:
01010 kfree(filp->private_data);
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
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)) {
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++;
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,
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);