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 #include <linux/module.h>
00091 #include <linux/sched.h>
00092 #include <linux/slab.h>
00093 #include <linux/errno.h>
00094 #include <linux/kernel.h>
00095 #include <linux/fs.h>
00096 #include <linux/string.h>
00097 #include <linux/init.h>
00098 #include <linux/autoconf.h>
00099
00100 #include <asm/system.h>
00101
00102 #include <asm/io.h>
00103
00104
00105
00106 #include <asm/irq.h>
00107
00108 #include <asm/delay.h>
00109 #include <asm/uaccess.h>
00110 #include <asm/elphel/fpgaconfa.h>
00111 #include <asm/elphel/c313a.h>
00112 #include "framepars.h"
00113
00114 #include <asm/arch/hwregs/reg_map.h>
00115 #include <asm/arch/hwregs/bif_core_defs.h>
00116
00117 #include "x3x3.h"
00118
00119 #include "fpgactrl.h"
00120 #include "fpga_io.h"
00121
00122 #define D(x)
00123
00124
00125
00126
00127
00128
00129
00130
00133 #if ELPHEL_DEBUG
00134 #define D12(x) { if (GLOBALPARS(G_DEBUG) & (1 <<12)) { x ;} }
00135 #define D13(x) { if (GLOBALPARS(G_DEBUG) & (1 <<13)) { x ;} }
00136 #define MDF12(x) { if (GLOBALPARS(G_DEBUG) & (1 <<12)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;} }
00137
00138 #define MDF13(x) { if (GLOBALPARS(G_DEBUG) & (1 <<13)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;} }
00139 #else
00140 #define D12(x)
00141 #define MDF12(x)
00142 #define MDF13(x)
00143 #endif
00144
00145 unsigned long fpga_tables_buffer[CX313_FPGA_TABLES_SIZE];
00146
00147 #define CAPTURE_SIZE 8192
00148 static char capture_buf[CAPTURE_SIZE];
00149 static int capture_length;
00150 static int capture_pointer;
00151 int fpga_io_open(void) {
00152 return 0;
00153 }
00154 int fpga_io_close (void){
00155 return 0;
00156 }
00157
00158
00159 int canon_lens_io (int d) {
00160 unsigned long flags;
00161 int res,i,j;
00162
00163
00164 if ((port_csp0_addr[0x70] & 5) !=5) {
00165 port_csp0_addr[0x70]=0x33;
00166 udelay (200);
00167 }
00168 res=0;
00169
00170 port_csp0_addr[0x70]=0x23;
00171 udelay (60);
00172 local_irq_save(flags);
00173
00174 for (i=0; i<8; i++) {
00175 port_csp0_addr[0x70]= 0x22 | ((d & 0x80)?0x10:0);
00176 udelay (6);
00177 res=(res<<1) | ( (port_csp0_addr[0x70] & 2)>>1);
00178 port_csp0_addr[0x70]= 0x23 | ((d & 0x80)?0x10:0);
00179 udelay (6);
00180
00181 for (j=0;j<1000000;j++) {
00182 if (port_csp0_addr[0x70] & 8) break;
00183 udelay (1);
00184 }
00185 d<<=1;
00186 }
00187
00188 for (j=0;j<1000000;j++) {
00189 if (!(port_csp0_addr[0x70] & 8)) break;
00190 udelay (1);
00191 }
00192 udelay (6);
00193 port_csp0_addr[0x70]=0x33;
00194 local_irq_restore(flags);
00195 udelay (200);
00196 return res;
00197 }
00198
00199
00200 int capture_pins (int n, int m) {
00201 int i;
00202 unsigned long flags;
00203 char b0,b1,b;
00204 int msk;
00205 msk=0xff& ((m!=0)?m:0xff);
00206
00207 capture_length=0;
00208 capture_pointer=0;
00209 b0=b1=0xff;
00210
00211 local_irq_save(flags);
00212
00213 for (i=0; (i < n) && (capture_length < CAPTURE_SIZE); i++) {
00214 b=msk & port_csp0_addr[0x70];
00215 if (b==b1) {
00216 if (b!=b0) capture_buf[capture_length++]=b;
00217 b0=b;
00218 }
00219 b1=b;
00220 udelay(1);
00221 }
00222 local_irq_restore(flags);
00223 return capture_length;
00224 }
00225
00226 int capture_read (void) {
00227 if (capture_pointer < capture_length) {
00228 return capture_buf[capture_pointer++];
00229 } else return -EINVAL;
00230 }
00231 #if 0
00232
00233 typedef struct {
00234 unsigned int lw : 6;
00235 unsigned int ew : 3;
00236 unsigned int zw : 3;
00237 unsigned int aw : 2;
00238 unsigned int dw : 2;
00239 unsigned int ewb : 2;
00240 unsigned int bw : 1;
00241 unsigned int wr_extend : 1;
00242 unsigned int erc_en : 1;
00243 unsigned int mode : 1;
00244 unsigned int dummy1 : 10;
00245 } reg_bif_core_rw_grp2_cfg;
00246 #define REG_RD_ADDR_bif_core_rw_grp2_cfg 4
00247 #define REG_WR_ADDR_bif_core_rw_grp2_cfg 4
00248 reg_bif_core_rw_grp3_cfg bif_cfg = REG_RD(bif_core, regi_bif_core, rw_grp3_cfg);
00249 REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg);
00250
00251
00252 #endif
00253
00254
00255
00256
00257
00258 int fpga_io_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){
00259 reg_bif_core_rw_grp1_cfg csr1_cfg;
00260 reg_bif_core_rw_grp2_cfg csr2_cfg;
00261 reg_bif_core_rw_grp3_cfg csr3_cfg;
00262 reg_bif_core_rw_grp4_cfg csr4_cfg;
00263
00264
00265 int d;
00266 D(printk("csp0rw_ioctl cmd= %x, arg= %x\n\r",cmd,arg));
00267 D(printk("csp0rw_ioctl: ((int *)file->private_data)[0]= %x\n\r",((int *)file->private_data)[0]));
00268 D(printk("fpga_io.c:fpga_io_ioctl:_IOC_NR(cmd)=%x\n",(int) _IOC_NR(cmd)));
00269 switch (_IOC_TYPE(cmd)) {
00270
00271 case FPGACONF_READREG:
00272 d=(int)port_csp0_addr[_IOC_NR(cmd)];
00273 D(printk ("port_csp0_addr[%x]=%x\n",(int) _IOC_NR(cmd),d));
00274 return d;
00275 case FPGACONF_READREG_L:
00276 d=(int)port_csp0_addr[_IOC_NR(cmd)] & 0x0000ffff;
00277 D(printk ("port_csp0_addr[%x]=%x\n",(int) _IOC_NR(cmd),d));
00278 return d;
00279 case FPGACONF_READREG_H:
00280 d=((int)port_csp0_addr[_IOC_NR(cmd)]>>16) & 0x0000ffff;
00281 D(printk ("port_csp0_addr[%x]=%x\n",(int) _IOC_NR(cmd),d));
00282 return d;
00283 case FPGACONF_READREG4:
00284 d=(int)port_csp4_addr[_IOC_NR(cmd)];
00285 D(printk ("port_csp4_addr[%x]=%x\n",(int) _IOC_NR(cmd),d));
00286 return d;
00287 case FPGACONF_READREG_L4:
00288 return (long ) ( port_csp4_addr[_IOC_NR(cmd)] & 0x0000ffff);
00289 case FPGACONF_READREG_H4:
00290 return (long ) ((port_csp4_addr[_IOC_NR(cmd)]>>16) & 0x0000ffff);
00291
00292 case FPGACONF_WRITEREG:
00293 if (_IOC_NR(cmd)==0) arg |= ((arg & 0x40000000)<<1);
00294
00295 port_csp0_addr[_IOC_NR(cmd)]=arg;
00296 return (long ) arg;
00297 case FPGACONF_WRITEREG4:
00298
00299 port_csp4_addr[_IOC_NR(cmd)]=arg;
00300 return (long ) arg;
00301 case FPGACONF_WR_WAITSTATES:
00302 ((int *) &csr1_cfg)[0]=arg;
00303 ((int *) &csr2_cfg)[0]=arg;
00304 ((int *) &csr3_cfg)[0]=arg;
00305 ((int *) &csr4_cfg)[0]=arg;
00306 switch (_IOC_NR(cmd)) {
00307 case 1:
00308 REG_WR(bif_core, regi_bif_core, rw_grp1_cfg, csr1_cfg);
00309 break;
00310 case 2:
00311 REG_WR(bif_core, regi_bif_core, rw_grp2_cfg, csr2_cfg);
00312 break;
00313 case 3:
00314 REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, csr3_cfg);
00315 break;
00316 case 4:
00317 REG_WR(bif_core, regi_bif_core, rw_grp4_cfg, csr4_cfg);
00318 break;
00319 default:
00320 printk ("address should be 1,2,3, or 4\n");
00321 return -EINVAL;
00322 }
00323 case FPGACONF_RD_WAITSTATES:
00324 switch (_IOC_NR(cmd)) {
00325 case 1:
00326 csr1_cfg=REG_RD(bif_core, regi_bif_core, rw_grp1_cfg);
00327 d=((int *) &csr1_cfg)[0];
00328 break;
00329 case 2:
00330 csr2_cfg=REG_RD(bif_core, regi_bif_core, rw_grp2_cfg);
00331 d=((int *) &csr2_cfg)[0];
00332 break;
00333 case 3:
00334 csr3_cfg=REG_RD(bif_core, regi_bif_core, rw_grp3_cfg);
00335 d=((int *) &csr3_cfg)[0];
00336 break;
00337 case 4:
00338 csr4_cfg=REG_RD(bif_core, regi_bif_core, rw_grp4_cfg);
00339 d=((int *) &csr4_cfg)[0];
00340 break;
00341 default:
00342 printk ("address should be 1,2,3, or 4\n");
00343 return -EINVAL;
00344 }
00345 printk ("rw_grp%d_cfg=%x\n",_IOC_NR(cmd),d);
00346 return d;
00347 case FPGACONF_CANON_IOBYTE:
00348 return canon_lens_io (arg);
00349 case FPGACONF_START_CAPTURE:
00350 return capture_pins (arg, _IOC_NR(cmd));
00351 case FPGACONF_READ_CAPTURE:
00352 return capture_read();
00353 default:
00354 return -EINVAL;
00355 }
00356 return 0;
00357 }
00358
00359 loff_t fpga_io_lseek (struct file * file, loff_t offset, int orig) {
00360 size_t size=0x4000;
00361 switch (orig) {
00362 case SEEK_SET:
00363 file->f_pos = offset;
00364 break;
00365 case SEEK_CUR:
00366 file->f_pos += offset;
00367 break;
00368 case SEEK_END:
00369 file->f_pos = size + offset;
00370 break;
00371 default:
00372 return -EINVAL;
00373 }
00374
00375 if (file->f_pos < 0) {
00376 file->f_pos = 0;
00377 return (-EOVERFLOW);
00378 }
00379 if (file->f_pos > size) {
00380 file->f_pos = size;
00381 return (-EOVERFLOW);
00382 }
00383 D(printk("fpga_io_lseek, file->f_pos= 0x%x\n", (int) file->f_pos));
00384 return (file->f_pos);
00385 }
00386
00391
00392
00394
00395
00396 ssize_t fpga_io_read (struct file * file, char * buf, size_t count, loff_t *off){
00397 int l;
00398 unsigned long rbuf[1024];
00399 D(printk("fpga_io_read: buf address=%lx count=%lx *offs=%lx\r\n", (long) buf, (long) count, (long) *off));
00401 if (count > sizeof(rbuf)) count =sizeof(rbuf);
00403 for (l=0; (l<<2) < count; l++)
00404 rbuf[l]=((*off) & 0x2000)?
00405 (unsigned long) port_csp4_addr[(*off) & 0x1fff]:
00406 (unsigned long) port_csp0_addr[(*off) & 0x1fff];
00408 if (copy_to_user(buf,rbuf,count)) return -EFAULT;
00410 return count;
00411 }
00412
00413
00414 ssize_t fpga_io_write (struct file * file, const char * buf, size_t count, loff_t *off){
00415 int l,n;
00416 unsigned long wbuf[1024];
00417 D(printk("fpga_io_write: buf address=%lx count=%lx *offs=%lx\r\n",(long) buf, (long) count, (long) *off));
00419 if (count > sizeof(wbuf)) count =sizeof(wbuf);
00421 n=count>>2;
00422 if (count & 3) {
00423 wbuf[count>>2]=0;
00424 n++;
00425 }
00426 if (copy_from_user(wbuf,buf,count)) return -EFAULT;
00428 if ((*off) & 0x2000) for (l=0; l < n; l++) port_csp4_addr[(*off) & 0x1fff]= wbuf[l];
00429 else for (l=0; l < n; l++) port_csp0_addr[(*off) & 0x1fff]= wbuf[l];
00431 return count;
00432 }
00433
00434
00437 #define FPGA_TABLE_CHUNK 64 // up to 64 words to send to the table/from histogram on a single IRQ-off transfer
00438 void fpga_table_write_nice (int addr, int len, unsigned long * data) {
00439 unsigned long flags;
00440 int l,i;
00441 MDF12(printk("addr=0x%x, len=0x%x, data=0x%08lx 0x%08lx 0x%08lx 0x%08lx...\n", addr, len, data[0], data[1], data[2], data[3]));
00442 while (len>0) {
00443 l=(len < FPGA_TABLE_CHUNK)?len:FPGA_TABLE_CHUNK;
00444 local_irq_save(flags);
00445 port_csp0_addr[X313_WA_COMP_TA]=addr;
00446 for (i=0; i<l; i++) port_csp0_addr[X313_WA_COMP_TD]=data[i];
00447 local_irq_restore(flags);
00448 len -=l;
00449 addr +=l;
00450 data +=l;
00451 }
00452 }
00453
00457 void fpga_hist_read_nice (int addr, int len, unsigned long * data) {
00458 unsigned long flags;
00459 int l,i;
00460 MDF13(printk("addr=0x%x, len=0x%x, ",addr, len));
00461 while (len>0) {
00462 l=(len < FPGA_TABLE_CHUNK)?len:FPGA_TABLE_CHUNK;
00463 local_irq_save(flags);
00464
00465
00466 port_csp0_addr[X313_WA_HIST_ADDR]=addr;
00467 X3X3_AFTERWRITE ;
00468 for (i=0; i<l; i++) data[i]=port_csp4_addr[X313_RA_HIST_DATA];
00469 local_irq_restore(flags);
00470 len -=l;
00471 addr +=l;
00472 data +=l;
00473 }
00474 D13(printk("data=0x%08lx 0x%08lx 0x%08lx 0x%08lx...\n", data[0], data[1], data[2], data[3]));
00475 }
00476
00477 ssize_t fpga_io_table_write (struct file * file, const char * buf, size_t count, loff_t *off) {
00478 unsigned long p;
00479 char * fpga_tables_char= (char *) fpga_tables_buffer;
00480 int sa,l;
00481 D(printk("fpga_io_table_write, count= %x\n", (int) count));
00482 p = *off;
00483 if (p >= (CX313_FPGA_TABLES_SIZE<<2)) p = (CX313_FPGA_TABLES_SIZE<<2);
00484 if( (p + count) > (CX313_FPGA_TABLES_SIZE<<2)) {
00485 count = (CX313_FPGA_TABLES_SIZE<<2) - p;
00486 }
00487 D(printk("fpga_io_table_write, p=%x, count= %x\n", (int) p,(int) count));
00488 if (count) {
00489 if (copy_from_user(&fpga_tables_char[p],buf, count)) return -EFAULT;
00490 *off+=count;
00491 sa= p>>2;
00492 l=count>>2;
00493 fpga_table_write_nice (sa, l, &fpga_tables_buffer[sa]);
00494 }
00495 return count;
00496 }
00497
00498
00499 loff_t fpga_io_table_lseek (struct file * file, loff_t offset, int orig) {
00500 int l;
00501 l=(CX313_FPGA_TABLES_SIZE<<2);
00502 switch (orig)
00503 {
00504 case 0:
00505 file->f_pos = offset;
00506 break;
00507 case 1:
00508 file->f_pos += offset;
00509 break;
00510 case 2:
00511 file->f_pos = l + offset;
00512 break;
00513 default:
00514 return -EINVAL;
00515 }
00516
00517 if (file->f_pos < 0) {
00518 file->f_pos = 0;
00519 return(-EOVERFLOW);
00520 }
00521 if (file->f_pos > l) {
00522 file->f_pos = l;
00523 }
00524 return ( file->f_pos );
00525 }