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 #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
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
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
00080
00081 static const char fpga_name[] = "fpga_control";
00082 static int minors[FPGA_MAXMINOR+1];
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
00091
00092
00093
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
00106
00107
00108
00109
00110
00111
00112
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
00125 if ((fpga_state & FPGA_STATE_LOADED) == 0) return -EACCES;
00126 if ((fpga_state & FPGA_STATE_CLOCKS) == 0) return -EACCES;
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
00148
00149
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) {
00173
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 : {
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
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
00226 }
00227 }
00228
00229
00230 static int __init
00231 fpga_init(void)
00232 {
00233 init_elphel_ioremap();
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
00246
00247
00248
00249
00250
00251 return 0;
00252 }
00253
00254
00255
00256
00257
00258 module_init(fpga_init);
00259 MODULE_LICENSE("GPL");
00260 MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
00261 MODULE_DESCRIPTION(FPGA_MODULE_DESCRIPTION);