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 #include <linux/module.h>
00058 #include <linux/sched.h>
00059 #include <linux/slab.h>
00060 #include <linux/errno.h>
00061 #include <linux/kernel.h>
00062 #include <linux/fs.h>
00063 #include <linux/string.h>
00064 #include <linux/init.h>
00065 #include <linux/autoconf.h>
00066
00067 #include <asm/system.h>
00068
00069 #include <asm/io.h>
00070
00071
00072
00073 #include <asm/irq.h>
00074
00075 #include <asm/delay.h>
00076 #include <asm/uaccess.h>
00077 #include <asm/elphel/fpgactrl.h>
00078 #include <asm/arch/hwregs/reg_map.h>
00079 #include <asm/arch/hwregs/bif_core_defs.h>
00080
00081 #include "x3x3.h"
00082
00083 #include "fpgactrl.h"
00084 #include "fpga_io.h"
00085
00086 #define D(x)
00087
00088
00089 extern volatile unsigned long ccam_cr_shadow;
00090
00091
00092
00093
00094
00095 #define CAPTURE_SIZE 8192
00096 static char capture_buf[CAPTURE_SIZE];
00097 static int capture_length;
00098 static int capture_pointer;
00099 int fpga_io_open(void) {
00100 return 0;
00101 }
00102 int fpga_io_close (void){
00103 return 0;
00104 }
00105
00106
00107 int canon_lens_io (int d) {
00108 unsigned long flags;
00109 int res,i,j;
00110
00111
00112 if ((port_csp0_addr[0x70] & 5) !=5) {
00113 port_csp0_addr[0x70]=0x33;
00114 udelay (200);
00115 }
00116 res=0;
00117
00118 port_csp0_addr[0x70]=0x23;
00119 udelay (60);
00120 local_irq_save(flags);
00121
00122 for (i=0; i<8; i++) {
00123 port_csp0_addr[0x70]= 0x22 | ((d & 0x80)?0x10:0);
00124 udelay (6);
00125 res=(res<<1) | ( (port_csp0_addr[0x70] & 2)>>1);
00126 port_csp0_addr[0x70]= 0x23 | ((d & 0x80)?0x10:0);
00127 udelay (6);
00128
00129 for (j=0;j<1000000;j++) {
00130 if (port_csp0_addr[0x70] & 8) break;
00131 udelay (1);
00132 }
00133 d<<=1;
00134 }
00135
00136 for (j=0;j<1000000;j++) {
00137 if (!(port_csp0_addr[0x70] & 8)) break;
00138 udelay (1);
00139 }
00140 udelay (6);
00141 port_csp0_addr[0x70]=0x33;
00142 local_irq_restore(flags);
00143 udelay (200);
00144 return res;
00145 }
00146
00147
00148 int capture_pins (int n, int m) {
00149 int i;
00150 unsigned long flags;
00151 char b0,b1,b;
00152 int msk;
00153 msk=0xff& ((m!=0)?m:0xff);
00154
00155 capture_length=0;
00156 capture_pointer=0;
00157 b0=b1=0xff;
00158
00159 local_irq_save(flags);
00160
00161 for (i=0; (i < n) && (capture_length < CAPTURE_SIZE); i++) {
00162 b=msk & port_csp0_addr[0x70];
00163 if (b==b1) {
00164 if (b!=b0) capture_buf[capture_length++]=b;
00165 b0=b;
00166 }
00167 b1=b;
00168 udelay(1);
00169 }
00170 local_irq_restore(flags);
00171 return capture_length;
00172 }
00173
00174 int capture_read (void) {
00175 if (capture_pointer < capture_length) {
00176 return capture_buf[capture_pointer++];
00177 } else return -EINVAL;
00178 }
00179 #if 0
00180
00181 typedef struct {
00182 unsigned int lw : 6;
00183 unsigned int ew : 3;
00184 unsigned int zw : 3;
00185 unsigned int aw : 2;
00186 unsigned int dw : 2;
00187 unsigned int ewb : 2;
00188 unsigned int bw : 1;
00189 unsigned int wr_extend : 1;
00190 unsigned int erc_en : 1;
00191 unsigned int mode : 1;
00192 unsigned int dummy1 : 10;
00193 } reg_bif_core_rw_grp2_cfg;
00194 #define REG_RD_ADDR_bif_core_rw_grp2_cfg 4
00195 #define REG_WR_ADDR_bif_core_rw_grp2_cfg 4
00196 reg_bif_core_rw_grp3_cfg bif_cfg = REG_RD(bif_core, regi_bif_core, rw_grp3_cfg);
00197 REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg);
00198
00199
00200 #endif
00201
00202
00203
00204
00205
00206 int fpga_io_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){
00207 reg_bif_core_rw_grp1_cfg csr1_cfg;
00208 reg_bif_core_rw_grp2_cfg csr2_cfg;
00209 reg_bif_core_rw_grp3_cfg csr3_cfg;
00210 reg_bif_core_rw_grp4_cfg csr4_cfg;
00211 unsigned long flags;
00212 int i1;
00213 int d;
00214 D(printk("csp0rw_ioctl cmd= %x, arg= %x\n\r",cmd,arg));
00215 D(printk("csp0rw_ioctl: ((int *)file->private_data)[0]= %x\n\r",((int *)file->private_data)[0]));
00216 D(printk("fpga_io.c:fpga_io_ioctl:_IOC_NR(cmd)=%x\n",(int) _IOC_NR(cmd)));
00217 switch (_IOC_TYPE(cmd)) {
00218
00219 case FPGACONF_READREG:
00220 d=(int)port_csp0_addr[_IOC_NR(cmd)];
00221 D(printk ("port_csp0_addr[%x]=%x\n",(int) _IOC_NR(cmd),d));
00222 return d;
00223 case FPGACONF_READREG_L:
00224 d=(int)port_csp0_addr[_IOC_NR(cmd)] & 0x0000ffff;
00225 D(printk ("port_csp0_addr[%x]=%x\n",(int) _IOC_NR(cmd),d));
00226 return d;
00227 case FPGACONF_READREG_H:
00228 d=((int)port_csp0_addr[_IOC_NR(cmd)]>>16) & 0x0000ffff;
00229 D(printk ("port_csp0_addr[%x]=%x\n",(int) _IOC_NR(cmd),d));
00230 return d;
00231 case FPGACONF_READREG4:
00232 d=(int)port_csp4_addr[_IOC_NR(cmd)];
00233 D(printk ("port_csp4_addr[%x]=%x\n",(int) _IOC_NR(cmd),d));
00234 return d;
00235 case FPGACONF_READREG_L4:
00236 return (long ) ( port_csp4_addr[_IOC_NR(cmd)] & 0x0000ffff);
00237 case FPGACONF_READREG_H4:
00238 return (long ) ((port_csp4_addr[_IOC_NR(cmd)]>>16) & 0x0000ffff);
00239
00240 case FPGACONF_WRITEREG:
00241 if (_IOC_NR(cmd)==0) arg |= ((arg & 0x40000000)<<1);
00242
00243 port_csp0_addr[_IOC_NR(cmd)]=arg;
00244 return (long ) arg;
00245 case FPGACONF_WRITEREG4:
00246
00247 port_csp4_addr[_IOC_NR(cmd)]=arg;
00248 return (long ) arg;
00249 case FPGACONF_WR_WAITSTATES:
00250 ((int *) &csr1_cfg)[0]=arg;
00251 ((int *) &csr2_cfg)[0]=arg;
00252 ((int *) &csr3_cfg)[0]=arg;
00253 ((int *) &csr4_cfg)[0]=arg;
00254 switch (_IOC_NR(cmd)) {
00255 case 1:
00256 REG_WR(bif_core, regi_bif_core, rw_grp1_cfg, csr1_cfg);
00257 break;
00258 case 2:
00259 REG_WR(bif_core, regi_bif_core, rw_grp2_cfg, csr2_cfg);
00260 break;
00261 case 3:
00262 REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, csr3_cfg);
00263 break;
00264 case 4:
00265 REG_WR(bif_core, regi_bif_core, rw_grp4_cfg, csr4_cfg);
00266 break;
00267 default:
00268 printk ("address should be 1,2,3, or 4\n");
00269 return -EINVAL;
00270 }
00271 case FPGACONF_RD_WAITSTATES:
00272 switch (_IOC_NR(cmd)) {
00273 case 1:
00274 csr1_cfg=REG_RD(bif_core, regi_bif_core, rw_grp1_cfg);
00275 d=((int *) &csr1_cfg)[0];
00276 break;
00277 case 2:
00278 csr2_cfg=REG_RD(bif_core, regi_bif_core, rw_grp2_cfg);
00279 d=((int *) &csr2_cfg)[0];
00280 break;
00281 case 3:
00282 csr3_cfg=REG_RD(bif_core, regi_bif_core, rw_grp3_cfg);
00283 d=((int *) &csr3_cfg)[0];
00284 break;
00285 case 4:
00286 csr4_cfg=REG_RD(bif_core, regi_bif_core, rw_grp4_cfg);
00287 d=((int *) &csr4_cfg)[0];
00288 break;
00289 default:
00290 printk ("address should be 1,2,3, or 4\n");
00291 return -EINVAL;
00292 }
00293 printk ("rw_grp%d_cfg=%x\n",_IOC_NR(cmd),d);
00294 return d;
00295 case FPGACONF_CANON_IOBYTE:
00296 return canon_lens_io (arg);
00297 case FPGACONF_START_CAPTURE:
00298 return capture_pins (arg, _IOC_NR(cmd));
00299 case FPGACONF_READ_CAPTURE:
00300 return capture_read();
00301 case FPGACONF_CONTROL_REG:
00302 switch(_IOC_NR(cmd)){
00303 case FPGACONF_CR_MODIFY : {
00304 local_irq_save(flags);
00305
00306 i1=((ccam_cr_shadow & (1<<(arg>>2)))!=0);
00307 switch (arg & 3) {
00308 case 1: {ccam_cr_shadow &= ~(1<<(arg>>2));break;}
00309 case 2: {ccam_cr_shadow |= (1<<(arg>>2));break;}
00310 case 3: {ccam_cr_shadow ^= (1<<(arg>>2));break;}
00311 }
00312 port_csp0_addr[X313_WA_WCTL]= ccam_cr_shadow;
00313 local_irq_restore(flags);
00314 return i1;
00315 }
00316 case FPGACONF_CR_SHADOW : return ccam_cr_shadow & 0x7fffffff;
00317 case FPGACONF_CR_SHADOW1 : return (ccam_cr_shadow >>1) & 0x7fffffff;
00318 default: return -EINVAL;
00319 }
00320 default:
00321 return -EINVAL;
00322 }
00323 return 0;
00324 }
00325
00326 loff_t fpga_io_lseek (struct file * file, loff_t offset, int orig) {
00327 size_t size=0x4000;
00328 switch (orig) {
00329 case SEEK_SET:
00330 file->f_pos = offset;
00331 break;
00332 case SEEK_CUR:
00333 file->f_pos += offset;
00334 break;
00335 case SEEK_END:
00336 file->f_pos = size + offset;
00337 break;
00338 default:
00339 return -EINVAL;
00340 }
00341
00342 if (file->f_pos < 0) {
00343 file->f_pos = 0;
00344 return (-EOVERFLOW);
00345 }
00346 if (file->f_pos > size) {
00347 file->f_pos = size;
00348 return (-EOVERFLOW);
00349 }
00350 D(printk("fpga_io_lseek, file->f_pos= 0x%x\n", (int) file->f_pos));
00351 return (file->f_pos);
00352 }
00353
00358
00359
00361
00362
00363 ssize_t fpga_io_read (struct file * file, char * buf, size_t count, loff_t *off){
00364 int l;
00365 unsigned long rbuf[1024];
00366 D(printk("fpga_io_read: buf address=%lx count=%lx *offs=%lx\r\n", (long) buf, (long) count, (long) *off));
00368 if (count > sizeof(rbuf)) count =sizeof(rbuf);
00370 for (l=0; (l<<2) < count; l++)
00371 rbuf[l]=((*off) & 0x2000)?
00372 (unsigned long) port_csp4_addr[(*off) & 0x1fff]:
00373 (unsigned long) port_csp0_addr[(*off) & 0x1fff];
00375 if (copy_to_user(buf,rbuf,count)) return -EFAULT;
00377 return count;
00378 }
00379
00380
00381 ssize_t fpga_io_write (struct file * file, const char * buf, size_t count, loff_t *off){
00382 int l,n;
00383 unsigned long wbuf[1024];
00384 D(printk("fpga_io_write: buf address=%lx count=%lx *offs=%lx\r\n",(long) buf, (long) count, (long) *off));
00386 if (count > sizeof(wbuf)) count =sizeof(wbuf);
00388 n=count>>2;
00389 if (count & 3) {
00390 wbuf[count>>2]=0;
00391 n++;
00392 }
00393 if (copy_from_user(wbuf,buf,count)) return -EFAULT;
00395 if ((*off) & 0x2000) for (l=0; l < n; l++) port_csp4_addr[(*off) & 0x1fff]= wbuf[l];
00396 else for (l=0; l < n; l++) port_csp0_addr[(*off) & 0x1fff]= wbuf[l];
00398 return count;
00399 }
00400
00401
00402 void fpga_table_write(unsigned long fpga_addr, unsigned long *data, int length) {
00403 unsigned long addr = fpga_addr;
00404 int off = 0;
00405 int i, c;
00406 unsigned long flags;
00407 while(length > 0) {
00408 c = (length < 32) ? length : 32;
00409
00410 local_irq_save(flags);
00411 port_csp0_addr[0x0E] = fpga_addr + off;
00412 for(i = 0; i < c; i++)
00413 port_csp0_addr[0x0F] = data[off + i];
00414
00415 port_csp0_addr[0x0E] = fpga_addr + off;
00416 local_irq_restore(flags);
00417
00418 length -= c;
00419 off += c;
00420 }
00421 }