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
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 #define USE_HARDWARE_I2C y
00317 #include <linux/module.h>
00318 #include <linux/sched.h>
00319 #include <linux/slab.h>
00320 #include <linux/errno.h>
00321 #include <linux/kernel.h>
00322 #include <linux/fs.h>
00323 #include <linux/string.h>
00324 #include <linux/init.h>
00325 #include <linux/autoconf.h>
00326
00327 #include <linux/interrupt.h>
00328 #include <linux/time.h>
00329
00330 #include <asm/system.h>
00331
00332
00333
00334
00335 #include <asm/arch/hwregs/intr_vect.h>
00336
00337 #include <asm/arch/hwregs/intr_vect_defs.h>
00338
00339
00340 #include <asm/io.h>
00341
00342 #include <asm/irq.h>
00343
00344 #include <asm/delay.h>
00345 #include <asm/uaccess.h>
00346
00347 #include <asm/arch/cache.h>
00348
00349
00350
00351 #include <asm/elphel/c313a.h>
00352 #include <asm/elphel/exifa.h>
00353
00354 #include "fpgactrl.h"
00355 #include "fpga_sdram.h"
00356
00357
00358 #include "x3x3.h"
00359 #include "cc3x3.h"
00360 #include "cxsdram.h"
00361 #include "cci2c.h"
00362 #include "cxdma.h"
00363 #include "circbuf.h"
00364
00365 #include "fpgaconfi2c.h"
00366
00367 #include "hist.h"
00368 #include "exif353.h"
00369
00370
00371 #ifdef CONFIG_ETRAX_323
00372 #include "sensorfpgajtag.h"
00373 #endif
00374 #ifdef CONFIG_ETRAX_ELPHEL_MCP
00375 #include "ccmcp.h"
00376 #else
00377 #define MCPpresent() 0
00378 #define MCP_open(inode,filp) -1
00379 #define MCP_lseek(file,offset,orig) 0
00380 #define MCP_read(file,buf,count,off) 0
00381
00382
00383 #define MCP_write(file,buf,count,off) 0
00384 #endif
00385
00386 #ifdef CONFIG_ETRAX_ELPHEL_ZR32112
00387 #include "cczr32112.h"
00388 #endif
00389
00390 #ifdef CONFIG_ETRAX_ELPHEL_ZR32212
00391 #include "cczr32212.h"
00392 #endif
00393
00394 #ifdef CONFIG_ETRAX_ELPHEL_KAC1310
00395 #include "cckac1310.h"
00396
00397 #endif
00398
00399
00400
00401
00402
00403
00404
00405 #ifdef CONFIG_ETRAX_ELPHEL_MT9X001
00406 #include "mt9x001.h"
00407 #endif
00408 #ifdef CONFIG_ETRAX_ELPHEL_IBIS51300
00409 #include "ccibis51300.h"
00410 #endif
00411 #ifdef CONFIG_ETRAX_ELPHEL_KAC1310
00412 #include "kac5000.h"
00413 #endif
00414
00415
00416 #if ELPHEL_DEBUG
00417 #define MD1(x) printk("%s:%d:",__FILE__,__LINE__);x
00418
00419 #define MD12(x) printk("%s:%d:",__FILE__,__LINE__);x
00420
00421 #define MD13(x) printk("%s:%d:",__FILE__,__LINE__);x
00422
00423 #define MD20(x) printk("%s:%d:",__FILE__,__LINE__);x
00424 #else
00425 #define MD1(x)
00426 #define MD12(x)
00427 #define MD13(x)
00428 #define MD20(x)
00429 #endif
00430
00431
00432
00434
00435 #define MD11(x)
00436
00437
00438 #define MD10(x)
00439
00440 #define MD9(x)
00441
00442
00443
00444 #define MD8(x)
00445
00447
00448 #define MD7(x)
00449
00450
00451 #define MD6(x)
00452
00454
00455 #define MD2(x)
00456
00457
00458 #define D(x)
00459 #define D1(x)
00460 #define D2(x)
00461 #define D3(x)
00462 #define D4(x)
00463
00464 #define D5(x) printk("%s:%d:",__FILE__,__LINE__);x
00465
00466
00467 #define CMOSCAM_MAJOR 126
00468 static const char cmoscam_name[] = "cmoscam353";
00469
00470
00471
00472 #define MY_MODULE_DESCRIPTION "Elphel model 353 camera driver"
00473 #define CMOSCAM_DRIVER_NAME "CMOS/MCP camera 353 driver\n"
00474
00475
00476 #define X313_ACQUIRE_STOP port_csp0_addr[X313_WA_TRIG]=0
00477 #define X313_ACQUIRE_ONCE port_csp0_addr[X313_WA_TRIG]=(imageParamsR[P_TRIG] & 1)?6:4
00478 #define X313_ACQUIRE_INTERNAL port_csp0_addr[X313_WA_TRIG]=4
00479 #define X313_ACQUIRE_EXTERNAL port_csp0_addr[X313_WA_TRIG]=6
00480 #define X313_ACQUIRE_ON port_csp0_addr[X313_WA_TRIG]=5
00481
00482
00483
00484
00485
00486
00487 #ifdef CONFIG_ETRAX_ELPHEL353
00488 #define EN_INTERRUPT(x) port_csp0_addr[X313_WA_IRQ_ENA]= (1<< x )
00489 #define DIS_INTERRUPT(x) {port_csp0_addr[X313_WA_IRQ_DIS]= (1<< x ); port_csp0_addr[X313_WA_IRQ_RST]= (1<< x );}
00490 #define DIS_INTERRUPTS {port_csp0_addr[X313_WA_IRQ_DIS]= 0xff; port_csp0_addr[X313_WA_IRQ_RST]= 0xff;}
00491 #else
00492 #ifdef CONFIG_ETRAX_333
00493 #define EN_INTERRUPT(x) port_csp0_addr[X313_WA_IRQ_ENA]= (1<< x )
00494 #define DIS_INTERRUPT(x) {port_csp0_addr[X313_WA_IRQ_DIS]= (1<< x ); port_csp0_addr[X313_WA_IRQ_RST]= (1<< x );}
00495 #define DIS_INTERRUPTS {port_csp0_addr[X313_WA_IRQ_DIS]= 0xff; port_csp0_addr[X313_WA_IRQ_RST]= 0xff;}
00496 #else
00497 #define EN_INTERRUPT(x) port_csp0_addr[X313_WA_IRQM]= (intm_shadow |= (1<< x ))
00498 #define DIS_INTERRUPT(x) port_csp0_addr[X313_WA_IRQM]= (intm_shadow &= ~(1<< x ))
00499 #define DIS_INTERRUPTS port_csp0_addr[X313_WA_IRQM]= (intm_shadow = 0)
00500 #endif
00501 #endif
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 #define PROGRAM_FPN(t,s,m,d,l) port_csp0_addr[X313_WA_SENSFPN]= \
00513 (((t) & 1) << 10) | \
00514 (((s) & 7) << 7) | \
00515 (((m) & 7) << 4) | \
00516 (((d) & 1) << 3) | \
00517 (((l) & 7) << 0)
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 #define PROGRAM_CLK_EN(x) X313_SETFIELD(CLKEN, x )
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 #define CCAM_DONOTUSEAUX (ccam_cr_shadow & X313_MASK(KAI11000))
00552
00553
00554 #define CCAM_ARO_ON \
00555 ccamCROr( X313_BITS(ARO,1) )
00556 #define CCAM_ARO_OFF \
00557 ccamCRAnd(~X313_BITS(ARO,1) )
00558
00559
00560 #define CCAM_DCLK_OFF \
00561 ccamCROr( X313_BITS(DCLKMODE,1) )
00562 #define CCAM_DCLK_ON \
00563 ccamCRAnd(~X313_BITS(DCLKMODE,1) )
00564
00565
00566 #define CCAM_ARST_OFF \
00567 ccamCROr( X313_BITS(ARST,1) )
00568 #define CCAM_ARST_ON \
00569 ccamCRAnd(~X313_BITS(ARST,1) )
00570
00571 #define CCAM_MRST_OFF \
00572 ccamCROr( X313_BITS(MRST,1) )
00573 #define CCAM_MRST_ON \
00574 ccamCRAnd(~X313_BITS(MRST,1) )
00575
00576 #define CCAM_NEGRST \
00577 ccamCROr( X313_BITS(NEGRST,1) )
00578 #define CCAM_POSRST \
00579 ccamCRAnd(~X313_BITS(NEGRST,1) )
00580
00581
00582 #define CCAM_CNVEN_OFF \
00583 ccamCRAnd(~X313_BITS(CNVEN,1) )
00584
00586 #define CCAM_TRIG_INT \
00587 ccamCRAnd(~X313_BITS(TRIGSRC,1) )
00588 #define CCAM_TRIG_EXT \
00589 ccamCROr( X313_BITS(TRIGSRC,1) )
00590
00592 #define CCAM_TIMESTAMP_NORMAL \
00593 ccamCRAnd(~X313_BITS(EARLYTRIG,1) )
00594 #define CCAM_TIMESTAMP_EARLY \
00595 ccamCROr( X313_BITS(EARLYTRIG,1) )
00596
00597
00598
00599
00600
00601
00602 #define CCAM_SET_HACT_PHASE(x) ccamCRAndOr(~X313_MASK(HACT_PHASE), X313_BITS(HACT_PHASE, (x)))
00603
00604
00605 #if 0 // restore that back after playing with 10359 board
00606 #ifdef CONFIG_ETRAX_ELPHEL_FORCE_MT9P001
00607 #define CCAM_CNVEN_ON \
00608 printk ("\r\n*** Turning voltage is disabled in kernel config - CONFIG_ETRAX_ELPHEL_FORCE_MT9P001 ***\r\n")
00609 #else
00610 #define CCAM_CNVEN_ON \
00611 printk ("\r\n*** Maybe fatal for MT9P001 !!! Set CONFIG_ETRAX_ELPHEL_FORCE_MT9P001 if troubleshooting MT9P001 ***\r\n");ccamCROr( X313_BITS(CNVEN,1) )
00612 #endif
00613 #else
00614 #define CCAM_CNVEN_ON \
00615 printk ("\r\n*** Maybe fatal for MT9P001 !!! Set CONFIG_ETRAX_ELPHEL_FORCE_MT9P001 if troubleshooting MT9P001 ***\r\n");ccamCROr( X313_BITS(CNVEN,1) )
00616 #endif
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626 #define X313_MAXMINOR 15
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 struct sensor_t sensor;
00640 unsigned short gamma_tables_soft[1028];
00641 int gamma_tables_changed=0;
00642
00643 static DECLARE_MUTEX(sensor_lock);
00644
00645
00646 static unsigned long default_common[]= \
00647 {
00648 P_WOI_WIDTH, 1280,
00649 P_WOI_HEIGHT, 1024,
00650 P_WOI_LEFT, 0,
00651 P_WOI_TOP, 0,
00652 P_SENSOR, 0,
00653 P_TRIG, 2,
00654 P_EXPOS, 1,
00655
00656
00657 P_PAGE_ACQ, 0,
00658 P_PAGE_READ, 0,
00659
00660
00661 P_BGFRAME, 0,
00662 P_OVERLAP, 0,
00663 P_AUXCM, 0,
00664 P_BIN_HOR, 0,
00665 P_BIN_VERT, 0,
00666 P_COLOR, 0,
00667
00668
00669 P_MCLK, 4,
00670
00671 P_DCM_HOR, 0,
00672 P_DCM_VERT, 0,
00673
00674 P_BITS, 8,
00675 P_SHIFTL, 0,
00676 P_FPNS, 0,
00677 P_FPNM, 0,
00678
00679 P_VEXPOS, 0,
00680
00681 P_GAINR, 0,
00682 P_GAING, 0,
00683 P_GAINB, 0,
00684 P_GAINGB, 0,
00685 P_FATZERO, 0,
00686 P_VIRTTRIG, 0,
00687 P_QUALITY, 50,
00688 P_COLOR_SATURATION_BLUE, 100,
00689 P_COLOR_SATURATION_RED, 100,
00690 P_GSCALE, 256,
00691
00692 P_GAMMA, 100,
00693 P_PIXEL_LOW, 0,
00694 P_PIXEL_HIGH, 255,
00695 P_FRAMESYNC_DLY, 0,
00696 P_PF_HEIGHT, 0,
00697 P_FPSLM, 0,
00698 P_TASKLET_CTL, 0,
00699 P_SKIP_FRAMES, 1,
00700 P_I2C_QPERIOD, 100,
00701 P_I2C_BYTES,2,
00702 P_OVERSIZE,0,
00703 P_I2C_BYTES,2,
00704 P_IRQ_SMART,3
00705 };
00706
00707 #define SCALE_MIN 0x040
00708 #define SCALE_MAX 0x400
00709 extern unsigned long gain_balance(unsigned long *scale, unsigned long gain);
00710 struct gains_t gains = {
00711 .red = 0x100,
00712 .green = 0x100,
00713 .blue = 0x100,
00714 };
00715
00716 struct frame_params_t frame_params ={
00717 .exposure=0,
00718 .width=0,
00719 .height=0,
00720 .colorsat= DEFAULT_COLOR_SATURATION_BLUE | (DEFAULT_COLOR_SATURATION_RED << 16),
00721 .color=0,
00722 .quality=50,
00723 .gamma=100,
00724 .black=0,
00725 .rscale=0,
00726 .bscale=0,
00727
00728 .gain_r=0,
00729 .gain_g=0,
00730 .gain_b=0,
00731 .gain_gb=0,
00732 .meta_index =0,
00733
00734 .signffff=0xffff,
00735
00736 {.timestamp_sec=0},
00737 .timestamp_usec=0
00738 };
00739 unsigned long * frame_params_ul= (unsigned long *) &frame_params;
00740
00741 unsigned short * exif_index= (unsigned short * ) &frame_params.meta_index;
00742 static struct meta_offsets_t {
00743 int Image_DateTime;
00744 int Photo_DateTimeOriginal;
00745 int Photo_ExposureTime;
00746 int Image_FrameNumber;
00747 } meta_offsets;
00748
00749 char * exif_meta_time_string;
00750 void dumpFrameParams(struct frame_params_t * fp, const char * title) {
00751
00752
00753 printk ("%s\n",title);
00754 printk (".exposure= %d * 100usec\n",(int)fp->exposure);
00755 printk (".width= %d\n", (int)fp->width);
00756 printk (".height= %d\n",(int)fp->height);
00757 printk (".colorsat= 0x%x (%d / %d)\n",(int)fp->colorsat, (int)((100.0*(fp->colorsat>>16))/DEFAULT_COLOR_SATURATION_RED), (int) ((100.0*(fp->colorsat & 0xffff))/DEFAULT_COLOR_SATURATION_BLUE));
00758 printk (".color= 0x%x (color=%d, flipX=%d, flipY=%d)\n",(int) fp->color, (int) fp->color & 0x0f, (int) (fp->color >> 6) & 1, (int) (fp->color >> 7) & 1);
00759 printk (".quality= %d\n",(int) fp->quality);
00760 printk (".gamma= %d\n",(int) fp->gamma);
00761 printk (".black= %d\n",(int) fp->black);
00762 printk (".rscale= 0x%x (%d)\n",(int) fp->rscale, (int)((100.0*fp->rscale)/256));
00763 printk (".bscale= 0x%x (%d)\n",(int) fp->bscale, (int)((100.0*fp->bscale)/256));
00764 printk (".gain_r= 0x%x (%d)\n",(int) fp->gain_r, (int)((100.0*fp->gain_r)/16));
00765 printk (".gain_g= 0x%x (%d)\n",(int) fp->gain_g, (int)((100.0*fp->gain_g)/16));
00766 printk (".gain_b= 0x%x (%d)\n",(int) fp->gain_b, (int)((100.0*fp->gain_b)/16));
00767 printk (".gain_gb= 0x%x (%d)\n",(int) fp->gain_gb, (int)((100.0*fp->gain_gb)/16));
00768
00769
00770 printk (".meta_index= 0x%x\n",(int) fp->meta_index);
00771 printk (".signffff= 0x%x\n",(int) fp->signffff);
00772 printk (".timestamp_sec= 0x%x\n",(int) fp->timestamp_sec);
00773 printk (".timestamp_usec= 0x%x\n",(int) fp->timestamp_usec);
00774 }
00775 static int minors[X313_MAXMINOR+1];
00776
00777 static unsigned char sensor_i2c_addr;
00778
00779
00780 static unsigned short sensor_i2c_regs16[0x100];
00781 unsigned char * sensor_i2c_regs;
00782
00783
00784
00785
00786
00787 static unsigned long imageParamsR[P_NUMBER * 4] __attribute__ ((aligned (PAGE_SIZE)));
00788 unsigned long *imageParamsW=&imageParamsR[P_NUMBER];
00789 unsigned long *imageParamsR_PREV=&imageParamsR[2*P_NUMBER];
00790 unsigned long *imageParamsR_PREV_PREV=&imageParamsR[3*P_NUMBER];
00791
00792
00793
00794 struct autoexp_t * autoexp_state= NULL;
00795 struct autoexp_t * autoexp_set= NULL;
00796 struct aexp_window_t * aexp_window = NULL;
00797 struct aexp_window_t * aexp_window_set = NULL;
00798
00799
00800 static int jpeg_sdram_ctl0;
00801
00802 volatile unsigned long ccam_cr_shadow=0;
00803
00804
00805
00806
00807 static int getCamSeqState(void);
00808 static int getCamSeqCount(void);
00809 static void setCamSeqState(int v);
00810 static void setCamSeqCount(int v);
00811 static void initCamIRQs(void);
00812
00813 static int camSeqStart(void);
00814
00815
00816 static irqreturn_t camSeq_interrupt(int irq, void *dev_id);
00817 static int x313_JPEG_cmd_wrapper(int arg);
00818 static int ccam_DMA_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg);
00819
00820 static int cmoscam_open(struct inode *inode, struct file *filp);
00821
00822 static int cmoscam_release(struct inode *inode, struct file *filp);
00823 static int cmoscam_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
00824 static loff_t cmoscam_lseek(struct file * file, loff_t offset, int orig);
00825 static ssize_t cmoscam_read(struct file * file, char * buf, size_t count, loff_t *off);
00826 static ssize_t cmoscam_write(struct file * file, const char * buf, size_t count, loff_t *off);
00827 static int cmoscam_mmap (struct file *file, struct vm_area_struct *vma);
00828 static unsigned int cmoscam_poll (struct file *file, poll_table *wait);
00829
00830 static int __init cmoscam_init(void);
00831 static int init_sensor(void);
00832 static int programSensor(int nonstop);
00833 static int init_FPGA(void);
00834
00835 static void camSeq_dump (void);
00836
00837 void adjust_fps_2_compressor(void);
00838
00839
00840
00841 void x313_tables_gammainitlinear(void);
00842 loff_t x313_tables_lseek(struct file * file, loff_t offset, int orig) ;
00843 ssize_t x313_tables_write(struct file * file, const char * buf, size_t count, loff_t *off) ;
00844 ssize_t x313_tables_read(struct file * file, char * buf, size_t count, loff_t *off) ;
00845 loff_t x313_histogram_lseek(struct file * file, loff_t offset, int orig) ;
00846 ssize_t x313_histogram_read(struct file * file, char * buf, size_t count, loff_t *off) ;
00847
00848 int write_gamma_fpga (unsigned short gamma_table[1028]);
00849 loff_t x313_gamma_lseek(struct file * file, loff_t offset, int orig);
00850 ssize_t x313_gamma_read(struct file * file, char * buf, size_t count, loff_t *off) ;
00851 ssize_t x313_gamma_write(struct file * file, const char * buf, size_t count, loff_t *off) ;
00852
00853 loff_t x313_senspars_lseek(struct file * file, loff_t offset, int orig);
00854 ssize_t x313_senspars_read(struct file * file, char * buf, size_t count, loff_t *off);
00855 ssize_t x313_senspars_write(struct file * file, const char * buf, size_t count, loff_t *off);
00856 int x313_senspars_mmap (struct file *file, struct vm_area_struct *vma);
00857
00858 void x313_program_focus(int totalwidth);
00859
00860
00861 static struct file_operations cmoscam_fops = {
00862 owner: THIS_MODULE,
00863 llseek: cmoscam_lseek,
00864 read: cmoscam_read,
00865 write: cmoscam_write,
00866 ioctl: cmoscam_ioctl,
00867 open: cmoscam_open,
00868 mmap: cmoscam_mmap,
00869 poll: cmoscam_poll,
00870
00871 release: cmoscam_release
00872 };
00873
00874
00875
00876
00877 #define nint_vact 0 // start of VACT pulse
00878 #define nint_xint 1 // external enterrupt
00879 #define nint_xferovr 2 // DMA xfer over
00880 #define nint_done 3 // DMA xfer over, persistent till reset through...
00881
00882 #define nint_eot 4
00883 #define nint_overrun 5 // persistent till compressor reset
00884 #define nint_done_input 6 // persistent till compressor reset/restarted
00885 #define nint_done_compress 7 // persistent till compressor reset/restarted
00886 #define nint_smart 8 // Single cycle, does not need restart, configurable to wait for VACT, always at VACT if no compression is underway
00887
00888
00889 #define MAXEXPOSURE 60000 //60 sec, in 1ms increments
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 #ifndef CONFIG_ETRAX_ELPHEL353
00918 #ifdef CONFIG_ETRAX_333
00919 #else
00920 static volatile unsigned long intm_shadow=0;
00921 #endif
00922 #endif
00923
00924 static volatile int camSeqCount;
00925 static volatile int camSeqState;
00926 static volatile int JPEG_wp;
00927 static volatile int JPEG_rp;
00928 static volatile int JPEG_len;
00929
00930
00931 static unsigned long DMA_buf_start;
00932
00933 static volatile int JPEG_nfr;
00934 static volatile int JPEG_lfr;
00935
00936 static volatile int dbg_20;
00937 static volatile int dbg_28;
00938
00939
00940
00941
00942
00943 wait_queue_head_t x313_wait_queue;
00944 static inline void startAcquire(void) {
00945
00946 camSeqState=CAMSEQ_WAIT_F;
00947 camSeqCount=0;
00948 imageParamsR[P_CAMSEQSTATE]=CAMSEQ_WAIT_F;
00949 imageParamsR[P_CAMSEQCOUNT]=0;
00950 if (imageParamsR[P_BGFRAME]) X313_ACQUIRE_INTERNAL ;
00951 else X313_ACQUIRE_ONCE ;
00952 EN_INTERRUPT(nint_xferovr);
00953
00954 }
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991 void tasklet_irq_f(unsigned long arg) {
00992 hist_irq(arg);
00993 }
00994
00995 DECLARE_TASKLET(tasklet_vact, tasklet_irq_f, IRQ_SRC_VACT);
00996 DECLARE_TASKLET(tasklet_done_compress, tasklet_irq_f, IRQ_SRC_DONE_COMPRESS);
00997
00998 extern unsigned long ccam_dma_length;
00999
01000 static int fpga_counter_prev=0;
01001 static int JPEG_wp_prev=0;
01002
01014
01015
01016
01017
01018 inline void compressorSingle(void) {
01020 port_csp0_addr[X313_WA_COMP_CMD] = \
01021 imageParamsR[P_COMPRESSOR_CMD]= \
01022 (x313_get_JPEG_ctrl() & (~COMPRESSOR_CMD_RUN)) | COMPRESSOR_CMD_SINGLE;
01023 X313_CHN_EN(2);
01024 }
01025 inline void compressorRun(void) {
01026 port_csp0_addr[X313_WA_COMP_CMD] = \
01027 imageParamsR[P_COMPRESSOR_CMD]= \
01028 x313_get_JPEG_ctrl() | COMPRESSOR_CMD_RUN;
01029 X313_CHN_EN(2);
01030 }
01031 inline void compressorStop(void) {
01032 port_csp0_addr[X313_WA_COMP_CMD] = \
01033 imageParamsR[P_COMPRESSOR_CMD]= 0;
01034 X313_CHN_DIS(2);
01035 fpga_counter_prev=0;
01036 }
01038 inline void updateJPEG_wp(void) {
01039 int xferred;
01040
01042 int fpga_cntr=X313_XFERCNTR;
01043
01044 xferred=fpga_cntr-fpga_counter_prev;
01045 fpga_counter_prev=fpga_cntr;
01046 if (xferred <0) xferred+= (1 <<24) ;
01047 JPEG_wp_prev=JPEG_wp;
01048 JPEG_wp+= (xferred << 3);
01049 if (JPEG_wp > CCAM_DMA_SIZE) JPEG_wp-=CCAM_DMA_SIZE;
01050 imageParamsR[P_JPEG_WP] = JPEG_wp;
01051 imageParamsR[P_CIRCBUFWP]= JPEG_wp<<2;
01052 imageParamsR[P_FREECIRCBUF] = ((imageParamsR[P_CIRCBUFRP] < imageParamsR[P_CIRCBUFWP])? imageParamsR[P_CIRCBUFSIZE]:0)+
01053 imageParamsR[P_CIRCBUFRP] - imageParamsR[P_CIRCBUFWP];
01054 imageParamsR[P_FOCUS_VALUE]= X313_HIGHFREQ ;
01055 }
01056 void resetPointers(void) {
01057 JPEG_wp=0;
01058 imageParamsR[P_JPEG_WP]=JPEG_wp;
01059 imageParamsR[P_CIRCBUFWP]= JPEG_wp<<2;
01060 imageParamsR[P_FREECIRCBUF] = imageParamsR[P_CIRCBUFRP];
01061
01062 JPEG_rp=0;
01063 imageParamsR[P_FREECIRCBUF] = 0;
01064 JPEG_len=0;
01065 }
01066
01067
01079 inline void advance_imageParamsR(void) {
01080
01081 putlong_meta_irq(imageParamsR_PREV[P_EXPOS], &meta_offsets.Photo_ExposureTime, Exif_Photo_ExposureTime);
01082 putlong_meta_irq(imageParamsR[P_FRAME], &meta_offsets.Image_FrameNumber, Exif_Image_FrameNumber);
01083 frame_params.exposure=imageParamsR_PREV_PREV[P_EXPOS];
01084 imageParamsR_PREV_PREV[P_EXPOS]=imageParamsR_PREV[P_EXPOS] ;
01085 imageParamsR_PREV[P_EXPOS]= imageParamsR[P_EXPOS] ;
01086 int i2c_frame_number= X3X3_I2C_FRAME ;
01087 imageParamsR[P_FRAME]= (imageParamsR[P_FRAME] & 0xfffffff8) + i2c_frame_number +(((imageParamsR[P_FRAME] & 7) > i2c_frame_number)?8:0);
01088 }
01089
01090
01091 inline void add_frame_params(void) {
01092 int alen = JPEG_wp-9; if (alen<0) alen+=CCAM_DMA_SIZE;
01093 int jpeg_len=ccam_dma_buf_ptr[alen] & 0xffffff;
01094 int aframe_params=(alen & 0xfffffff8)-
01095 (((jpeg_len + CCAM_MMAP_META + 3) & 0xffffffe0)>>2)
01096 -8;
01097 if(aframe_params < 0) aframe_params += CCAM_DMA_SIZE;
01098
01099
01100
01101 exif_meta_time_string=encode_time(ccam_dma_buf_ptr[alen-2], ccam_dma_buf_ptr[alen-1]);
01102 write_meta_irq(exif_meta_time_string, &meta_offsets.Photo_DateTimeOriginal, Exif_Photo_DateTimeOriginal, 27);
01103 write_meta_irq(exif_meta_time_string, &meta_offsets.Image_DateTime, Exif_Image_DateTime, 20);
01104 *exif_index= store_meta();
01105 memcpy ((void *) &ccam_dma_buf_ptr[aframe_params], &frame_params, 28) ;
01106 ccam_dma_buf_ptr[aframe_params+7]=jpeg_len;
01107 advance_imageParamsR();
01108
01114 wake_up_interruptible(&circbuf_wait_queue);
01115
01116
01117 }
01118
01119
01120 extern int slock;
01121 extern void ch0_lock(void);
01122 extern wait_queue_head_t vack_wait_queue;
01123
01124 #define SIMPLE_IRQ y
01125
01126 static irqreturn_t camSeq_interrupt(int irq, void *dev_id) {
01127 unsigned long irq_state;
01128
01129 irq_state = X313_IRQSTATE;
01130
01131
01132 #define CONFIG_ETRAX_ELPHEL_AUTOEXP y
01133 #ifdef CONFIG_ETRAX_ELPHEL_AUTOEXP
01134 if((irq_state & 0x01) && slock == 2) {
01135 ch0_lock();
01136 slock = 1;
01137
01138
01139 }
01140
01141
01142
01143 if ((imageParamsR[P_TASKLET_CTL] & 1) == 0) tasklet_schedule(&tasklet_vact);
01144
01145 #warning using autoexposure
01146 #else
01147 #warning not using autoexposure
01148 #endif
01149
01150 DIS_INTERRUPTS;
01151
01152
01153
01154
01155
01156 #ifndef SIMPLE_IRQ
01157 #warning using wake_up_interruptible
01158
01159 #else
01160 #warning no wake_up_interruptible
01161 #endif
01162 if((camSeqState == CAMSEQ_RUN) || (camSeqState == CAMSEQ_SINGLE)) {
01163
01164 if(camSeqCount > 0) {
01165 advance_imageParamsR();
01166 imageParamsR[P_CAMSEQCOUNT]=(--camSeqCount);
01167 EN_INTERRUPT(nint_vact);
01168 } else {
01169 if((camSeqCount) == 0) {
01170 advance_imageParamsR();
01171 X313_POSTINIT_SDCHAN(2,(jpeg_sdram_ctl0 | 0x2000));
01172 compressorRun();
01173 imageParamsR[P_CAMSEQCOUNT]= (--camSeqCount);
01174 EN_INTERRUPT(nint_done_compress);
01175 } else {
01176 updateJPEG_wp();
01177 add_frame_params();
01178 if((camSeqState == CAMSEQ_SINGLE) && (JPEG_wp < JPEG_wp_prev)) {
01179 camSeqState = CAMSEQ_STOP;
01180 imageParamsR[P_CAMSEQSTATE]=CAMSEQ_STOP;
01181 }
01182 compressorRun();
01183
01184 EN_INTERRUPT(nint_done_compress);
01185 }
01186 }
01187 } else {
01188 if(camSeqState == CAMSEQ_STOP) {
01189 updateJPEG_wp();
01190 add_frame_params();
01191 camSeqState = CAMSEQ_JPEG;
01192 imageParamsR[P_CAMSEQSTATE]=CAMSEQ_JPEG;
01193 JPEG_nfr = 0;
01194 compressorSingle();
01195
01196 EN_INTERRUPT(nint_done_compress);
01197 } else {
01198 if(camSeqState == CAMSEQ_JPEG) {
01199 if(X313_SR(DONE_CMPRS)) {
01200 updateJPEG_wp();
01201 add_frame_params();
01202 if(JPEG_nfr > 0)
01203 JPEG_nfr--;
01204 compressorStop();
01205
01206
01207 if (X313_CHN0_BOUND) {
01208
01209 EN_INTERRUPT(nint_vact);
01210 }
01211 } else {
01212
01213 advance_imageParamsR();
01214 JPEG_len = JPEG_wp - JPEG_rp;
01215 if(JPEG_len < 0)
01216 JPEG_len += CCAM_DMA_SIZE;
01218 if(((camSeqCount--) <= 0) && (JPEG_nfr > 0) && (JPEG_len< JPEG_lfr)) {
01219 X313_POSTINIT_SDCHAN(2,(jpeg_sdram_ctl0 | 0x2000));
01220 compressorSingle();
01221 EN_INTERRUPT(nint_done_compress);
01222 } else {
01223 compressorStop();
01224 EN_INTERRUPT(nint_vact);
01225 }
01226 }
01227 } else {
01228 advance_imageParamsR();
01229 if(camSeqState == CAMSEQ_WAIT_F) {
01230 camSeqState = CAMSEQ_DONE;
01231 imageParamsR[P_CAMSEQSTATE]=CAMSEQ_DONE;
01232 } else {
01233 if((camSeqCount--) <= 0) {
01234 startAcquire();
01235 } else {
01236 EN_INTERRUPT(nint_vact);
01237 }
01238 }
01239 }
01240 }
01241 }
01242 return IRQ_HANDLED;
01243 }
01244
01245 static int getCamSeqCount(void) {return camSeqCount;}
01246 static void setCamSeqState(int v) {camSeqState=v;
01247 imageParamsR[P_CAMSEQSTATE]=v;
01248 imageParamsR[P_CAMSEQCOUNT]=0;
01249 MD (printk ("camSeqState=0x%x\n",v));}
01250
01251
01252 static void setCamSeqCount(int v) {camSeqCount=v;
01253 imageParamsR[P_CAMSEQCOUNT]=v;
01254 }
01255
01256
01257 static void initCamIRQs(void){
01258 reg_intr_vect_rw_mask intr_mask;
01259 DIS_INTERRUPTS;
01260 setCamSeqState(CAMSEQ_OFF);
01261 camSeqStop();
01262 resetPointers();
01263 JPEG_nfr=0;
01264 JPEG_lfr=0;
01265
01266
01267 intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
01268 intr_mask.ext = 1;
01269 REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
01270
01271 printk ("Camera interrupts enabled\n");
01272
01273 }
01274
01275 static int getCamSeqState(void) {
01276 int res=-1;
01277 unsigned long flags;
01278 if (camSeqState==CAMSEQ_WAIT_F) {
01279 local_irq_save(flags);
01280 if (X313_SR(SENST1)) res=X313_SR(SENST0)?CAMSEQ_ACQUIRE:CAMSEQ_WAIT_T;
01281 else if (X313_SR(SENST0)) res=CAMSEQ_WAIT_F;
01282 else res= ((camSeqState=CAMSEQ_READY));
01283 local_irq_restore(flags);
01284
01285 return res;
01286 }
01287 return camSeqState;
01288 }
01289
01290
01291 static int camSeqStart(void) {
01292 int i;
01293 if (((i=getCamSeqState()) != CAMSEQ_READY) && (i!=CAMSEQ_DONE)) {
01294 printk("camSeqStart error - CamSeqState was %d\n",i);
01295 return -1;
01296 }
01297 MD1(printk("camSeqStart:getCamSeqCount()=%x\n",getCamSeqCount()));
01298 if (getCamSeqCount()) {
01299
01300 setCamSeqState(CAMSEQ_SKIP);
01301 EN_INTERRUPT(nint_vact);
01302 } else {startAcquire();}
01303 return 0;
01304 }
01305
01306 static void camSeq_dump (void) {
01307 printk (" camSeqCount= %x\n",camSeqCount);
01308 printk (" camSeqState= %x\n",camSeqState);
01309 printk (" JPEG_wp= %x\n",JPEG_wp);
01310 printk (" JPEG_rp= %x\n",JPEG_rp);
01311 printk (" JPEG_len= %x\n",JPEG_len);
01312 printk (" DMA_buf_start=%lx\n",DMA_buf_start);
01313 printk (" JPEG_nfr= %x, (%d)\n",JPEG_nfr,JPEG_nfr);
01314 printk (" JPEG_lfr= %x\n",JPEG_lfr);
01315 printk (" 0x20 was= %x\n",dbg_20);
01316 printk (" 0x28 was= %x\n",dbg_28);
01317 printk("\n");
01318 }
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 int camSeqGetJPEG_wp(void) {return JPEG_wp;}
01338 int camSeqGetJPEG_rp(void) {return JPEG_rp;}
01339 void camSeqSetJPEG_rp(int p) {
01340 JPEG_rp=p;
01341 imageParamsR[P_CIRCBUFRP] = p<< 2;
01342 imageParamsR[P_FREECIRCBUF] =
01343 ((imageParamsR[P_CIRCBUFRP] < imageParamsR[P_CIRCBUFWP])?
01344 imageParamsR[P_CIRCBUFSIZE]:0)+
01345 imageParamsR[P_CIRCBUFRP] - imageParamsR[P_CIRCBUFWP];
01346 }
01358
01359
01360 int camSeqStartClip(int nfr, int len) {
01361 unsigned long flags;
01362 int res=-1;
01363 MD1(printk("camSeqStartClip nfr=%d, len=%d, getCamSeqState()=%d \n", nfr, len, getCamSeqState()));
01364 MD7(printk("camSeqStartClip nfr=%d, len=%d, getCamSeqState()=%d \n", nfr, len, getCamSeqState()));
01365
01366 if (((res=getCamSeqState()) != CAMSEQ_READY) && (res!=CAMSEQ_DONE) && (res!=CAMSEQ_JPEG) && (res!=CAMSEQ_RUN)) {
01367 printk("camSeqStartClip error - CamSeqState was %d\n",res);
01368 return -1;
01369 }
01370 MD7(printk("camSeqStartClip nfr=%d, len=%d, getCamSeqState()=%d \n", nfr, len, res));
01371 if ((res==CAMSEQ_RUN)) {
01372 if ((nfr<0) && (len ==0)){
01373 setCamSeqState(CAMSEQ_STOP);
01374 return 0;
01375 } else {
01376 printk("camSeqStartClip error - CamSeqState was %d\n",res);
01377 return -1;
01378 }
01379 }
01380 if ((nfr<0) && (len ==0)){
01381
01382
01383 if (nfr<-1) return 0;
01384 JPEG_wp=0;
01385 imageParamsR[P_JPEG_WP]=JPEG_wp;
01386 imageParamsR[P_CIRCBUFWP]= JPEG_wp<<2;
01387 imageParamsR[P_FREECIRCBUF] = imageParamsR[P_CIRCBUFRP];
01388
01389
01390 JPEG_rp=-1;
01391 imageParamsR[P_FREECIRCBUF] = 0xffffffff;
01392
01393 JPEG_len=0;
01394 x313_dma_reset_chain();
01395 x313_dma_start();
01396 setCamSeqState(CAMSEQ_SINGLE);
01397
01398 X313_CHN_DIS(2);
01399 setCamSeqCount(imageParamsR[P_SKIP_FRAMES]);
01400 X313_ACQUIRE_ON;
01401 EN_INTERRUPT(nint_vact);
01402 return 0;
01403 }
01404 if ((nfr==0) && (len == -1)) {
01405 if (res==CAMSEQ_JPEG) {
01406 MD1(printk("Restarting RUN\n"));
01407 setCamSeqState(CAMSEQ_RUN);
01408 setCamSeqCount(0);
01409 return 0;
01410 } else {
01411 MD1(printk("Starting RUN\n"));
01412 resetPointers();
01413 x313_dma_reset_chain();
01414 x313_dma_start();
01415 setCamSeqState(CAMSEQ_RUN);
01416
01417
01418 if (IS_KAI11000) {
01419 MD7(printk("camSeqStartClip - using KAI-11002"));
01420 setCamSeqCount(imageParamsR[P_SKIP_FRAMES]);
01421 X313_ACQUIRE_ON;
01422
01424 X313_POSTINIT_SDCHAN(2,(jpeg_sdram_ctl0 | 0x2000));
01425 compressorRun();
01426 camSeqCount--;
01427 EN_INTERRUPT(nint_done_compress);
01428 } else {
01429 X313_CHN_DIS(2);
01430 setCamSeqCount(imageParamsR[P_SKIP_FRAMES]);
01431 X313_ACQUIRE_ON;
01432 EN_INTERRUPT(nint_vact);
01433 }
01434 return 0;
01435 }
01436 }
01437 MD7(printk("camSeqStartClip(0x%x, 0x%x), state=%d\n",nfr,len,res));
01438 if (res==CAMSEQ_JPEG) {
01439 MD1(printk("Restarting SINGLE\n"));
01440 local_irq_save(flags);
01441 if (nfr<0) JPEG_nfr=0x7fffffff;
01442 else JPEG_nfr+=nfr;
01443 if (len<0) JPEG_lfr=0x7fffffff;
01444 else if (len>0) JPEG_lfr=len;
01445
01446 local_irq_restore(flags);
01447 return 0;
01448 } else {
01449 MD1(printk("Starting SINGLE\n"));
01450 resetPointers();
01451 x313_dma_reset_chain();
01452 x313_dma_start();
01453 setCamSeqState(CAMSEQ_JPEG);
01454
01455 X313_CHN_DIS(2);
01456
01457 if ((len!=0) || (nfr !=0)) {
01458 if (nfr<0) JPEG_nfr=0x7fffffff;
01459 else JPEG_nfr+=nfr;
01460 if (len<0) JPEG_lfr=0x7fffffff;
01461 else if (len>0) JPEG_lfr=len;
01462 if (IS_KAI11000) {
01463 MD7(printk("camSeqStartClip - using KAI-11002"));
01464 setCamSeqCount(imageParamsR[P_SKIP_FRAMES]);
01465
01466 X313_ACQUIRE_ON;
01467 writeSensorReg16(0x14, 0, 1);
01469 X313_POSTINIT_SDCHAN(2,(jpeg_sdram_ctl0 | 0x2000));
01470 compressorRun();
01471
01472 camSeqCount--;
01473 EN_INTERRUPT(nint_done_compress);
01474 } else {
01475
01476
01477 setCamSeqCount(imageParamsR[P_SKIP_FRAMES]);
01478 X313_ACQUIRE_ON;
01479 EN_INTERRUPT(nint_vact);
01480 }
01481 } else {
01482
01483 JPEG_nfr=1;
01484 JPEG_lfr=0x7fffffff;
01485
01486 JPEG_len= JPEG_wp-JPEG_rp;
01487 if (JPEG_len<0) JPEG_len+=CCAM_DMA_SIZE;
01488 X313_POSTINIT_SDCHAN(2,jpeg_sdram_ctl0);
01489
01490 compressorSingle();
01491 EN_INTERRUPT(nint_done_compress);
01492 }
01493 }
01494 return 0;
01495 }
01496
01497
01499
01500 #define OLD_CAMSEQSTOP 0
01501
01502
01503
01504
01505
01506 void camSeqStop(void) {
01507
01508 MD1(printk("camSeqStop:getCamSeqState()=0x%x, imageParamsR[P_COMPRESSOR_CMD]=0x%x\n",getCamSeqState(), (int) imageParamsR[P_COMPRESSOR_CMD]));
01509 MD12(printk ("camSeqStop: state=%d rp=0x%x, wp=0x%x\r\n", getCamSeqState(), JPEG_rp, JPEG_wp ));
01510 MD11(printk ("camSeqStop: state=%d rp=0x%x, wp=0x%x\r\n", getCamSeqState(), JPEG_rp, JPEG_wp ));
01511 DIS_INTERRUPTS;
01512 X313_ACQUIRE_STOP ;
01514
01515 if (imageParamsR[P_COMPRESSOR_CMD]) {
01517 compressorStop();
01518 }
01519
01520
01521
01522 #if OLD_CAMSEQSTOP
01524 if (getCamSeqState()>=CAMSEQ_JPEG) { // stop acquisition
01525 x313_dma_stop();
01526 setCamSeqState(CAMSEQ_READY);
01527 } else {
01528
01529 JPEG_wp=0;
01530 imageParamsR[P_JPEG_WP]=JPEG_wp;
01531 imageParamsR[P_CIRCBUFWP]= JPEG_wp<<2;
01532 imageParamsR[P_FREECIRCBUF] = imageParamsR[P_CIRCBUFRP];
01533
01534 JPEG_rp=0;
01535 imageParamsR[P_FREECIRCBUF] = 0;
01536 JPEG_len=0;
01537 JPEG_nfr=0;
01538 JPEG_lfr=0;
01539 x313_dma_reset_chain();
01540 }
01541 #endif
01542 setCamSeqCount(0);
01543
01544 if (getCamSeqState()!=CAMSEQ_OFF) setCamSeqState(CAMSEQ_READY);
01545 MD11(printk ("camSeqStop-exit: state=%d rp=0x%x, wp=0x%x\r\n", getCamSeqState(), JPEG_rp, JPEG_wp ));
01546 }
01547
01548
01549 int get_sensor_i2c_regs16(int n) {return (((int) (sensor_i2c_regs[n<<1]))<<8)+sensor_i2c_regs[(n<<1)+1] ;}
01550 unsigned char get_sensor_i2c_regs (int n) {return sensor_i2c_regs[n] ;}
01551 unsigned long get_imageParamsR (int n) {return imageParamsR[n];}
01552 unsigned long get_imageParamsW (int n) {return imageParamsW[n];}
01553 unsigned char get_sensor_i2c_addr (void) {return sensor_i2c_addr ;}
01554 void set_sensor_i2c_regs (int n, unsigned char d) {sensor_i2c_regs[n]=d;}
01555 void set_imageParamsR (int n, unsigned long d) {imageParamsR[n]=d;}
01556 void set_imageParamsW (int n, unsigned long d) {imageParamsW[n]=d;}
01557 void set_sensor_i2c_addr ( unsigned char d) {sensor_i2c_addr=d;}
01558
01559
01560
01561 void ccamCRAnd(unsigned long d) {
01562 unsigned long flags;
01563 local_irq_save(flags);
01564 port_csp0_addr[X313_WA_WCTL]= (ccam_cr_shadow &= d);
01565 local_irq_restore(flags);
01566 }
01567
01568 void ccamCROr(unsigned long d) {
01569 unsigned long flags;
01570 local_irq_save(flags);
01571 port_csp0_addr[X313_WA_WCTL]= (ccam_cr_shadow |= d);
01572 local_irq_restore(flags);
01573 }
01574
01575 void ccamCRXor(unsigned long d) {
01576 unsigned long flags;
01577 local_irq_save(flags);
01578 port_csp0_addr[X313_WA_WCTL]= (ccam_cr_shadow ^= d);
01579 local_irq_restore(flags);
01580 }
01581
01582
01583 void ccamCRAndOr(unsigned long d_and, unsigned long d_or) {
01584 unsigned long flags;
01585 local_irq_save(flags);
01586 ccam_cr_shadow &= d_and;
01587 port_csp0_addr[X313_WA_WCTL]= (ccam_cr_shadow |= d_or);
01588 local_irq_restore(flags);
01589 }
01590
01591 unsigned long ccamGetCR(void) {return ccam_cr_shadow;}
01592
01593 void writeSensorDefaults(unsigned long * data, int count) {
01594 int i;
01595 MD7 (printk ("writing sensor defaults to imageParamsW[] (needs update to copy to imageParamsR[]), count=%d (decimal)\r\n",count));
01596 for (i=0;i<count;i++) {
01597 imageParamsW[data[2*i]]=data[2*i+1];
01598 MD7 (printk ("%ld(0x%lx): %ld(0x%lx)\r\n",data[2*i],data[2*i],data[2*i+1],data[2*i+1]));
01599
01600 }
01601 imageParamsR[P_PARS_CHANGED]=1;
01602 }
01603
01604
01605
01606
01607
01608 int readSensorReg(unsigned int ra, int mode) {
01609 int i;
01610 unsigned long flags;
01611 int i1=0;
01612 unsigned char rab=ra & 0xff;
01613 int rindx= (ra>>16) & 0x1ff; if (!rindx) rindx=rab;
01614 if(mode) {
01615 MD7 (printk ("ra= 0x%x, rab=0x%x, shadow was =0x%x - ",ra, (int) rab, (int)sensor_i2c_regs[rindx]));
01616 local_irq_save(flags);
01617 X3X3_I2C_STOP_WAIT ;
01618 i= i2c_writeData(0, sensor_i2c_addr & 0xfe, &rab, 1, 0);
01619 if (!i) i1= i2c_readData(0, sensor_i2c_addr | 0x01, &sensor_i2c_regs[rindx], 1, 0);
01620 X3X3_I2C_RUN ;
01621 local_irq_restore(flags);
01622 if (i1) return -i1-1000;
01623 if (i) return -i;
01624 }
01625 MD7 (printk (" new x%x\r\n",(int)sensor_i2c_regs[rindx]));
01626
01627 return (int)sensor_i2c_regs[rindx];
01628 }
01629
01630 int writeSensorReg(unsigned int ra, unsigned char rd, int uncond) {
01631 int i, res;
01632 unsigned long flags;
01633 unsigned char rab=ra & 0xff;
01634 int rindx= (ra>>16) & 0x1ff; if (!rindx) rindx=rab;
01635 unsigned char d[2];
01636
01637 if (!uncond && (sensor_i2c_regs[rindx] == rd)) {
01638 MD8(printk("writeSensorReg(0x%x,0x%x) did not do anything\n",(int) ra,(int) rd));
01639 return 0;
01640
01641 }
01642 d[0]=rab;
01643 d[1]=rd;
01644 local_irq_save(flags);
01645 X3X3_I2C_STOP_WAIT ;
01646 i=i2c_writeData(0, sensor_i2c_addr, &d[0], 2, 1 );
01647 X3X3_I2C_RUN ;
01648 local_irq_restore(flags);
01649 if (i) {
01650 i=d[0]; res=d[1];
01651 printk ("\tError writing I2C register %2x with data %2x\r\n",i,res);
01652 return -1;
01653 }
01654 MD8(printk("writeSensorReg(0x%x,0x%x) wrote to sensor (shadow was 0x%x)\r\n",(int) ra,(int) rd, (int) sensor_i2c_regs[rindx]));
01655 sensor_i2c_regs[rindx] = rd;
01656 return 1;
01657 }
01658
01659
01660
01661 int readSensorReg16(unsigned char ra, int mode) {
01662 int i,a;
01663 int i1=0;
01664 a=ra;
01665 unsigned long flags;
01666 if(mode) {
01667 MD8 (printk ("ra= 0x%x, shadow was =0x%x - ",(int) ra, get_sensor_i2c_regs16(ra)));
01668 local_irq_save(flags);
01669 X3X3_I2C_STOP_WAIT ;
01670 i= i2c_writeData(0, sensor_i2c_addr & 0xfe, &ra, 1, 0);
01671 if (!i) i1= i2c_readData(0, sensor_i2c_addr | 0x01, &sensor_i2c_regs[a<<1], 2, 0);
01672 X3X3_I2C_RUN ;
01673 local_irq_restore(flags);
01674 if (i1) return -i1-1000;
01675 if (i) return -i;
01676 }
01677 MD8 (printk (" new 0x%x\r\n",get_sensor_i2c_regs16(ra)));
01678 return get_sensor_i2c_regs16(ra);
01679 }
01680
01681 int writeSensorReg16(unsigned char ra, int rd, int uncond) {
01682 int res, a;
01683 unsigned char d[3];
01684 #ifndef USE_HARDWARE_I2C
01685 unsigned long flags;
01686 #endif
01687 a=ra;
01688 d[0]=ra;
01689 d[1]=(rd>>8) & 0xff;
01690 d[2]= rd & 0xff;
01691 if (!uncond && (sensor_i2c_regs[(a<<1)] == d[1]) && (sensor_i2c_regs[(a<<1)+1] == d[2])) return 0;
01692 #ifdef USE_HARDWARE_I2C
01693
01694
01695 X3X3_I2C_SEND2(X313_I2C_ASAP, sensor_i2c_addr, a, rd);
01696 res=0;
01697 #else
01698 local_irq_save(flags);
01699 X3X3_I2C_STOP_WAIT ;
01700 res=i2c_writeData(0, sensor_i2c_addr, &d[0], 3, 1);
01701 X3X3_I2C_RUN ;
01702 local_irq_restore(flags);
01703 #endif
01704 if (res) {
01705 printk ("\tError (%x) writing 16-bit I2C register %2x with data %4x, dev_addr=%2x\r\n",res,a,((int) d[1]<<8)+ (int) d[2],sensor_i2c_addr);
01706 return -1;
01707 }
01708 MD8(printk("writeSensorReg(0x%x,0x%x) wrote to sensor (shadow was 0x%x)\r\n",(int) ra,(int) rd,get_sensor_i2c_regs16(a)));
01709 sensor_i2c_regs[(a<<1) ] = d[1];
01710 sensor_i2c_regs[(a<<1)+1] = d[2];
01711 return 1;
01712 }
01713
01714
01715
01716 int writeSensorRegFF(unsigned char ra, int rd, int uncond) {
01717 int res, a;
01718 unsigned char d[3];
01719 unsigned long flags;
01720
01721 a=ra;
01722 d[0]=((ra & 0x0f) << 4) | ((rd >> 8) & 0x0f);
01723 d[1]= rd & 0xff;
01724
01725 if (!uncond && (sensor_i2c_regs[(a<<1)] == (d[0] & 0xf)) && (sensor_i2c_regs[(a<<1)+1] == d[1])) {
01726 MD(printk("writeSensorRegFF(0x%x,0x%x) did not do anything\r\n",(int) ra,(int) rd));
01727
01728
01729
01730
01731
01732
01733
01734
01735 return 0;
01736 }
01737
01738
01739 local_irq_save(flags);
01740 X3X3_I2C_STOP_WAIT ;
01741
01742 if ((res=i2c_writeData(0, sensor_i2c_addr, &d[0], 2, 1))) {
01743 printk ("\tError (%x) writing 16-bit I2C register %2x with data %4x\r\n",res,a,((int) d[1]<<8)+ (int) d[2]);
01744 return -1;
01745 }
01746 X3X3_I2C_RUN ;
01747 local_irq_restore(flags);
01748
01749 MD(printk("writeSensorReg(0x%x,0x%x) wrote to sensor (shadow was 0x%x)\r\n",(int) ra,(int) rd, ((int)sensor_i2c_regs[a<<1])<<8 +((int)sensor_i2c_regs[(a<<1)+1])));
01750 sensor_i2c_regs[(a<<1) ] = (d[0] & 0x0f);
01751 sensor_i2c_regs[(a<<1)+1] = d[1];
01752 return 1;
01753 }
01754
01755
01756
01757 static int __init
01758 cmoscam_init(void) {
01759 int res;
01760 ccam_cr_shadow=0;
01761 init_ccam_dma_buf_ptr();
01762 init_autoexp_struct();
01763 sensor_i2c_regs = (char*) sensor_i2c_regs16;
01764
01765 res = register_chrdev(CMOSCAM_MAJOR, cmoscam_name, &cmoscam_fops);
01766 if(res < 0) {
01767 printk(KERN_ERR "ccam: couldn't get a major number.\n");
01768 return res;
01769 }
01770 if(request_irq(EXT_INTR_VECT,
01771 camSeq_interrupt,
01772 SA_INTERRUPT,
01773 "Elphel FPGA interrupts",
01774 NULL)) {
01775 printk(KERN_ERR "Can't allocate Elphel FPGA interrupts");
01776 return -EBUSY;
01777 }
01778 printk("CMOS/MCP camera interrupts initialized\n");
01779 init_waitqueue_head(&x313_wait_queue);
01780 DMA_buf_start=x313_dma_init();
01781 printk(CMOSCAM_DRIVER_NAME);
01782 return 0;
01783 }
01784
01785
01786 static int init_FPGA(void) {
01787 int i;
01788 int f1,f2;
01789
01790 if ((i=port_csp0_addr[X313__RA__MODEL]) < X313_MINMODREV) {
01791 printk ("too old fpga rev - found %x, software wants >= %x\n",i,X313_MINMODREV);
01792 return -1;
01793 }
01794 if (i > X313_MAXMODREV) {
01795 printk ("too new fpga rev - found %x, software wants <= %x\n",i,X313_MAXMODREV);
01796 return -1;
01797 }
01798
01799
01800 if (!X313_IS_SDRAM_ON) fpga_initSDRAM();
01801
01802
01803
01804
01805 if (X313_CHN0_USED!=0) return 0;
01806 D5(printk ("FPGA/Sensor need initialization. Wait 1 sec for troubleshooting\n"); udelay (1000000));
01807
01808
01809
01810
01811
01812 f1=imageParamsR[P_CLK_SENSOR]=20000000; setClockFreq(1, imageParamsR[P_CLK_SENSOR]); X3X3_RSTSENSDCM;
01813
01814
01815 f2=imageParamsR[P_CLK_FPGA]=getClockFreq(0);
01816 D5(printk("clock1=%d,clck0=%d\r\n",f1,f2));
01817
01818
01819
01820 udelay (50000);
01821 fpga_initSDRAM();
01822 D5(printk ("------init_FPGA\n"));
01823 init_sensor();
01824 D5(printk ("init_sensor() finished\n"));
01825 udelay (1000000);
01826
01827
01828 #ifdef CONFIG_ETRAX_ELPHEL_MCP
01829 if (MCP_initmodule()== 0) printk ("MCP module initialized\r\n");
01830 else printk ("no MCP module detected\r\n");
01831 #endif
01832
01833 printk("FPGA rev %x\n", (unsigned int) port_csp0_addr[X313__RA__MODEL]);
01834 x313_tables_gammainitlinear();
01835 printk("Programmed linear intensity table (gamma=1.0)\n");
01836
01837
01838
01839
01840
01841 initCamIRQs();
01842
01843
01844
01845 return 1;
01846
01847 }
01848
01849 struct sensor_t kai11002={
01850
01851 .imageWidth = 4008,
01852 .imageHeight = 2672,
01853 .clearWidth = 4032,
01854 .clearHeight = 2688,
01855 .clearTop = 16,
01856 .clearLeft = 20,
01857 .arrayWidth = 4072,
01858 .arrayHeight = 2720,
01859 .minWidth = 4,
01860 .minHeight = 3,
01861 .minHorBlank = 999,
01862 .minLineDur = 999,
01863 .maxHorBlank = 9999,
01864 .minVertBlank= 99,
01865 .maxVertBlank= 9999,
01866 .maxShutter = 0x3fff,
01867 .flips = 3,
01868 .dcmHor = 0x1,
01869 .dcmVert = 0x1,
01870 .binHor = 0x1,
01871 .binVert = 0x1,
01872 .maxGain256 = 4032,
01873 .maxClockFreq= 48000000,
01874 .nomClockFreq= 48000000,
01875 .sensorType = SENSOR_KAI11000,
01876 .i2c_addr = 0x10,
01877 .i2c_period = 2500,
01878 .i2c_bytes = 2,
01879 .margins = 0,
01880
01881 .pixelWidth = 0,
01882 .pixelHeight = 0
01883 };
01884
01885 int init_sensor(void) {
01886 int i;
01887
01888
01889 MD10(dumpFrameParams(&frame_params,"\nframe parameters before init_sensor:"));
01891 program_i2c();
01892 X3X3_I2C_RESET_WAIT ;
01893
01894 if (IS_KAI11000) {
01895 printk("------------------ using KAI-11000 ---------------------- \n");
01896
01897 memcpy(&sensor, &kai11002, sizeof(kai11002));
01898 imageParamsR[P_SENSOR_WIDTH]=sensor.imageWidth;
01899 imageParamsR[P_SENSOR_HEIGHT]=sensor.imageHeight;
01900 imageParamsW[P_WOI_WIDTH]=sensor.imageWidth;
01901 imageParamsW[P_WOI_HEIGHT]=sensor.imageHeight;
01902 imageParamsR[P_SENSOR]= sensor.sensorType;
01903 imageParamsW[P_CLK_SENSOR]=sensor.nomClockFreq;
01904 imageParamsR[P_VIDEO]=0;
01905 imageParamsW[P_VIDEO]=0;
01906 imageParamsW[P_SKIP_FRAMES]=imageParamsR[P_SKIP_FRAMES]=0;
01907 sensor.margins =X313_MARGINS;
01908 writeSensorDefaults(&default_common[0],sizeof(default_common)/sizeof(default_common[0])/2);
01909 MD7(printk ("sensorType=%ld,sensor.imageWidth=%ld,sensor.imageHeight=%ld\r\n", sensor.sensorType,sensor.imageWidth,sensor.imageHeight));
01910 set_sensor_i2c_addr(0x20);
01911 imageParamsW[P_IRQ_SMART] &= 2;
01912 program_smart_irq();
01913 X3X3_RSTSENSDCM;
01914 printk ("pclk2x DCM is reset\r\n");
01915 i=programSensor(0);
01916 udelay (1000);
01917 X3X3_I2C_RUN ;
01918 return i;
01919 }
01920
01921
01922
01923 printk("removing MRST from the sensor, setting DMA burst size, setting MCLK to 20MHz\r\n");
01924
01925 ccamCRAndOr(0,0x80000000);
01926 PROGRAM_CLK_EN(1);
01927 udelay (100);
01928
01929
01930
01931 CCAM_NEGRST;
01932 CCAM_MRST_OFF;
01933 CCAM_ARST_OFF;
01934 writeSensorDefaults(&default_common[0],sizeof(default_common)/sizeof(default_common[0])/2);
01935 program_smart_irq();
01936
01937 imageParamsR[P_SENSOR]=0;
01938 for (i=0;i<256;i++) sensor_i2c_regs[i]=0;
01939
01940 #ifdef CONFIG_ETRAX_ELPHEL_MT9X001
01941 printk("trying MT9X001\r\n");
01942 if (imageParamsR[P_SENSOR]==0) init_mt9x001();
01943 #endif
01944
01945
01946 #define ENABLE_OLD_SENSORS 1
01947 #ifdef ENABLE_OLD_SENSORS
01948 if (imageParamsR[P_SENSOR]==0) {
01949 CCAM_CNVEN_ON;
01950
01951
01952
01953
01954
01955
01956
01957 port_csp0_addr[X313_WA_DCDC] = 0x44;
01958 printk ("sensor power set low\r\n ");
01959 udelay (10000);
01960
01961 printk ("will set to 0x41\r\n");
01962 udelay (10000);
01963 port_csp0_addr[X313_WA_DCDC] = 0x41;
01964 printk ("will set to 0x30\r\n");
01965 udelay (10000);
01966 port_csp0_addr[X313_WA_DCDC] = 0x30;
01967 printk ("will set to 0x28\r\n");
01968 udelay (10000);
01969 port_csp0_addr[X313_WA_DCDC] = 0x28;
01970 printk ("will set to 0x24\r\n");
01971 udelay (10000);
01972 port_csp0_addr[X313_WA_DCDC] = 0x24;
01973 printk ("will set to 0x22\r\n");
01974 udelay (10000);
01975 port_csp0_addr[X313_WA_DCDC] = 0x22;
01976
01977 udelay (100000);
01978 port_csp0_addr[X313_WA_DCDC] = 0x10;
01979 printk (".. full\r\n");
01980
01981 udelay (10000);
01982 ccamCRAndOr(0,0x80000800);
01983 CCAM_CNVEN_ON;
01984 PROGRAM_CLK_EN(1);
01985 udelay (100);
01986
01987 CCAM_POSRST;
01988 udelay (100);
01989 CCAM_MRST_OFF;
01990 }
01991
01992
01993
01994
01995
01996
01997
01998 #ifdef CONFIG_ETRAX_ELPHEL_KAC1310
01999 if (imageParamsR[P_SENSOR]==0) init_KAC1310();
02000 #endif
02001 #ifdef CONFIG_ETRAX_ELPHEL_IBIS51300
02002 if (imageParamsR[P_SENSOR]==0) init_IBIS51300();
02003 #endif
02004
02005 if (imageParamsR[P_SENSOR]==0) {
02006 CCAM_NEGRST;
02007 printk ("Inverted MRST, ccam_cr_shadow= %x\n", (int) ccam_cr_shadow);
02008 udelay (100);
02009 }
02010 #ifdef CONFIG_ETRAX_ELPHEL_MT9X001
02011 printk("trying MT9X001\n");
02012 if (imageParamsR[P_SENSOR]==0) init_mt9x001();
02013 #endif
02014
02015 #ifdef CONFIG_ETRAX_ELPHEL_KAC1310
02016 if (imageParamsR[P_SENSOR]==0) init_KAC5000();
02017 #endif
02018
02019 #ifdef CONFIG_ETRAX_ELPHEL_ZR32112
02020 if (imageParamsR[P_SENSOR]==0) init_ZR32112();
02021 #endif
02022
02023 #ifdef CONFIG_ETRAX_ELPHEL_ZR32212
02024 if (imageParamsR[P_SENSOR]==0) init_ZR32212();
02025 #endif
02026
02027 #endif // *************** temporary disabling other sensors ********************
02028
02029 if (imageParamsR[P_SENSOR]==0) {
02030 sensor.sensorType=SENSOR_NONE;
02031 imageParamsR[P_SENSOR]=SENSOR_NONE;
02032 printk("No image sensor found\r\n");
02033
02034 }
02035 imageParamsR[P_SENSOR_WIDTH]=sensor.imageWidth;
02036 imageParamsR[P_SENSOR_HEIGHT]=sensor.imageHeight;
02037 imageParamsW[P_WOI_WIDTH]=sensor.imageWidth;
02038 imageParamsW[P_WOI_HEIGHT]=sensor.imageHeight;
02039 imageParamsR[P_SENSOR]= sensor.sensorType;
02040 imageParamsW[P_CLK_SENSOR]=sensor.nomClockFreq;
02041 imageParamsR[P_VIDEO]=1;
02042 imageParamsW[P_VIDEO]=1;
02043 sensor.margins =X313_MARGINS;
02045
02046 imageParamsW[P_I2C_QPERIOD]= (sensor.i2c_period * (imageParamsR[P_CLK_FPGA]/1000))/4000000;
02047 imageParamsW[P_I2C_BYTES]=sensor.i2c_bytes;
02048 program_i2c();
02049 X3X3_I2C_RESET_WAIT ;
02050 X3X3_I2C_RUN ;
02051 imageParamsR[P_FRAME]=0 ;
02052
02053 MD7(printk ("sensorType=%ld,sensor.imageWidth=%ld,sensor.imageHeight=%ld,sensor.margins=%ld\r\n", sensor.sensorType,sensor.imageWidth,sensor.imageHeight,sensor.margins));
02054
02055 return programSensor(0);
02056 }
02057
02058
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071 void x313_program_focus(int totalwidth) {
02072 unsigned long flags;
02073 totalwidth&= 0xfff0;
02074 int left, right, top, bottom, filter_no,show1;
02075 show1=imageParamsW[P_FOCUS_SHOW1];
02076 left=imageParamsW[P_FOCUS_LEFT] & 0xff8;
02077 right=(left+imageParamsW[P_FOCUS_WIDTH] -8);
02078 if (right<0) {
02079 right=0;
02080 left=8;
02081 }
02082 else if (right > 0xfff) right = 0xfff;
02083 right &=0xff8;
02084
02085 top=imageParamsW[P_FOCUS_TOP] & 0xff8;
02086 bottom=(top+imageParamsW[P_FOCUS_HEIGHT] -8);
02087 if (bottom<0) {
02088 bottom=0;
02089 top=8;
02090 }
02091 else if (bottom > 0xfff) bottom = 0xfff;
02092 bottom &=0xff8;
02093
02094 filter_no=imageParamsW[P_FOCUS_FILTER];
02095 if (filter_no > 14) filter_no=14;
02096
02097 if ((totalwidth!=imageParamsR[P_FOCUS_TOTWIDTH]) ||
02098 (left != imageParamsR[P_FOCUS_LEFT]) ||
02099 (right != (left+imageParamsR[P_FOCUS_WIDTH] -8)) ||
02100 (top != imageParamsR[P_FOCUS_TOP]) ||
02101 (bottom != (top+imageParamsR[P_FOCUS_HEIGHT] -8)) ||
02102 (filter_no != imageParamsR[P_FOCUS_FILTER]) ||
02103 (show1 != imageParamsR[P_FOCUS_SHOW1])) {
02104 imageParamsR[P_FOCUS_SHOW1]= show1;
02105 imageParamsR[P_FOCUS_TOTWIDTH]=totalwidth;
02106 imageParamsR[P_FOCUS_LEFT]= left;
02107 imageParamsR[P_FOCUS_WIDTH]= right-left+8;
02108 imageParamsR[P_FOCUS_TOP]= top;
02109 imageParamsR[P_FOCUS_HEIGHT]= bottom-top+8;
02110 imageParamsR[P_FOCUS_FILTER]= filter_no;
02111 local_irq_save(flags);
02112
02113 port_csp0_addr[X313_WA_COMP_TA]=CX313_FPGA_TABLES_FOCUSPARS;
02114 port_csp0_addr[X313_WA_COMP_TD]=left;
02115 port_csp0_addr[X313_WA_COMP_TD]=right;
02116 port_csp0_addr[X313_WA_COMP_TD]=top;
02117 port_csp0_addr[X313_WA_COMP_TD]=bottom;
02118 port_csp0_addr[X313_WA_COMP_TD]=totalwidth-1;
02119 port_csp0_addr[X313_WA_COMP_TD]=filter_no;
02120 port_csp0_addr[X313_WA_COMP_TD]=show1;
02121 port_csp0_addr[X313_WA_COMP_TA]=CX313_FPGA_TABLES_FOCUSPARS;
02122 local_irq_restore(flags);
02123 }
02124
02125 imageParamsR[P_FOCUS_SHOW]=imageParamsW[P_FOCUS_SHOW] & 3;
02126 x313_JPEG_ctrl((x313_get_JPEG_ctrl() & 0x9fff) | (imageParamsR[P_FOCUS_SHOW] << 13));
02127 }
02128
02129
02130
02131
02132
02133 static int program_KAI11000(void) {
02134 printk("here programmimbg KAI11000\n");
02135 return 1;
02136 }
02137 #define PROGRAM_SENSOR_DIS_IRQ 0
02138 static int programSensor(int nonstop){
02139 struct hist_sensor_t *hist_s = NULL;
02140
02141 float fscale_r;
02142 float fscale_g;
02143 float fscale_b;
02144 float fscale_g1;
02145 int hact_shift;
02146 unsigned long scale_r;
02147 unsigned long scale_g;
02148 unsigned long scale_b;
02149 unsigned long scale_g1;
02150 int ntilex,ntiley,padlen,n,sa,i;
02151
02152 int ntilex_compressor,ntiley_compressor;
02153
02154 int dh,dv,bh,bv,l,h,t,timestamp_len,pfh,pf_stripes;
02155 int goodEOL=0;
02156 int sensRslt=0;
02157 #if PROGRAM_SENSOR_DIS_IRQ
02158 unsigned long flags;
02159 #endif
02160 short * shortP;
02161 int scales_changed;
02162 MD1(printk("programSensor:, imageParamsR[P_PARS_CHANGED]=%x, nonstop=%d\n", (int) imageParamsR[P_PARS_CHANGED], nonstop));
02163 MD11(printk ("programSensor rp=0x%x, wp=0x%x\r\n", JPEG_rp, JPEG_wp ));
02164
02165
02166
02167 imageParamsR[P_TASKLET_CTL]=imageParamsW[P_TASKLET_CTL];
02168
02169 if (imageParamsW[P_CLK_SENSOR]) {
02170 if (setClockFreq(1, imageParamsW[P_CLK_SENSOR])>=0) imageParamsR[P_CLK_SENSOR]=imageParamsW[P_CLK_SENSOR];
02171 imageParamsW[P_CLK_SENSOR]=0;
02172 X3X3_RSTSENSDCM;
02173
02174
02175
02176
02177 hact_shift= 0.004 * (sensor.hact_delay/(1000000000.0/imageParamsR[P_CLK_SENSOR])) + 0.5;
02178 MD12(printk ("hact_shift=%d\r\n",hact_shift));
02179 if (hact_shift>3) hact_shift=3;
02180 CCAM_SET_HACT_PHASE(hact_shift) ;
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196 MD12(printk("imageParamsR[%d]=0x%x imageParamsW[%d]=0x%x\r\n", (int) P_SENSOR_PHASE, (int) imageParamsR[P_SENSOR_PHASE], (int) P_SENSOR_PHASE, (int) imageParamsW[P_SENSOR_PHASE]) );
02197 if (imageParamsW[P_SENSOR_PHASE] !=0 ) {
02198 imageParamsR[P_SENSOR_PHASE]=imageParamsW[P_SENSOR_PHASE];
02199 imageParamsW[P_SENSOR_PHASE]=0;
02200 }
02201
02202 if (imageParamsR[P_SENSOR_PHASE] !=0 ) {
02203 MD12(printk("imageParamsR[%d]=0x%x\r\n", (int) P_SENSOR_PHASE, (int) imageParamsR[P_SENSOR_PHASE]));
02204 shortP= (short * ) &imageParamsR[P_SENSOR_PHASE];
02205 sensor.sensorPhase= shortP[0];
02206 sensor.sensorPhase90=shortP[1] & 3;
02207 MD12(printk ("sensor.sensorPhase=0x%x, sensor.sensorPhase90=0x%x\r\n",(int) sensor.sensorPhase, (int) sensor.sensorPhase90));
02208 }
02209
02210
02211 for (i=sensor.sensorPhase90;i>0;i--) {
02212 X3X3_SENSDCM_INC90 ;
02213 }
02214 if (sensor.sensorPhase > 0) for (i=sensor.sensorPhase; i > 0; i--) {X3X3_SENSDCM_INC ; udelay(1); }
02215 else if (sensor.sensorPhase < 0) for (i=sensor.sensorPhase; i < 0; i++) {X3X3_SENSDCM_DEC ; udelay(1); }
02216
02217 shortP= (short * ) &imageParamsR[P_SENSOR_PHASE];
02218 shortP[0] = sensor.sensorPhase;
02219 shortP[1] = sensor.sensorPhase90 | 4;
02220 MD12(printk("imageParamsR[%d]=0x%x\r\n", (int) P_SENSOR_PHASE, (int) imageParamsW[P_SENSOR_PHASE]));
02221
02222 switch (imageParamsR[P_SENSOR] & SENSOR_MASK) {
02223
02224
02225 case SENSOR_KAI11000: { break;}
02226
02227
02228
02229 #ifdef CONFIG_ETRAX_ELPHEL_ZR32112
02230 case SENSOR_ZR32112: { break;}
02231 #endif
02232 #ifdef CONFIG_ETRAX_ELPHEL_ZR32212
02233 case SENSOR_ZR32212: { break;}
02234 #endif
02235 #ifdef CONFIG_ETRAX_ELPHEL_KAC1310
02236 case SENSOR_KAC1310: { break;}
02237 #endif
02238 #ifdef CONFIG_ETRAX_ELPHEL_KAC1310
02239 case SENSOR_KAC5000: { break;}
02240 #endif
02241 #ifdef CONFIG_ETRAX_ELPHEL_MT9X001
02242 case SENSOR_MT9X001:
02243 case SENSOR_MT9Y001:
02244 {
02245
02246 CCAM_MRST_ON;
02247 udelay (100);
02248 CCAM_MRST_OFF;
02249 printk ("Resetting sensor after sensor clock change\n");
02250 init_mt9x001();
02251 sensor.margins =X313_MARGINS;
02252
02253
02254
02255 nonstop=0;
02256 break;}
02257 #endif
02258 #ifdef CONFIG_ETRAX_ELPHEL_IBIS51300
02259 case SENSOR_IBIS51300: { break;}
02260 #endif
02261 }
02262 }
02263
02264
02265 if ((imageParamsR[P_SENSOR] & SENSOR_MASK)==SENSOR_NONE) {
02266 printk("can not program unknown/unexistent sensor\r\n");
02267
02268
02269 X313_CHN0_SET_USED;
02270 return 0;
02271 }
02272
02273
02274
02275
02276
02277 if(down_interruptible(&sensor_lock) != 0) return -1;
02278
02279
02280
02281 MD8(printk("nonstop=%d\r\n", nonstop));
02282
02283 if (!nonstop) {
02284 imageParamsR[P_OVERSIZE]=imageParamsW[P_OVERSIZE]?1:0;
02285 #if PROGRAM_SENSOR_DIS_IRQ
02286 local_irq_save(flags);
02287 #endif
02288 MD11(printk ("program sensor, !nonstop -> ... "));
02289
02290 camSeqStop();
02291 MD6(printk ("programSensor imageParamsR[P_PARS_CHANGED]=0x%x\r\n",imageParamsR[P_PARS_CHANGED]));
02293 imageParamsR[P_PARS_CHANGED]=1;
02294
02295 }
02296 if (imageParamsR[P_PARS_CHANGED]) {
02297 imageParamsR[P_EXPOS]= (imageParamsW[P_EXPOS]>0)?imageParamsW[P_EXPOS]:1;
02298
02299 if ((imageParamsW[P_COLOR_SATURATION_BLUE] != imageParamsR[P_COLOR_SATURATION_BLUE]) ||
02300 (imageParamsW[P_COLOR_SATURATION_RED] != imageParamsR[P_COLOR_SATURATION_RED])) {
02301 if (imageParamsW[P_COLOR_SATURATION_BLUE]<0) imageParamsW[P_COLOR_SATURATION_BLUE]=0;
02302 if (imageParamsW[P_COLOR_SATURATION_RED]<0) imageParamsW[P_COLOR_SATURATION_RED]=0;
02303 if ((imageParamsW[P_COLOR_SATURATION_BLUE]*DEFAULT_COLOR_SATURATION_BLUE) > 102300)
02304 imageParamsW[P_COLOR_SATURATION_BLUE]=102300/DEFAULT_COLOR_SATURATION_BLUE;
02305 if ((imageParamsW[P_COLOR_SATURATION_RED]*DEFAULT_COLOR_SATURATION_RED) > 102300)
02306 imageParamsW[P_COLOR_SATURATION_RED]=102300/DEFAULT_COLOR_SATURATION_RED;
02307 imageParamsR[P_COLOR_SATURATION_BLUE]=imageParamsW[P_COLOR_SATURATION_BLUE];
02308 imageParamsR[P_COLOR_SATURATION_RED]=imageParamsW[P_COLOR_SATURATION_RED];
02309
02310
02311
02312 frame_params.colorsat = ((DEFAULT_COLOR_SATURATION_BLUE*imageParamsR[P_COLOR_SATURATION_BLUE])/100) |
02313 (((DEFAULT_COLOR_SATURATION_RED *imageParamsR[P_COLOR_SATURATION_RED])/100)<<16);
02314 port_csp0_addr[X313_WA_COLOR_SAT]=frame_params.colorsat;
02315 }
02316
02317
02318
02319 port_csp0_addr[X313_WA_FRAMESYNC_DLY]= imageParamsR[P_FRAMESYNC_DLY]= imageParamsW[P_FRAMESYNC_DLY];
02320
02321
02322
02323
02324 if (!nonstop) {
02325 imageParamsR[P_DMA_VALID]=0;
02326
02327 imageParamsR[P_PAGE_ACQ]=imageParamsW[P_PAGE_ACQ];
02328 imageParamsR[P_BGFRAME]= imageParamsW[P_BGFRAME];
02329 imageParamsR[P_OVERLAP]=imageParamsW[P_OVERLAP];
02330
02331
02332
02333 imageParamsR[P_TRIG]= (imageParamsR[P_TRIG] & 4) | (imageParamsW[P_TRIG] & ~4);
02334 imageParamsR[P_VIRTTRIG]= imageParamsW[P_VIRTTRIG];
02335 imageParamsR[P_BITS]= (imageParamsW[P_BITS] < 5)? 4 : (imageParamsW[P_BITS] < 9)? 8: 10;
02336
02337
02338 imageParamsR[P_SHIFTL]=imageParamsW[P_SHIFTL]& 0x7;
02339 imageParamsR[P_FPNS]= imageParamsW[P_FPNS] & 0x7;
02340 imageParamsR[P_FPNM]= imageParamsW[P_FPNM] & 0x7;
02341 imageParamsR[P_AUXCM]=(imageParamsW[P_AUXCM] < 2)? imageParamsW[P_AUXCM] : 2;
02342 imageParamsR[P_MCLK]= (imageParamsW[P_MCLK]<129)?((imageParamsW[P_MCLK]>1)?imageParamsW[P_MCLK]:((imageParamsW[P_MCLK]>0)?2:0)):129;
02343
02344
02345
02346 PROGRAM_CLK_EN(1);
02347 }
02348
02349 if ((imageParamsW[P_FPSLM] & ~3) == 0) imageParamsR[P_FPSLM]= imageParamsW[P_FPSLM] & 0x3;
02350 MD9 (printk ("\r\n============ imageParamsW[P_FPSLM]=0x%08x=== imageParamsR[P_FPSLM]=0x%08x\r\n",imageParamsW[P_FPSLM],imageParamsR[P_FPSLM]));
02351
02352 imageParamsR[P_PERIOD]=0;
02353
02354 sensRslt=-1;
02355
02356
02357
02358
02359
02360
02361
02362 hist_image_exp(get_imageParamsR(P_VEXPOS));
02363 hist_s = hist_sensor_lock();
02364 if(hist_s != NULL) {
02365 set_imageParamsW(P_VEXPOS, hist_s->exposure);
02366
02367 hist_sensor_unlock();
02368 }
02369
02370
02371
02372
02373
02374
02376
02377
02378 if ((imageParamsW[P_GAMMA] != imageParamsR[P_GAMMA]) ||
02379 (imageParamsW[P_PIXEL_LOW] != imageParamsR[P_PIXEL_LOW] ) ||
02380 (imageParamsW[P_PIXEL_HIGH]!= imageParamsR[P_PIXEL_HIGH] ) ||
02381 (imageParamsW[P_RSCALE] != imageParamsR[P_RSCALE] ) ||
02382 (imageParamsW[P_GSCALE] != imageParamsR[P_GSCALE] ) ||
02383 (imageParamsW[P_BSCALE] != imageParamsR[P_BSCALE] )) {
02384
02385 imageParamsR[P_GAMMA]=imageParamsW[P_GAMMA];
02386 imageParamsR[P_PIXEL_LOW]=imageParamsW[P_PIXEL_LOW];
02387 imageParamsR[P_PIXEL_HIGH]=imageParamsW[P_PIXEL_HIGH];
02388
02390 scales_changed=0;
02391 scale_g1 = imageParamsW[P_GSCALE];
02392 if(scale_g1 > SCALE_MAX)
02393 scale_g1 = SCALE_MAX;
02394 if(scale_g1 < SCALE_MIN)
02395 scale_g1 = SCALE_MIN;
02396 if (imageParamsR[P_GSCALE] != scale_g1 ) { imageParamsR[P_GSCALE]=scale_g1; scales_changed=1; }
02397 fscale_g1 = scale_g1;
02398 fscale_g1 /= 0x100;
02399 scale_r = imageParamsW[P_RSCALE];
02400 if(scale_r > SCALE_MAX)
02401 scale_r = SCALE_MAX;
02402 if(scale_r < SCALE_MIN)
02403 scale_r = SCALE_MIN;
02404 if (imageParamsR[P_RSCALE] != scale_r ) { imageParamsR[P_RSCALE]=scale_r; scales_changed=1; }
02405 fscale_r = scale_r;
02406 fscale_r /= 0x100;
02407 scale_b = imageParamsW[P_BSCALE];
02408 if(scale_b > SCALE_MAX)
02409 scale_b = SCALE_MAX;
02410 if(scale_b < SCALE_MIN)
02411 scale_b = SCALE_MIN;
02412 if (imageParamsR[P_BSCALE] != scale_b ) { imageParamsR[P_BSCALE]=scale_b; scales_changed=1; }
02413 if (scales_changed){
02414 MD13(printk("imageParamsW[P_GAMMA]= 0x%x, imageParamsR[P_GAMMA]= 0x%x\n" \
02415 "imageParamsW[P_PIXEL_LOW]= 0x%x, imageParamsR[P_PIXEL_LOW]= 0x%x\n" \
02416 "imageParamsW[P_PIXEL_HIGH]= 0x%x, imageParamsR[P_PIXEL_HIGH]= 0x%x\n" \
02417 "imageParamsW[P_RSCALE]= 0x%x, imageParamsR[P_RSCALE]= 0x%x\n" \
02418 "imageParamsW[P_GSCALE]= 0x%x, imageParamsR[P_GSCALE]= 0x%x\n" \
02419 "imageParamsW[P_BSCALE]= 0x%x, imageParamsR[P_BSCALE]= 0x%x\n", \
02420 (int) imageParamsW[P_GAMMA], (int) imageParamsR[P_GAMMA], \
02421 (int) imageParamsW[P_PIXEL_LOW], (int) imageParamsR[P_PIXEL_LOW], \
02422 (int) imageParamsW[P_PIXEL_HIGH], (int) imageParamsR[P_PIXEL_HIGH], \
02423 (int) imageParamsW[P_RSCALE], (int) imageParamsR[P_RSCALE], \
02424 (int) imageParamsW[P_GSCALE], (int) imageParamsR[P_GSCALE], \
02425 (int) imageParamsW[P_BSCALE], (int) imageParamsR[P_BSCALE]));
02426
02427 fscale_b = scale_b;
02428 fscale_b /= 0x100;
02429 fscale_g = 1.0;
02430
02431
02432 if((fscale_r < fscale_g) || (fscale_b < fscale_g) || (fscale_g1 < fscale_g)) {
02433 if((fscale_r < fscale_b) && (fscale_r < fscale_g1)) {
02434 fscale_g1 /= fscale_r;
02435 fscale_g /= fscale_r;
02436 fscale_b /= fscale_r;
02437 fscale_r = 1.0;
02438 } else {
02439 if(fscale_b < fscale_g1) {
02440 fscale_r /= fscale_b;
02441 fscale_g /= fscale_b;
02442 fscale_g1 /= fscale_b;
02443 fscale_b = 1.0;
02444 } else {
02445 fscale_r /= fscale_g1;
02446 fscale_g /= fscale_g1;
02447 fscale_b /= fscale_g1;
02448 fscale_g1 = 1.0;
02449 }
02450 }
02451 }
02452 scale_r = fscale_r * 0x100;
02453 scale_g = fscale_g * 0x100;
02454 scale_b = fscale_b * 0x100;
02455 scale_g1 = fscale_g1 * 0x100;
02456 gains.used = 1;
02457
02458
02459
02460
02461
02462 set_gamma(imageParamsR[P_GAMMA], imageParamsR[P_PIXEL_LOW], scale_r, scale_g, scale_b, scale_g1);
02463 }
02464 }
02465
02466
02467 frame_params.gamma=imageParamsR[P_GAMMA];
02468 frame_params.black=imageParamsR[P_PIXEL_LOW];
02469
02470 frame_params.rscale=imageParamsR[P_RSCALE];
02471 frame_params.bscale=imageParamsR[P_BSCALE];
02472
02473
02474
02475 imageParamsR[P_COLOR]=imageParamsW[P_COLOR];
02476
02477
02478 if (!nonstop) {
02479
02480 if (sensor.flips & 1) imageParamsR[P_FLIP]=((imageParamsR[P_FLIP] ^ imageParamsW[P_FLIP]) & (sensor.flips & 3)) ^ imageParamsR[P_FLIP];
02481 dh = imageParamsW[P_DCM_HOR];
02482 dv = imageParamsW[P_DCM_VERT];
02483 if (dh<1) dh=1; else if (dh>32) dh=32;
02484 if (dv<1) dv=1; else if (dv>32) dv=32;
02485 MD8(printk("dv=%d, dh=%d\r\n", dv,dh));
02486
02487 while ((dh>1) && !(sensor.dcmHor & (1 << (dh-1)))) dh--;
02488 while ((dv>1) && !(sensor.dcmVert & (1 << (dv-1)))) dv--;
02489 bh = imageParamsW[P_BIN_HOR]; if (bh<1) bh=1; else if (bh>dh) bh=dh;
02490 bv = imageParamsW[P_BIN_VERT];if (bv<1) bv=1; else if (bv>dv) bv=dv;
02491 while ((bh>1) && !(sensor.dcmHor & (1 << (bh-1)))) bh--;
02492 while ((bv>1) && !(sensor.dcmVert & (1 << (bv-1)))) bv--;
02493 imageParamsR[P_DCM_HOR] = dh;
02494 imageParamsR[P_DCM_VERT]= dv;
02495 imageParamsR[P_BIN_HOR] = bh;
02496 imageParamsR[P_BIN_VERT]= bv;
02497
02498
02499
02500
02501
02502 MD8(printk("dv=%d, dh=%d\r\n", dv,dh));
02503
02504 switch (imageParamsR[P_SENSOR] & SENSOR_MASK) {
02505 #ifdef CONFIG_ETRAX_ELPHEL_MT9X001
02506 case SENSOR_MT9X001:
02507 case SENSOR_MT9Y001:
02508 adjustBinning_mt9x001();
02509 break;
02510 #endif
02511 }
02512
02513 timestamp_len = (((imageParamsW[P_PF_HEIGHT] >> 16) & 3)==2)? X313_TIMESTAMPLEN*dh : 0;
02514
02515 l=imageParamsW[P_WOI_WIDTH];
02516 if (!imageParamsR[P_OVERSIZE]) {
02517 if ((l-timestamp_len) > sensor.imageWidth) l = sensor.imageWidth+timestamp_len;
02518 }
02519 l=l/dh/X313_TILEHOR;
02520 l*=X313_TILEHOR;
02521
02522 while (l < sensor.minWidth) l+=X313_TILEHOR;
02523 imageParamsR[P_ACTUAL_WIDTH]=l;
02524 sensor.pixelWidth=l+sensor.margins-timestamp_len;
02525 MD8(printk("sensor.pixelWidth=0x%x, sensor.margins=0x%x\r\n", sensor.pixelWidth,sensor.margins));
02526 l*=dh;
02527
02528 imageParamsR[P_WOI_WIDTH]=l;
02529
02530
02531 pfh = (imageParamsW[P_PF_HEIGHT] & 0xffff);
02532 h=imageParamsW[P_WOI_HEIGHT];
02533 if(pfh > 0) {
02534 if (pfh < sensor.minHeight) pfh = sensor.minHeight;
02535 if (imageParamsR[P_COLOR] && (pfh & 1)) pfh++;
02536 if (h > X313_MAXHEIGHT*dv) h=X313_MAXHEIGHT*dv;
02537 pf_stripes = h / (pfh * dv);
02538 if(pf_stripes < 1) pf_stripes = 1;
02539 sensor.pixelHeight=pfh;
02540
02541 } else {
02542 if (!imageParamsR[P_OVERSIZE]) {
02543 if (h > sensor.imageHeight) h=sensor.imageHeight;
02544 }
02545 h=h/dv/X313_TILEVERT;
02546 h*=X313_TILEVERT;
02547
02548 while (h < sensor.minHeight) h+=X313_TILEVERT;
02549 sensor.pixelHeight=h+sensor.margins;
02550 h*=dv;
02551 pf_stripes = 0;
02552 pfh = 0;
02553 }
02554 imageParamsR[P_PF_HEIGHT]=(imageParamsW[P_PF_HEIGHT] & 0xffff0000) | pfh;
02555 imageParamsR[P_WOI_HEIGHT]=h;
02556 imageParamsR[P_ACTUAL_HEIGHT]=h/dv;
02557 MD8(printk("pfh=0x%x, pf_stripes=0x%x, h=%d(0x%x)\r\n", pfh, pf_stripes,h,h));
02558 } else {
02559 dh = imageParamsR[P_DCM_HOR];
02560 dv = imageParamsR[P_DCM_VERT];
02561 pfh= imageParamsR[P_PF_HEIGHT] & 0xffff;
02562 timestamp_len = (((imageParamsR[P_PF_HEIGHT] >> 16) & 3)==2)? X313_TIMESTAMPLEN*dh : 0;
02563 }
02564
02565
02566 frame_params.color=(imageParamsR[P_COLOR] & 0x0f) | (imageParamsR[P_FLIP] << 6) ;
02567
02568 MD8(printk("sensor.pixelWidth=0x%lx, sensor.pixelHeight=0x%lx\r\n", sensor.pixelWidth,sensor.pixelHeight));
02569
02570
02571
02572
02573
02574
02575
02576 l = imageParamsW[P_WOI_LEFT];
02577 if (!imageParamsR[P_OVERSIZE]) {
02578 if(imageParamsR[P_COLOR])
02579 l &= 0xfffe;
02580 if((l < 0) || (l & 0x8000))
02581 l = 0;
02582 if ((l + imageParamsR[P_WOI_WIDTH] + sensor.margins) > sensor.clearWidth) {
02583 l = sensor.clearWidth - imageParamsR[P_WOI_WIDTH] - sensor.margins;
02584 if(imageParamsR[P_COLOR])
02585 l &= 0xfffe;
02586 }
02587 if(l & 0x8000) l = 0;
02588 }
02589 imageParamsR[P_WOI_LEFT] = l;
02590
02591 t = imageParamsW[P_WOI_TOP];
02592 if (!imageParamsR[P_OVERSIZE]) {
02593 if(imageParamsR[P_COLOR])
02594 t &= 0xfffe;
02595 if((t < 0) || (t & 0x8000))
02596 t = 0;
02597 if(pfh > 0) {
02598 if((t + pfh * dv) > sensor.clearHeight)
02599 t = sensor.clearHeight - pfh * dv;
02600 } else {
02601 if((t + imageParamsR[P_WOI_HEIGHT] + sensor.margins) > sensor.clearHeight)
02602 t = sensor.clearHeight - imageParamsR[P_WOI_HEIGHT] - sensor.margins;
02603 }
02604 if (imageParamsR[P_COLOR]) t &= 0xfffe;
02605 }
02606 imageParamsR[P_WOI_TOP]=t;
02607
02608 if (imageParamsW[P_CLK_SENSOR] > sensor.maxClockFreq) imageParamsW[P_CLK_SENSOR] = sensor.maxClockFreq;
02609 imageParamsR[P_FPGA_XTRA]=imageParamsW[P_FPGA_XTRA];
02610
02611
02612 switch (imageParamsR[P_SENSOR] & SENSOR_MASK) {
02613
02614
02615 case SENSOR_KAI11000: { CCAM_ARST_OFF; sensRslt=program_KAI11000();break;}
02616
02617
02618
02619 #ifdef CONFIG_ETRAX_ELPHEL_ZR32112
02620 case SENSOR_ZR32112: { CCAM_ARST_OFF; sensRslt=program_ZR32112();break;}
02621 #endif
02622 #ifdef CONFIG_ETRAX_ELPHEL_ZR32212
02623 case SENSOR_ZR32212: {CCAM_ARST_OFF; sensRslt=program_ZR32212();break;}
02624 #endif
02625 #ifdef CONFIG_ETRAX_ELPHEL_KAC1310
02626 case SENSOR_KAC1310: {sensRslt=program_KAC1310(nonstop);break;}
02627 #endif
02628 #ifdef CONFIG_ETRAX_ELPHEL_KAC1310
02629 case SENSOR_KAC5000: {sensRslt=program_KAC5000(nonstop);break;}
02630 #endif
02631 #ifdef CONFIG_ETRAX_ELPHEL_MT9X001
02632 case SENSOR_MT9X001:
02633 case SENSOR_MT9Y001:
02634
02635 if ((imageParamsR[P_SENSOR] & 7)!=0) {
02636
02637
02638 sensRslt=program_woi_mt9x001(nonstop);
02639 if (sensRslt>=0) {i=program_gains_mt9x001(); if ((i<0) || (i>sensRslt)) sensRslt=i;}
02640
02641
02642 break;}
02643 #endif
02644 #ifdef CONFIG_ETRAX_ELPHEL_IBIS51300
02645 case SENSOR_IBIS51300: {sensRslt=program_IBIS51300();break;}
02646 #endif
02647 }
02648
02652 #if 0
02653 if(sensRslt>= 0) {
02654 i = program_sensor_exposition_just();
02655 if((i < 0) || (i > sensRslt))
02656 sensRslt = i;
02657 }
02658 #endif
02659
02660
02661
02662
02663
02664
02665
02666
02667 hist_image_size(get_imageParamsR(P_ACTUAL_WIDTH), get_imageParamsR(P_ACTUAL_HEIGHT));
02668
02669 if (imageParamsW[P_BAYER]<=3) imageParamsR[P_BAYER]=imageParamsW[P_BAYER];
02670
02671 if (!nonstop) {
02673 if (imageParamsR[P_TRIG] & 0x4) {CCAM_TRIG_EXT ; program_early_timestamp(); }
02674 else CCAM_TRIG_INT ;
02675
02676 if (imageParamsW[P_CLK_FPGA]) {
02677
02678 #if 0 // disable changing FPGA clock here - needs readjusting the phase
02679 if (setClockFreq(0, imageParamsW[P_CLK_FPGA])>=0) {
02680 imageParamsR[P_CLK_FPGA]=imageParamsW[P_CLK_FPGA];
02681
02682 initSDRAM();
02683 }
02684 #endif
02685 imageParamsW[P_CLK_FPGA]=0;
02686 }
02687
02688
02689 #if 0
02690 if (imageParamsW[P_CLK_SENSOR]) {
02691 if (setClockFreq(1, imageParamsW[P_CLK_SENSOR])>=0) imageParamsR[P_CLK_SENSOR]=imageParamsW[P_CLK_SENSOR];
02692 imageParamsW[P_CLK_SENSOR]=0;
02693 X3X3_RSTSENSDCM;
02694 }
02695 #endif
02696
02697 ccamCRAndOr(~X313_MASK(BAYER_PHASE), X313_BITS(BAYER_PHASE,imageParamsR[P_BAYER]));
02698
02699 if ((imageParamsW[P_COLOR] & 3)==2) {
02700 x313_JPEG_ctrl(x313_get_JPEG_ctrl() | JPEG_CTRL_MONOCHROME | JPEG_CTRL_NOMOSAIC);
02701 imageParamsR[P_COLOR] = 2;
02702 } else if ((imageParamsW[P_COLOR] & 3)==1) {
02703 x313_JPEG_ctrl(x313_get_JPEG_ctrl() & ~JPEG_CTRL_MONOCHROME & ~JPEG_CTRL_NOMOSAIC);
02704 imageParamsR[P_COLOR] = 1;
02705 } else {
02706 x313_JPEG_ctrl((x313_get_JPEG_ctrl() & ~JPEG_CTRL_NOMOSAIC) | JPEG_CTRL_MONOCHROME);
02707 imageParamsR[P_COLOR] = 0;
02708 }
02709
02710 if (sensRslt>=0) {
02711
02712 if ((imageParamsR[P_MCLK]!=4) && (imageParamsR[P_MCLK]!=0)) imageParamsR[P_EXPOS]= (imageParamsR[P_EXPOS]<<2)/imageParamsR[P_MCLK];
02713 if (imageParamsR[P_EXPOS]<1) imageParamsR[P_EXPOS]=1;
02714
02715 PROGRAM_CLK_EN( (imageParamsR[P_MCLK]>0)?1:0);
02716
02717 MD8(printk ("set timestamp mode to %lx\r\n", ((imageParamsR[P_PF_HEIGHT] >>16) & 3)));
02718 port_csp0_addr[X313_WA_TIMESTAMP] = (imageParamsR[P_PF_HEIGHT] >>16) & 3;
02719
02720
02721 if (imageParamsR[P_PERIOD]==0) imageParamsR[P_PERIOD]=(imageParamsR[P_ACTUAL_WIDTH]+20)*(imageParamsR[P_ACTUAL_HEIGHT]+1);
02722
02723 port_csp0_addr[X313_WA_VIRTTRIG]= imageParamsR[P_VIRTTRIG];
02724 if (imageParamsW[P_COLOR] & 0x300) imageParamsR[P_COLOR] |= 0x200;
02725 if (imageParamsR[P_BGFRAME]) PROGRAM_FPN(0,0,0,0,0);
02726
02727 else PROGRAM_FPN(((imageParamsR[P_COLOR]& 0x200)>0), \
02728 (imageParamsR[P_FPNS]), \
02729 (imageParamsR[P_FPNM]), \
02730 (imageParamsR[P_BITS]!=8), \
02731 imageParamsR[P_SHIFTL]);
02732
02733 ntilex=((imageParamsR[P_ACTUAL_WIDTH]+sensor.margins+7)>>3);
02734 if ((imageParamsR[P_PF_HEIGHT] & 0xffff)>0) {
02735 ntiley=imageParamsR[P_ACTUAL_HEIGHT];
02736
02737 } else {
02738 ntiley=imageParamsR[P_ACTUAL_HEIGHT]+sensor.margins;
02739
02740 if(!imageParamsR[P_BGFRAME] && ((imageParamsR[P_FPNS]!=0) || (imageParamsR[P_FPNM]!=0))) {
02741 X313_INIT_SDCHAN(1,0,0,0, X313_MAP_FPN, (ntilex-1), (ntiley-1));
02742
02743 X313_CHN_EN(1);
02744
02745 }
02746 }
02747
02748
02749 if ((imageParamsR[P_BITS]==8) && (!imageParamsR[P_BGFRAME])) {
02750 ntilex=((imageParamsR[P_ACTUAL_WIDTH]+sensor.margins+15)>>4);
02751
02752
02753
02754 goodEOL=((imageParamsR[P_ACTUAL_WIDTH] & 0x0f) == 0) && ((imageParamsR[P_ACTUAL_WIDTH] & 0x1f0) != 0);
02755 if (goodEOL) ntilex--;
02756 }
02757 if (imageParamsR[P_OVERLAP]>=(imageParamsR[P_ACTUAL_HEIGHT]+2)) imageParamsR[P_OVERLAP]=imageParamsR[P_ACTUAL_HEIGHT]+1;
02758 if (imageParamsR[P_OVERLAP]>0) ntiley=(ntiley<<1);
02759
02760 padlen=((ntilex+31)>>5) << 8;
02761 sa=X313_MAP_FRAME + ((padlen * (imageParamsR[P_ACTUAL_HEIGHT]+sensor.margins) * imageParamsR[P_PAGE_ACQ]) << ((get_imageParamsR(P_TRIG) & 1)?1:0));
02762 MD8(printk ("-->> sa frame = 0x%08X, ntilex=0x%04X, ntiley=0x%04X\r\n", sa, ntilex, ntiley));
02763
02764
02765 X313_INIT_SDCHAN(0,0,1,1, \
02766 sa, \
02767 (ntilex-1),(ntiley-1));
02768 X313_CHN_EN(0);
02769
02770 if ((imageParamsR[P_PF_HEIGHT] & 0xffff)>0) {
02771 i = (imageParamsR[P_ACTUAL_HEIGHT] & 0xfff) | ((imageParamsR[P_ACTUAL_HEIGHT]/(imageParamsR[P_PF_HEIGHT] & 0xffff))<<16) ;
02772 } else {
02773 i= (imageParamsR[P_ACTUAL_HEIGHT]+sensor.margins+imageParamsR[P_OVERLAP]);
02774 }
02775 port_csp0_addr[X313_WA_NLINES] = i;
02776 MD8(printk ("port_csp0_addr[X313_WA_NLINES] =%d(0x%x)\r\n", i,i));
02777
02778
02779
02780
02781
02782
02783 #if 0
02784 jpeg_sdram_ctl0=X313_PREINIT_SDCHAN(2,1,
02785 ((imageParamsR[P_PF_HEIGHT] & 0xffff)>0)?1:0,
02786 0,
02787 sa,
02788 ntilex - (goodEOL?1:2),
02789 ((imageParamsR[P_PF_HEIGHT] & 0xffff)>0)?(ntiley-0x10):(ntiley-sensor.margins-0x10) );
02790 #endif
02791 ntilex_compressor=ntilex - (goodEOL?1:2);
02792 ntiley_compressor=((imageParamsR[P_PF_HEIGHT] & 0xffff)>0)?(ntiley-0x10):(ntiley-sensor.margins-0x10);
02793 jpeg_sdram_ctl0=X313_PREINIT_SDCHAN(2,1,
02794 ((imageParamsR[P_PF_HEIGHT] & 0xffff)>0)?1:0,
02795 0,
02796 sa,
02797 ntilex_compressor,
02798 ntiley_compressor );
02799
02800 frame_params.width=(ntilex_compressor+1)<<4;
02801 frame_params.height=(ntiley_compressor &0xfff0)+0x10;
02802
02803
02804
02805 MD8(printk ("programSensor ntilex=0x%x, ntiley=0x%x jpeg_sdram_ctl0=0x%x\r\n", ntilex, ntiley,jpeg_sdram_ctl0));
02806 MD8(printk ("programSensor 2ctl1=0x%lx, 2ctl2=0x%lx\r\n", port_csp0_addr[X313_WA_SDCH2_CTL1], port_csp0_addr[X313_WA_SDCH2_CTL2]));
02807
02808 if (imageParamsR[P_OVERLAP]>0) ntiley=(ntiley>>1);
02809 if ((imageParamsR[P_PF_HEIGHT] & 0xffff)>0) {
02810 n= ((ntilex - (goodEOL?0:1)) & 0x3ff) * ((ntiley)>>4) -1;
02811 } else {
02812 n= ((ntilex - (goodEOL?0:1)) & 0x3ff) * ((ntiley-sensor.margins)>>4) -1;
02813 }
02814 port_csp0_addr[X313_WA_MCUNUM]= n;
02815 imageParamsR[P_TILES]=n+1;
02817
02818
02819 MD8(printk ("port_csp0_addr[X313_WA_MCUNUM] =%d (0x%x)\r\n", n,n));
02820
02821
02822
02823 if ((imageParamsR[P_FPNS]!=0) ||(imageParamsR[P_FPNM]!=0)) {
02824
02825 n=1000;
02826 while (((n--)>0) && !X313_SR(CH1RDY)); udelay (1);
02827 }
02828 } else {
02829 setCamSeqState(CAMSEQ_OFF);
02830 printk("Error programming sensor\n");
02831 }
02832 }
02833
02835
02836 if(sensRslt>= 0) {
02837 i = program_sensor_exposition_just();
02838 if((i < 0) || (i > sensRslt))
02839 sensRslt = i;
02840 }
02841
02842
02843
02844
02845 x313_program_focus(frame_params.width) ;
02846
02847 }
02848
02849 imageParamsR[P_UPDATE]=1;
02850 imageParamsW[P_UPDATE]=0;
02852 imageParamsR[P_PARS_CHANGED]=0;
02853
02854 if (!nonstop) {
02856 setCamSeqCount(((sensRslt>=0) && ((imageParamsW[P_PF_HEIGHT] & 0xffff)==0))?sensRslt:0);
02857 setCamSeqState((sensRslt>=0)?CAMSEQ_READY:CAMSEQ_OFF);
02858 #if PROGRAM_SENSOR_DIS_IRQ
02859 local_irq_restore(flags);
02860 #endif
02861 }
02862 MD2(printk("programSensor:, sensRslt=%x,getCamSeqState()=%x\n", (int) sensRslt, (int) getCamSeqState()));
02863 up(&sensor_lock);
02864 MD10(dumpFrameParams(&frame_params,"\nframe parameters after ProgramSensor:"));
02865 MD11(printk ("rp=0x%x, wp=0x%x\r\n", JPEG_rp, JPEG_wp ));
02866 imageParamsR[P_PGMSENSRSLT]=sensRslt;
02867 imageParamsR[P_SKIP_FRAMES]=imageParamsW[P_SKIP_FRAMES];
02868 return sensRslt;
02869 }
02870
02871 void exposition_unlock(void) {
02872 set_imageParamsW(P_EXPOS, get_imageParamsR(P_EXPOS));
02873 set_imageParamsW(P_VEXPOS, 0);
02874 }
02875
02876 int program_sensor_exposition(void) {
02877 int sensRslt = -1;
02878
02879 struct hist_sensor_t *hist_s = NULL;
02880 unsigned long exp = 0x00;
02881 if(down_trylock(&sensor_lock) != 0)
02882 return -1;
02883
02884 hist_s = hist_sensor_lock();
02885 if(hist_s != NULL) {
02886 set_imageParamsW(P_VEXPOS, hist_s->exposure);
02887 exp = hist_s->exposure;
02888 hist_sensor_unlock();
02889 } else {
02890 up(&sensor_lock);
02891 return -1;
02892 }
02893
02894 sensRslt = program_sensor_exposition_just();
02895
02896 up(&sensor_lock);
02897
02898 return sensRslt;
02899 }
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910 void adjust_fps_2_compressor(void) {
02911
02912 int cycles = imageParamsR[P_TILES] * 768 + imageParamsR[P_FPGA_XTRA];
02913 int fp100s = imageParamsR[P_CLK_FPGA] / ((cycles/100) + 1);
02914
02915
02916 if(((imageParamsR[P_FPSLM] & 1) == 0) || (imageParamsW[P_FP100S] > fp100s))
02917 imageParamsW[P_FP100S] = fp100s ;
02918 MD9(printk("\r\n+++++++++ fp100s=0x%08x imageParamsR[P_FPSLM]=0x%01X, imageParamsW[P_FPSLM]=0x%01X, imageParamsR[P_FP100S] = 0x%08X, imageParamsW[P_FP100S] = 0x%08X\r\n",fp100s, imageParamsR[P_FPSLM], imageParamsW[P_FPSLM], imageParamsR[P_FP100S], imageParamsW[P_FP100S]));
02919
02920 }
02922 int program_sensor_exposition_just(void) {
02923 int res = -1;
02924 adjust_fps_2_compressor();
02925 switch(imageParamsR[P_SENSOR] & SENSOR_MASK) {
02926
02927 case SENSOR_KAI11000:
02928 res=1;
02929 break;
02930
02931 #ifdef CONFIG_ETRAX_ELPHEL_ZR32112
02932 case SENSOR_ZR32112: break;
02933 #endif
02934 #ifdef CONFIG_ETRAX_ELPHEL_ZR32212
02935 case SENSOR_ZR32212: break;
02936 #endif
02937 #ifdef CONFIG_ETRAX_ELPHEL_KAC1310
02938 case SENSOR_KAC1310: break;
02939 #endif
02940 #ifdef CONFIG_ETRAX_ELPHEL_KAC1310
02941 case SENSOR_KAC5000: break;
02942 #endif
02943 #ifdef CONFIG_ETRAX_ELPHEL_MT9X001
02944 case SENSOR_MT9X001:
02945 case SENSOR_MT9Y001:
02946 res = program_exposure_mt9x001();
02947 break;
02948 #endif
02949 #ifdef CONFIG_ETRAX_ELPHEL_IBIS51300
02950 case SENSOR_KAC5000: break;
02951 #endif
02952 }
02953
02954
02955
02956
02957
02958 return res;
02959 }
02960
02961
02962
02963
02964 static int cmoscam_open(struct inode *inode, struct file *filp) {
02965 int p,res;
02966
02967
02968 p = MINOR(inode->i_rdev);
02969
02970 MD(printk("cmoscam_open: minor=%x\r\n",p));
02971 D1(printk("cmoscam_open: minor=%x\r\n",p) );
02972 D1(printk("filp=%lx\r\n",(unsigned long)filp) );
02973
02974
02975 switch ( p ) {
02976 case CMOSCAM_MINOR_HISTOGRAM :
02977 {
02978 if (minors[p]) {
02979 printk("***** Attemped to open twice CMOSCAM_MINOR_HISTOGRAM *****\n");
02980 return -EACCES;
02981 }
02982 break;
02983 }
02984 case CMOSCAM_MINOR_RWTABLES :
02985 {
02986 if (minors[p]) {
02987 printk("***** Attemped to open twice CMOSCAM_MINOR_RWTABLES *****\n");
02988 return -EACCES;
02989 }
02990 break;
02991 }
02992 case CMOSCAM_MINOR_GAMMA :
02993 {
02994 if (minors[p]) {
02995 printk("***** Attemped to open twice CMOSCAM_MINOR_GAMMA *****\n");
02996 return -EACCES;
02997 }
02998 gamma_tables_changed=0;
02999 break;
03000 }
03001 #ifdef CONFIG_ETRAX_323
03002 case CMOSCAM_MINOR_SENSORJTAGFPGA :
03003 {
03004
03005 port_csp0_addr[X313_WA_SDCH0_CTL2]=0x8000;
03006 ccamCROr( X313_BITS(KAI11000,1));
03007 if (minors[p]) {
03008 printk("***** Attemped to open CMOSCAM_MINOR_SENSORJTAGFPGA w/o closing\n");
03009 }
03010 if ((res =sfjtag_open())) return res;
03011 break;
03012 }
03013 #endif
03014 case CMOSCAM_MINOR_FRAME: {
03015 if(init_FPGA() < 0)
03016 return -EACCES;
03017 if(minors[p]) {
03018 printk("***** Attemped to open CMOSCAM_MINOR_FRAME w/o closing\n");
03019
03020 }
03021 if((res = x313_frame_open(inode, filp)))
03022 return res;
03023 break;
03024 }
03025
03026 case CMOSCAM_MINOR_LOCK :
03027 {
03028 if (minors[p]) {
03029 printk("***** Attemped to access locked camera *****\n");
03030 return -EACCES;
03031 }
03032 break;
03033 }
03034
03035 case CMOSCAM_MINOR_UNLOCK :
03036 {
03037 minors[CMOSCAM_MINOR_LOCK]=0;
03038 break;
03039 }
03040
03041
03042 case CMOSCAM_MINOR_FPN :
03043 {
03044 if (minors[p]) {
03045 printk("***** Attemped to open CMOSCAM_MINOR_FPN w/o closing\n");
03046
03047
03048 }
03049 if ((res =x313_fpn_open(inode, filp))) return res;
03050 break;
03051 }
03052 case CMOSCAM_MINOR_I2C :
03053 {
03054 if (minors[p]) return -EACCES;
03055 break;
03056 }
03057 case CMOSCAM_MINOR_DMA :
03058 {
03059
03060 if (((res=getCamSeqState())==CAMSEQ_RUN) || (res == CAMSEQ_STOP)) inode->i_size=0;
03061 else if ((res =cmoscam_open_dma(inode, filp))) return res;
03062 break;
03063 }
03064 case CMOSCAM_MINOR_MCP :
03065 {
03066 if (init_FPGA()<0) return -EACCES;
03067 if (CCAM_DONOTUSEAUX) return -EACCES;
03068 if ((minors[p]) && ((ccam_cr_shadow & X313_MASK(XRST)) != 0)) return -EACCES;
03069 if ((res =MCP_open(inode, filp))) return res;
03070 break;
03071 }
03072 case CMOSCAM_MINOR_CIRCBUF :
03073 {
03074
03075 break;
03076 }
03077 case CMOSCAM_MINOR_JPEAGHEAD :
03078 {
03079
03080 break;
03081 }
03082 case CMOSCAM_MINOR_SENSPARS :
03083 {
03084 break;
03085 }
03086
03087 default: return -EINVAL;
03088 }
03089
03090 minors[p]=p;
03091
03092 filp->private_data = &minors[p];
03093
03094
03095
03096 return 0;
03097 }
03098 static int cmoscam_release(struct inode *inode, struct file *filp) {
03099 int p = MINOR(inode->i_rdev);
03100 int i=0;
03101 MD(printk("cmoscam_release: minor=%x\r\n",p));
03102 switch ( p ) {
03103 #ifdef CONFIG_ETRAX_323
03104 case CMOSCAM_MINOR_SENSORJTAGFPGA :
03105 {
03106 i=sfjtag_close();
03107 printk("sfjtag_close returned %x\r\n",i);
03108 if (i>0) i=0;
03109 minors[p]=0;
03110 break;
03111 }
03112 #endif
03113 case CMOSCAM_MINOR_GAMMA :
03114 if (gamma_tables_changed) write_gamma_fpga (gamma_tables_soft);
03115 gamma_tables_changed=0;
03116 minors[p]=0;
03117 break;
03118 case CMOSCAM_MINOR_FPN :
03119 x313_fpn_release();
03120 case CMOSCAM_MINOR_HISTOGRAM :
03121 case CMOSCAM_MINOR_RWTABLES :
03122 case CMOSCAM_MINOR_I2C :
03123 case CMOSCAM_MINOR_MCP :
03124 case CMOSCAM_MINOR_LOCK :
03125 case CMOSCAM_MINOR_UNLOCK :
03126
03127 {
03128 minors[p]=0;
03129 break;
03130 }
03131 case CMOSCAM_MINOR_FRAME: {
03132 x313_frame_release();
03133 minors[p]=0;
03134 break;
03135 }
03137 case CMOSCAM_MINOR_SENSPARS :
03138 case CMOSCAM_MINOR_DMA :
03139 case CMOSCAM_MINOR_CIRCBUF :
03140 case CMOSCAM_MINOR_JPEAGHEAD :
03141 {
03142 break;
03143 }
03144 default: return -EINVAL;
03145 }
03146
03147 D(printk("cmoscam_release: done\r\n"));
03148 return i;
03149 }
03150
03151
03152
03153 static int cmoscam_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) {
03154 int rv;
03155
03156
03157
03158
03159 switch (((int *)filp->private_data)[0]) {
03160
03161 case CMOSCAM_MINOR_I2C : return i2c_ioctl (inode, filp, cmd, arg);
03162 case CMOSCAM_MINOR_DMA :
03163 if (init_FPGA()<0) return -EACCES;
03164 case CMOSCAM_MINOR_SENSPARS :
03165 case CMOSCAM_MINOR_MCP :
03166 case CMOSCAM_MINOR_FPN :
03167 case CMOSCAM_MINOR_FRAME :
03168 case CMOSCAM_MINOR_CIRCBUF :
03169 case CMOSCAM_MINOR_JPEAGHEAD : {
03170 rv= ccam_DMA_ioctl(inode, filp, cmd, arg);
03171 return rv;
03172 }
03173 default:return -EINVAL;
03174 }
03175 }
03176
03177 static loff_t cmoscam_lseek(struct file * file, loff_t offset, int orig) {
03178 int i;
03179 switch (((int *)file->private_data)[0]) {
03180 case CMOSCAM_MINOR_GAMMA : return x313_gamma_lseek (file, offset, orig);
03181 case CMOSCAM_MINOR_HISTOGRAM : return x313_histogram_lseek (file, offset, orig);
03182 case CMOSCAM_MINOR_RWTABLES : return x313_tables_lseek (file, offset, orig);
03183 case CMOSCAM_MINOR_MCP : return MCP_lseek (file, offset, orig);
03184 case CMOSCAM_MINOR_FPN : return x313_fpn_lseek (file, offset, orig);
03185 case CMOSCAM_MINOR_FRAME : return x313_frame_lseek (file, offset, orig);
03186 case CMOSCAM_MINOR_DMA :{
03187 if ( (((i=getCamSeqState()))== CAMSEQ_RUN ) ||
03188 (i == CAMSEQ_STOP ) ||
03189 (i == CAMSEQ_SINGLE)) return 0;
03190 return x313_dma_lseek (file, offset, orig);
03191 }
03192
03193
03194 case CMOSCAM_MINOR_SENSPARS : return x313_senspars_lseek (file, offset, orig);
03195 default: return -EINVAL;
03196 }
03197 }
03198
03199 static ssize_t cmoscam_read(struct file * file, char * buf, size_t count, loff_t *off) {
03200
03201 switch (((int *)file->private_data)[0]) {
03202 case CMOSCAM_MINOR_GAMMA : return x313_gamma_read (file, buf, count, off);
03203 case CMOSCAM_MINOR_HISTOGRAM: return x313_histogram_read (file, buf, count, off);
03204 case CMOSCAM_MINOR_RWTABLES : return x313_tables_read (file, buf, count, off);
03205 case CMOSCAM_MINOR_MCP : return MCP_read (file, buf, count, off);
03206 case CMOSCAM_MINOR_FPN : return x313_fpn_read (file, buf, count, off);
03207 case CMOSCAM_MINOR_FRAME : return x313_frame_read (file, buf, count, off);
03208 case CMOSCAM_MINOR_DMA : return x313_dma_read (file, buf, count, off);
03209
03210
03211 case CMOSCAM_MINOR_SENSPARS : return x313_senspars_read (file, buf, count, off);
03212 default: return -EINVAL;
03213 }
03214 }
03215 static ssize_t cmoscam_write(struct file * file, const char * buf, size_t count, loff_t *off) {
03216
03217 switch (((int *)file->private_data)[0]) {
03218 case CMOSCAM_MINOR_GAMMA: return x313_gamma_write (file, buf, count, off);
03219 case CMOSCAM_MINOR_RWTABLES: return x313_tables_write (file, buf, count, off);
03220 #ifdef CONFIG_ETRAX_323
03221 case CMOSCAM_MINOR_SENSORJTAGFPGA: return sfjtag_write (file, buf, count, off);
03222 #endif
03223 case CMOSCAM_MINOR_MCP : return MCP_write (file, buf, count, off);
03224 case CMOSCAM_MINOR_FPN : return x313_fpn_write (file, buf, count, off);
03225 case CMOSCAM_MINOR_DMA : return x313_dma_write (file, buf, count, off);
03226
03227 case CMOSCAM_MINOR_JPEAGHEAD : return x313_dma_write (file, buf, count, off);
03228 case CMOSCAM_MINOR_SENSPARS : return x313_senspars_write(file, buf, count, off);
03229 default: return -EINVAL;
03230 }
03231
03232 }
03233
03234
03235 static int cmoscam_mmap (struct file *file, struct vm_area_struct *vma) {
03236 switch (((int *)file->private_data)[0]) {
03237 case CMOSCAM_MINOR_SENSPARS : return x313_senspars_mmap (file, vma);
03238 default: return -EINVAL;
03239 }
03240 }
03241 static unsigned int cmoscam_poll (struct file *file, poll_table *wait) {
03242 switch (((int *)file->private_data)[0]) {
03243 case CMOSCAM_MINOR_DMA :
03244
03245 break;
03246 case CMOSCAM_MINOR_CIRCBUF :
03248 if(imageParamsR[P_CIRCBUFWP]==file->f_pos) poll_wait(file, &x313_wait_queue, wait);
03249 if(imageParamsR[P_CIRCBUFWP]==file->f_pos) return 0;
03250 }
03251 return POLLIN | POLLRDNORM;
03252 }
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267 void program_trigger(void) {
03268 port_csp0_addr[X313_WA_CAMSYNCTRIG]=(imageParamsR[P_TRIG_CONDITION]=imageParamsW[P_TRIG_CONDITION]);
03269 port_csp0_addr[X313_WA_CAMSYNCDLY] =(imageParamsR[P_TRIG_DELAY]= imageParamsW[P_TRIG_DELAY]);
03270 port_csp0_addr[X313_WA_CAMSYNCOUT] =(imageParamsR[P_TRIG_OUT]= imageParamsW[P_TRIG_OUT]);
03271 port_csp0_addr[X313_WA_CAMSYNCPER] =(imageParamsR[P_TRIG_PERIOD]= imageParamsW[P_TRIG_PERIOD]);
03272 }
03273
03274
03275 void program_i2c(void) {
03276 if ((imageParamsW[P_I2C_QPERIOD]<256) && (imageParamsW[P_I2C_QPERIOD]> 2)) imageParamsR[P_I2C_QPERIOD]=imageParamsW[P_I2C_QPERIOD];
03277 if ((imageParamsW[P_I2C_BYTES]<3) && (imageParamsW[P_I2C_BYTES]>=0)) imageParamsR[P_I2C_BYTES]=imageParamsW[P_I2C_BYTES];
03278 port_csp0_addr[X313_I2C_CMD]=X3X3_SET_I2C_BYTES(imageParamsR[P_I2C_BYTES]+1) | X3X3_SET_I2C_DLY(imageParamsR[P_I2C_QPERIOD]) ;
03279 MD20(printk ("program_i2c (0x%x)\n",X3X3_SET_I2C_BYTES(imageParamsR[P_I2C_BYTES]+1) | X3X3_SET_I2C_DLY(imageParamsR[P_I2C_QPERIOD])));
03280 }
03281
03282 void program_smart_irq(void) {
03283 imageParamsR[P_IRQ_SMART]=imageParamsW[P_IRQ_SMART];
03284 port_csp0_addr[X313_WA_SMART_IRQ]=(2 | ((imageParamsR[P_IRQ_SMART] & 1)?1:0)) | \
03285 (8 | ((imageParamsR[P_IRQ_SMART] & 2)?4:0));
03286 }
03287
03288 void program_early_timestamp(void) {
03289 imageParamsR[P_EARLY_TIMESTAMP]=imageParamsW[P_EARLY_TIMESTAMP]?1:0;
03290 if (imageParamsR[P_EARLY_TIMESTAMP]) CCAM_TIMESTAMP_EARLY ;
03291 else CCAM_TIMESTAMP_NORMAL ;
03292 }
03293
03294
03295 int flush_par_cache(void) {
03296
03297 int sum, i;
03298 sum=0;
03299 for (i=0;i<=P_MAX_PAR; i+=8) sum+=ccam_dma_buf_ptr[i]+ccam_dma_buf_ptr[i+P_NUMBER]+ccam_dma_buf_ptr[i+(PAGE_SIZE>>2)]+ccam_dma_buf_ptr[i+P_NUMBER+(PAGE_SIZE>>2)];
03300 return sum;
03301 }
03302 loff_t x313_senspars_lseek(struct file * file, loff_t offset, int orig) {
03303 int l=(P_NUMBER<<3);
03304
03305 switch (orig)
03306 {
03307 case SEEK_SET:
03308 file->f_pos = offset;
03309 break;
03310 case SEEK_CUR:
03311 file->f_pos += offset;
03312 break;
03313 case SEEK_END:
03314 if (offset <= 0) {
03315 file->f_pos = l + offset;
03316 } else switch (offset) {
03317
03318
03320 case LSEEK_RESET_SENSOR:
03321 X313_CHN0_SET_UNUSED;
03322 imageParamsR[P_SENSOR]=0;
03323 return 0;
03324 case LSEEK_INIT_SENSOR:
03325 if (imageParamsR[P_SENSOR]) return 0;
03326 init_FPGA();
03327 return 0;
03328 case LSEEK_CAMSEQSTATE:
03329 return (file->f_pos=camSeqState);
03330 case LSEEK_GET_FPGA_TIME:
03331 X313_GET_FPGA_TIME( imageParamsR[P_SECONDS] , imageParamsR[P_MICROSECONDS] );
03332 return 0;
03333 case LSEEK_SET_FPGA_TIME:
03334 X313_SET_FPGA_TIME( imageParamsW[P_SECONDS] , imageParamsW[P_MICROSECONDS] );
03335 return 0;
03336 case LSEEK_FLUSH_CACHE:
03337 flush_par_cache();
03338 return 0;
03339 case LSEEK_AUTOEXP_SET:
03340 set_autoexposure_parameters();
03341 return 0;
03342 case LSEEK_AUTOEXP_GET:
03343 get_autoexposure_parameters();
03344 return 0;
03345 case LSEEK_TRIGGER_PGM:
03346 program_trigger();
03347 return 0;
03348 case LSEEK_I2C_PGM:
03349 program_i2c();
03350 return 0;
03351 case LSEEK_IRQ_SMART_PGM:
03352 program_smart_irq();
03353 return 0;
03354 case LSEEK_EARLY_TIMESTAMP_PGM:
03355 program_early_timestamp();
03356 return 0;
03357 default:
03358 return (x313_JPEG_cmd_wrapper(offset)<0)?-EINVAL:0;
03359 }
03360 break;
03361 default:
03362 return -EINVAL;
03363 }
03364
03365 if (file->f_pos < 0) {
03366 file->f_pos = 0;
03367 return(-EOVERFLOW);
03368 }
03369 if (file->f_pos > l) {
03370 file->f_pos = l;
03371 }
03372 return ( file->f_pos );
03373 }
03374
03375 ssize_t x313_senspars_read(struct file * file, char * buf, size_t count, loff_t *off) {
03376 unsigned long p;
03377 int l=(P_NUMBER<<3);
03378 char * imageParamsRb= (char *) imageParamsR;
03379 p = file->f_pos;
03380 if( (p + count) > l) {
03381 count = l - p;
03382 }
03383 if (count && (copy_to_user(buf, & imageParamsRb[p], count)))
03384 {printk("copy_to_user1 (0x%x) error\n",(int) count);return -EFAULT;}
03385
03386 file->f_pos+=count;
03387 return count;
03388 }
03389
03390 ssize_t x313_senspars_write(struct file * file, const char * buf, size_t count, loff_t *off) {
03391 unsigned long flags;
03392
03393 unsigned long p,p0;
03394 int l=(P_NUMBER<<2);
03395 char * imageParamsWb= (char *) imageParamsW;
03396 D(printk("x313_senspars_write, count= %x\n", (int) count));
03397 p = file->f_pos;
03398 if (p >= (l<<1)) p = (l<<1);
03399 p0=p;
03400 if (p0 >= l) p0-=l;
03401 if( (p0 + count) > l) {
03402 count = l - p0;
03403 }
03404 D(printk("x313_senspars_write, p=%x, p0=%x, count= %x\n", (int) p, (int) p0, (int) count));
03405
03406 if (count) {
03407 if (copy_from_user(&imageParamsWb[p0],buf, count)) return -EFAULT;
03408 file->f_pos+=count;
03409 if ((count==4) && (p0==(P_UPDATE<<2))) {
03410 local_irq_save(flags);
03411
03412 if (imageParamsW[P_UPDATE]) imageParamsR[P_UPDATE]=2;
03413 else imageParamsR[P_UPDATE]=0;
03414 local_irq_restore(flags);
03415 if (imageParamsW[P_UPDATE]==1) programSensor(0);
03416 else if (imageParamsW[P_UPDATE]>=3) programSensor(1);
03417 }
03418 }
03419 return count;
03420 }
03421
03422 int x313_senspars_mmap (struct file *file, struct vm_area_struct *vma) {
03423 int rslt;
03424
03425 rslt=remap_pfn_range(vma,
03426 vma->vm_start,
03427
03428 ((unsigned long) virt_to_phys(imageParamsR)) >> PAGE_SHIFT,
03429 vma->vm_end-vma->vm_start,
03430 vma->vm_page_prot);
03431
03432 MD6(printk("remap_pfn_range returned=%x\r\n",rslt));
03433 if (rslt) return -EAGAIN;
03434
03435
03436 return 0;
03437 }
03438
03439 static int x313_JPEG_cmd_wrapper(int arg) {
03440 switch (arg) {
03441 MD6(printk("IO_CCAM_JPEG cmd=0x%x arg=0x%x\r\n", cmd,arg));
03442 case PROGRAM_SENSOR_0: imageParamsR[P_PARS_CHANGED]=1; programSensor(0); return 0;
03443 case PROGRAM_SENSOR_1: imageParamsR[P_PARS_CHANGED]=1; programSensor(1); return 0;
03444 case JPEG_CMD_N_DONE: return (JPEG_nfr >0)?0:1;
03445 case JPEG_CMD_L_DONE: return (JPEG_len < JPEG_lfr )?0:1;
03446 case JPEG_CMD_DUMP: camSeq_dump ();
03447 default: {return x313_JPEG_cmd(arg);}
03448 }
03449 }
03450
03451 static int ccam_DMA_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg) {
03452
03453
03454 unsigned long flags;
03455 int i1,r;
03456
03457
03458
03459 switch(_IOC_NR(cmd)){
03460 case IO_CCAM_DMA : switch (arg) {
03461 case CCAM_DMA_CMD_STOP: {x313_dma_stop(); return 0;}
03462 case CCAM_DMA_CMD_START: {x313_dma_start();return 0;}
03463 default:return -EINVAL ;
03464 }
03465 case IO_CCAM_JPEG_QUALITY: {
03466 if (arg <1) arg=1;
03467 if (arg >100) arg=100;
03468 imageParamsR[P_QUALITY]=arg;
03469 imageParamsW[P_QUALITY]=arg;
03470 return 0;
03471 }
03472 case IO_CCAM_JPEG_GET_N: {
03473 if (getCamSeqState() != CAMSEQ_JPEG) x313_dma_update_jpeg_header();
03474 return camSeqStartClip(arg, -1);
03475 }
03476 case IO_CCAM_JPEG_GET_L: {
03477 if (getCamSeqState() != CAMSEQ_JPEG) x313_dma_update_jpeg_header();
03478 return camSeqStartClip(-1, arg);
03479 }
03480 case IO_CCAM_JPEG: return x313_JPEG_cmd_wrapper(arg);
03481 #if 0
03482 switch (arg) {
03483 MD6(printk("IO_CCAM_JPEG cmd=0x%x arg=0x%x\r\n", cmd,arg));
03484 case JPEG_CMD_N_DONE: return (JPEG_nfr >0)?0:1;
03485 case JPEG_CMD_L_DONE: return (JPEG_len < JPEG_lfr )?0:1;
03486 case JPEG_CMD_DUMP: camSeq_dump ();
03487 default: {return x313_JPEG_cmd(arg);}
03488 }
03489 #endif
03490 case IO_CCAM_JPEG_CTRL: { x313_JPEG_ctrl(arg); return 0;}
03491
03492 case IO_CCAM_MONITOR_SEQ : {
03493 MD( printk("IO_CCAM_MONITOR_SEQ, arg=%x,getCamSeqCount()=%x, getCamSeqState()=%x\r\n",(int) arg, (int) getCamSeqCount(),(int) getCamSeqState()));
03494 if (arg) return getCamSeqCount();
03495
03496 if (((r=getCamSeqState())==CAMSEQ_DONE) && (imageParamsR[P_PAGE_ACQ]!= imageParamsR[P_PAGE_READ])) {
03497 x313_f_invalidate();
03498 MD1(printk ("imageParamsR[P_PAGE_READ]=0x%lx, imageParamsR[P_PAGE_ACQ]=0x%lx\n",imageParamsR[P_PAGE_READ],imageParamsR[P_PAGE_ACQ]));
03499 imageParamsR[P_PAGE_READ] = imageParamsR[P_PAGE_ACQ];
03500 }
03501 return r;
03502 }
03503 case IO_CCAM_SET_EXT_EXPOSURE : {
03504 MD1(printk("+OBSOLETE?+IO_CCAM_SET_EXT_EXPOSURE, arg=%x\r\n",(int) arg));
03505 if (arg) camSeqStart();
03506 else {camSeqStop();
03507 }
03508 return 0;
03509 }
03510 case IO_CCAM_CR_MODIFY : {
03511 local_irq_save(flags);
03512
03513 i1=((ccam_cr_shadow & (1<<(arg>>2)))!=0);
03514 switch (arg & 3) {
03515 case 1: {ccam_cr_shadow &= ~(1<<(arg>>2));break;}
03516 case 2: {ccam_cr_shadow |= (1<<(arg>>2));break;}
03517 case 3: {ccam_cr_shadow ^= (1<<(arg>>2));break;}
03518 }
03519 port_csp0_addr[X313_WA_WCTL]= ccam_cr_shadow;
03520 local_irq_restore(flags);
03521 MD(printk("ccam_cr_shadow=0x%x\n",ccam_cr_shadow));
03522 return i1;
03523 }
03524 case IO_CCAM_PINS_WRITE : {
03525
03526 i1 = arg;
03527 local_irq_save(flags);
03528
03529 port_csp0_addr[X313_WA_IOPINS] = i1;
03530 local_irq_restore(flags);
03531 MD(printk("write_iopins=0x%x\n", i1));
03532 return i1;
03533 }
03534 case IO_CCAM_PINS_READ : {
03535 local_irq_save(flags);
03536
03537
03538
03539 i1=X313_IOPINS;
03540 local_irq_restore(flags);
03541 MD(printk("read_iopins=0x%x\n", i1));
03542 return i1;
03543 }
03544 }
03545 MD(printk("CCAM_CTRL(cmd)=%lx\n", CCAM_CTRL(cmd)));
03546
03547 switch(CCAM_CTRL(cmd)){
03548
03549 case CCAM_RPARS:{
03550
03551 MD(printk("CCAM_RPARS: imageParamsR[%lx]=%lx\n",CCAM_ADDR(cmd),imageParamsR[CCAM_ADDR(cmd)]));
03552
03553 return imageParamsR[CCAM_ADDR(cmd)];
03554 }
03555
03556
03557
03558 case CCAM_WPARS: {
03559 if (CCAM_ADDR(cmd) == P_UPDATE) {
03560
03561
03562
03563 if (imageParamsR[P_UPDATE] == 3) return -EINVAL ;
03564 local_irq_save(flags);
03565
03566
03567 imageParamsW[P_UPDATE]= arg;
03568 if (imageParamsW[P_UPDATE]) imageParamsR[P_UPDATE]=2;
03569 else imageParamsR[P_UPDATE]=0;
03570 local_irq_restore(flags);
03571 if (imageParamsW[P_UPDATE]==1) return programSensor(0);
03572 if (imageParamsW[P_UPDATE]>=3) return programSensor(1);
03573
03574 return 0;
03575 } else {
03576 if (imageParamsR[P_UPDATE]>1) {
03577 MD(printk("*****No write permitted if update is schedulled\n"));
03578 return -EINVAL ;
03579 }
03580 imageParamsR[P_PARS_CHANGED] |= (imageParamsW[CCAM_ADDR(cmd)]!=arg);
03581 imageParamsW[CCAM_ADDR(cmd)]=arg;
03582 MD(printk("writing: imageParamsW[%lx]=%lx\n",CCAM_ADDR(cmd),arg));
03583 return 0;
03584 }
03585 }
03586
03587 default:return -EINVAL ;
03588 }
03589
03590
03591 }
03592
03593
03594
03595
03596
03598
03599
03600
03601 unsigned long fpga_tables_buffer[CX313_FPGA_TABLES_SIZE];
03602
03603
03604
03605
03606
03607 int write_gamma_fpga (unsigned short gamma_table[1028]) {
03608 int i,n,base,diff,d;
03609 printk("\nwrite_gamma_fpga()\n");
03610
03611 port_csp0_addr[X313_WA_COMP_TA]=CX313_FPGA_TABLES_GAMMA;
03612 for (n=0;n<4;n++) {
03613 for (i=0;i<256;i++) {
03614 base=gamma_table[257*n+i];
03615 diff=gamma_table[257*n+i+1];
03616 diff-=base;
03617 if ((diff>63) || (diff < -64)) {
03618 diff=(diff+8)>>4;
03619 d=(base & 0x3ff) | ((diff & 0x7f) << 10) | (1 << 17);
03620 } else {
03621 d=(base & 0x3ff) | ((diff & 0x7f) << 10);
03622 }
03623 port_csp0_addr[X313_WA_COMP_TD]=d;
03624 }
03625 }
03626 port_csp0_addr[X313_WA_COMP_TA] = CX313_FPGA_TABLES_GAMMA;
03627
03628 gamma_tables_changed=0;
03629 return 0;
03630 }
03631
03632 void x313_tables_gammainitlinear(void) {
03633 int i,j;
03634 for (j=0; j<4; j++) {
03635 for (i = 0; i <= 256; i+=1) {
03636 gamma_tables_soft[257*j+i]=4*i;
03637 }
03638 gamma_tables_soft[257*j+256]=1023;
03639 }
03640 gamma_tables_changed=1;
03641 write_gamma_fpga(gamma_tables_soft);
03642
03643 }
03644
03645 loff_t x313_gamma_lseek(struct file * file, loff_t offset, int orig){
03646
03647
03648
03649
03650
03651 int l;
03652 l=(1028<<1);
03653
03654 switch (orig)
03655 {
03656 case 0:
03657 file->f_pos = offset;
03658 break;
03659 case 1:
03660 file->f_pos += offset;
03661 break;
03662 case 2:
03663 file->f_pos = l + offset;
03664 break;
03665 default:
03666 return -EINVAL;
03667 }
03668
03669 if (file->f_pos < 0) {
03670 file->f_pos = 0;
03671 return(-EOVERFLOW);
03672 }
03673 if (file->f_pos > l) {
03674 file->f_pos = l;
03675 }
03676 return ( file->f_pos );
03677 }
03678
03679
03680
03681
03682 ssize_t x313_gamma_read(struct file * file, char * buf, size_t count, loff_t *off) {
03683 unsigned long p;
03684 char * gamma_tables_char= (char *) gamma_tables_soft;
03685 D(printk("x313_gamma_read\n"));
03686 p = file->f_pos;
03687
03688 if( (p + count) > (1028 << 1)) {
03689 count = (1028 << 1) - p;
03690 }
03691 if (count && (copy_to_user(buf, &gamma_tables_char[p], count)))
03692 {printk("copy_to_user1 (0x%x) error\n",(int) count);return -EFAULT;}
03693
03694 file->f_pos+=count;
03695 return count;
03696 }
03697
03698 ssize_t x313_gamma_write(struct file * file, const char * buf, size_t count, loff_t *off) {
03699 unsigned long p;
03700 char * gamma_tables_char= (char *) gamma_tables_soft;
03701 D(printk("x313_gamma_write, count= %x\n", (int) count));
03702 p = file->f_pos;
03703 if (p >= (1028 << 1)) p = (1028 << 1);
03704 if( (p + count) > (1028 << 1)) {
03705 count = (1028 << 1) - p;
03706 }
03707 D(printk("x313_gamma_write, p=%x, count= %x\n", (int) p,(int) count));
03708
03709 if (count) {
03710
03711 if (copy_from_user(&gamma_tables_char[p],buf, count)) return -EFAULT;
03712 file->f_pos+=count;
03713 gamma_tables_changed=1;
03714 }
03715 return count;
03716 }
03717
03718 loff_t x313_tables_lseek(struct file * file, loff_t offset, int orig){
03719
03720
03721
03722
03723
03724 int l;
03725 l=(CX313_FPGA_TABLES_SIZE<<2);
03726
03727 switch (orig)
03728 {
03729 case 0:
03730 file->f_pos = offset;
03731 break;
03732 case 1:
03733 file->f_pos += offset;
03734 break;
03735 case 2:
03736 file->f_pos = l + offset;
03737 break;
03738 default:
03739 return -EINVAL;
03740 }
03741
03742
03743 if (file->f_pos < 0) {
03744 file->f_pos = 0;
03745 return(-EOVERFLOW);
03746 }
03747
03748
03749 if (file->f_pos > l) {
03750 file->f_pos = l;
03751 }
03752 return ( file->f_pos );
03753 }
03754
03755
03756 ssize_t x313_tables_write(struct file * file, const char * buf, size_t count, loff_t *off) {
03757 unsigned long flags;
03758 unsigned long p;
03759 char * fpga_tables_char= (char *) fpga_tables_buffer;
03760 int sa,l,i;
03761 D(printk("x313_tables_write, count= %x\n", (int) count));
03762 p = file->f_pos;
03763 if (p >= (CX313_FPGA_TABLES_SIZE<<2)) p = (CX313_FPGA_TABLES_SIZE<<2);
03764 if( (p + count) > (CX313_FPGA_TABLES_SIZE<<2)) {
03765 count = (CX313_FPGA_TABLES_SIZE<<2) - p;
03766 }
03767 D(printk("x313_tables_write, p=%x, count= %x\n", (int) p,(int) count));
03768
03769 if (count) {
03770
03771 if (copy_from_user(&fpga_tables_char[p],buf, count)) return -EFAULT;
03772 file->f_pos+=count;
03773 sa= p>>2;
03774 l=count>>2;
03775 local_irq_save(flags);
03776
03777 port_csp0_addr[X313_WA_COMP_TA]=sa;
03778 for (i = 0; i < l; i++) {
03779 port_csp0_addr[X313_WA_COMP_TD]=fpga_tables_buffer[sa++];
03780 }
03781 port_csp0_addr[X313_WA_COMP_TA]=sa;
03782 local_irq_restore(flags);
03783 }
03784 return count;
03785 }
03786
03787
03788
03789
03790 ssize_t x313_tables_read(struct file * file, char * buf, size_t count, loff_t *off) {
03791 unsigned long sa,p;
03792
03793 char * fpga_tables_char= (char *) fpga_tables_buffer;
03794
03795 D(printk("x313_tables_read\n"));
03796 p = file->f_pos;
03797 sa=p>>2;
03798
03799 if( (p + count) > (CX313_FPGA_TABLES_SIZE<<2)) {
03800 count = (CX313_FPGA_TABLES_SIZE<<2) - p;
03801 }
03802 if (count && (copy_to_user(buf, &fpga_tables_char[p], count)))
03803 {printk("copy_to_user1 (0x%x) error\n",(int) count);return -EFAULT;}
03804
03805 file->f_pos+=count;
03806 return count;
03807 }
03808
03809
03810 #define CX313_FPGA_HISTOGRAM_SIZE 0x400 //=0x1000 bytes, 32-bit wide, LSB first
03811
03812 loff_t x313_histogram_lseek(struct file * file, loff_t offset, int orig){
03813
03814
03815
03816
03817
03818
03819 int l;
03820 l=(CX313_FPGA_HISTOGRAM_SIZE<<2);
03821
03822 switch (orig)
03823 {
03824 case 0:
03825 file->f_pos = offset;
03826 break;
03827 case 1:
03828 file->f_pos += offset;
03829 break;
03830 case 2:
03831 file->f_pos = l + offset;
03832 break;
03833 default:
03834 return -EINVAL;
03835 }
03836
03837
03838 if (file->f_pos < 0) {
03839 file->f_pos = 0;
03840 return(-EOVERFLOW);
03841 }
03842
03843
03844 if (file->f_pos > l) {
03845 file->f_pos = l;
03846 }
03847 return ( file->f_pos );
03848 }
03849
03850
03851
03852
03853
03854
03855
03856 ssize_t x313_histogram_read(struct file * file, char * buf, size_t count, loff_t *off) {
03857 unsigned long sa,p,l,i;
03858 int histogram_buffer[1024];
03859 char * histogram_buffer_char= (char *) histogram_buffer;
03860
03861 D(printk("x313_histogram_read\n"));
03862
03863 p = file->f_pos;
03864 sa=p>>2;
03865
03866 if( (p + count) > (CX313_FPGA_HISTOGRAM_SIZE<<2)) {
03867 count = (CX313_FPGA_HISTOGRAM_SIZE<<2) - p;
03868 }
03869 l=((p+count-1)>>2)-sa+1;
03870 port_csp0_addr[X313_WA_COMP_TA]=sa;
03871 for (i=0;i<l;i++) {
03872 port_csp0_addr[X313_WA_HIST_ADDR]=sa;
03873 X3X3_AFTERWRITE ;
03874 fpga_tables_buffer[sa++]=port_csp4_addr[X313_RA_HIST_DATA];
03875 }
03876
03877 if (count && (copy_to_user(buf, &histogram_buffer_char[p], count)))
03878 {printk("copy_to_user1 (0x%x) error\n",(int) count);return -EFAULT;}
03879
03880 file->f_pos+=count;
03881 return count;
03882 }
03883
03884
03885
03886 void init_autoexp_struct(void) {
03887 autoexp_state = (struct autoexp_t *) &imageParamsR[P_AUTOEXP];
03888 autoexp_set= (struct autoexp_t *) &imageParamsW[P_AUTOEXP];
03889 aexp_window= (struct aexp_window_t * ) &imageParamsR[P_AEXPWND];
03890 aexp_window_set=(struct aexp_window_t * ) &imageParamsW[P_AEXPWND];
03891 }
03892
03893
03894
03895
03896
03897 module_init(cmoscam_init);
03898 MODULE_LICENSE("GPL");
03899 MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
03900 MODULE_DESCRIPTION(MY_MODULE_DESCRIPTION);
03901 MODULE_DESCRIPTION("Elphel Model 353 camera driver");
03902
03903
03904