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

Go to the documentation of this file.
00001 /*!***************************************************************************
00002 *! FILE NAME  : fpga_io.c
00003 *! DESCRIPTION: TBD
00004 *! Copyright (C) 2002-2006 Elphel, Inc.
00005 *! -----------------------------------------------------------------------------**
00006 *!  This program is free software: you can redistribute it and/or modify
00007 *!  it under the terms of the GNU General Public License as published by
00008 *!  the Free Software Foundation, either version 3 of the License, or
00009 *!  (at your option) any later version.
00010 *!
00011 *!  This program is distributed in the hope that it will be useful,
00012 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 *!  GNU General Public License for more details.
00015 *!
00016 *!  You should have received a copy of the GNU General Public License
00017 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 *! -----------------------------------------------------------------------------**
00019 *!  $Log: fpga_io.c,v $
00020 *!  Revision 1.6  2008/04/29 05:49:27  elphel
00021 *!  typo
00022 *!
00023 *!  Revision 1.5  2008/04/14 17:15:52  spectr_rain
00024 *!  200 gamma tables, correct 257 values tables
00025 *!
00026 *!  Revision 1.4  2008/04/11 23:16:51  elphel
00027 *!  removed unneeded local_irq_disable() after local_irq_save_flags()
00028 *!
00029 *!  Revision 1.3  2008/04/09 21:01:25  elphel
00030 *!  added access to individual wait state registers
00031 *!
00032 *!  Revision 1.2  2007/10/23 16:58:51  elphel
00033 *!  Improved r/w access to FPGA registers (available from PHP)
00034 *!
00035 *!  Revision 1.1.1.1  2007/08/17 10:23:18  elphel
00036 *!  This is a fresh tree based on elphel353-2.10
00037 *!
00038 *!  Revision 1.7  2007/08/17 10:23:18  spectr_rain
00039 *!  switch to GPL3 license
00040 *!
00041 *!  Revision 1.6  2007/07/20 10:17:46  spectr_rain
00042 *!  *** empty log message ***
00043 *!
00044 *!  Revision 1.2  2007/05/21 17:45:10  elphel
00045 *!  boundary scan support, added 359/347 detection
00046 *!
00047 *!  Revision 1.1.1.1  2007/02/23 10:11:48  elphel
00048 *!  initial import into CVS
00049 *!
00050 *!  Revision 1.3  2006/04/06 07:46:33  elphel
00051 *!  control for canon lenses
00052 *!
00053 */
00054 
00055 /****************** INCLUDE FILES SECTION ***********************************/
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 //#include <asm/svinto.h>
00069 #include <asm/io.h>
00070 //#include <linux/interrupt.h>
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 //#define D(x) printk("%s:%d:",__FILE__,__LINE__);x
00088 
00089 extern volatile unsigned long ccam_cr_shadow;
00090 
00091 
00092 
00093 //#define FPGACONF_RD_WAITSTATES     150    // read R_WAITSTATES
00094 //#define FPGACONF_WR_WAITSTATES     151    // write R_WAITSTATES
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 // will use 1.2-us "debounce/metastability" filter, so minimal pulse width detected will be 2.5us
00107 int canon_lens_io (int d) {
00108   unsigned long flags;
00109   int res,i,j;
00110 
00111 // make sure pins initialized
00112    if ((port_csp0_addr[0x70] & 5) !=5) {
00113      port_csp0_addr[0x70]=0x33;
00114      udelay (200);
00115    } 
00116    res=0;
00117 // start condition   
00118    port_csp0_addr[0x70]=0x23;
00119    udelay (60);
00120    local_irq_save(flags);
00121    //local_irq_disable();  //disable all interrupts for the time of capture
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 // wait clock is high here
00129      for (j=0;j<1000000;j++) {  // timeout
00130        if (port_csp0_addr[0x70] & 8) break;
00131        udelay (1);
00132      }  
00133      d<<=1;
00134    }
00135 // wait clock low (by the lens)
00136    for (j=0;j<1000000;j++) {  // timeout
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    //local_irq_disable();  //disable all interrupts for the time of capture
00161    for (i=0; (i < n) && (capture_length < CAPTURE_SIZE); i++) {
00162     b=msk & port_csp0_addr[0x70]; //X313__RA__IOPINS
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 /* Register rw_grp2_cfg, scope bif_core, type rw */
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);    // control MSB of CR
00242 //                      return (long )   port_csp0_addr[_IOC_NR(cmd)]=arg; // read back after write
00243                         port_csp0_addr[_IOC_NR(cmd)]=arg;
00244                         return (long )   arg;
00245                 case FPGACONF_WRITEREG4:
00246 //                      return (long )   port_csp4_addr[_IOC_NR(cmd)]=arg; // read back after write
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); // and fall through
00257             break;
00258            case 2:
00259             REG_WR(bif_core, regi_bif_core, rw_grp2_cfg, csr2_cfg); // and fall through
00260             break;
00261            case 3:
00262             REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, csr3_cfg); // and fall through
00263             break;
00264            case 4:
00265             REG_WR(bif_core, regi_bif_core, rw_grp4_cfg, csr4_cfg); // and fall through
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); // second agrument - mask. 0 will be the same as 0xff
00297       case FPGACONF_START_CAPTURE:
00298          return capture_pins (arg, _IOC_NR(cmd)); // second agrument - mask. 0 will be the same as 0xff
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              //local_irq_disable();
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    /* truncate position */
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]; // up to 4096 bytes/read
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]; // up to 4096 bytes/write
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                 // flush the last table write - probably is deprecated
00415                 port_csp0_addr[0x0E] = fpga_addr + off;
00416                 local_irq_restore(flags);
00417 
00418                 length -= c;
00419                 off += c;
00420         }
00421 }

Generated on Thu Aug 7 16:19:00 2008 for elphel by  doxygen 1.5.1