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 #include <linux/module.h>
00041 #include <linux/sched.h>
00042 #include <linux/slab.h>
00043 #include <linux/errno.h>
00044 #include <linux/kernel.h>
00045 #include <linux/fs.h>
00046 #include <linux/string.h>
00047 #include <linux/init.h>
00048 #include <linux/autoconf.h>
00049
00050 #include <asm/system.h>
00051 #include <asm/svinto.h>
00052 #include <asm/io.h>
00053
00054 #include <asm/irq.h>
00055
00056 #include <asm/delay.h>
00057 #include <asm/uaccess.h>
00058 #include <asm/fpgaconfa.h>
00059
00060 #include "fpgaconf.h"
00061 #include "fpgaconfi2c.h"
00062 #include "fpgajtag.h"
00063 #include "fpga_io.h"
00064 #include "fpga_sdram.h"
00065 #include "x313.h"
00066
00067
00068
00069
00070
00071
00072
00073
00074 #define D(x)
00075 #define D1(x)
00076 #define FPGA_MAJOR 129
00077 #define MY_MODULE_DESCRIPTION "Elphel model 313 fpga/clock configuration driver"
00078 #define FPGACONF_DRIVER_NAME "fpga/clock configuration driver v1.0n"
00079 #define FPGACONF_MAXMINOR 10
00080 static const char fpga_name[] = "fpga_loader";
00081 static int minors[FPGACONF_MAXMINOR+1];
00082 static int fpga_open (struct inode *inode, struct file *filp);
00083 static int fpga_release(struct inode *inode, struct file *filp);
00084 static int fpga_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
00085 static ssize_t fpga_write (struct file * file, const char * buf, size_t count, loff_t *off);
00086 static loff_t fpga_lseek (struct file * file, loff_t offset, int orig);
00087 static ssize_t fpga_read (struct file * file, char * buf, size_t count, loff_t *off);
00088
00089
00090
00091
00092
00093
00094 static struct file_operations fpga_fops = {
00095 owner: THIS_MODULE,
00096 open: fpga_open,
00097 release: fpga_release,
00098 ioctl: fpga_ioctl,
00099 llseek: fpga_lseek,
00100 read: fpga_read,
00101 write: fpga_write
00102 };
00103
00104
00105
00106
00107
00108 static int fpga_state=0;
00109
00110 int initClockDefault(void) {
00111 int i,r;
00112 unsigned char d[2];
00113
00114 unsigned int clocks_inits[]= \
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 {0x1640, 0x150c, 0x1402, 0x0902, 0x0802,
00127 0x42c4, 0x4109, 0x4003,
00128 0x45c4, 0x4409, 0x4303,
00129 0x48c4, 0x4709, 0x4603,
00130 0x4bc4, 0x4a09, 0x4903,
00131 0x4ec4, 0x4d09, 0x4c03,
00132 0x51c4, 0x5009, 0x4f03,
00133 0x54c4, 0x5309, 0x5203,
00134 0x57c4, 0x5609, 0x5503,
00135 0x0a05, 0x0b05,
00136 0x0e87 };
00137
00138 for (i=0;i<sizeof( clocks_inits)/sizeof( clocks_inits[0]);i++) {
00139 d[0]=((clocks_inits[i]>>8) & 0xff);
00140 d[1]=( clocks_inits[i] & 0xff);
00141 if ((r=fi2c_writeData(0xd2, d, 2))) return r;
00142 }
00143 fpga_state |= 0x00020000;
00144 return 0;
00145 }
00146
00147
00148 static int fpga_open(struct inode *inode, struct file *filp) {
00149 int p;
00150 int res;
00151
00152 p = MINOR(inode->i_rdev);
00153 D1(printk("fpga_open: minor=%x\r\n",p) );
00154 D1(printk("filp=%lx\r\n",(unsigned long)filp) );
00155
00156 switch ( p ) {
00157 case FPGACONF_MINOR_SDRAM : {
00158 if (minors[p]) return -EACCES;
00159
00160 if ((fpga_state & FPGA_STATE_LOADED) == 0) return -EACCES;
00161 if ((fpga_state & FPGA_STATE_CLOCKS) == 0) return -EACCES;
00162 if ((fpga_state & FPGA_STATE_SDRAM_INIT) == 0) {
00163 fpga_initSDRAM();
00164 fpga_state |= FPGA_STATE_SDRAM_INIT;
00165 }
00166 D(printk("fsdram_open\n"));
00167 if ((res=fsdram_open(inode, filp))<0)return res;
00168 break;
00169 }
00170 case FPGACONF_MINOR_IORW :
00171 case FPGACONF_MINOR_I2C :
00172 {
00173 if (minors[p]) return -EACCES;
00174 break;
00175 }
00176
00177 case FPGACONF_MINOR_JTAG :
00178 {
00179 if (minors[p]) return -EACCES;
00180
00181 fpga_state &= ~FPGA_STATE_LOADED;
00182 fpga_state &= ~FPGA_STATE_SDRAM_INIT;
00183
00184
00185
00186
00187
00188 *R_IRQ_MASK0_CLR = 0x10;
00189
00190 printk ("Camera interrupts disabled\n");
00191
00192
00193
00194
00195 if ((res =fjtag_open())) return res;
00196 break;
00197 }
00198
00199 default: return -EINVAL;
00200 }
00201
00202 minors[p]=p;
00203
00204 filp->private_data = &minors[p];
00205
00206 return 0;
00207 }
00208
00209
00210
00211
00212 static int fpga_release(struct inode *inode, struct file *filp) {
00213 int res=0;
00214 int p = MINOR(inode->i_rdev);
00215 switch ( p ) {
00216 case FPGACONF_MINOR_SDRAM : {
00217 res= fsdram_release();
00218 minors[p]=0;
00219 return res;
00220 }
00221
00222 case FPGACONF_MINOR_JTAG :
00223 if ((res=fjtag_close ()) >=0) {
00224 fpga_state|=1;
00225 }
00226
00227 fpga_state &=~FPGA_STATE_INITIALIZED;
00228 case FPGACONF_MINOR_I2C :
00229 case FPGACONF_MINOR_IORW :
00230 {
00231 minors[p]=0;
00232 break;
00233 }
00234 default: return -EINVAL;
00235 }
00236
00237 D(printk("fpga_release: done\r\n"));
00238 return 0;
00239 }
00240
00241
00242
00243 static int fpga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) {
00244 int res=0;
00245 D(printk("fpga_ioctl cmd= %x, arg= %x\n\r",cmd,(int) arg));
00246
00247 switch (((int *)filp->private_data)[0]) {
00248
00249 case FPGACONF_MINOR_I2C :
00250 {
00251 switch (_IOC_NR(cmd)) {
00252 case I2C_WRITEREG: {
00253
00254
00255
00256 res=fi2c_ioctl (inode, filp, cmd, arg);
00257 if (res >=0) fpga_state|=0x10000;
00258 return res;
00259 }
00260 case I2C_READREG: {
00261 return fi2c_ioctl (inode, filp, cmd, arg);
00262 }
00263 case FPGA_PGM:
00264 case FPGA_STAT:
00265 case FPGA_JTAG:
00266 case FPGA_PA_RD:
00267 case FPGA_PA_WR:
00268 return fjtag_ioctl (inode, filp, cmd, arg);
00269 default:return -EINVAL;
00270 }
00271 }
00272 case FPGACONF_MINOR_IORW :
00273 {
00274 D(printk("fpga_ioctl cmd= %x, arg= %x\n\r",cmd,(int) arg));
00275
00276 if(_IOC_TYPE(cmd) == FPGACONF_GETSTATE) {
00277
00278
00279 D(printk ("R_PORT_PA_READ=%x\r\n",(int) *R_PORT_PA_READ));
00280
00281 D(printk ("R_PORT_PB_READ=%x\r\n",(int) *R_PORT_PB_READ));
00282
00283 return fpga_state;
00284 }
00285 return fpga_io_ioctl (inode, filp, cmd, arg);
00286 }
00287
00288 default:return -EINVAL;
00289 }
00290 }
00291
00292
00293
00294 static ssize_t fpga_write(struct file * file, const char * buf, size_t count, loff_t *off) {
00295
00296 switch (((int *)file->private_data)[0]) {
00297 case FPGACONF_MINOR_SDRAM : return fsdram_write (file, buf, count, off);
00298 case FPGACONF_MINOR_JTAG : return fjtag_write (file, buf, count, off);
00299 default: return -EINVAL;
00300 }
00301
00302 }
00303
00304 static loff_t fpga_lseek(struct file * file, loff_t offset, int orig) {
00305
00306 D(printk (" file=%x, offset=%x, orig=%x\r\n", (int) file, (int) offset, (int) orig));
00307 switch (((int *)file->private_data)[0]) {
00308 case FPGACONF_MINOR_SDRAM : return fsdram_lseek(file, offset, orig);
00309 default: return -EINVAL;
00310 }
00311 }
00312
00313 static ssize_t fpga_read(struct file * file, char * buf, size_t count, loff_t *off) {
00314
00315 switch (((int *)file->private_data)[0]) {
00316 case FPGACONF_MINOR_SDRAM : return fsdram_read(file, buf, count, off);
00317 default: return -EINVAL;
00318 }
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 static int __init
00331 fpga_init(void)
00332 {
00333
00334 int i,res;
00335 res = register_chrdev(FPGA_MAJOR, fpga_name, &fpga_fops);
00336 if(res < 0) {
00337 printk(KERN_ERR "fpga_init: couldn't get a major number.\n");
00338 return res;
00339 }
00340 printk(FPGACONF_DRIVER_NAME);
00341
00342
00343 for (i=0;i<=FPGACONF_MAXMINOR;i++) minors[i]=0;
00344
00345
00346 initPortA();
00347 initPortB();
00348
00349 printk("Ports A and B initialized\r\n");
00350 fpga_state=0;
00351 printk("FPGA is not loaded, clocks are not programmed, SDRAM is not initialized\r\n");
00352 if (initClockDefault()==0) printk("Clocks initialized (clk0=75MHz, clk1=60MHz)\r\n");
00353 else printk("Clocks initialization failed\r\n");
00354 return 0;
00355 }
00356
00357
00358
00359
00360
00361 module_init(fpga_init);
00362 MODULE_LICENSE("GPL");
00363 MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
00364 MODULE_DESCRIPTION(MY_MODULE_DESCRIPTION);
00365 MODULE_DESCRIPTION("Elphel model 333 fpga download driver");