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 #include <linux/module.h>
00060 #include <linux/sched.h>
00061 #include <linux/slab.h>
00062 #include <linux/errno.h>
00063 #include <linux/kernel.h>
00064 #include <linux/fs.h>
00065 #include <linux/string.h>
00066 #include <linux/init.h>
00067 #include <linux/autoconf.h>
00068
00069 #include <asm/system.h>
00070 #include <asm/arch/memmap.h>
00071
00072
00073 #include <asm/io.h>
00074
00075 #include <asm/irq.h>
00076
00077 #include <asm/delay.h>
00078 #include <asm/uaccess.h>
00079 #include <asm/elphel/driver_numbers.h>
00080 #include <asm/elphel/fpgaconfa.h>
00081 #include <asm/elphel/c313a.h>
00082
00083 #include "fpgactrl.h"
00084 #include "fpga_io.h"
00085 #include "fpga_sdram.h"
00086 #include "x3x3.h"
00087 #define ELPHEL_DEBUG_THIS 0
00088 #if ELPHEL_DEBUG_THIS
00089
00090 #define D1(x) x
00091 #define MD1(x) printk("%s:%d:",__FILE__,__LINE__);x
00092 #define MDD1(x) printk("%s:%d:",__FILE__,__LINE__); x ; udelay (ELPHEL_DEBUG_DELAY)
00093 #define D1I(x)
00094 #else
00095 #define D1(x)
00096
00097 #define MD1(x)
00098 #define MDD1(x)
00099 #define D1I(x) x
00100 #endif
00101
00102
00103 #define FPGA_MODULE_DESCRIPTION "FPGA control driver for Elphel (R) Model 353 camera"
00104 #define FPGA_DRIVER_NAME "fpga_control"
00105 #define FPGA_MAXMINOR 10
00106
00107
00108
00109 static const char fpga_name[] = "fpga_control";
00110 static int minors[FPGA_MAXMINOR+1];
00111 static int fpga_open (struct inode *inode, struct file *filp);
00112 static int fpga_release(struct inode *inode, struct file *filp);
00113 static int fpga_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
00114 static ssize_t fpga_write (struct file * file, const char * buf, size_t count, loff_t *off);
00115 static loff_t fpga_lseek (struct file * file, loff_t offset, int orig);
00116 static ssize_t fpga_read (struct file * file, char * buf, size_t count, loff_t *off);
00117
00118
00119
00120
00121
00122
00123 static struct file_operations fpga_fops = {
00124 owner: THIS_MODULE,
00125 open: fpga_open,
00126 release: fpga_release,
00127 ioctl: fpga_ioctl,
00128 llseek: fpga_lseek,
00129 read: fpga_read,
00130 write: fpga_write
00131 };
00132
00133
00134 static int fpga_open(struct inode *inode, struct file *filp) {
00135 int p;
00136 int res;
00137
00138 p = MINOR(inode->i_rdev);
00139 D1(printk("fpga_open: minor=%x\r\n",p) );
00140 D1(printk("filp=%lx\r\n",(unsigned long)filp) );
00141
00142 switch ( p ) {
00143 case FPGACONF_MINOR_SDRAM : {
00144 if (minors[p]) return -EACCES;
00145
00146 MD1(printk("fpga_open: fpga_state=0x%x\n",(int) fpga_state) );
00147 if ((fpga_state & FPGA_STATE_LOADED) == 0) return -EACCES;
00148 if ((fpga_state & FPGA_STATE_CLOCKS) == 0) return -EACCES;
00150 if (((fpga_state & FPGA_STATE_SDRAM_INIT) == 0) || (!X313_IS_SDRAM_ON))fpga_initSDRAM();
00151
00152 MD1(printk("fpga_open: fpga_state=0x%x\n",(int) fpga_state) );
00153 if ((res=fsdram_open(inode, filp))<0)return res;
00154 break;
00155 }
00156 case FPGACONF_MINOR_IORW :
00157 case FPGACONF_MINOR_TABLES:
00158 {
00159 if (minors[p]) return -EACCES;
00160 break;
00161 }
00162 default: return -EINVAL;
00163 }
00164 minors[p]=p;
00165
00166 filp->private_data = &minors[p];
00167 return 0;
00168 }
00169
00170 static int fpga_release(struct inode *inode, struct file *filp) {
00171 int res=0;
00172 int p = MINOR(inode->i_rdev);
00173 switch ( p ) {
00174 case FPGACONF_MINOR_SDRAM :
00175 res= fsdram_release();
00176 minors[p]=0;
00177 return res;
00178 case FPGACONF_MINOR_IORW :
00179 case FPGACONF_MINOR_TABLES:
00180 minors[p]=0;
00181 break;
00182 default: return -EINVAL;
00183 }
00184 D1(printk("fpga_release: done\r\n"));
00185 return 0;
00186 }
00187
00188
00189
00190 static int fpga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) {
00191
00192 D1(printk("fpga_ioctl cmd= %x, arg= %x\n\r",cmd,(int) arg));
00193
00194 switch (((int *)filp->private_data)[0]) {
00195 case FPGACONF_MINOR_IORW : {
00196 D1(printk("fpga_ioctl cmd= %x, arg= %x\n\r",cmd,(int) arg));
00197 if(_IOC_TYPE(cmd) == FPGACONF_GETSTATE) {
00198 return fpga_state;
00199 }
00200 return fpga_io_ioctl (inode, filp, cmd, arg);
00201 }
00202 default:return -EINVAL;
00203 }
00204 }
00205
00206
00207
00208 static ssize_t fpga_write(struct file * file, const char * buf, size_t count, loff_t *off) {
00209 D1(printk("fpga_write: ((int *)file->private_data)[0]= %x\r\n",((int *)file->private_data)[0]));
00210 switch (((int *)file->private_data)[0]) {
00211 case FPGACONF_MINOR_IORW : return fpga_io_write (file, buf, count, off);
00212 case FPGACONF_MINOR_SDRAM : return fsdram_write (file, buf, count, off);
00213 case FPGACONF_MINOR_TABLES: return fpga_io_table_write(file, buf, count, off);
00214 default: return -EINVAL;
00215 }
00216 }
00217
00218 static loff_t fpga_lseek(struct file * file, loff_t offset, int orig) {
00219 D1(printk (" file=%x, offset=%x, orig=%x\r\n", (int) file, (int) offset, (int) orig));
00220 switch (((int *)file->private_data)[0]) {
00221 case FPGACONF_MINOR_IORW : return fpga_io_lseek (file, offset, orig);
00222 case FPGACONF_MINOR_SDRAM : return fsdram_lseek (file, offset, orig);
00223 case FPGACONF_MINOR_TABLES: return fpga_io_table_lseek (file, offset, orig);
00224 default: return -EINVAL;
00225 }
00226 }
00227
00228 static ssize_t fpga_read(struct file * file, char * buf, size_t count, loff_t *off) {
00229 switch (((int *)file->private_data)[0]) {
00230 case FPGACONF_MINOR_IORW : return fpga_io_read(file, buf, count, off);
00231 case FPGACONF_MINOR_SDRAM : return fsdram_read(file, buf, count, off);
00232 default: return -EINVAL;
00233 }
00234 }
00235
00236
00237
00238
00239 void init_elphel_ioremap(void) {
00240
00241 port_csp0_addr = ioremap(MEM_CSR0_START | MEM_NON_CACHEABLE, 8192);
00242 port_csp4_addr = ioremap(MEM_CSP4_START | MEM_NON_CACHEABLE, 8192);
00243 if (!port_csp0_addr || !port_csp0_addr) {
00244 printk(FPGA_MODULE_DESCRIPTION" failed to ioremap\n");
00245
00246 }
00247 }
00248
00249
00250 static int __init
00251 fpga_init(void)
00252 {
00253 init_elphel_ioremap();
00254 int i,res;
00255 res = register_chrdev(FPGA_MAJOR, fpga_name, &fpga_fops);
00256 if(res < 0) {
00257 printk(KERN_ERR "\nfpga_init: couldn't get a major number %d.\n ",FPGA_MAJOR);
00258 return res;
00259 }
00260 printk(FPGA_DRIVER_NAME"- %d\n",FPGA_MAJOR);
00261
00262
00263 for (i=0;i<=FPGA_MAXMINOR;i++) minors[i]=0;
00264 fpga_state=0;
00265
00266 return 0;
00267 }
00268
00269
00270
00271
00272
00273 module_init(fpga_init);
00274 MODULE_LICENSE("GPL");
00275 MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
00276 MODULE_DESCRIPTION(FPGA_MODULE_DESCRIPTION);