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

Go to the documentation of this file.
00001 /*!***************************************************************************
00002 *! FILE NAME  : fpgactrl353.c
00003 *! DESCRIPTION: Provides sensor-independent access to FPGA in Elphel mModel 353 camera
00004 *! Includes I/O for the dedicated (to FPGA) DDR SDRAM
00005 *! Copyright 2002-2007 (C) Elphel, Inc.
00006 *! -----------------------------------------------------------------------------**
00007 *!
00008 *!  This program is free software: you can redistribute it and/or modify
00009 *!  it under the terms of the GNU General Public License as published by
00010 *!  the Free Software Foundation, either version 3 of the License, or
00011 *!  (at your option) any later version.
00012 *!
00013 *!  This program is distributed in the hope that it will be useful,
00014 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 *!  GNU General Public License for more details.
00017 *!
00018 *!  You should have received a copy of the GNU General Public License
00019 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00020 *! -----------------------------------------------------------------------------**
00021 *!  $Log: fpgactrl353.c,v $
00022 *!  Revision 1.1.1.1  2007/08/17 10:23:18  elphel
00023 *!  This is a fresh tree based on elphel353-2.10
00024 *!
00025 *!  Revision 1.7  2007/08/17 10:23:18  spectr_rain
00026 *!  switch to GPL3 license
00027 *!
00028 *!  Revision 1.6  2007/07/20 10:17:46  spectr_rain
00029 *!  *** empty log message ***
00030 *!
00031 *!  Revision 1.2  2007/05/21 17:45:10  elphel
00032 *!  boundary scan support, added 359/347 detection
00033 *!
00034 *!  Revision 1.1.1.1  2007/02/23 10:11:48  elphel
00035 *!  initial import into CVS
00036 *!
00037 *!  Revision 1.2  2005/05/10 21:08:49  elphel
00038 *!  *** empty log message ***
00039 *!
00040 */
00041 /****************** INCLUDE FILES SECTION ***********************************/
00042 
00043 
00044 #include <linux/module.h>
00045 #include <linux/sched.h>
00046 #include <linux/slab.h>
00047 #include <linux/errno.h>
00048 #include <linux/kernel.h>
00049 #include <linux/fs.h>
00050 #include <linux/string.h>
00051 #include <linux/init.h>
00052 #include <linux/autoconf.h>
00053 
00054 #include <asm/system.h>
00055 #include <asm/arch/memmap.h>
00056 
00057 //#include <asm/svinto.h>
00058 #include <asm/io.h>
00059 
00060 #include <asm/irq.h>
00061 
00062 #include <asm/delay.h>
00063 #include <asm/uaccess.h>
00064 #include <asm/elphel/fpgactrl.h>
00065 
00066 #include "fpgactrl.h"
00067 #include "fpga_io.h"
00068 #include "fpga_sdram.h"
00069 #include "x3x3.h"
00070 
00071 
00072 #define D(x)
00073 #define D1(x)
00074 #define FPGA_MAJOR 129  /* LOCAL/EXPERIMENTAL */
00075 #define FPGA_MODULE_DESCRIPTION "FPGA control driver for Elphel (R) Model 353 camera"
00076 #define FPGA_DRIVER_NAME "fpga_control"
00077 #define FPGA_MAXMINOR 10
00078 
00079 //extern volatile unsigned long ccam_cr_shadow;
00080 
00081 static const char fpga_name[] = "fpga_control";
00082 static int minors[FPGA_MAXMINOR+1];     // each minor can be opened only once
00083 static int     fpga_open   (struct inode *inode, struct file *filp);
00084 static int     fpga_release(struct inode *inode, struct file *filp);
00085 static int     fpga_ioctl  (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
00086 static ssize_t fpga_write  (struct file * file, const char * buf, size_t count, loff_t *off);
00087 static loff_t  fpga_lseek  (struct file * file, loff_t offset, int orig);
00088 static ssize_t fpga_read   (struct file * file, char * buf, size_t count, loff_t *off);
00089 
00090 //static loff_t fpga_lseek(struct file * file, loff_t offset, int orig);
00091 //static ssize_t fpga_read(struct file * file, char * buf, size_t count, loff_t *off);
00092 
00093 //static int __init fpga_init(void);
00094 
00095 static struct file_operations fpga_fops = {
00096         owner:    THIS_MODULE,
00097         open:     fpga_open,
00098         release:  fpga_release,
00099         ioctl:    fpga_ioctl,
00100         llseek:   fpga_lseek,
00101         read:     fpga_read,
00102         write:    fpga_write
00103 };
00104 
00105 //#define FPGA_STATE_LOADED       0x0000FFFF; //
00106 //#define FPGA_STATE_CLOCKS       0x000F0000; // 
00107 //#define FPGA_STATE_INITIALIZED  0x00100000; //
00108 //FPGA_STATE_SDRAM_INIT 
00109 //static int fpga_state=0; 
00110 // **************************************************************
00111 
00112 /* ======================================== Top level file operations =================================================================== */
00113 static int fpga_open(struct inode *inode, struct file *filp) {
00114         int p;
00115         int res;
00116 
00117         p = MINOR(inode->i_rdev);
00118      D1(printk("fpga_open: minor=%x\r\n",p) );
00119      D1(printk("filp=%lx\r\n",(unsigned long)filp) );
00120 
00121         switch ( p ) {
00122         case FPGACONF_MINOR_SDRAM : {
00123               if (minors[p])  return -EACCES;
00124 // is fpga loaded?
00125           if ((fpga_state & FPGA_STATE_LOADED) ==     0) return -EACCES; // change to particular fpga revision
00126           if ((fpga_state & FPGA_STATE_CLOCKS) ==     0) return -EACCES; // clocks not running
00127           if ((fpga_state & FPGA_STATE_SDRAM_INIT) == 0) {
00128                fpga_initSDRAM();
00129                fpga_state |= FPGA_STATE_SDRAM_INIT;
00130           }
00131   D(printk("fsdram_open\n"));
00132           if ((res=fsdram_open(inode, filp))<0)return res;
00133           break;
00134         }
00135         case FPGACONF_MINOR_IORW :
00136           {
00137             if (minors[p])  return -EACCES;
00138             break;
00139           }
00140         default: return -EINVAL;
00141         }
00142         minors[p]=p;
00143 
00144         filp->private_data = &minors[p];
00145         return 0;
00146 }
00147 //#define FPGA_STATE_LOADED       0x0000FFFF; //
00148 //#define FPGA_STATE_CLOCKS       0x000F0000; // 
00149 //#define FPGA_STATE_INITIALIZED  0x00100000; // 
00150 
00151 static int fpga_release(struct inode *inode, struct file *filp) {
00152    int res=0;
00153    int p = MINOR(inode->i_rdev);
00154    switch ( p ) {
00155      case FPGACONF_MINOR_SDRAM : {
00156        res= fsdram_release();
00157        minors[p]=0;
00158        return res;
00159      }
00160      case FPGACONF_MINOR_IORW :  {
00161        minors[p]=0;
00162        break;
00163      }
00164      default: return -EINVAL;
00165    }
00166   D(printk("fpga_release:  done\r\n"));
00167   return 0;
00168 }
00169 
00170 
00171 
00172 static int fpga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { // switch by minor
00173 //   int res=0;
00174    D(printk("fpga_ioctl cmd= %x, arg= %x\n\r",cmd,(int) arg));
00175 
00176    switch (((int *)filp->private_data)[0]) {
00177       case FPGACONF_MINOR_IORW : {// read write FPGA registers
00178         D(printk("fpga_ioctl cmd= %x, arg= %x\n\r",cmd,(int) arg));
00179         if(_IOC_TYPE(cmd) == FPGACONF_GETSTATE) {
00180             return fpga_state;
00181         }
00182         return fpga_io_ioctl (inode, filp, cmd, arg);
00183       }
00184       default:return -EINVAL;
00185    }
00186 }
00187 
00188 
00189 
00190 static ssize_t fpga_write(struct file * file, const char * buf, size_t count, loff_t *off) {
00191     D(printk("fpga_write: ((int *)file->private_data)[0]= %x\r\n",((int *)file->private_data)[0]));
00192     switch (((int *)file->private_data)[0]) {
00193        case FPGACONF_MINOR_IORW :   return fpga_io_write (file, buf, count, off);
00194        case FPGACONF_MINOR_SDRAM :      return fsdram_write (file, buf, count, off);
00195        default:                 return -EINVAL;
00196     }
00197 }
00198 
00199 static loff_t  fpga_lseek(struct file * file, loff_t offset, int orig) {
00200     D(printk (" file=%x, offset=%x, orig=%x\r\n", (int) file, (int) offset, (int) orig));
00201      switch (((int *)file->private_data)[0]) {
00202        case FPGACONF_MINOR_IORW :   return fpga_io_lseek(file, offset, orig);
00203        case FPGACONF_MINOR_SDRAM :      return fsdram_lseek(file, offset, orig);
00204        default:                 return -EINVAL;
00205     }
00206 }
00207 
00208 static ssize_t fpga_read(struct file * file, char * buf, size_t count, loff_t *off) {
00209     switch (((int *)file->private_data)[0]) {
00210        case FPGACONF_MINOR_IORW :   return fpga_io_read(file, buf, count, off);
00211        case FPGACONF_MINOR_SDRAM :      return fsdram_read(file, buf, count, off);
00212        default:                 return -EINVAL;
00213     }
00214 }
00215 
00216 
00217 
00218 
00219 void init_elphel_ioremap(void) {
00220 // Do not need to iounmap as these addersses will stay on with the camera
00221         port_csp0_addr = ioremap(MEM_CSR0_START | MEM_NON_CACHEABLE, 8192);
00222         port_csp4_addr = ioremap(MEM_CSP4_START | MEM_NON_CACHEABLE, 8192);
00223         if (!port_csp0_addr || !port_csp0_addr) {
00224                 printk(FPGA_MODULE_DESCRIPTION" failed to ioremap\n");
00225 // panic here?
00226         }
00227 }
00228 
00229 
00230 static int __init 
00231 fpga_init(void)
00232 {
00233         init_elphel_ioremap(); // map address ranges to use port0 and port4 in FPGA accesses.
00234         int i,res;
00235         res = register_chrdev(FPGA_MAJOR, fpga_name, &fpga_fops);
00236         if(res < 0) {
00237                 printk(KERN_ERR "fpga_init: couldn't get a major number.\n");
00238                 return res;
00239         }
00240         printk(FPGA_DRIVER_NAME);
00241 
00242 
00243         for (i=0;i<=FPGA_MAXMINOR;i++) minors[i]=0;
00244 /*
00245         Use extern to invoke clock driver? How do we know it is already initialized? Or delay everything to the startup script?
00246         fpga_state=0;    // bit 0 - FPGA state, 1 - Clocks, 2 - SDRAM
00247         printk("FPGA is not loaded, clocks are not programmed, SDRAM is not initialized\r\n");
00248         if (initClockDefault()==0) printk("Clocks initialized (clk0=75MHz, clk1=60MHz)\r\n");
00249         else                       printk("Clocks initialization failed\r\n");
00250 */
00251         return 0;
00252 }
00253 
00254 
00255 
00256 /* this makes sure that fpga_init is called during boot */
00257 
00258 module_init(fpga_init);
00259 MODULE_LICENSE("GPL");
00260 MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
00261 MODULE_DESCRIPTION(FPGA_MODULE_DESCRIPTION);

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