Commit 38b6079d authored by Andrey Filippov's avatar Andrey Filippov

moving all driver definitions into uapi/elphel/x393_devices.h

parent 39905996
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <elphel/driver_numbers.h> #include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/c313a.h> #include <uapi/elphel/c313a.h>
#include <elphel/elphel393-mem.h> #include <elphel/elphel393-mem.h>
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
#include "x393_helpers.h" #include "x393_helpers.h"
/** @brief Driver name displayed in system logs */ /** @brief Driver name displayed in system logs */
#define CIRCBUF_DRIVER_NAME "circbuf driver" //#define CIRCBUF_DRIVER_NAME "circbuf driver"
/** @brief Wait queue for the processes waiting for a new frame to appear in the circular buffer */ /** @brief Wait queue for the processes waiting for a new frame to appear in the circular buffer */
wait_queue_head_t circbuf_wait_queue; wait_queue_head_t circbuf_wait_queue;
...@@ -115,13 +115,13 @@ int circbuf_all_open(struct inode *inode, struct file *filp) ...@@ -115,13 +115,13 @@ int circbuf_all_open(struct inode *inode, struct file *filp)
minor_to_chn(minor, &dev_type); minor_to_chn(minor, &dev_type);
switch (dev_type) { switch (dev_type) {
case CIRCBUF_MINOR: case DEV393_MINOR(DEV393_CIRCBUF0):
res = circbuf_open(inode, filp); res = circbuf_open(inode, filp);
break; break;
case JPEGHEAD_MINOR: case DEV393_MINOR(DEV393_JPEGHEAD0):
res = jpeghead_open(inode, filp); res = jpeghead_open(inode, filp);
break; break;
case HUFFMAN_MINOR: case DEV393_MINOR(DEV393_HUFFMAN0):
res = huffman_open(inode, filp); res = huffman_open(inode, filp);
break; break;
default: default:
...@@ -146,13 +146,13 @@ int circbuf_all_release(struct inode *inode, struct file *filp) ...@@ -146,13 +146,13 @@ int circbuf_all_release(struct inode *inode, struct file *filp)
minor_to_chn(minor, &dev_type); minor_to_chn(minor, &dev_type);
switch (dev_type) { switch (dev_type) {
case CIRCBUF_MINOR: case DEV393_MINOR(DEV393_CIRCBUF0):
// res=circbuf_release(inode,filp); // res=circbuf_release(inode,filp);
break; break;
case JPEGHEAD_MINOR: case DEV393_MINOR(DEV393_JPEGHEAD0):
// res=jpeghead_release(inode,filp); // res=jpeghead_release(inode,filp);
break; break;
case HUFFMAN_MINOR: case DEV393_MINOR(DEV393_HUFFMAN0):
// res=huffman_release(inode,filp); // res=huffman_release(inode,filp);
break; break;
default: default:
...@@ -180,15 +180,15 @@ loff_t circbuf_all_lseek(struct file *file, loff_t offset, int orig) ...@@ -180,15 +180,15 @@ loff_t circbuf_all_lseek(struct file *file, loff_t offset, int orig)
dev_dbg(g_dev_ptr, "circbuf_all_lseek, minor = 0x%x\n", minor); dev_dbg(g_dev_ptr, "circbuf_all_lseek, minor = 0x%x\n", minor);
switch (dev_type) { switch (dev_type) {
case CIRCBUF_MINOR: case DEV393_MINOR(DEV393_CIRCBUF0):
return circbuf_lseek(file, offset, orig); return circbuf_lseek(file, offset, orig);
case JPEGHEAD_MINOR: case DEV393_MINOR(DEV393_JPEGHEAD0):
if (orig == SEEK_END && offset > 0) { if (orig == SEEK_END && offset > 0) {
rp = BYTE2DW(X393_BUFFSUB(offset, CHUNK_SIZE)) & (~7); // convert to index to long, align to 32-bytes rp = BYTE2DW(X393_BUFFSUB(offset, CHUNK_SIZE)) & (~7); // convert to index to long, align to 32-bytes
fp = (struct interframe_params_t *) &circbuf_priv[chn].buf_ptr[rp]; fp = (struct interframe_params_t *) &circbuf_priv[chn].buf_ptr[rp];
} }
return jpeghead_lseek(file, offset, orig, fp); return jpeghead_lseek(file, offset, orig, fp);
case HUFFMAN_MINOR: case DEV393_MINOR(DEV393_HUFFMAN0):
return huffman_lseek(file, offset, orig); return huffman_lseek(file, offset, orig);
default: default:
return -EINVAL; return -EINVAL;
...@@ -212,11 +212,11 @@ ssize_t circbuf_all_read(struct file *file, char *buf, size_t count, loff_t *off ...@@ -212,11 +212,11 @@ ssize_t circbuf_all_read(struct file *file, char *buf, size_t count, loff_t *off
minor_to_chn(minor, &dev_type); minor_to_chn(minor, &dev_type);
switch (dev_type) { switch (dev_type) {
case CIRCBUF_MINOR: case DEV393_MINOR(DEV393_CIRCBUF0):
return circbuf_read(file, buf, count, off); return circbuf_read(file, buf, count, off);
case JPEGHEAD_MINOR: case DEV393_MINOR(DEV393_JPEGHEAD0):
return jpeghead_read(file, buf, count, off); return jpeghead_read(file, buf, count, off);
case HUFFMAN_MINOR: case DEV393_MINOR(DEV393_HUFFMAN0):
return huffman_read(file, buf, count, off); return huffman_read(file, buf, count, off);
default: default:
return -EINVAL; return -EINVAL;
...@@ -240,12 +240,12 @@ ssize_t circbuf_all_write(struct file *file, const char *buf, size_t count, loff ...@@ -240,12 +240,12 @@ ssize_t circbuf_all_write(struct file *file, const char *buf, size_t count, loff
minor_to_chn(minor, &dev_type); minor_to_chn(minor, &dev_type);
switch (dev_type) { switch (dev_type) {
case CIRCBUF_MINOR: case DEV393_MINOR(DEV393_CIRCBUF0):
return circbuf_write (file, buf, count, off); return circbuf_write (file, buf, count, off);
case JPEGHEAD_MINOR: case DEV393_MINOR(DEV393_JPEGHEAD0):
// no method for this module // no method for this module
return -EINVAL; return -EINVAL;
case HUFFMAN_MINOR: case DEV393_MINOR(DEV393_HUFFMAN0):
return huffman_write (file, buf, count, off); return huffman_write (file, buf, count, off);
default: default:
return -EINVAL; return -EINVAL;
...@@ -268,7 +268,7 @@ int circbuf_all_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -268,7 +268,7 @@ int circbuf_all_mmap(struct file *file, struct vm_area_struct *vma)
minor_to_chn(minor, &dev_type); minor_to_chn(minor, &dev_type);
switch (dev_type) { switch (dev_type) {
case CIRCBUF_MINOR: case DEV393_MINOR(DEV393_CIRCBUF0):
return circbuf_mmap(file, vma); return circbuf_mmap(file, vma);
default: default:
return -EINVAL; return -EINVAL;
...@@ -292,7 +292,7 @@ unsigned int circbuf_all_poll(struct file *file, poll_table *wait) ...@@ -292,7 +292,7 @@ unsigned int circbuf_all_poll(struct file *file, poll_table *wait)
minor_to_chn(minor, &dev_type); minor_to_chn(minor, &dev_type);
switch (dev_type) { switch (dev_type) {
case CIRCBUF_MINOR: case DEV393_MINOR(DEV393_CIRCBUF0):
return circbuf_poll(file, wait); return circbuf_poll(file, wait);
default: default:
return 0; return 0;
...@@ -963,12 +963,12 @@ static int circbuf_all_init(struct platform_device *pdev) ...@@ -963,12 +963,12 @@ static int circbuf_all_init(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
dev_dbg(dev, "registering character device with name 'circbuf_operations'"); dev_dbg(dev, "registering character device with name 'circbuf_operations'");
res = register_chrdev(CIRCBUF_MAJOR, "circbuf_operations", &circbuf_fops); res = register_chrdev(DEV393_MAJOR(DEV393_CIRCBUF0), "circbuf_operations", &circbuf_fops);
if(res < 0) { if(res < 0) {
dev_err(dev, "couldn't get a major number %d.\n", CIRCBUF_MAJOR); dev_err(dev, "couldn't get a major number %d.\n", DEV393_MAJOR(DEV393_CIRCBUF0));
return res; return res;
} }
dev_info(dev, "registered MAJOR: %d\n", CIRCBUF_MAJOR); dev_info(dev, "registered MAJOR: %d\n", DEV393_MAJOR(DEV393_CIRCBUF0));
res = jpeghead_init(pdev); res = jpeghead_init(pdev);
if (res < 0) { if (res < 0) {
...@@ -1002,7 +1002,7 @@ static int circbuf_all_init(struct platform_device *pdev) ...@@ -1002,7 +1002,7 @@ static int circbuf_all_init(struct platform_device *pdev)
*/ */
static int circbuf_remove(struct platform_device *pdev) static int circbuf_remove(struct platform_device *pdev)
{ {
unregister_chrdev(CIRCBUF_MAJOR, "circbuf_operations"); unregister_chrdev(DEV393_MAJOR(DEV393_CIRCBUF0), "circbuf_operations");
return 0; return 0;
} }
...@@ -1017,7 +1017,7 @@ static struct platform_driver elphel393_circbuf = { ...@@ -1017,7 +1017,7 @@ static struct platform_driver elphel393_circbuf = {
.probe = circbuf_all_init, .probe = circbuf_all_init,
.remove = circbuf_remove, .remove = circbuf_remove,
.driver = { .driver = {
.name = CIRCBUF_DRIVER_NAME, .name = DEV393_NAME(DEV393_CIRCBUF0),
.of_match_table = elphel393_circbuf_of_match, .of_match_table = elphel393_circbuf_of_match,
}, },
}; };
...@@ -1026,4 +1026,4 @@ module_platform_driver(elphel393_circbuf); ...@@ -1026,4 +1026,4 @@ module_platform_driver(elphel393_circbuf);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>."); MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
MODULE_DESCRIPTION(CIRCBUF_DRIVER_NAME); MODULE_DESCRIPTION(DEV393_NAME(DEV393_CIRCBUF0));
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <elphel/driver_numbers.h> #include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/c313a.h> #include <uapi/elphel/c313a.h>
#include "x393.h" #include "x393.h"
...@@ -621,9 +621,9 @@ int i2c_ioctl(struct inode *inode, struct file *file, ...@@ -621,9 +621,9 @@ int i2c_ioctl(struct inode *inode, struct file *file,
//#define X3X3_I2C 134 //#define X3X3_I2C 134
// minors (add more later - maybe different minors for different speed - set speed when opening) // minors (add more later - maybe different minors for different speed - set speed when opening)
//#define X3X3_I2C_CTRL 0 // control/reset i2c //#define DEV393_MINOR(DEV393_I2C_CTRL) 0 // control/reset i2c
//#define X3X3_I2C_8_AINC 1 // 8bit registers, autoincement while read/write //#define DEV393_MINOR(DEV393_I2C_8_AINC) 1 // 8bit registers, autoincement while read/write
//#define X3X3_I2C_16_AINC 2 // 16bit registers, autoincement while read/write //#define DEV393_MINOR(DEV393_I2C_16_AINC) 2 // 16bit registers, autoincement while read/write
#define X3X3_I2C_DRIVER_NAME "Elphel (R) model 353 i2c character device driver" #define X3X3_I2C_DRIVER_NAME "Elphel (R) model 353 i2c character device driver"
//#define X3X3_I2C_CHANNELS 2 //#define X3X3_I2C_CHANNELS 2
//#define X3X3_I2C_MAXMINOR 4 // //#define X3X3_I2C_MAXMINOR 4 //
...@@ -662,18 +662,18 @@ int xi2c_open(struct inode *inode, struct file *filp) { ...@@ -662,18 +662,18 @@ int xi2c_open(struct inode *inode, struct file *filp) {
int bus=-1; int bus=-1;
int * pd= (int *) &(filp->private_data); int * pd= (int *) &(filp->private_data);
switch (p) { switch (p) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
bus=0; bus=0;
break; break;
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
bus=1; bus=1;
break; break;
case X3X3_I2C_ENABLE: case DEV393_MINOR(DEV393_I2C_ENABLE):
case X3X3_I2C_CTRL : case DEV393_MINOR(DEV393_I2C_CTRL) :
bus=-1; bus=-1;
break; break;
} }
...@@ -685,22 +685,22 @@ int xi2c_open(struct inode *inode, struct file *filp) { ...@@ -685,22 +685,22 @@ int xi2c_open(struct inode *inode, struct file *filp) {
if (bus>=0) inuse[bus] =1; if (bus>=0) inuse[bus] =1;
switch ( p ) { switch ( p ) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
inode->i_size=128*256; inode->i_size=128*256;
burst_sizes[p]=1; //!fix for PHP read (always 8192) -> 1 byte/read burst_sizes[p]=1; //!fix for PHP read (always 8192) -> 1 byte/read
break; break;
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
inode->i_size=256*256; inode->i_size=256*256;
burst_sizes[p]=2; //!fix for PHP read (always 8192) -> 2 bytes/read burst_sizes[p]=2; //!fix for PHP read (always 8192) -> 2 bytes/read
break; break;
case X3X3_I2C_CTRL : case DEV393_MINOR(DEV393_I2C_CTRL) :
inode->i_size=sizeof(bitdelays); inode->i_size=sizeof(bitdelays);
break; break;
case X3X3_I2C_ENABLE: case DEV393_MINOR(DEV393_I2C_ENABLE):
inode->i_size=sizeof(i2c_enable); inode->i_size=sizeof(i2c_enable);
break; break;
default:return -EINVAL; default:return -EINVAL;
...@@ -721,24 +721,24 @@ static int xi2c_release(struct inode *inode, struct file *filp){ ...@@ -721,24 +721,24 @@ static int xi2c_release(struct inode *inode, struct file *filp){
int p = MINOR(inode->i_rdev); int p = MINOR(inode->i_rdev);
int bus=-1; int bus=-1;
switch (p) { switch (p) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
bus=0; bus=0;
break; break;
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
bus=1; bus=1;
break; break;
case X3X3_I2C_ENABLE: case DEV393_MINOR(DEV393_I2C_ENABLE):
case X3X3_I2C_CTRL : case DEV393_MINOR(DEV393_I2C_CTRL) :
bus=-1; bus=-1;
break; break;
} }
D(printk("xi2c_release, minor=%d\n",p)); D(printk("xi2c_release, minor=%d\n",p));
if (bus>=0) inuse[bus]=0; if (bus>=0) inuse[bus]=0;
else if (p==X3X3_I2C_CTRL) for (bus=0; bus < X3X3_I2C_CHANNELS; bus++) inuse[bus]=0; else if (p==DEV393_MINOR(DEV393_I2C_CTRL)) for (bus=0; bus < X3X3_I2C_CHANNELS; bus++) inuse[bus]=0;
// thisminor =0; // thisminor =0;
return 0; return 0;
} }
...@@ -775,12 +775,12 @@ static loff_t xi2c_lseek(struct file * file, loff_t offset, int orig) { ...@@ -775,12 +775,12 @@ static loff_t xi2c_lseek(struct file * file, loff_t offset, int orig) {
} }
// switch (((int *)file->private_data)[0]) { // switch (((int *)file->private_data)[0]) {
switch (p) { switch (p) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
(file->f_pos) &= ~(0x7f); // zero out 7 MSBs (file->f_pos) &= ~(0x7f); // zero out 7 MSBs
break; break;
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
case X3X3_I2C1_16_AINC : { case DEV393_MINOR(DEV393_I2C1_16_AINC) : {
if ((file->f_pos) & 1) (file->f_pos)++; // increment to the next (if odd) for 16-bit accesses if ((file->f_pos) & 1) (file->f_pos)++; // increment to the next (if odd) for 16-bit accesses
break; break;
} }
...@@ -818,19 +818,19 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) { ...@@ -818,19 +818,19 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
// switch (((int *)file->private_data)[0]) { // switch (((int *)file->private_data)[0]) {
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
bus=0; bus=0;
i2cbuf = &i2cbuf_all[0]; i2cbuf = &i2cbuf_all[0];
break; break;
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
bus=1; bus=1;
i2cbuf = &i2cbuf_all[1*I2CBUFSIZE]; i2cbuf = &i2cbuf_all[1*I2CBUFSIZE];
break; break;
// case X3X3_I2C_CTRL : // case DEV393_MINOR(DEV393_I2C_CTRL) :
// i2cbuf = &i2cbuf_all[X3X3_I2C_CHANNELS*I2CBUFSIZE]; // i2cbuf = &i2cbuf_all[X3X3_I2C_CHANNELS*I2CBUFSIZE];
} }
userbuf=&i2cbuf[1]; userbuf=&i2cbuf[1];
...@@ -838,14 +838,14 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) { ...@@ -838,14 +838,14 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
// switch (((int *)file->private_data)[0]) { // switch (((int *)file->private_data)[0]) {
slave_adr=(p >> 7) & 0xfe; slave_adr=(p >> 7) & 0xfe;
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
if (count == 8192) count=burst_sizes[(int)file->private_data]; //! PHP "feature" fix if (count == 8192) count=burst_sizes[(int)file->private_data]; //! PHP "feature" fix
break; break;
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
p&=0xfffffffe; p&=0xfffffffe;
if (count == 8192) count=burst_sizes[(int)file->private_data]; //! PHP "feature" fix if (count == 8192) count=burst_sizes[(int)file->private_data]; //! PHP "feature" fix
if (count & 1) count++; if (count & 1) count++;
...@@ -855,28 +855,28 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) { ...@@ -855,28 +855,28 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
D(printk("xi2c_read (bus=%d) from 0x%x, count=%d\n", bus, (int) *off, (int) count)); D(printk("xi2c_read (bus=%d) from 0x%x, count=%d\n", bus, (int) *off, (int) count));
//! Verify if this slave is enabled for the I2C operation requested //! Verify if this slave is enabled for the I2C operation requested
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_RAW); en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_RAW);
break; break;
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_8); en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_8);
break; break;
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_16); en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_16);
break; break;
} }
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
en_bits=i2c_enable[ slave_adr>>1 ]; en_bits=i2c_enable[ slave_adr>>1 ];
break; break;
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
en_bits=i2c_enable[(slave_adr>>1) + 128]; en_bits=i2c_enable[(slave_adr>>1) + 128];
break; break;
} }
...@@ -895,14 +895,14 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) { ...@@ -895,14 +895,14 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
} }
if (count==0) return 0; if (count==0) return 0;
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
i2cbuf[0]=p & 0xff; i2cbuf[0]=p & 0xff;
error=i2c_readData (bus, slave_adr | 0x01, &i2cbuf[1], count, 1); // will start with start, not restart error=i2c_readData (bus, slave_adr | 0x01, &i2cbuf[1], count, 1); // will start with start, not restart
if (error) return -EINVAL; if (error) return -EINVAL;
break; break;
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
i2cbuf[0]=p & 0xff; i2cbuf[0]=p & 0xff;
if (bus==0) { if (bus==0) {
...@@ -922,8 +922,8 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) { ...@@ -922,8 +922,8 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
if (error) return -EINVAL; if (error) return -EINVAL;
break; break;
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
i2cbuf[0]=(p>>1) & 0xff; i2cbuf[0]=(p>>1) & 0xff;
if (bus==0) { if (bus==0) {
...@@ -943,11 +943,11 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) { ...@@ -943,11 +943,11 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
if (error) return -EINVAL; if (error) return -EINVAL;
break; break;
case X3X3_I2C_CTRL : case DEV393_MINOR(DEV393_I2C_CTRL) :
userbuf=&bbitdelays[*off]; userbuf=&bbitdelays[*off];
// memcpy(&i2cbuf[1],&bbitdelays[*off],count); // memcpy(&i2cbuf[1],&bbitdelays[*off],count);
break; break;
case X3X3_I2C_ENABLE: case DEV393_MINOR(DEV393_I2C_ENABLE):
userbuf=&i2c_enable[*off]; userbuf=&i2c_enable[*off];
break; break;
default:return -EINVAL; default:return -EINVAL;
...@@ -958,8 +958,8 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) { ...@@ -958,8 +958,8 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
//! do not increment pointer for raw accesses //! do not increment pointer for raw accesses
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
*off &= ~(0x7f); // zero out 7 MSBs *off &= ~(0x7f); // zero out 7 MSBs
break; break;
default: default:
...@@ -988,26 +988,26 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -988,26 +988,26 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
// switch (((int *)file->private_data)[0]) { // switch (((int *)file->private_data)[0]) {
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
bus=0; bus=0;
i2cbuf = &i2cbuf_all[0]; i2cbuf = &i2cbuf_all[0];
break; break;
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
bus=1; bus=1;
i2cbuf = &i2cbuf_all[1*I2CBUFSIZE]; i2cbuf = &i2cbuf_all[1*I2CBUFSIZE];
break; break;
// case X3X3_I2C_CTRL : // case DEV393_MINOR(DEV393_I2C_CTRL) :
// i2cbuf = &i2cbuf_all[X3X3_I2C_CHANNELS*I2CBUFSIZE]; // i2cbuf = &i2cbuf_all[X3X3_I2C_CHANNELS*I2CBUFSIZE];
} }
userbuf=&i2cbuf[1]; userbuf=&i2cbuf[1];
slave_adr=(p >> 7) & 0xfe; slave_adr=(p >> 7) & 0xfe;
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
p&=0xfffffffe; p&=0xfffffffe;
if (count & 1) count++; if (count & 1) count++;
slave_adr=(p >> 8) & 0xfe; slave_adr=(p >> 8) & 0xfe;
...@@ -1017,28 +1017,28 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1017,28 +1017,28 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
//! Verify if this slave is enabled for the I2C operation requested //! Verify if this slave is enabled for the I2C operation requested
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_RAW); en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_RAW);
break; break;
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_8); en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_8);
break; break;
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_16); en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_16);
break; break;
} }
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
en_bits=i2c_enable[ slave_adr>>1 ]; en_bits=i2c_enable[ slave_adr>>1 ];
break; break;
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
en_bits=i2c_enable[(slave_adr>>1) + 128]; en_bits=i2c_enable[(slave_adr>>1) + 128];
break; break;
} }
...@@ -1058,10 +1058,10 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1058,10 +1058,10 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
if (count==0) return 0; if (count==0) return 0;
//!only for control files that write directly to static arrays, no buffering //!only for control files that write directly to static arrays, no buffering
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_CTRL : case DEV393_MINOR(DEV393_I2C_CTRL) :
userbuf=&bbitdelays[p]; userbuf=&bbitdelays[p];
break; break;
case X3X3_I2C_ENABLE: case DEV393_MINOR(DEV393_I2C_ENABLE):
userbuf=&i2c_enable[p]; userbuf=&i2c_enable[p];
break; break;
} }
...@@ -1069,8 +1069,8 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1069,8 +1069,8 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
// if (copy_from_user( &i2cbuf[1], buf, count)) return -EFAULT; // if (copy_from_user( &i2cbuf[1], buf, count)) return -EFAULT;
if (copy_from_user( userbuf, buf, count)) return -EFAULT; if (copy_from_user( userbuf, buf, count)) return -EFAULT;
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
if (bus==0) { if (bus==0) {
#ifdef NC353 #ifdef NC353
...@@ -1087,8 +1087,8 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1087,8 +1087,8 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
if (error) return -EINVAL; if (error) return -EINVAL;
break; break;
case X3X3_I2C_8_AINC : case DEV393_MINOR(DEV393_I2C_8_AINC) :
case X3X3_I2C1_8_AINC : case DEV393_MINOR(DEV393_I2C1_8_AINC) :
i2cbuf[0]=p & 0xff; i2cbuf[0]=p & 0xff;
if (bus==0) { if (bus==0) {
...@@ -1106,8 +1106,8 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1106,8 +1106,8 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
if (error) return -EINVAL; if (error) return -EINVAL;
break; break;
case X3X3_I2C_16_AINC : case DEV393_MINOR(DEV393_I2C_16_AINC) :
case X3X3_I2C1_16_AINC : case DEV393_MINOR(DEV393_I2C1_16_AINC) :
i2cbuf[0]=(p>>1) & 0xff; i2cbuf[0]=(p>>1) & 0xff;
if (bus==0) { if (bus==0) {
...@@ -1125,7 +1125,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1125,7 +1125,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
if (error) return -EINVAL; if (error) return -EINVAL;
break; break;
// case X3X3_I2C_CTRL : // case DEV393_MINOR(DEV393_I2C_CTRL) :
// memcpy(&bbitdelays[*off],&i2cbuf[1],count); // memcpy(&bbitdelays[*off],&i2cbuf[1],count);
// break; // break;
default:return -EINVAL; default:return -EINVAL;
...@@ -1133,8 +1133,8 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1133,8 +1133,8 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
// *off+=count; // *off+=count;
//! do not increment pointer for raw accesses //! do not increment pointer for raw accesses
switch ((int)file->private_data) { switch ((int)file->private_data) {
case X3X3_I2C_RAW: case DEV393_MINOR(DEV393_I2C_RAW):
case X3X3_I2C1_RAW: case DEV393_MINOR(DEV393_I2C1_RAW):
*off &= ~(0x7f); // zero out 7 MSBs *off &= ~(0x7f); // zero out 7 MSBs
break; break;
default: default:
...@@ -1147,12 +1147,12 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1147,12 +1147,12 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
static int __init xi2c_init(void) { static int __init xi2c_init(void) {
int i,res; int i,res;
res = register_chrdev(X3X3_I2C_MAJOR, "fpga_xi2c", &xi2c_fops); res = register_chrdev(DEV393_MAJOR(DEV393_I2C_CTRL), DEV393_NAME(DEV393_I2C_CTRL), &xi2c_fops);
if(res < 0) { if(res < 0) {
printk(KERN_ERR "\nxi2c_init: couldn't get a major number %d.\n",X3X3_I2C_MAJOR); printk(KERN_ERR "\nxi2c_init: couldn't get a major number %d.\n",DEV393_MAJOR(DEV393_I2C_CTRL));
return res; return res;
} }
printk(X3X3_I2C_DRIVER_NAME" - %d, %d channels\n",X3X3_I2C_MAJOR,X3X3_I2C_CHANNELS); printk(X3X3_I2C_DRIVER_NAME" - %d, %d channels\n",DEV393_MAJOR(DEV393_I2C_CTRL),X3X3_I2C_CHANNELS);
// thisminor =0; // thisminor =0;
bitdelays[0].scl_high=2; //! SCL high: bitdelays[0].scl_high=2; //! SCL high:
...@@ -1172,14 +1172,14 @@ static int __init xi2c_init(void) { ...@@ -1172,14 +1172,14 @@ static int __init xi2c_init(void) {
for (i=0; i<X3X3_I2C_CHANNELS;i++) { for (i=0; i<X3X3_I2C_CHANNELS;i++) {
inuse[i]=0; inuse[i]=0;
} }
sizes[X3X3_I2C_CTRL]= sizeof(bitdelays); // control/reset i2c sizes[DEV393_MINOR(DEV393_I2C_CTRL)]= sizeof(bitdelays); // control/reset i2c
sizes[X3X3_I2C_8_AINC]= 128*256; // 8bit registers, autoincement while read/write sizes[DEV393_MINOR(DEV393_I2C_8_AINC)]= 128*256; // 8bit registers, autoincement while read/write
sizes[X3X3_I2C_16_AINC]= 256*256; // 16bit registers, autoincement while read/write sizes[DEV393_MINOR(DEV393_I2C_16_AINC)]= 256*256; // 16bit registers, autoincement while read/write
sizes[X3X3_I2C1_8_AINC]= 128*256; // 8bit registers, autoincement while read/write (bus 1) sizes[DEV393_MINOR(DEV393_I2C1_8_AINC)]= 128*256; // 8bit registers, autoincement while read/write (bus 1)
sizes[X3X3_I2C1_16_AINC]= 256*256; // 16bit registers, autoincement while read/write (bus 1) sizes[DEV393_MINOR(DEV393_I2C1_16_AINC)]= 256*256; // 16bit registers, autoincement while read/write (bus 1)
sizes[X3X3_I2C_RAW]= 128*256; // 8bit single register, sizes[DEV393_MINOR(DEV393_I2C_RAW)]= 128*256; // 8bit single register,
sizes[X3X3_I2C1_RAW]= 128*256; // 8bit single register, sizes[DEV393_MINOR(DEV393_I2C1_RAW)]= 128*256; // 8bit single register,
sizes[X3X3_I2C_ENABLE]= sizeof(i2c_enable); // enable particular types of accesses for I2C devices sizes[DEV393_MINOR(DEV393_I2C_ENABLE)]= sizeof(i2c_enable); // enable particular types of accesses for I2C devices
//! Enable/protect known I2C devices. For now - unprotect all unknown //! Enable/protect known I2C devices. For now - unprotect all unknown
for (i=0; i<X3X3_I2C_CHANNELS*128; i++) i2c_enable[i]=0xff; for (i=0; i<X3X3_I2C_CHANNELS*128; i++) i2c_enable[i]=0xff;
//! now protect known devices from undesired/unintended accesses: //! now protect known devices from undesired/unintended accesses:
...@@ -1236,8 +1236,8 @@ static int __init xi2c_init(void) { ...@@ -1236,8 +1236,8 @@ static int __init xi2c_init(void) {
//#define X3X3_I2C_RAW 5 // 8bit registers, no address byte (just slave, then read/write byte(s) //#define X3X3_I2C_RAW 5 // 8bit registers, no address byte (just slave, then read/write byte(s)
//#define X3X3_I2C1_RAW 6 // 8bit registers, no address byte (just slave, then read/write byte(s) //#define DEV393_MINOR(DEV393_I2C1_RAW) 6 // 8bit registers, no address byte (just slave, then read/write byte(s)
//#define X3X3_I2C_ENABLE 7 // enable(/protect) different I2C devices for different types of I2C accesses //#define DEV393_MINOR(DEV393_I2C_ENABLE) 7 // enable(/protect) different I2C devices for different types of I2C accesses
//static unsigned char i2c_enable[X3X3_I2C_CHANNELS*128]; //128 devices in a bus //static unsigned char i2c_enable[X3X3_I2C_CHANNELS*128]; //128 devices in a bus
//#define X3X3_I2C_ENABLE_RD 0 // bit 0 - enable i2c read //#define X3X3_I2C_ENABLE_RD 0 // bit 0 - enable i2c read
//#define X3X3_I2C_ENABLE_WR 1 // bit 1 - enable i2c write //#define X3X3_I2C_ENABLE_WR 1 // bit 1 - enable i2c write
......
...@@ -31,15 +31,13 @@ ...@@ -31,15 +31,13 @@
#include <linux/fs.h> #include <linux/fs.h>
#include "x393.h" #include "x393.h"
//#include "x393_detect_sensors.h" #include <uapi/elphel/x393_devices.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/c313a.h> #include <uapi/elphel/c313a.h>
#include "mt9x001.h" #include "mt9x001.h"
#include "multi10359.h" #include "multi10359.h"
#include "detect_sensors.h" #include "detect_sensors.h"
#define DETECT_SENSORS_MODULE_DESCRIPTION "Detect sensor type(s) attached to each of the ports" #define DETECT_SENSORS_MODULE_DESCRIPTION "Detect sensor type(s) attached to each of the ports"
#define DETECT_SENSORS_DRIVER_NAME "detect_sensors"
#define OF_PREFIX_NAME "elphel393-detect_sensors" #define OF_PREFIX_NAME "elphel393-detect_sensors"
struct sensor_port_config_t struct sensor_port_config_t
{ {
...@@ -359,31 +357,39 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev) ...@@ -359,31 +357,39 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev)
///< @return 0 on success, or negative error. ///< @return 0 on success, or negative error.
{ {
const char * config_string; const char * config_string;
// struct x393_i2c_device_list * dl;
char names[4][80]; char names[4][80];
// int rslt;
// int num_devs, nd, ni, sa7, num_addr, num_data, khz;
struct device_node *node = pdev->dev.of_node; struct device_node *node = pdev->dev.of_node;
// struct device_attribute *new_attr;
// struct device *dev =&pdev->dev;
int num_ports, port, num_sub, sub_chn; int num_ports, port, num_sub, sub_chn;
if (node) { if (node) {
if (num_ports > SENSOR_PORTS) config_string = of_get_property(node, OF_PREFIX_NAME",port-mux", NULL); // &len);
num_ports = SENSOR_PORTS; pr_info ("Mux config_string = %s (was looking for '%s')\n",config_string, OF_PREFIX_NAME",port-mux");
config_string = of_get_property(node, OF_PREFIX_NAME",ports", NULL); // &len); if (config_string) {
num_ports = sscanf(config_string,"%79s %79s %79s %79s", names[0], names[1], names[2], names[3]); num_ports = sscanf(config_string,"%79s %79s %79s %79s", names[0], names[1], names[2], names[3]);
for (port = 0; port < num_ports; port++){ if (num_ports > SENSOR_PORTS)
set_detected_mux_code(port, get_code_by_name(names[sub_chn], DETECT_MUX)); num_ports = SENSOR_PORTS;
pr_info ("num_ports= %d\n",num_ports);
for (port = 0; port < num_ports; port++){
pr_info ("Setting port %d mux '%s' (0x%x)\n",port, names[port], get_code_by_name(names[port], DETECT_MUX));
set_detected_mux_code(port, get_code_by_name(names[port], DETECT_MUX));
}
} }
num_ports = of_property_count_strings(node,OF_PREFIX_NAME",sensors"); num_ports = of_property_count_strings(node,OF_PREFIX_NAME",sensors");
if (num_ports > SENSOR_PORTS)
num_ports = SENSOR_PORTS;
pr_info ("num_ports = %d (was looking for '%s')\n",num_ports, OF_PREFIX_NAME",sensors");
for (port = 0; port < num_ports; port++){ for (port = 0; port < num_ports; port++){
if (of_property_read_string_index(node, OF_PREFIX_NAME",sensors", port, &config_string)) { if (of_property_read_string_index(node, OF_PREFIX_NAME",sensors", port, &config_string)) {
pr_err("%s: No data for selected port\n", __func__); pr_err("%s: No data for selected port\n", __func__);
BUG(); BUG();
} }
num_sub = sscanf(config_string,"%79s %79s %79s %79s", names[0], names[1], names[2], names[3]); pr_info ("Sensor config_string = %s\n",config_string);
for (sub_chn = 0; sub_chn < num_sub; sub_chn++){ if (config_string) {
set_detected_sensor_code(port, sub_chn, get_code_by_name(names[sub_chn], DETECT_SENSOR)); num_sub = sscanf(config_string,"%79s %79s %79s %79s", names[0], names[1], names[2], names[3]);
pr_info ("port %d : %d subchannels\n",port, num_sub);
for (sub_chn = 0; sub_chn < num_sub; sub_chn++){
pr_info ("Setting sensor %d:%d '%s' (0x%x)\n",port, sub_chn, names[sub_chn], get_code_by_name(names[sub_chn], DETECT_SENSOR));
set_detected_sensor_code(port, sub_chn, get_code_by_name(names[sub_chn], DETECT_SENSOR));
}
} }
} }
} }
...@@ -402,17 +408,18 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev) ...@@ -402,17 +408,18 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev)
// pSensorPortConfig = sensorPortConfig; // pSensorPortConfig = sensorPortConfig;
elphel393_detect_sensors_sysfs_register(pdev); elphel393_detect_sensors_sysfs_register(pdev);
pr_info ("Registered sysfs for detect_sensors");
match = of_match_device(elphel393_detect_sensors_of_match, dev); match = of_match_device(elphel393_detect_sensors_of_match, dev);
if (!match) if (!match) {
pr_err("Detect sensors ERROR: No device tree for '%s' node found\n",elphel393_detect_sensors_of_match[0].compatible); pr_err("Detect sensors ERROR: No device tree for '%s' node found\n",elphel393_detect_sensors_of_match[0].compatible);
return -EINVAL; return -EINVAL;
}
detect_sensors_init_of(pdev); detect_sensors_init_of(pdev);
// dev_dbg(dev, "Registering character device with name "DETECT_SENSORS_DRIVER_NAME); // dev_dbg(dev, "Registering character device with name "DEV393_NAME(DEV393_DETECT_SENSORS));
// res = register_chrdev(DETECT_SENSORS_MAJOR, DETECT_SENSORS_DRIVER_NAME, &detect_sensors_fops); // res = register_chrdev(DETECT_SENSORS_MAJOR, DEV393_NAME(DEV393_DETECT_SENSORS), &detect_sensors_fops);
// if(res < 0) { // if(res < 0) {
// dev_err(dev, "\nlogger_init: couldn't get a major number %d.\n ",DETECT_SENSORS_MAJOR); // dev_err(dev, "\nlogger_init: couldn't get a major number %d.\n ",DETECT_SENSORS_MAJOR);
// return res; // return res;
...@@ -426,7 +433,7 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev) ...@@ -426,7 +433,7 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev)
static int detect_sensors_remove(struct platform_device *pdev) ///< [in] pointer to @e platform_device structure static int detect_sensors_remove(struct platform_device *pdev) ///< [in] pointer to @e platform_device structure
///< @return always 0 ///< @return always 0
{ {
// unregister_chrdev(DETECT_SENSORS_MAJOR, DETECT_SENSORS_DRIVER_NAME); // unregister_chrdev(DETECT_SENSORS_MAJOR, DEV393_NAME(DEV393_DETECT_SENSORS));
return 0; return 0;
} }
...@@ -442,7 +449,7 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev) ...@@ -442,7 +449,7 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev)
.probe = detect_sensors_probe, .probe = detect_sensors_probe,
.remove = detect_sensors_remove, .remove = detect_sensors_remove,
.driver = { .driver = {
.name = DETECT_SENSORS_DRIVER_NAME, .name = DEV393_NAME(DEV393_DETECT_SENSORS),
.of_match_table = elphel393_detect_sensors_of_match, .of_match_table = elphel393_detect_sensors_of_match,
}, },
}; };
......
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/c313a.h> #include <uapi/elphel/c313a.h>
#include <uapi/elphel/exifa.h> #include <uapi/elphel/exifa.h>
#include <uapi/elphel/x393_devices.h>
//#include "fpgactrl.h" // defines port_csp0_addr, port_csp4_addr //#include "fpgactrl.h" // defines port_csp0_addr, port_csp4_addr
// //
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
#define X3X3_EXIF_DRIVER_NAME "Elphel (R) model 353 Exif device driver" #define X3X3_EXIF_DRIVER_DESCRIPTION "Elphel (R) model 393 Exif device driver"
static DEFINE_SPINLOCK(lock); static DEFINE_SPINLOCK(lock);
//#define MAX_EXIF_FIELDS 256 // number of Exif tags in the header //#define MAX_EXIF_FIELDS 256 // number of Exif tags in the header
...@@ -125,17 +125,17 @@ ssize_t minor_file_size(int minor) { //return current file size for different mi ...@@ -125,17 +125,17 @@ ssize_t minor_file_size(int minor) { //return current file size for different mi
switch (minor) { switch (minor) {
case X3X3_EXIF_TEMPLATE: case X3X3_EXIF_TEMPLATE:
return exif_template_size; return exif_template_size;
case X3X3_EXIF_EXIF_CHN_0: case DEV393_MINOR(DEV393_EXIF0):
case X3X3_EXIF_EXIF_CHN_1: case DEV393_MINOR(DEV393_EXIF1):
case X3X3_EXIF_EXIF_CHN_2: case DEV393_MINOR(DEV393_EXIF2):
case X3X3_EXIF_EXIF_CHN_3: case DEV393_MINOR(DEV393_EXIF3):
sensor_port = minor - X3X3_EXIF_EXIF_CHN_0; sensor_port = minor - DEV393_MINOR(DEV393_EXIF0);
return aexif_enabled[sensor_port]? (exif_template_size * (MAX_EXIF_FRAMES+1)):0; return aexif_enabled[sensor_port]? (exif_template_size * (MAX_EXIF_FRAMES+1)):0;
case X3X3_EXIF_META_CHN_0: case DEV393_MINOR(DEV393_EXIF_META0):
case X3X3_EXIF_META_CHN_1: case DEV393_MINOR(DEV393_EXIF_META1):
case X3X3_EXIF_META_CHN_2: case DEV393_MINOR(DEV393_EXIF_META2):
case X3X3_EXIF_META_CHN_3: case DEV393_MINOR(DEV393_EXIF_META3):
sensor_port = minor - X3X3_EXIF_META_CHN_0; sensor_port = minor - DEV393_MINOR(DEV393_EXIF_META0);
return aexif_meta_size[sensor_port]; return aexif_meta_size[sensor_port];
case X3X3_EXIF_METADIR: case X3X3_EXIF_METADIR:
return exif_fields * sizeof(struct exif_dir_table_t); return exif_fields * sizeof(struct exif_dir_table_t);
...@@ -148,15 +148,15 @@ ssize_t minor_max_size(int minor) { //return max file size for different minors ...@@ -148,15 +148,15 @@ ssize_t minor_max_size(int minor) { //return max file size for different minors
switch (minor) { switch (minor) {
case X3X3_EXIF_TEMPLATE: case X3X3_EXIF_TEMPLATE:
return MAX_EXIF_SIZE; return MAX_EXIF_SIZE;
case X3X3_EXIF_EXIF_CHN_0: case DEV393_MINOR(DEV393_EXIF0):
case X3X3_EXIF_EXIF_CHN_1: case DEV393_MINOR(DEV393_EXIF1):
case X3X3_EXIF_EXIF_CHN_2: case DEV393_MINOR(DEV393_EXIF2):
case X3X3_EXIF_EXIF_CHN_3: case DEV393_MINOR(DEV393_EXIF3):
return MAX_EXIF_SIZE * (MAX_EXIF_FRAMES+1); return MAX_EXIF_SIZE * (MAX_EXIF_FRAMES+1);
case X3X3_EXIF_META_CHN_0: case DEV393_MINOR(DEV393_EXIF_META0):
case X3X3_EXIF_META_CHN_1: case DEV393_MINOR(DEV393_EXIF_META1):
case X3X3_EXIF_META_CHN_2: case DEV393_MINOR(DEV393_EXIF_META2):
case X3X3_EXIF_META_CHN_3: case DEV393_MINOR(DEV393_EXIF_META3):
return MAX_EXIF_SIZE; return MAX_EXIF_SIZE;
case X3X3_EXIF_METADIR: case X3X3_EXIF_METADIR:
return MAX_EXIF_FIELDS * sizeof(struct exif_dir_table_t); return MAX_EXIF_FIELDS * sizeof(struct exif_dir_table_t);
...@@ -430,14 +430,14 @@ static int exif_open(struct inode *inode, struct file *filp) { ...@@ -430,14 +430,14 @@ static int exif_open(struct inode *inode, struct file *filp) {
int p = MINOR(inode->i_rdev); int p = MINOR(inode->i_rdev);
int * pd= (int *) &(filp->private_data); int * pd= (int *) &(filp->private_data);
switch (p) { switch (p) {
case X3X3_EXIF_EXIF_CHN_0: case DEV393_MINOR(DEV393_EXIF0):
case X3X3_EXIF_EXIF_CHN_1: case DEV393_MINOR(DEV393_EXIF1):
case X3X3_EXIF_EXIF_CHN_2: case DEV393_MINOR(DEV393_EXIF2):
case X3X3_EXIF_EXIF_CHN_3: case DEV393_MINOR(DEV393_EXIF3):
case X3X3_EXIF_META_CHN_0: case DEV393_MINOR(DEV393_EXIF_META0):
case X3X3_EXIF_META_CHN_1: case DEV393_MINOR(DEV393_EXIF_META1):
case X3X3_EXIF_META_CHN_2: case DEV393_MINOR(DEV393_EXIF_META2):
case X3X3_EXIF_META_CHN_3: case DEV393_MINOR(DEV393_EXIF_META3):
case X3X3_EXIF_TEMPLATE: case X3X3_EXIF_TEMPLATE:
case X3X3_EXIF_METADIR: case X3X3_EXIF_METADIR:
case X3X3_EXIF_TIME: case X3X3_EXIF_TIME:
...@@ -457,15 +457,15 @@ static int exif_release(struct inode *inode, struct file *filp){ ...@@ -457,15 +457,15 @@ static int exif_release(struct inode *inode, struct file *filp){
int p = MINOR(inode->i_rdev); int p = MINOR(inode->i_rdev);
int * pd= (int *) &(filp->private_data); int * pd= (int *) &(filp->private_data);
switch (p) { switch (p) {
case X3X3_EXIF_EXIF_CHN_0: case DEV393_MINOR(DEV393_EXIF0):
case X3X3_EXIF_EXIF_CHN_1: case DEV393_MINOR(DEV393_EXIF1):
case X3X3_EXIF_EXIF_CHN_2: case DEV393_MINOR(DEV393_EXIF2):
case X3X3_EXIF_EXIF_CHN_3: case DEV393_MINOR(DEV393_EXIF3):
break; break;
case X3X3_EXIF_META_CHN_0: case DEV393_MINOR(DEV393_EXIF_META0):
case X3X3_EXIF_META_CHN_1: case DEV393_MINOR(DEV393_EXIF_META1):
case X3X3_EXIF_META_CHN_2: case DEV393_MINOR(DEV393_EXIF_META2):
case X3X3_EXIF_META_CHN_3: case DEV393_MINOR(DEV393_EXIF_META3):
break; break;
case X3X3_EXIF_TEMPLATE: case X3X3_EXIF_TEMPLATE:
break; break;
...@@ -521,11 +521,11 @@ static loff_t exif_lseek (struct file * file, loff_t offset, int orig) { ...@@ -521,11 +521,11 @@ static loff_t exif_lseek (struct file * file, loff_t offset, int orig) {
default:return -EINVAL; default:return -EINVAL;
} }
break; break;
case X3X3_EXIF_EXIF_CHN_0: case DEV393_MINOR(DEV393_EXIF0):
case X3X3_EXIF_EXIF_CHN_1: case DEV393_MINOR(DEV393_EXIF1):
case X3X3_EXIF_EXIF_CHN_2: case DEV393_MINOR(DEV393_EXIF2):
case X3X3_EXIF_EXIF_CHN_3: case DEV393_MINOR(DEV393_EXIF3):
// sensor_port = p - X3X3_EXIF_EXIF_CHN_0; // sensor_port = p - DEV393_MINOR(DEV393_EXIF0);
if (offset > MAX_EXIF_FRAMES) return -EOVERFLOW; //larger than buffer if (offset > MAX_EXIF_FRAMES) return -EOVERFLOW; //larger than buffer
// file->f_pos=exif_meta_size * offset; // file->f_pos=exif_meta_size * offset;
file->f_pos=exif_template_size * offset; file->f_pos=exif_template_size * offset;
...@@ -535,10 +535,10 @@ static loff_t exif_lseek (struct file * file, loff_t offset, int orig) { ...@@ -535,10 +535,10 @@ static loff_t exif_lseek (struct file * file, loff_t offset, int orig) {
if (fp < 0) return -EOVERFLOW; // tag is not in the directory if (fp < 0) return -EOVERFLOW; // tag is not in the directory
file->f_pos=fp; file->f_pos=fp;
break; break;
case X3X3_EXIF_META_CHN_0: case DEV393_MINOR(DEV393_EXIF_META0):
case X3X3_EXIF_META_CHN_1: case DEV393_MINOR(DEV393_EXIF_META1):
case X3X3_EXIF_META_CHN_2: case DEV393_MINOR(DEV393_EXIF_META2):
case X3X3_EXIF_META_CHN_3: case DEV393_MINOR(DEV393_EXIF_META3):
file->f_pos=offset*sizeof(struct exif_dir_table_t); file->f_pos=offset*sizeof(struct exif_dir_table_t);
break; break;
case X3X3_EXIF_TIME: case X3X3_EXIF_TIME:
...@@ -609,11 +609,11 @@ static ssize_t exif_write (struct file * file, const char * buf, size_t coun ...@@ -609,11 +609,11 @@ static ssize_t exif_write (struct file * file, const char * buf, size_t coun
cp= (char *) &exif_time; cp= (char *) &exif_time;
if (copy_from_user(&cp[*off], buf, count)) return -EFAULT; if (copy_from_user(&cp[*off], buf, count)) return -EFAULT;
break; break;
case X3X3_EXIF_META_CHN_0: case DEV393_MINOR(DEV393_EXIF_META0):
case X3X3_EXIF_META_CHN_1: case DEV393_MINOR(DEV393_EXIF_META1):
case X3X3_EXIF_META_CHN_2: case DEV393_MINOR(DEV393_EXIF_META2):
case X3X3_EXIF_META_CHN_3: case DEV393_MINOR(DEV393_EXIF_META3):
sensor_port = p - X3X3_EXIF_META_CHN_0; sensor_port = p - DEV393_MINOR(DEV393_EXIF_META0);
if (copy_from_user(tmp, buf, count)) return -EFAULT; if (copy_from_user(tmp, buf, count)) return -EFAULT;
local_irq_save(flags); local_irq_save(flags);
//local_irq_disable(); //local_irq_disable();
...@@ -625,10 +625,10 @@ static ssize_t exif_write (struct file * file, const char * buf, size_t coun ...@@ -625,10 +625,10 @@ static ssize_t exif_write (struct file * file, const char * buf, size_t coun
count=0; count=0;
} }
break; break;
case X3X3_EXIF_EXIF_CHN_0: case DEV393_MINOR(DEV393_EXIF0):
case X3X3_EXIF_EXIF_CHN_1: case DEV393_MINOR(DEV393_EXIF1):
case X3X3_EXIF_EXIF_CHN_2: case DEV393_MINOR(DEV393_EXIF2):
case X3X3_EXIF_EXIF_CHN_3: case DEV393_MINOR(DEV393_EXIF3):
return -EINVAL; // no writing - read only return -EINVAL; // no writing - read only
break; break;
default:return -EINVAL; default:return -EINVAL;
...@@ -673,19 +673,19 @@ static ssize_t exif_read (struct file * file, char * buf, size_t count, lof ...@@ -673,19 +673,19 @@ static ssize_t exif_read (struct file * file, char * buf, size_t count, lof
cp= (char *) &exif_time; cp= (char *) &exif_time;
if (copy_to_user(buf, &cp[*off], count)) return -EFAULT; if (copy_to_user(buf, &cp[*off], count)) return -EFAULT;
break; break;
case X3X3_EXIF_META_CHN_0: case DEV393_MINOR(DEV393_EXIF_META0):
case X3X3_EXIF_META_CHN_1: case DEV393_MINOR(DEV393_EXIF_META1):
case X3X3_EXIF_META_CHN_2: case DEV393_MINOR(DEV393_EXIF_META2):
case X3X3_EXIF_META_CHN_3: case DEV393_MINOR(DEV393_EXIF_META3):
sensor_port = p - X3X3_EXIF_META_CHN_0; sensor_port = p - DEV393_MINOR(DEV393_EXIF_META0);
if (!aexif_enabled[sensor_port]) return 0; if (!aexif_enabled[sensor_port]) return 0;
if (copy_to_user(buf, &ameta_buffer[sensor_port][*off], count)) return -EFAULT; if (copy_to_user(buf, &ameta_buffer[sensor_port][*off], count)) return -EFAULT;
break; break;
case X3X3_EXIF_EXIF_CHN_0:// generates exif data by merging exif_template with the selected meta_buffer page case DEV393_MINOR(DEV393_EXIF0):// generates exif data by merging exif_template with the selected meta_buffer page
case X3X3_EXIF_EXIF_CHN_1: case DEV393_MINOR(DEV393_EXIF1):
case X3X3_EXIF_EXIF_CHN_2: case DEV393_MINOR(DEV393_EXIF2):
case X3X3_EXIF_EXIF_CHN_3: case DEV393_MINOR(DEV393_EXIF3):
sensor_port = p - X3X3_EXIF_EXIF_CHN_0; sensor_port = p - DEV393_MINOR(DEV393_EXIF0);
//will truncate by the end of current page //will truncate by the end of current page
if (!aexif_enabled[sensor_port]) return 0; if (!aexif_enabled[sensor_port]) return 0;
i=((int) *off) / exif_template_size; i=((int) *off) / exif_template_size;
...@@ -716,16 +716,16 @@ static ssize_t exif_read (struct file * file, char * buf, size_t count, lof ...@@ -716,16 +716,16 @@ static ssize_t exif_read (struct file * file, char * buf, size_t count, lof
static int __init exif_init(void) { static int __init exif_init(void) {
int res; int res;
res = register_chrdev(X3X3_EXIF_MAJOR, "Exif", &exif_fops); res = register_chrdev(DEV393_MAJOR(DEV393_EXIF0), "Exif", &exif_fops);
if(res < 0) { if(res < 0) {
printk(KERN_ERR "\nexif_init: couldn't get a major number %d.\n",X3X3_EXIF_MAJOR); printk(KERN_ERR "\nexif_init: couldn't get a major number %d.\n",DEV393_MAJOR(DEV393_EXIF0));
return res; return res;
} }
printk(X3X3_EXIF_DRIVER_NAME" - %d\n",X3X3_EXIF_MAJOR); printk(DEV393_NAME(DEV393_EXIF0)" - %d\n",DEV393_MAJOR(DEV393_EXIF0));
return 0; return 0;
} }
module_init(exif_init); module_init(exif_init);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>."); MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
MODULE_DESCRIPTION(X3X3_EXIF_DRIVER_NAME); MODULE_DESCRIPTION(X3X3_EXIF_DRIVER_DESCRIPTION);
/**************************************************************************//** /**************************************************************************//**
* @file fpgajtag353.c * @file fpgajtag353.c
* @brief TBD * @brief TBD
* @copyright Copyright 2002-20016 (C) Elphel, Inc. * @copyright Copyright 2002-20016 (C) Elphel, Inc.
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or * the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* @par <b>License</b>* * @par <b>License</b>*
*/ */
#undef DEBUG #undef DEBUG
/****************** INCLUDE FILES SECTION ***********************************/ /****************** INCLUDE FILES SECTION ***********************************/
#include <linux/module.h> #include <linux/module.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/ioport.h> // needed? #include <linux/ioport.h> // needed?
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/fs.h> #include <linux/fs.h>
...@@ -39,7 +39,9 @@ ...@@ -39,7 +39,9 @@
//#include <asm/system.h> //#include <asm/system.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <elphel/driver_numbers.h> #include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/c313a.h> // for #define SENSOR_PORTS 4
//#include <elphel/fpgaconfa.h> //defines for fpga_state fields //#include <elphel/fpgaconfa.h> //defines for fpga_state fields
...@@ -70,7 +72,7 @@ port C 353: ...@@ -70,7 +72,7 @@ port C 353:
5 - DONE (in) 5 - DONE (in)
6 - RSTBTN 6 - RSTBTN
7 - PGM (out) 7 - PGM (out)
*/ */
#define FPGAJTAG_TDO_BIT 0 #define FPGAJTAG_TDO_BIT 0
#define FPGAJTAG_TDI_BIT 1 #define FPGAJTAG_TDI_BIT 1
#define FPGAJTAG_TMS_BIT 2 #define FPGAJTAG_TMS_BIT 2
...@@ -81,20 +83,19 @@ port C 353: ...@@ -81,20 +83,19 @@ port C 353:
#ifndef XC2S300E_BITSIZE #ifndef XC2S300E_BITSIZE
#define XC3S1000_BITSIZE 3223488 #define XC3S1000_BITSIZE 3223488
#define XC3S1200E_BITSIZE 3841189 #define XC3S1200E_BITSIZE 3841189
#define XC3S1200E_BOUNDARY_SIZE 772 #define XC3S1200E_BOUNDARY_SIZE 772
// #define XC3S1200E_BOUNDARY_SIZE 812 // #define XC3S1200E_BOUNDARY_SIZE 812
#define FJTAG_BUF_SIZE 0x77000 #define FJTAG_BUF_SIZE 0x77000
#define FJTAG_MAX_HEAD 0x1000 #define FJTAG_MAX_HEAD 0x1000
#define FJTAG_RAW_WSIZE 0x40000 // shared with bitstream buffer #define FJTAG_RAW_WSIZE 0x40000 // shared with bitstream buffer
#define FJTAG_RAW_RSIZE 0x30000 // shared with bitstream buffer #define FJTAG_RAW_RSIZE 0x30000 // shared with bitstream buffer
#define FJTAG_IDSIZE 0x40 // bits - ID and User #define FJTAG_IDSIZE 0x40 // bits - ID and User
#endif #endif
//#define FPGA_JTAG_DRIVER_NAME "Elphel (R) model 353 FPGA (Xilinx (R) XC3S1200E) configuration driver" #define FPGA_JTAG_DRIVER_DESCRIPTION "Elphel (R) model 393 FPGA (Xilinx (R) XC3S1200E) configuration driver"
#define FPGA_JTAG_DRIVER_NAME "Elphel (R) model 393 FPGA (Xilinx (R) XC3S1200E) configuration driver"
#define FPGA_JTAG_MAXMINOR 16 // 10 #define FPGA_JTAG_MAXMINOR 16 // 10
...@@ -105,8 +106,8 @@ port C 353: ...@@ -105,8 +106,8 @@ port C 353:
//#define JTAG_NCHANNELS 4 //#define JTAG_NCHANNELS 4
#define JTAG_NCHANNELS 16 // 4 << 2 #define JTAG_NCHANNELS 16 // 4 << 2
#define JTAG_SENSOR_OFFSET 4 // Sensor ports minors start (4..7) - (2 LSB should be 0) //#define JTAG_SENSOR_OFFSET 4 // Sensor ports minors start (4..7) - (2 LSB should be 0)
#define JTAG_SENSOR_CHANNELS 4 // Number of sensor ports for JTAG //#define JTAG_SENSOR_CHANNELS 4 // Number of sensor ports for JTAG
#define JTAG_MODE_CLOSED 0 // JTAG channel is closed #define JTAG_MODE_CLOSED 0 // JTAG channel is closed
...@@ -119,15 +120,15 @@ port C 353: ...@@ -119,15 +120,15 @@ port C 353:
// configuration and raw minors use whole buffer, ID and boundary can be opened at the same time // configuration and raw minors use whole buffer, ID and boundary can be opened at the same time
struct JTAG_channel_t { struct JTAG_channel_t {
int mode; // 0..5 -JTAG_MODE_CLOSED...JTAG_MODE_EXTEST int mode; // 0..5 -JTAG_MODE_CLOSED...JTAG_MODE_EXTEST
unsigned char * dbuf; // data buffer (shared, boundary mode use different parts) unsigned char * dbuf; // data buffer (shared, boundary mode use different parts)
int sizew; // byte size that can be written int sizew; // byte size that can be written
int sizer; // byte size that can be read int sizer; // byte size that can be read
int bitsw; // bit size to be written int bitsw; // bit size to be written
int bitsr; // bit size to be read int bitsr; // bit size to be read
int wp; // byte pointer for file write int wp; // byte pointer for file write
int rp; // byte pointer for file read int rp; // byte pointer for file read
int wdirty; // some data is buffered but not yet sent out in EXTEST mode int wdirty; // some data is buffered but not yet sent out in EXTEST mode
}; };
static unsigned char bitstream_data[FJTAG_BUF_SIZE]; // will fit bitstream and the header (if any). Also used for boundary write static unsigned char bitstream_data[FJTAG_BUF_SIZE]; // will fit bitstream and the header (if any). Also used for boundary write
//static unsigned short *raw_fifo_w= (unsigned short) &bitstream_data[0]; //static unsigned short *raw_fifo_w= (unsigned short) &bitstream_data[0];
...@@ -158,12 +159,12 @@ static ssize_t fpga_jtag_read (struct file * file, char * buf, size_t count, l ...@@ -158,12 +159,12 @@ static ssize_t fpga_jtag_read (struct file * file, char * buf, size_t count, l
static int __init fpga_jtag_init(void); static int __init fpga_jtag_init(void);
static struct file_operations fpga_jtag_fops = { static struct file_operations fpga_jtag_fops = {
owner: THIS_MODULE, owner: THIS_MODULE,
open: fpga_jtag_open, open: fpga_jtag_open,
release: fpga_jtag_release, release: fpga_jtag_release,
llseek: fpga_jtag_lseek, llseek: fpga_jtag_lseek,
read: fpga_jtag_read, read: fpga_jtag_read,
write: fpga_jtag_write write: fpga_jtag_write
}; };
//static int sens_num = 0; //static int sens_num = 0;
...@@ -178,11 +179,11 @@ void set_pgm (int chn, int pgmon); ...@@ -178,11 +179,11 @@ void set_pgm (int chn, int pgmon);
int read_done (int chn); int read_done (int chn);
int jtag_send (int chn, int tms, int len, int d); int jtag_send (int chn, int tms, int len, int d);
int jtag_write_bits (int chn, int jtag_write_bits (int chn,
unsigned char *buf, // data to write unsigned char *buf, // data to write
int len, // number of bytes to write int len, // number of bytes to write
int check, // compare readback data with previously written, abort on mismatch int check, // compare readback data with previously written, abort on mismatch
int last, // output last bit with TMS=1 int last, // output last bit with TMS=1
int prev[2]); // if null - don't use int prev[2]); // if null - don't use
int JTAG_configure (int chn, unsigned char * buf, int len); int JTAG_configure (int chn, unsigned char * buf, int len);
int JTAG_readID (int chn, unsigned char * buf); int JTAG_readID (int chn, unsigned char * buf);
int JTAG_openChannel (int chn); int JTAG_openChannel (int chn);
...@@ -195,13 +196,16 @@ int JTAG_process_raw(void); ...@@ -195,13 +196,16 @@ int JTAG_process_raw(void);
int JTAG_channel(int minor) { int JTAG_channel(int minor) {
if ((minor >= FPGA_SJTAG_MINOR_OFFSET) && (minor < (FPGA_SJTAG_MINOR_OFFSET + FPGA_SJTAG_CHANNELS))) if ((minor >= DEV393_MINOR(DEV393_JTAGS_CONF0)) && (minor < (DEV393_MINOR(DEV393_JTAGS_CONF0) + SENSOR_PORTS)))
return (minor - FPGA_SJTAG_MINOR_OFFSET) + (JTAG_SENSOR_FPGA << 2); return (minor - DEV393_MINOR(DEV393_JTAGS_CONF0)) + (JTAG_SENSOR_FPGA << 2);
if ((minor >= FPGA_SJTAG_BOUNDARY_OFFSET) && (minor < (FPGA_SJTAG_BOUNDARY_OFFSET + FPGA_SJTAG_CHANNELS)))
return (minor - FPGA_SJTAG_BOUNDARY_OFFSET) + (JTAG_SENSOR_FPGA << 2);
// maybe will never be used if ((minor >= DEV393_MINOR(DEV393_JTAGS_BSCAN0)) && (minor < (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + SENSOR_PORTS)))
switch (minor) { return (minor - DEV393_MINOR(DEV393_JTAGS_BSCAN0)) + (JTAG_SENSOR_FPGA << 2);
case FPGA_JTAG_RESET_MINOR : // same as RAW // maybe will never be used
#ifdef NC353
switch (minor) {
case DEV393_MINOR(DEV393_JTAG_RESET) : // same as RAW
return JTAG_RAW << 2; return JTAG_RAW << 2;
case FPGA_JTAG_MINOR: case FPGA_JTAG_MINOR:
case FPGA_JTAG_BOUNDARY_MINOR: case FPGA_JTAG_BOUNDARY_MINOR:
...@@ -212,8 +216,9 @@ int JTAG_channel(int minor) { ...@@ -212,8 +216,9 @@ int JTAG_channel(int minor) {
case FPGA_AJTAG_MINOR: case FPGA_AJTAG_MINOR:
case FPGA_AJTAG_BOUNDARY_MINOR: case FPGA_AJTAG_BOUNDARY_MINOR:
return JTAG_AUX_FPGA << 2; return JTAG_AUX_FPGA << 2;
} }
return 0; #endif
return 0;
} }
static int raw_fifo_w_wp; static int raw_fifo_w_wp;
static int raw_fifo_w_rp; static int raw_fifo_w_rp;
...@@ -245,204 +250,208 @@ void set_pgm (int chn, int pgmon); ...@@ -245,204 +250,208 @@ void set_pgm (int chn, int pgmon);
#define JTAG_RAW_WAIT 0x80 #define JTAG_RAW_WAIT 0x80
void JTAG_push_raw (int b) { void JTAG_push_raw (int b) {
raw_fifo_r[raw_fifo_r_wp++]=b; raw_fifo_r[raw_fifo_r_wp++]=b;
if (raw_fifo_r_wp > FJTAG_RAW_RSIZE) raw_fifo_r_wp-=FJTAG_RAW_RSIZE; if (raw_fifo_r_wp > FJTAG_RAW_RSIZE) raw_fifo_r_wp-=FJTAG_RAW_RSIZE;
} }
// TODO: Not updated for 393. Is it needed? // TODO: Not updated for 393. Is it needed?
int JTAG_process_raw(void) { int JTAG_process_raw(void) {
unsigned char b0, b1; unsigned char b0, b1;
while (raw_fifo_w_rp != (raw_fifo_w_wp & ~1)) { while (raw_fifo_w_rp != (raw_fifo_w_wp & ~1)) {
b0=raw_fifo_w[raw_fifo_w_rp++]; b0=raw_fifo_w[raw_fifo_w_rp++];
b1=raw_fifo_w[raw_fifo_w_rp++]; b1=raw_fifo_w[raw_fifo_w_rp++];
if (raw_fifo_w_rp > FJTAG_RAW_WSIZE) raw_fifo_w_rp-=FJTAG_RAW_WSIZE; if (raw_fifo_w_rp > FJTAG_RAW_WSIZE) raw_fifo_w_rp-=FJTAG_RAW_WSIZE;
if (b1 == JTAG_RAW_SETCHN) { // set channel number if (b1 == JTAG_RAW_SETCHN) { // set channel number
raw_chn = b0; raw_chn = b0;
if (raw_chn>=JTAG_NCHANNELS) raw_chn=0; //illegal channel if (raw_chn>=JTAG_NCHANNELS) raw_chn=0; //illegal channel
JTAG_push_raw (raw_chn); JTAG_push_raw (raw_chn);
} else if (raw_chn) { // ignore commands until the JTAG channel number is specified } else if (raw_chn) { // ignore commands until the JTAG channel number is specified
if ((b1 & 0xf0) == JTAG_RAW_SEND) { // send JTAG data if ((b1 & 0xf0) == JTAG_RAW_SEND) { // send JTAG data
JTAG_push_raw (jtag_send(raw_chn, (b1 >> 3) & 1, b1 & 7, (int) b0 )); JTAG_push_raw (jtag_send(raw_chn, (b1 >> 3) & 1, b1 & 7, (int) b0 ));
} else if ((b1 & 0x80) == JTAG_RAW_WAIT) { // delay } else if ((b1 & 0x80) == JTAG_RAW_WAIT) { // delay
/* possible bug here, udelay is used for delays less then 2 ms */ /* possible bug here, udelay is used for delays less then 2 ms */
udelay(((b1 & 0x7f) <<8) + b0); udelay(((b1 & 0x7f) <<8) + b0);
JTAG_push_raw (0x80); JTAG_push_raw (0x80);
} else switch (b1) { } else switch (b1) {
case JTAG_RAW_DEACT: case JTAG_RAW_DEACT:
set_pgm_mode (raw_chn, 0); set_pgm_mode (raw_chn, 0);
JTAG_push_raw (0x0); JTAG_push_raw (0x0);
break; break;
case JTAG_RAW_ACT: case JTAG_RAW_ACT:
set_pgm_mode (raw_chn, 1); set_pgm_mode (raw_chn, 1);
JTAG_push_raw (0x0); JTAG_push_raw (0x0);
break; break;
case JTAG_RAW_PGMOFF: case JTAG_RAW_PGMOFF:
set_pgm (raw_chn, 0); set_pgm (raw_chn, 0);
JTAG_push_raw (read_done(raw_chn)); JTAG_push_raw (read_done(raw_chn));
break; // was missing for 353 break; // was missing for 353
case JTAG_RAW_PGMON: case JTAG_RAW_PGMON:
set_pgm (raw_chn, 1); set_pgm (raw_chn, 1);
JTAG_push_raw (0xf0); JTAG_push_raw (0xf0);
break; break;
default: default:
JTAG_push_raw (0xff); JTAG_push_raw (0xff);
} }
} else { // make output always be 1 byte for 2 bytes input } else { // make output always be 1 byte for 2 bytes input
JTAG_push_raw (0xf0); JTAG_push_raw (0xf0);
} // end of if (raw_chn) /else } // end of if (raw_chn) /else
} // while (raw_fifo_w_rp != (raw_fifo_w_wp & ~1)) } // while (raw_fifo_w_rp != (raw_fifo_w_wp & ~1))
return 0; // will think of return value later return 0; // will think of return value later
} }
//returns 0 if all channels closed //returns 0 if all channels closed
// //
int JTAG_whatopen(void) { int JTAG_whatopen(void) {
int i,r=0; int i,r=0;
for (i=0;i<JTAG_NCHANNELS;i++) r |= 1 << JTAG_channels[i].mode; for (i=0;i<JTAG_NCHANNELS;i++) r |= 1 << JTAG_channels[i].mode;
return r; return r;
} }
//++++++++++++++++++++++++++++++++++++ open() ++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++ open() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
static int fpga_jtag_open(struct inode *inode, struct file *filp) { static int fpga_jtag_open(struct inode *inode, struct file *filp) {
int i; int i;
// int res; // int res;
int p = MINOR(inode->i_rdev); int p = MINOR(inode->i_rdev);
int chn= JTAG_channel(p); int chn= JTAG_channel(p);
//reg_intr_vect_rw_mask intr_mask; //reg_intr_vect_rw_mask intr_mask;
//D(printk("fpga_jtag_open: minor=%x, channel=%x, buf=%p\r\n",p,chn,bitstream_data )); //D(printk("fpga_jtag_open: minor=%x, channel=%x, buf=%p\r\n",p,chn,bitstream_data ));
dev_dbg(NULL, "fpga_jtag_open: minor=%x, channel=%x, buf=%p\r\n",p ,chn, bitstream_data); dev_dbg(NULL, "fpga_jtag_open: minor=%x, channel=%x, buf=%p\r\n",p ,chn, bitstream_data);
switch ( p ) { switch ( p ) {
case FPGA_JTAG_RESET_MINOR : // same as RAW case DEV393_MINOR(DEV393_JTAG_RESET) : // same as RAW
for (i=1; i<JTAG_NCHANNELS; i++) JTAG_channels[i].mode=JTAG_MODE_CLOSED; for (i=1; i<JTAG_NCHANNELS; i++) JTAG_channels[i].mode=JTAG_MODE_CLOSED;
JTAG_channels[chn].mode=JTAG_MODE_RAW; JTAG_channels[chn].mode=JTAG_MODE_RAW;
JTAG_channels[chn].sizew = FJTAG_RAW_WSIZE; JTAG_channels[chn].sizew = FJTAG_RAW_WSIZE;
JTAG_channels[chn].sizer = FJTAG_RAW_RSIZE; JTAG_channels[chn].sizer = FJTAG_RAW_RSIZE;
JTAG_channels[chn].wp = 0; JTAG_channels[chn].wp = 0;
JTAG_channels[chn].rp = 0; // will read IDs if actually read JTAG_channels[chn].rp = 0; // will read IDs if actually read
raw_fifo_w_wp=0; raw_fifo_w_wp=0;
raw_fifo_w_rp=0; raw_fifo_w_rp=0;
raw_fifo_r_wp=0; raw_fifo_r_wp=0;
raw_fifo_r_rp=0; raw_fifo_r_rp=0;
raw_chn=0; raw_chn=0;
break; break;
case FPGA_JTAG_MINOR : // case FPGA_JTAG_MINOR :
// if ( JTAG_whatopen() & 0x7e) return -EACCES; // none of the channels could be open when opening this file // if ( JTAG_whatopen() & 0x7e) return -EACCES; // none of the channels could be open when opening this file
// JTAG_channels[chn].mode = JTAG_MODE_PGM; // JTAG_channels[chn].mode = JTAG_MODE_PGM;
// JTAG_channels[chn].dbuf = &bitstream_data[0]; // JTAG_channels[chn].dbuf = &bitstream_data[0];
// JTAG_channels[chn].sizew = FJTAG_BUF_SIZE; // JTAG_channels[chn].sizew = FJTAG_BUF_SIZE;
// JTAG_channels[chn].sizer = FJTAG_IDSIZE >> 3; // JTAG_channels[chn].sizer = FJTAG_IDSIZE >> 3;
// JTAG_channels[chn].wp = 0; // JTAG_channels[chn].wp = 0;
// JTAG_channels[chn].rp = 0; // will read IDs if actually read // JTAG_channels[chn].rp = 0; // will read IDs if actually read
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
fpga_state &= ~FPGA_STATE_LOADED; // is it still used? fpga_state &= ~FPGA_STATE_LOADED; // is it still used?
fpga_state &= ~FPGA_STATE_SDRAM_INIT; // not needed fpga_state &= ~FPGA_STATE_SDRAM_INIT; // not needed
// disable camera interrupts here (while reprogramming FPGA could generate stray interrupts; // disable camera interrupts here (while reprogramming FPGA could generate stray interrupts;
/* Disable external interrupts.. */ /* Disable external interrupts.. */
intr_mask = REG_RD(intr_vect, regi_irq, rw_mask); intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
intr_mask.ext = 0; intr_mask.ext = 0;
REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
// printk ("Camera interrupts disabled\r\n"); // printk ("Camera interrupts disabled\r\n");
// break; // break;
// fall through // fall through
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1): case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 1):
case (FPGA_SJTAG_MINOR_OFFSET + 2): case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 2):
case (FPGA_SJTAG_MINOR_OFFSET + 3): case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 3):
case FPGA_SJTAG_MINOR : #ifdef NC353
case FPGA_AJTAG_MINOR : case FPGA_SJTAG_MINOR :
if ( JTAG_whatopen() & 0x7e) return -EACCES; // none of the channels could be open when opening this file case FPGA_AJTAG_MINOR :
JTAG_channels[chn].mode = JTAG_MODE_PGM; #endif
JTAG_channels[chn].dbuf = &bitstream_data[0]; if ( JTAG_whatopen() & 0x7e) return -EACCES; // none of the channels could be open when opening this file
JTAG_channels[chn].sizew = FJTAG_BUF_SIZE; JTAG_channels[chn].mode = JTAG_MODE_PGM;
JTAG_channels[chn].sizer = FJTAG_IDSIZE >> 3; JTAG_channels[chn].dbuf = &bitstream_data[0];
JTAG_channels[chn].wp = 0; JTAG_channels[chn].sizew = FJTAG_BUF_SIZE;
JTAG_channels[chn].rp = 0; // will read IDs if actually read JTAG_channels[chn].sizer = FJTAG_IDSIZE >> 3;
JTAG_channels[chn].bitsw = XC3S1200E_BITSIZE; // bit size to be written JTAG_channels[chn].wp = 0;
JTAG_channels[chn].bitsr= FJTAG_IDSIZE; JTAG_channels[chn].rp = 0; // will read IDs if actually read
JTAG_openChannel (chn); // configure channel access, reset JTAG and to RUN-TEST/IDLE state JTAG_channels[chn].bitsw = XC3S1200E_BITSIZE; // bit size to be written
break; JTAG_channels[chn].bitsr= FJTAG_IDSIZE;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0): JTAG_openChannel (chn); // configure channel access, reset JTAG and to RUN-TEST/IDLE state
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1): break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2): case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3): case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 1):
case FPGA_JTAG_BOUNDARY_MINOR : case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 2):
case FPGA_SJTAG_BOUNDARY_MINOR : case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 3):
case FPGA_AJTAG_BOUNDARY_MINOR : #ifdef NC353
if ( JTAG_whatopen() & 0x46) return -EACCES; // none of the channels could be open for program/id/raw when opening this file case FPGA_JTAG_BOUNDARY_MINOR :
if ( JTAG_channels[chn].mode != JTAG_MODE_CLOSED) return -EACCES; // already open case FPGA_SJTAG_BOUNDARY_MINOR :
JTAG_channels[chn].mode = JTAG_MODE_BOUNDARY; case FPGA_AJTAG_BOUNDARY_MINOR :
JTAG_channels[chn].sizew = (XC3S1200E_BOUNDARY_SIZE+7) >> 3; #endif
JTAG_channels[chn].sizer = (XC3S1200E_BOUNDARY_SIZE+7) >> 3; if ( JTAG_whatopen() & 0x46) return -EACCES; // none of the channels could be open for program/id/raw when opening this file
JTAG_channels[chn].dbuf = &bitstream_data[JTAG_channels[chn].sizew * chn]; if ( JTAG_channels[chn].mode != JTAG_MODE_CLOSED) return -EACCES; // already open
JTAG_channels[chn].wp = 0; JTAG_channels[chn].mode = JTAG_MODE_BOUNDARY;
JTAG_channels[chn].rp = 0; // will read IDs if actually read JTAG_channels[chn].sizew = (XC3S1200E_BOUNDARY_SIZE+7) >> 3;
JTAG_channels[chn].bitsw = XC3S1200E_BOUNDARY_SIZE; // bit size to be written JTAG_channels[chn].sizer = (XC3S1200E_BOUNDARY_SIZE+7) >> 3;
JTAG_channels[chn].bitsr= XC3S1200E_BOUNDARY_SIZE; JTAG_channels[chn].dbuf = &bitstream_data[JTAG_channels[chn].sizew * chn];
JTAG_openChannel (chn); // configure channel access, reset JTAG and to RUN-TEST/IDLE state JTAG_channels[chn].wp = 0;
break; JTAG_channels[chn].rp = 0; // will read IDs if actually read
default: return -EINVAL; JTAG_channels[chn].bitsw = XC3S1200E_BOUNDARY_SIZE; // bit size to be written
} JTAG_channels[chn].bitsr= XC3S1200E_BOUNDARY_SIZE;
dev_dbg(NULL, "fpga_jtag_open: chn=%x, JTAG_channels[chn].sizew=%x, JTAG_channels[chn].sizer=%x\r\n", chn, JTAG_channels[chn].sizew, JTAG_channels[chn].sizer); JTAG_openChannel (chn); // configure channel access, reset JTAG and to RUN-TEST/IDLE state
dev_dbg(NULL, "fpga_jtag_open: chn=%x, JTAG_channels[chn].bitsw=%x, JTAG_channels[chn].bitsr=%x\r\n", chn, JTAG_channels[chn].bitsw, JTAG_channels[chn].bitsr); break;
JTAG_channels[chn].wdirty=0; default: return -EINVAL;
inode->i_size=JTAG_channels[chn].sizer; }
minors[p]=p; dev_dbg(NULL, "fpga_jtag_open: chn=%x, JTAG_channels[chn].sizew=%x, JTAG_channels[chn].sizer=%x\r\n", chn, JTAG_channels[chn].sizew, JTAG_channels[chn].sizer);
filp->private_data = &minors[p]; dev_dbg(NULL, "fpga_jtag_open: chn=%x, JTAG_channels[chn].bitsw=%x, JTAG_channels[chn].bitsr=%x\r\n", chn, JTAG_channels[chn].bitsw, JTAG_channels[chn].bitsr);
dev_dbg(NULL, "fpga_jtag_open: inode->i_size=%x, chn=%x\r\n", (int) inode->i_size, chn); JTAG_channels[chn].wdirty=0;
return 0; inode->i_size=JTAG_channels[chn].sizer;
minors[p]=p;
filp->private_data = &minors[p];
dev_dbg(NULL, "fpga_jtag_open: inode->i_size=%x, chn=%x\r\n", (int) inode->i_size, chn);
return 0;
} }
//++++++++++++++++++++++++++++++++++++ release() ++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++ release() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
static int fpga_jtag_release(struct inode *inode, struct file *filp) { static int fpga_jtag_release(struct inode *inode, struct file *filp) {
int res=0; int res=0;
int p = MINOR(inode->i_rdev); int p = MINOR(inode->i_rdev);
int chn= JTAG_channel(p); int chn= JTAG_channel(p);
dev_dbg(NULL, "fpga_jtag_release: p=%x,chn=%x, wp=0x%x, rp=0x%x\r\n", p, chn, JTAG_channels[chn].wp, JTAG_channels[chn].rp); dev_dbg(NULL, "fpga_jtag_release: p=%x,chn=%x, wp=0x%x, rp=0x%x\r\n", p, chn, JTAG_channels[chn].wp, JTAG_channels[chn].rp);
switch ( p ) { switch ( p ) {
case FPGA_JTAG_RESET_MINOR : // same as RAW - do nothing, raw code should do it on it's own case DEV393_MINOR(DEV393_JTAG_RESET) : // same as RAW - do nothing, raw code should do it on it's own
break; break;
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1): case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 1):
case (FPGA_SJTAG_MINOR_OFFSET + 2): case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 2):
case (FPGA_SJTAG_MINOR_OFFSET + 3): case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 3):
case FPGA_JTAG_MINOR : // case FPGA_JTAG_MINOR :
case FPGA_SJTAG_MINOR : // case FPGA_SJTAG_MINOR :
case FPGA_AJTAG_MINOR : // case FPGA_AJTAG_MINOR :
if (JTAG_channels[chn].wp > 0) { // anything written? if (JTAG_channels[chn].wp > 0) { // anything written?
res=JTAG_configure (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].wp); res=JTAG_configure (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].wp);
JTAG_resetChannel (chn); JTAG_resetChannel (chn);
if ((res >=0) & (chn == JTAG_MAIN_FPGA)) { if ((res >=0) & (chn == JTAG_MAIN_FPGA)) {
// read FPGA model number/revision and OR it with current state // read FPGA model number/revision and OR it with current state
//fpga_state = (fpga_state & ~0xffff) | (port_csp0_addr[X313__RA__MODEL] & 0xffff); //fpga_state = (fpga_state & ~0xffff) | (port_csp0_addr[X313__RA__MODEL] & 0xffff);
} }
} else JTAG_resetChannel (chn); /// reset initializing in any case: } else JTAG_resetChannel (chn); /// reset initializing in any case:
//if (chn == JTAG_MAIN_FPGA) fpga_state &=~FPGA_STATE_INITIALIZED; //if (chn == JTAG_MAIN_FPGA) fpga_state &=~FPGA_STATE_INITIALIZED;
break; break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0): case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1): case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 1):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2): case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 2):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3): case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 3):
case FPGA_JTAG_BOUNDARY_MINOR : // case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR : // case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR : // case FPGA_AJTAG_BOUNDARY_MINOR :
// "dirty"? Send to JTAG // "dirty"? Send to JTAG
if (JTAG_channels[chn].wp >0) { if (JTAG_channels[chn].wp >0) {
// D(printk("fpga_jtag_release(), JTAG_channels[%d].wp = 0x%x",chn,JTAG_channels[chn].wp)); // D(printk("fpga_jtag_release(), JTAG_channels[%d].wp = 0x%x",chn,JTAG_channels[chn].wp));
JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // size in bits JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // size in bits
} }
JTAG_resetChannel (chn); JTAG_resetChannel (chn);
break; break;
default: return -EINVAL; default: return -EINVAL;
} }
minors[p]=0; minors[p]=0;
JTAG_channels[chn].mode=JTAG_MODE_CLOSED; JTAG_channels[chn].mode=JTAG_MODE_CLOSED;
//D(printk("fpga_jtag_release: done\r\n")); //D(printk("fpga_jtag_release: done\r\n"));
dev_dbg(NULL, "fpga_jtag_release: done\r\n"); dev_dbg(NULL, "fpga_jtag_release: done\r\n");
dev_info(NULL, "fpga_jtag_release: done, res= %d\n",res); dev_info(NULL, "fpga_jtag_release: done, res= %d\n",res);
return (res<0)?res:0; return (res<0)?res:0;
} }
...@@ -450,188 +459,188 @@ static int fpga_jtag_release(struct inode *inode, struct file *filp) { ...@@ -450,188 +459,188 @@ static int fpga_jtag_release(struct inode *inode, struct file *filp) {
//for boundary scan: writing before wp+1 will start EXTEST cycle (either rollover or lseek) //for boundary scan: writing before wp+1 will start EXTEST cycle (either rollover or lseek)
static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t count, loff_t *off) { static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t count, loff_t *off) {
int p = ((int *)file->private_data)[0]; int p = ((int *)file->private_data)[0];
int chn= JTAG_channel(p); int chn= JTAG_channel(p);
size_t size = JTAG_channels[chn].sizew; size_t size = JTAG_channels[chn].sizew;
dev_dbg(NULL, "fpga_jtag_write: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size); dev_dbg(NULL, "fpga_jtag_write: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size);
switch (p) { switch (p) {
case FPGA_JTAG_RESET_MINOR : // same as RAW - do nothing, raw code should do it on it's own case DEV393_MINOR(DEV393_JTAG_RESET) : // same as RAW - do nothing, raw code should do it on it's own
if (count > size) count= size; if (count > size) count= size;
if ((raw_fifo_w_wp+count) > size) { // read tail, then roll over to the head to the total of count if ((raw_fifo_w_wp+count) > size) { // read tail, then roll over to the head to the total of count
if (copy_from_user(&raw_fifo_w[raw_fifo_w_wp],buf,size-raw_fifo_w_wp)) return -EFAULT; // read tail if (copy_from_user(&raw_fifo_w[raw_fifo_w_wp],buf,size-raw_fifo_w_wp)) return -EFAULT; // read tail
if (copy_from_user(&raw_fifo_w[0],&buf[size-raw_fifo_w_wp],count+raw_fifo_w_wp-size)) return -EFAULT; // read head if (copy_from_user(&raw_fifo_w[0],&buf[size-raw_fifo_w_wp],count+raw_fifo_w_wp-size)) return -EFAULT; // read head
} else { } else {
if (copy_from_user(&raw_fifo_w[raw_fifo_w_wp],buf,count)) return -EFAULT; // read count if (copy_from_user(&raw_fifo_w[raw_fifo_w_wp],buf,count)) return -EFAULT; // read count
} }
raw_fifo_w_wp+=count; raw_fifo_w_wp+=count;
if (raw_fifo_w_wp > size) raw_fifo_w_wp -= size; if (raw_fifo_w_wp > size) raw_fifo_w_wp -= size;
JTAG_process_raw(); // send all the received data to JTAG - will cause read fifo to get ~1/2 of the number of bytes written JTAG_process_raw(); // send all the received data to JTAG - will cause read fifo to get ~1/2 of the number of bytes written
break; break;
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1): case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 1):
case (FPGA_SJTAG_MINOR_OFFSET + 2): case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 2):
case (FPGA_SJTAG_MINOR_OFFSET + 3): case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 3):
case FPGA_JTAG_MINOR : // case FPGA_JTAG_MINOR :
case FPGA_SJTAG_MINOR : // case FPGA_SJTAG_MINOR :
case FPGA_AJTAG_MINOR : // read configuration data to buffer // case FPGA_AJTAG_MINOR : // read configuration data to buffer
if (*off > size) return -EFAULT; if (*off > size) return -EFAULT;
if ((*off + count) > size) count= (size - *off); if ((*off + count) > size) count= (size - *off);
if (copy_from_user(&(JTAG_channels[chn].dbuf[*off]),buf,count)) return -EFAULT; if (copy_from_user(&(JTAG_channels[chn].dbuf[*off]),buf,count)) return -EFAULT;
*off+=count; *off+=count;
if (*off > JTAG_channels[chn].wp) JTAG_channels[chn].wp= *off; if (*off > JTAG_channels[chn].wp) JTAG_channels[chn].wp= *off;
break; break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0): case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1): case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 1):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2): case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 2):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3): case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 3):
case FPGA_JTAG_BOUNDARY_MINOR : // case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR : // case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR : // case FPGA_AJTAG_BOUNDARY_MINOR :
if (*off > size) return -EFAULT; if (*off > size) return -EFAULT;
if ((*off + count) > size) count= (size - *off); if ((*off + count) > size) count= (size - *off);
if (*off < JTAG_channels[chn].wp) { if (*off < JTAG_channels[chn].wp) {
// D(printk("fpga_jtag_write(), JTAG_channels[%d].wp = 0x%x",chn, JTAG_channels[chn].wp)); // D(printk("fpga_jtag_write(), JTAG_channels[%d].wp = 0x%x",chn, JTAG_channels[chn].wp));
JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // writing "before" causes EXTEST to fill in boundary scan register JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // writing "before" causes EXTEST to fill in boundary scan register
JTAG_channels[chn].wdirty=0; JTAG_channels[chn].wdirty=0;
} }
if (copy_from_user(&(JTAG_channels[chn].dbuf[*off]),buf,count)) return -EFAULT; if (copy_from_user(&(JTAG_channels[chn].dbuf[*off]),buf,count)) return -EFAULT;
*off+=count; *off+=count;
JTAG_channels[chn].wp= *off; // before rolling over JTAG_channels[chn].wp= *off; // before rolling over
if (*off >= size) { if (*off >= size) {
*off=0; // roll over *off=0; // roll over
} }
JTAG_channels[chn].mode=JTAG_MODE_EXTEST; //should write the last byte before reading - or buffer data will be just lost JTAG_channels[chn].mode=JTAG_MODE_EXTEST; //should write the last byte before reading - or buffer data will be just lost
JTAG_channels[chn].wdirty=1; JTAG_channels[chn].wdirty=1;
break; break;
default: return -EINVAL; default: return -EINVAL;
} }
dev_dbg(NULL, "fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size); dev_dbg(NULL, "fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size);
//D(printk("fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size)); //D(printk("fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size));
return count; return count;
} }
//++++++++++++++++++++++++++++++++++++ read() ++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++ read() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
ssize_t fpga_jtag_read(struct file * file, char * buf, size_t count, loff_t *off) { ssize_t fpga_jtag_read(struct file * file, char * buf, size_t count, loff_t *off) {
int p = ((int *)file->private_data)[0]; int p = ((int *)file->private_data)[0];
int chn= JTAG_channel(p); int chn= JTAG_channel(p);
size_t size = JTAG_channels[chn].sizer; size_t size = JTAG_channels[chn].sizer;
int size_av; // available data int size_av; // available data
dev_dbg(NULL, "fpga_jtag_read: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn,(long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size); dev_dbg(NULL, "fpga_jtag_read: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn,(long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size);
switch (p) { switch (p) {
case FPGA_JTAG_RESET_MINOR : // same as RAW - do nothing, raw code should do it on it's own case DEV393_MINOR(DEV393_JTAG_RESET) : // same as RAW - do nothing, raw code should do it on it's own
size_av=(raw_fifo_r_wp >= raw_fifo_r_rp)?(raw_fifo_r_wp - raw_fifo_r_rp):(size+raw_fifo_r_wp - raw_fifo_r_rp); size_av=(raw_fifo_r_wp >= raw_fifo_r_rp)?(raw_fifo_r_wp - raw_fifo_r_rp):(size+raw_fifo_r_wp - raw_fifo_r_rp);
if (count > size_av) count= size_av; if (count > size_av) count= size_av;
if ((raw_fifo_r_rp+count) > size) { // read tail, then roll over to the head to the total of count if ((raw_fifo_r_rp+count) > size) { // read tail, then roll over to the head to the total of count
if (copy_to_user(buf, &raw_fifo_r[raw_fifo_r_rp],size-raw_fifo_r_rp)) return -EFAULT; // read tail if (copy_to_user(buf, &raw_fifo_r[raw_fifo_r_rp],size-raw_fifo_r_rp)) return -EFAULT; // read tail
if (copy_to_user(&buf[size-raw_fifo_r_rp],&raw_fifo_r[0],count+raw_fifo_r_rp-size)) return -EFAULT; // read head if (copy_to_user(&buf[size-raw_fifo_r_rp],&raw_fifo_r[0],count+raw_fifo_r_rp-size)) return -EFAULT; // read head
} else { } else {
if (copy_to_user(buf,&raw_fifo_w[raw_fifo_w_wp],count)) return -EFAULT; // read count if (copy_to_user(buf,&raw_fifo_w[raw_fifo_w_wp],count)) return -EFAULT; // read count
} }
raw_fifo_r_rp+=count; raw_fifo_r_rp+=count;
if (raw_fifo_r_rp > size) raw_fifo_r_rp -= size; if (raw_fifo_r_rp > size) raw_fifo_r_rp -= size;
break; break;
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix case DEV393_MINOR(DEV393_JTAGS_CONF0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1): case DEV393_MINOR(DEV393_JTAGS_CONF1):
case (FPGA_SJTAG_MINOR_OFFSET + 2): case DEV393_MINOR(DEV393_JTAGS_CONF2):
case (FPGA_SJTAG_MINOR_OFFSET + 3): case DEV393_MINOR(DEV393_JTAGS_CONF3):
case FPGA_JTAG_MINOR : // case FPGA_JTAG_MINOR :
case FPGA_SJTAG_MINOR : // case FPGA_SJTAG_MINOR :
case FPGA_AJTAG_MINOR : // read configuration data to buffer // case FPGA_AJTAG_MINOR : // read configuration data to buffer
if ((JTAG_channels[chn].wp==0) && (JTAG_channels[chn].rp==0)) { // starting from read - get ID if ((JTAG_channels[chn].wp==0) && (JTAG_channels[chn].rp==0)) { // starting from read - get ID
JTAG_channels[chn].mode=JTAG_MODE_RDID; JTAG_channels[chn].mode=JTAG_MODE_RDID;
JTAG_readID (chn, JTAG_channels[chn].dbuf); JTAG_readID (chn, JTAG_channels[chn].dbuf);
} }
if (*off > size) return -EFAULT; if (*off > size) return -EFAULT;
if ((*off + count) > size) count= (size - *off); if ((*off + count) > size) count= (size - *off);
dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size); dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size);
if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT; if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT;
*off+=count; *off+=count;
JTAG_channels[chn].rp= *off; JTAG_channels[chn].rp= *off;
break; break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0): case DEV393_MINOR(DEV393_JTAGS_BSCAN0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1): case DEV393_MINOR(DEV393_JTAGS_BSCAN1):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2): case DEV393_MINOR(DEV393_JTAGS_BSCAN2):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3): case DEV393_MINOR(DEV393_JTAGS_BSCAN3):
case FPGA_JTAG_BOUNDARY_MINOR : // case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR : // case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR : // case FPGA_AJTAG_BOUNDARY_MINOR :
if ((JTAG_channels[chn].mode==JTAG_MODE_EXTEST) && (JTAG_channels[chn].wdirty || (*off < JTAG_channels[chn].rp))) { if ((JTAG_channels[chn].mode==JTAG_MODE_EXTEST) && (JTAG_channels[chn].wdirty || (*off < JTAG_channels[chn].rp))) {
JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsr); // writing last byte causes EXTEST to fill in boundary scan register JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsr); // writing last byte causes EXTEST to fill in boundary scan register
JTAG_channels[chn].wdirty=0; JTAG_channels[chn].wdirty=0;
} }
// (re)-read capture pins if it was a roll-over or the first access after open // (re)-read capture pins if it was a roll-over or the first access after open
if ((JTAG_channels[chn].mode!=JTAG_MODE_EXTEST) && ((*off < JTAG_channels[chn].rp) || (JTAG_channels[chn].mode==JTAG_MODE_BOUNDARY))) { if ((JTAG_channels[chn].mode!=JTAG_MODE_EXTEST) && ((*off < JTAG_channels[chn].rp) || (JTAG_channels[chn].mode==JTAG_MODE_BOUNDARY))) {
JTAG_CAPTURE (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsr); JTAG_CAPTURE (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsr);
} }
if (*off > size) return -EFAULT; if (*off > size) return -EFAULT;
if ((*off + count) > size) count= (size - *off); if ((*off + count) > size) count= (size - *off);
dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size); dev_dbg(NULL, "fpga_jtag_read_01: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size);
if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT; if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT;
*off+=count; *off+=count;
JTAG_channels[chn].rp= *off; // before rolling over JTAG_channels[chn].rp= *off; // before rolling over
if (*off >= size) { if (*off >= size) {
*off=0; // roll over *off=0; // roll over
} }
if (JTAG_channels[chn].mode == JTAG_MODE_BOUNDARY) JTAG_channels[chn].mode=JTAG_MODE_SAMPLE; //should write the last byte before reading - or buffer data will be just lost if (JTAG_channels[chn].mode == JTAG_MODE_BOUNDARY) JTAG_channels[chn].mode=JTAG_MODE_SAMPLE; //should write the last byte before reading - or buffer data will be just lost
break; break;
default: return -EINVAL; default: return -EINVAL;
} }
dev_dbg(NULL, "fpga_jtag_read_end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x, mode=%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size, JTAG_channels[chn].mode); dev_dbg(NULL, "fpga_jtag_read_end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, rp=%lx,size=0x%x, mode=%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].rp, (int) size, JTAG_channels[chn].mode);
return count; return count;
} }
//++++++++++++++++++++++++++++++++++++ lseek() ++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++ lseek() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
static loff_t fpga_jtag_lseek(struct file * file, loff_t offset, int orig) { static loff_t fpga_jtag_lseek(struct file * file, loff_t offset, int orig) {
/* /*
* orig 0: position from begning of * orig 0: position from begning of
* orig 1: relative from current position * orig 1: relative from current position
* orig 2: position from last address * orig 2: position from last address
*/ */
int p = ((int *)file->private_data)[0]; int p = ((int *)file->private_data)[0];
int chn= JTAG_channel(p); int chn= JTAG_channel(p);
size_t size; size_t size;
if (chn==JTAG_RAW) { if (chn==JTAG_RAW) {
size=raw_fifo_r_wp-raw_fifo_r_rp; size=raw_fifo_r_wp-raw_fifo_r_rp;
if (size<0) size+=FJTAG_RAW_RSIZE; if (size<0) size+=FJTAG_RAW_RSIZE;
} else size = JTAG_channels[chn].sizew; } else size = JTAG_channels[chn].sizew;
if (JTAG_channels[chn].mode == JTAG_MODE_RDID) size = JTAG_channels[chn].sizer; if (JTAG_channels[chn].mode == JTAG_MODE_RDID) size = JTAG_channels[chn].sizer;
dev_dbg(NULL, "fpga_jtag_lseek, fsize= 0x%x\n", (int) size); dev_dbg(NULL, "fpga_jtag_lseek, fsize= 0x%x\n", (int) size);
switch (orig) { switch (orig) {
case 0: case 0:
file->f_pos = offset; file->f_pos = offset;
break; break;
case 1: case 1:
file->f_pos += offset; file->f_pos += offset;
break; break;
case 2: case 2:
file->f_pos = size + offset; file->f_pos = size + offset;
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
/* truncate position */ /* truncate position */
if (file->f_pos < 0) { if (file->f_pos < 0) {
file->f_pos = 0; file->f_pos = 0;
return (-EOVERFLOW); return (-EOVERFLOW);
} }
if (file->f_pos > size) { if (file->f_pos > size) {
file->f_pos = size; file->f_pos = size;
return (-EOVERFLOW); return (-EOVERFLOW);
} }
dev_dbg(NULL,"fpga_jtag_lseek, file->f_pos= 0x%x\n", (int) file->f_pos); dev_dbg(NULL,"fpga_jtag_lseek, file->f_pos= 0x%x\n", (int) file->f_pos);
return (file->f_pos); return (file->f_pos);
} }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Initialize GPIOs of the CPU to access JTAG/programming of the main FPGA // Initialize GPIOs of the CPU to access JTAG/programming of the main FPGA
void initPortC(void) { void initPortC(void) {
// connect 8 lower bits of port C to GPIO, disconnect from IOP // connect 8 lower bits of port C to GPIO, disconnect from IOP
unsigned long tmp; unsigned long tmp;
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
reg_pinmux_rw_pc_iop pinmux_c_iop; reg_pinmux_rw_pc_iop pinmux_c_iop;
...@@ -650,98 +659,98 @@ void initPortC(void) { ...@@ -650,98 +659,98 @@ void initPortC(void) {
pinmux_c_gio = REG_TYPE_CONV(reg_pinmux_rw_pc_gio, unsigned long, tmp); pinmux_c_gio = REG_TYPE_CONV(reg_pinmux_rw_pc_gio, unsigned long, tmp);
REG_WR(pinmux, regi_pinmux, rw_pc_gio, pinmux_c_gio); REG_WR(pinmux, regi_pinmux, rw_pc_gio, pinmux_c_gio);
// now set data of port C pins (static pc_dout) // now set data of port C pins (static pc_dout)
pc_dout = REG_RD(gio, regi_gio, rw_pc_dout); pc_dout = REG_RD(gio, regi_gio, rw_pc_dout);
pc_dout.data &= ~0xff; pc_dout.data &= ~0xff;
pc_dout.data |= PC_DOUT_INITIAL; pc_dout.data |= PC_DOUT_INITIAL;
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout); REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
// now set directions of port C pins // now set directions of port C pins
pc_oe = REG_RD(gio, regi_gio, rw_pc_oe); pc_oe = REG_RD(gio, regi_gio, rw_pc_oe);
pc_oe.oe &= ~( (1 << FPGAJTAG_TDO_BIT) | pc_oe.oe &= ~( (1 << FPGAJTAG_TDO_BIT) |
(1 << FPGAJTAG_DONE_BIT) | (1 << FPGAJTAG_DONE_BIT) |
(1 << FPGAJTAG_RSTBTN_BIT)); (1 << FPGAJTAG_RSTBTN_BIT));
pc_oe.oe |= ( (1 << FPGAJTAG_TDI_BIT) | pc_oe.oe |= ( (1 << FPGAJTAG_TDI_BIT) |
(1 << FPGAJTAG_TMS_BIT) | (1 << FPGAJTAG_TMS_BIT) |
(1 << FPGAJTAG_TCK_BIT) | (1 << FPGAJTAG_TCK_BIT) |
(1 << FPGAJTAG_PGM_BIT)); (1 << FPGAJTAG_PGM_BIT));
REG_WR(gio, regi_gio, rw_pc_oe, pc_oe); REG_WR(gio, regi_gio, rw_pc_oe, pc_oe);
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
} }
inline u32 prep_sensio_status(int sens_num) inline u32 prep_sensio_status(int sens_num)
{ {
x393_status_sens_io_t stat; x393_status_sens_io_t stat;
x393_status_ctrl_t stat_ctrl; x393_status_ctrl_t stat_ctrl;
stat_ctrl.d32 = 0; stat_ctrl.d32 = 0;
stat = x393_sensio_status(sens_num); stat = x393_sensio_status(sens_num);
stat_ctrl.seq_num = stat.seq_num + 1; stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 1; stat_ctrl.mode = 1;
set_x393_sensio_status_cntrl(stat_ctrl, sens_num); set_x393_sensio_status_cntrl(stat_ctrl, sens_num);
// dev_dbg(NULL, "set seq_num = %d, chn = %d", stat_ctrl.seq_num, sens_num); // dev_dbg(NULL, "set seq_num = %d, chn = %d", stat_ctrl.seq_num, sens_num);
return stat_ctrl.seq_num; // Sequence number to expect (wait for) with return data return stat_ctrl.seq_num; // Sequence number to expect (wait for) with return data
} }
inline x393_status_sens_io_t wait_sensio_status(int chn, u32 seq_num) // reducing number of hardware reads inline x393_status_sens_io_t wait_sensio_status(int chn, u32 seq_num) // reducing number of hardware reads
{ {
int i; int i;
int ret = 0; int ret = 0;
x393_status_sens_io_t stat; x393_status_sens_io_t stat;
// dev_dbg(NULL, "waiting for seq_num = %d, chn = %d", seq_num, chn); // dev_dbg(NULL, "waiting for seq_num = %d, chn = %d", seq_num, chn);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
stat = x393_sensio_status(chn & 3); // sens_num); stat = x393_sensio_status(chn & 3); // sens_num);
if (stat.seq_num == seq_num) { if (stat.seq_num == seq_num) {
ret = -1; ret = -1;
if (i) if (i)
dev_dbg(NULL, "seq_num = %d received after %d wait cycles", seq_num, i); dev_dbg(NULL, "seq_num = %d received after %d wait cycles", seq_num, i);
break; break;
} }
} }
// return ret; // return ret;
return stat; return stat;
} }
inline u32 read_tdo(int sens_num) inline u32 read_tdo(int sens_num)
{ {
x393_status_sens_io_t stat; x393_status_sens_io_t stat;
x393_status_ctrl_t stat_ctrl; x393_status_ctrl_t stat_ctrl;
int i; int i;
stat_ctrl.d32 = 0; stat_ctrl.d32 = 0;
stat = x393_sensio_status(sens_num); stat = x393_sensio_status(sens_num);
stat_ctrl.seq_num = stat.seq_num + 1; stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 1; stat_ctrl.mode = 1;
set_x393_sensio_status_cntrl(stat_ctrl, sens_num); set_x393_sensio_status_cntrl(stat_ctrl, sens_num);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
stat = x393_sensio_status(sens_num & 3); // sens_num); stat = x393_sensio_status(sens_num & 3); // sens_num);
if (likely(stat.seq_num == stat_ctrl.seq_num)) { if (likely(stat.seq_num == stat_ctrl.seq_num)) {
return stat.xfpgatdo; return stat.xfpgatdo;
} }
} }
dev_err(NULL,"read_tdo(%d): failed to get expected seq_num in 10 cycles, expected = 0x%x, got 0x%x\n",sens_num,stat_ctrl.seq_num, stat.seq_num); dev_err(NULL,"read_tdo(%d): failed to get expected seq_num in 10 cycles, expected = 0x%x, got 0x%x\n",sens_num,stat_ctrl.seq_num, stat.seq_num);
return stat.xfpgatdo; return stat.xfpgatdo;
} }
// read last 8 TDO bits, shifted at rising edge of TCL // read last 8 TDO bits, shifted at rising edge of TCL
inline u32 read_tdo_byte(int sens_num) inline u32 read_tdo_byte(int sens_num)
{ {
x393_status_sens_io_t stat; x393_status_sens_io_t stat;
x393_status_ctrl_t stat_ctrl; x393_status_ctrl_t stat_ctrl;
int i; int i;
stat_ctrl.d32 = 0; stat_ctrl.d32 = 0;
stat = x393_sensio_status(sens_num); stat = x393_sensio_status(sens_num);
stat_ctrl.seq_num = stat.seq_num + 1; stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 1; stat_ctrl.mode = 1;
set_x393_sensio_status_cntrl(stat_ctrl, sens_num); set_x393_sensio_status_cntrl(stat_ctrl, sens_num);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
stat = x393_sensio_status(sens_num & 3); // sens_num); stat = x393_sensio_status(sens_num & 3); // sens_num);
if (likely(stat.seq_num == stat_ctrl.seq_num)) { if (likely(stat.seq_num == stat_ctrl.seq_num)) {
return stat.xfpgatdo_byte; return stat.xfpgatdo_byte;
} }
} }
dev_err(NULL,"read_tdo_byte(%d): failed to get expected seq_num in 10 cycles, expected = 0x%x, got 0x%x\n",sens_num,stat_ctrl.seq_num, stat.seq_num); dev_err(NULL,"read_tdo_byte(%d): failed to get expected seq_num in 10 cycles, expected = 0x%x, got 0x%x\n",sens_num,stat_ctrl.seq_num, stat.seq_num);
return stat.xfpgatdo_byte; return stat.xfpgatdo_byte;
} }
...@@ -749,167 +758,167 @@ inline u32 read_tdo_byte(int sens_num) ...@@ -749,167 +758,167 @@ inline u32 read_tdo_byte(int sens_num)
// set FPGA in programming/JTAG mode (only for sensor board) // set FPGA in programming/JTAG mode (only for sensor board)
// NOP for the main board FPGA configuration // NOP for the main board FPGA configuration
void set_pgm_mode (int chn, int en) { void set_pgm_mode (int chn, int en) {
u32 seq_num; u32 seq_num;
x393_sensio_jtag_t data; x393_sensio_jtag_t data;
dev_dbg(NULL, "set_pgm_mode (%d,%d)\n",chn,en); dev_dbg(NULL, "set_pgm_mode (%d,%d)\n",chn,en);
switch (chn >> 2) { switch (chn >> 2) {
case JTAG_SENSOR_FPGA: case JTAG_SENSOR_FPGA:
//port_csp0_addr[X313_WA_SENSFPGA] = (en ? (3 << SFPGA_PGMEN_BIT): (SFPGA_RD_SENSPGMPIN | (2 << SFPGA_PGMEN_BIT))) | (2 << SFPGA_TCK_BIT); // turn off TCK (if not turned off already) //port_csp0_addr[X313_WA_SENSFPGA] = (en ? (3 << SFPGA_PGMEN_BIT): (SFPGA_RD_SENSPGMPIN | (2 << SFPGA_PGMEN_BIT))) | (2 << SFPGA_TCK_BIT); // turn off TCK (if not turned off already)
/* ? SFPGA_RD_SENSPGMPIN */ /* ? SFPGA_RD_SENSPGMPIN */
data.d32 = 0; data.d32 = 0;
data.pgmen = (en) ? 1 : 0; data.pgmen = (en) ? 1 : 0;
data.pgmen_set = 1; data.pgmen_set = 1;
data.tck = 0; data.tck = 0;
data.tck_set = 1; data.tck_set = 1;
/* check status register */ /* check status register */
x393_sensio_jtag(data, chn & 3); // sens_num); x393_sensio_jtag(data, chn & 3); // sens_num);
/* wait for status register update */ /* wait for status register update */
wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ; // Not needed here wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ; // Not needed here
break; break;
} }
udelay (2); udelay (2);
} }
void set_pgm (int chn, int pgmon) { void set_pgm (int chn, int pgmon) {
u32 seq_num; u32 seq_num;
x393_sensio_jtag_t data; x393_sensio_jtag_t data;
dev_dbg(NULL, "set_pgm (%d,%d)\n",chn,pgmon); dev_dbg(NULL, "set_pgm (%d,%d)\n",chn,pgmon);
switch (chn >> 2) { switch (chn >> 2) {
case JTAG_MAIN_FPGA: case JTAG_MAIN_FPGA:
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
if (pgmon) pc_dout.data &= ~0x80; // set PGM low (active) if (pgmon) pc_dout.data &= ~0x80; // set PGM low (active)
else pc_dout.data |= 0x80; // set PGM high (inactive) else pc_dout.data |= 0x80; // set PGM high (inactive)
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout); // extend low? REG_WR(gio, regi_gio, rw_pc_dout, pc_dout); // extend low?
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
break; break;
case JTAG_SENSOR_FPGA: case JTAG_SENSOR_FPGA:
//port_csp0_addr[X313_WA_SENSFPGA] = (2 | (pgmon & 1)) << SFPGA_PROG_BIT; //port_csp0_addr[X313_WA_SENSFPGA] = (2 | (pgmon & 1)) << SFPGA_PROG_BIT;
data.prog= pgmon & 1; data.prog= pgmon & 1;
data.prog_set = 1; data.prog_set = 1;
x393_sensio_jtag(data, chn >> 2); // sens_num); x393_sensio_jtag(data, chn >> 2); // sens_num);
break; break;
case JTAG_AUX_FPGA: case JTAG_AUX_FPGA:
break; break;
} }
udelay (2); udelay (2);
} }
int read_done (int chn) { int read_done (int chn) {
x393_status_sens_io_t stat; x393_status_sens_io_t stat;
x393_sensio_jtag_t data; x393_sensio_jtag_t data;
switch (chn >> 2) { switch (chn >> 2) {
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
case JTAG_MAIN_FPGA: case JTAG_MAIN_FPGA:
return ((((REG_RD(gio, regi_gio, r_pc_din)).data & 0x20)==0) ? 0 : 1 ); return ((((REG_RD(gio, regi_gio, r_pc_din)).data & 0x20)==0) ? 0 : 1 );
#endif //* TEST_DISABLE_CODE */ #endif //* TEST_DISABLE_CODE */
case JTAG_SENSOR_FPGA: case JTAG_SENSOR_FPGA:
//port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_DONE; //port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_DONE;
//udelay (1); //udelay (1);
//return (port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1 ; //return (port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1 ;
stat = wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ; stat = wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ;
return stat.xfpgadone; return stat.xfpgadone;
case JTAG_AUX_FPGA: case JTAG_AUX_FPGA:
return 0; return 0;
} }
return 0; // just in case return 0; // just in case
} }
// send 1..8 bits through JTAG // send 1..8 bits through JTAG
int jtag_send (int chn, int tms, int len, int d) { int jtag_send (int chn, int tms, int len, int d) {
int sens_num = chn & 3; int sens_num = chn & 3;
x393_sensio_jtag_t data; x393_sensio_jtag_t data;
x393_status_sens_io_t stat; x393_status_sens_io_t stat;
// u32 seq_num; // u32 seq_num;
int i, bm = 0; //,m; int i, bm = 0; //,m;
int r=0; int r=0;
int d0; int d0;
i = len & 7; i = len & 7;
if (i==0) i=8; if (i==0) i=8;
d &= 0xff; d &= 0xff;
d0=d; d0=d;
dev_dbg(NULL, "jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\r\n", chn, tms,len,d); dev_dbg(NULL, "jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\r\n", chn, tms,len,d);
switch (chn >> 2) { switch (chn >> 2) {
case JTAG_MAIN_FPGA: case JTAG_MAIN_FPGA:
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
pc_dout.data &= ~0x0e; pc_dout.data &= ~0x0e;
pc_dout.data |= (tms & 1) << FPGAJTAG_TMS_BIT; pc_dout.data |= (tms & 1) << FPGAJTAG_TMS_BIT;
for (;i>0;i--){ for (;i>0;i--){
r= (r<<1)+ ((REG_RD(gio, regi_gio, r_pc_din)).data & 1); // read TDO before TCK pulse r= (r<<1)+ ((REG_RD(gio, regi_gio, r_pc_din)).data & 1); // read TDO before TCK pulse
pc_dout.data = (pc_dout.data & ~0x0a) | (((d<<=1)>>7) & 2); pc_dout.data = (pc_dout.data & ~0x0a) | (((d<<=1)>>7) & 2);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout); REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data |= (1 << FPGAJTAG_TCK_BIT); pc_dout.data |= (1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout); REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data &= ~(1 << FPGAJTAG_TCK_BIT); pc_dout.data &= ~(1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout); REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
} }
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
break; break;
case JTAG_SENSOR_FPGA: case JTAG_SENSOR_FPGA:
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_TDO; port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_TDO;
udelay (1); // wait MUX udelay (1); // wait MUX
for (;i>0;i--){ for (;i>0;i--){
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay
port_csp0_addr[X313_WA_SENSFPGA] = ((2 | (tms & 1)) << SFPGA_TMS_BIT) | port_csp0_addr[X313_WA_SENSFPGA] = ((2 | (tms & 1)) << SFPGA_TMS_BIT) |
(((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_BIT) | (((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_BIT) |
(2 << SFPGA_TCK_BIT) ; (2 << SFPGA_TCK_BIT) ;
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay
port_csp0_addr[X313_WA_SENSFPGA] = (3 << SFPGA_TCK_BIT); // TCK=1 port_csp0_addr[X313_WA_SENSFPGA] = (3 << SFPGA_TCK_BIT); // TCK=1
r= (r<<1)+ ((port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1); // read TDO before TCK pulse r= (r<<1)+ ((port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1); // read TDO before TCK pulse
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay
} }
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
data.d32 = 0; data.d32 = 0;
data.tck_set = 1; data.tck_set = 1;
data.tms_set = 1; data.tms_set = 1;
data.tdi_set = 1; data.tdi_set = 1;
dev_dbg(NULL, "jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\n", chn, tms,len,d); dev_dbg(NULL, "jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\n", chn, tms,len,d);
for ( ; i > 0; i--) { for ( ; i > 0; i--) {
/* TCK = 0 - just a delay; is it really needed? */ /* TCK = 0 - just a delay; is it really needed? */
data.tck = 0; data.tck = 0;
data.tms = tms & 1; data.tms = tms & 1;
data.tdi = ((d <<= 1) >> 8) & 1; data.tdi = ((d <<= 1) >> 8) & 1;
data.tck = 0; data.tck = 0;
x393_sensio_jtag(data, sens_num); x393_sensio_jtag(data, sens_num);
/* repeat writel - just a delay; is it really needed? */ /* repeat writel - just a delay; is it really needed? */
// x393_sensio_jtag(data, sens_num); // x393_sensio_jtag(data, sens_num);
/* read TDO before TCK pulse */ /* read TDO before TCK pulse */
#ifndef PARALLEL_JTAG #ifndef PARALLEL_JTAG
r = (r << 1) + read_tdo(sens_num); // may need to read twice to increase delay? r = (r << 1) + read_tdo(sens_num); // may need to read twice to increase delay?
#else #else
bm = (bm <<1 ) | 1; bm = (bm <<1 ) | 1;
#endif #endif
data.tck = 1; data.tck = 1;
x393_sensio_jtag(data, sens_num); // keep other signals, set TCK == 1 x393_sensio_jtag(data, sens_num); // keep other signals, set TCK == 1
// x393_sensio_jtag(data, sens_num); // repeat if delay will be needed to increase length of the TCK signal // x393_sensio_jtag(data, sens_num); // repeat if delay will be needed to increase length of the TCK signal
data.tck = 0; data.tck = 0;
// x393_sensio_jtag(data, sens_num); // x393_sensio_jtag(data, sens_num);
} }
x393_sensio_jtag(data, sens_num); x393_sensio_jtag(data, sens_num);
#ifdef PARALLEL_JTAG #ifdef PARALLEL_JTAG
r = read_tdo_byte(sens_num) & bm; r = read_tdo_byte(sens_num) & bm;
#endif #endif
// x393_sensio_jtag(data, sens_num); // x393_sensio_jtag(data, sens_num);
dev_dbg(NULL, " ---> %02x\n", r); dev_dbg(NULL, " ---> %02x\n", r);
break; break;
case JTAG_AUX_FPGA: case JTAG_AUX_FPGA:
break; break;
} }
return r; return r;
} }
//==================================== //====================================
...@@ -920,272 +929,272 @@ int jtag_send (int chn, int tms, int len, int d) { ...@@ -920,272 +929,272 @@ int jtag_send (int chn, int tms, int len, int d) {
// send/receive bits, raising TMS during the last one (if last==1). If number of bits are not multiple of 8, lower bits of the last byte will not be used. // send/receive bits, raising TMS during the last one (if last==1). If number of bits are not multiple of 8, lower bits of the last byte will not be used.
int jtag_write_bits (int chn, int jtag_write_bits (int chn,
unsigned char *buf, // data to write unsigned char *buf, // data to write
int len, // number of bits to write int len, // number of bits to write
int check, // compare readback data with previously written, abort on mismatch int check, // compare readback data with previously written, abort on mismatch
int last, // output last bit with TMS=1 int last, // output last bit with TMS=1
int prev[2]) // if null - don't use int prev[2]) // if null - don't use
{ {
int sens_num = chn & 3; int sens_num = chn & 3;
int i,j; int i,j;
int r = 0; int r = 0;
int bm = 0; int bm = 0;
int d,d0; int d,d0;
// u32 seq_num; // u32 seq_num;
x393_status_sens_io_t stat; x393_status_sens_io_t stat;
x393_sensio_jtag_t data; x393_sensio_jtag_t data;
dev_dbg(NULL, "jtag_write_bits(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\r\n", (int) chn, (int) buf, len, check, last); dev_dbg(NULL, "jtag_write_bits(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\r\n", (int) chn, (int) buf, len, check, last);
switch (chn >> 2) { switch (chn >> 2) {
case JTAG_MAIN_FPGA: //TODO: save some cycles like for FPGA_SJTAG_MINOR case JTAG_MAIN_FPGA: //TODO: save some cycles like for FPGA_SJTAG_MINOR
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
for (i=0; len>0;i++) { for (i=0; len>0;i++) {
pc_dout.data &= ~0x0e; pc_dout.data &= ~0x0e;
d0=(d=buf[i]); d0=(d=buf[i]);
for (j=0;j<8;j++) { for (j=0;j<8;j++) {
//D(printk("i=%x, j=%x, len=%x, d=%x ",i,j,len,d)); //D(printk("i=%x, j=%x, len=%x, d=%x ",i,j,len,d));
if (len>0) { if (len>0) {
r= (r<<1)+ ((REG_RD(gio, regi_gio, r_pc_din)).data & 1); r= (r<<1)+ ((REG_RD(gio, regi_gio, r_pc_din)).data & 1);
if ((len==1) && last) pc_dout.data = (pc_dout.data & ~0x0a) | (((d<<=1)>>7) & 2) | (1 << FPGAJTAG_TMS_BIT); if ((len==1) && last) pc_dout.data = (pc_dout.data & ~0x0a) | (((d<<=1)>>7) & 2) | (1 << FPGAJTAG_TMS_BIT);
else pc_dout.data = (pc_dout.data & ~0x0a) | (((d<<=1)>>7) & 2); else pc_dout.data = (pc_dout.data & ~0x0a) | (((d<<=1)>>7) & 2);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout); REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data |= (1 << FPGAJTAG_TCK_BIT); pc_dout.data |= (1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout); REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data &= ~(1 << FPGAJTAG_TCK_BIT); pc_dout.data &= ~(1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout); REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
} else r= (r<<1); } else r= (r<<1);
len--; len--;
//D(printk(", r=%x\r\n",r)); //D(printk(", r=%x\r\n",r));
} }
buf[i]=r; // read back in-place buf[i]=r; // read back in-place
if (check && ((r ^ (prev[1] >> 24)) & 0xff)) { if (check && ((r ^ (prev[1] >> 24)) & 0xff)) {
return -((r & 0xff) | ((i+1) << 8)); //readback mismatch return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
} }
if (prev) { if (prev) {
// prev64= (prev64<<8) | ((prev32>>24) & 0xff); // prev64= (prev64<<8) | ((prev32>>24) & 0xff);
// prev32= (prev32<<8) | (d0 & 0xff); // prev32= (prev32<<8) | (d0 & 0xff);
prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 0xff); prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 0xff);
prev[0]= (prev[0]<<8) | (d0 & 0xff); prev[0]= (prev[0]<<8) | (d0 & 0xff);
} }
} }
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
break; break;
case JTAG_SENSOR_FPGA: case JTAG_SENSOR_FPGA:
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_TDO; // just in case, it should be in that mode when calling jtag_write_bits() port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_TDO; // just in case, it should be in that mode when calling jtag_write_bits()
udelay (1); // wait MUX udelay (1); // wait MUX
for (i=0; len>0;i++) { for (i=0; len>0;i++) {
d0=(d=buf[i]); d0=(d=buf[i]);
for (j=0;j<8;j++) { for (j=0;j<8;j++) {
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay
if (len>0) { if (len>0) {
if ((len==1) && last) port_csp0_addr[X313_WA_SENSFPGA] = if ((len==1) && last) port_csp0_addr[X313_WA_SENSFPGA] =
(3 << SFPGA_TMS_BIT) | (3 << SFPGA_TMS_BIT) |
(((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_BIT) | (((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_BIT) |
(2 << SFPGA_TMS_BIT) | (2 << SFPGA_TMS_BIT) |
(2 << SFPGA_TCK_BIT) ; (2 << SFPGA_TCK_BIT) ;
else port_csp0_addr[X313_WA_SENSFPGA] = else port_csp0_addr[X313_WA_SENSFPGA] =
(((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_BIT) | (((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_BIT) |
(2 << SFPGA_TMS_BIT) | (2 << SFPGA_TMS_BIT) |
(2 << SFPGA_TCK_BIT) ; (2 << SFPGA_TCK_BIT) ;
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay
port_csp0_addr[X313_WA_SENSFPGA] = (3 << SFPGA_TCK_BIT); // TCK=1 port_csp0_addr[X313_WA_SENSFPGA] = (3 << SFPGA_TCK_BIT); // TCK=1
// add delays here if long cable? // add delays here if long cable?
r= ((r<<1)+ ((port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1)); // read TDO before TCK pulse r= ((r<<1)+ ((port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1)); // read TDO before TCK pulse
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay
} else r= (r<<1); } else r= (r<<1);
len--; len--;
} }
buf[i]=r; // read back in-place buf[i]=r; // read back in-place
if (check && ((r ^ (prev[1]>>24)) & 0xff)) { if (check && ((r ^ (prev[1]>>24)) & 0xff)) {
return -((r & 0xff) | ((i+1) << 8)); //readback mismatch return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
} }
if (prev) { if (prev) {
// prev64= (prev64<<8) | ((prev32>>24) & 0xff); // prev64= (prev64<<8) | ((prev32>>24) & 0xff);
// prev32= (prev32<<8) | (d0 & 0xff); // prev32= (prev32<<8) | (d0 & 0xff);
prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 0xff); prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 0xff);
prev[0]= (prev[0]<<8) | (d0 & 0xff); prev[0]= (prev[0]<<8) | (d0 & 0xff);
} }
} }
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
// Can be done once // Can be done once
data.d32 = 0; data.d32 = 0;
data.tck_set = 1; data.tck_set = 1;
data.tms_set = 1; data.tms_set = 1;
data.tdi_set = 1; data.tdi_set = 1;
for (i = 0; len > 0; i++) { for (i = 0; len > 0; i++) {
d0 = (d = buf[i]); d0 = (d = buf[i]);
dev_dbg(NULL,"jtag_write_bits(), i=0x%x ", i); dev_dbg(NULL,"jtag_write_bits(), i=0x%x ", i);
bm = 0; bm = 0;
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
if (len > 0) { if (len > 0) {
data.tms = (len == 1 && last)? 1:0 ; data.tms = (len == 1 && last)? 1:0 ;
data.tdi = ((d <<= 1) >> 8) & 1; data.tdi = ((d <<= 1) >> 8) & 1;
data.tck = 0; data.tck = 0;
x393_sensio_jtag(data, sens_num); x393_sensio_jtag(data, sens_num);
#ifndef PARALLEL_JTAG #ifndef PARALLEL_JTAG
r = (r << 1) + read_tdo(sens_num); r = (r << 1) + read_tdo(sens_num);
#else #else
bm = (bm <<1 ) | 1; bm = (bm <<1 ) | 1;
#endif #endif
data.tck = 1; data.tck = 1;
x393_sensio_jtag(data, sens_num); x393_sensio_jtag(data, sens_num);
data.tck = 0; data.tck = 0;
x393_sensio_jtag(data, sens_num); x393_sensio_jtag(data, sens_num);
} else { } else {
r <<= 1; r <<= 1;
} }
len--; len--;
} }
#ifdef PARALLEL_JTAG #ifdef PARALLEL_JTAG
r = read_tdo_byte(sens_num) & bm; r = read_tdo_byte(sens_num) & bm;
if (unlikely(len < 0)){ if (unlikely(len < 0)){
r <<= -len; r <<= -len;
} }
#endif #endif
buf[i] = r; buf[i] = r;
dev_dbg(NULL," ===> %02x\n", r); dev_dbg(NULL," ===> %02x\n", r);
if (check && ((r ^ (prev[1]>>24)) & 0xff)) { if (check && ((r ^ (prev[1]>>24)) & 0xff)) {
return -((r & 0xff) | ((i+1) << 8)); //readback mismatch return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
} }
if (prev) { if (prev) {
prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 0xff); prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 0xff);
prev[0]= (prev[0]<<8) | (d0 & 0xff); prev[0]= (prev[0]<<8) | (d0 & 0xff);
} }
} }
break; break;
case JTAG_AUX_FPGA: case JTAG_AUX_FPGA:
break; break;
} }
return 0; return 0;
} }
int JTAG_configure (int chn, unsigned char * buf, int len) { int JTAG_configure (int chn, unsigned char * buf, int len) {
int datastart, i, j ,r; int datastart, i, j ,r;
//static int prev32; //static int prev32;
//static int prev64; //static int prev64;
int prev[2]; int prev[2];
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
unsigned long flags; unsigned long flags;
#endif #endif
const unsigned char sync[]={0xff,0xff,0xff,0xff,0xaa,0x99,0x55,0x66}; const unsigned char sync[]={0xff,0xff,0xff,0xff,0xaa,0x99,0x55,0x66};
int skipvfy=8; int skipvfy=8;
dev_dbg(NULL, "JTAG_configure: chn=%x, wp=0x%x, rp=0x%x, len=0x%x\r\n",chn, JTAG_channels[chn].wp, JTAG_channels[chn].rp, len); dev_dbg(NULL, "JTAG_configure: chn=%x, wp=0x%x, rp=0x%x, len=0x%x\r\n",chn, JTAG_channels[chn].wp, JTAG_channels[chn].rp, len);
// all the programming goes here... // all the programming goes here...
// find sync: // find sync:
datastart=-1; datastart=-1;
for (i=0;i<(FJTAG_MAX_HEAD-8);i++) { for (i=0;i<(FJTAG_MAX_HEAD-8);i++) {
j=0; j=0;
while ((j<8) && (buf[i+j]==sync[j])) j++; while ((j<8) && (buf[i+j]==sync[j])) j++;
if (j==8) { if (j==8) {
datastart=i; datastart=i;
break; break;
}
} }
} if (datastart<0) {
if (datastart<0) { dev_err(NULL,"Bitstream not found - bad file\r\n");
dev_err(NULL,"Bitstream not found - bad file\r\n"); return -EFAULT;
return -EFAULT; }
} // check for right bitstream length
// check for right bitstream length if ((len-datastart)!=(XC3S1200E_BITSIZE>>3)) {
if ((len-datastart)!=(XC3S1200E_BITSIZE>>3)) { dev_err(NULL,"Wrong bitstream size - XC3S1200E has bitstream of %d bits (%d bytes)\n",XC3S1200E_BITSIZE,XC3S1200E_BITSIZE>>3);
dev_err(NULL,"Wrong bitstream size - XC3S1200E has bitstream of %d bits (%d bytes)\n",XC3S1200E_BITSIZE,XC3S1200E_BITSIZE>>3); dev_err(NULL,"header size - %d, data size - %d\r\n",datastart, len-datastart);
dev_err(NULL,"header size - %d, data size - %d\r\n",datastart, len-datastart); return -EFAULT;
return -EFAULT; }
} // enable programmimg mode (nop for the 10353 FPGA)
// enable programmimg mode (nop for the 10353 FPGA) set_pgm_mode(chn, 1);
set_pgm_mode(chn, 1); // reset device
// reset device set_pgm (chn, 1);
set_pgm (chn, 1); //udelay (1000); // needed?
//udelay (1000); // needed? mdelay(1);
mdelay(1); set_pgm (chn, 0);
set_pgm (chn, 0); // wait INIT over - no init connected, just wait >2ms
// wait INIT over - no init connected, just wait >2ms //udelay (2500);
//udelay (2500); mdelay(3);
mdelay(3); //*************************** NOW DISABLE INTERRUPS FOR THE WHOLE PROGRAMMING CYCLE ***********************
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE PROGRAMMING CYCLE *********************** //D( udelay (100000);printk("JTAG_configure(): IRQ off!\r\n"); udelay (100000););
//D( udelay (100000);printk("JTAG_configure(): IRQ off!\r\n"); udelay (100000);); D( mdelay (100);printk("JTAG_configure(): IRQ off!\r\n"); mdelay (100););
D( mdelay (100);printk("JTAG_configure(): IRQ off!\r\n"); mdelay (100););
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
local_irq_save(flags); local_irq_save(flags);
//local_irq_disable(); //local_irq_disable();
#endif #endif
// prepare JTAG // prepare JTAG
jtag_send(chn, 1, 5, 0 ); //step 1 - set Test-Logic-Reset state jtag_send(chn, 1, 5, 0 ); //step 1 - set Test-Logic-Reset state
jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state
jtag_send(chn, 1, 2, 0 ); //step 3 - set SELECT-IR state jtag_send(chn, 1, 2, 0 ); //step 3 - set SELECT-IR state
jtag_send(chn, 0, 2, 0 ); //step 4 - set SHIFT-IR state jtag_send(chn, 0, 2, 0 ); //step 4 - set SHIFT-IR state
jtag_send(chn, 0, 5, 0xa0); //step 5 - start of CFG_IN ***NOW 6 bits *** jtag_send(chn, 0, 5, 0xa0); //step 5 - start of CFG_IN ***NOW 6 bits ***
jtag_send(chn, 1, 1, 0 ); //step 6 - finish CFG_IN jtag_send(chn, 1, 1, 0 ); //step 6 - finish CFG_IN
jtag_send(chn, 1, 2, 0 ); //step 7 - set SELECT-DR state jtag_send(chn, 1, 2, 0 ); //step 7 - set SELECT-DR state
jtag_send(chn, 0, 2, 0 ); //step 8 - set SHIFT-DR state jtag_send(chn, 0, 2, 0 ); //step 8 - set SHIFT-DR state
// write data (first 8 bytes - just fill the buffer, no readback comparison) // write data (first 8 bytes - just fill the buffer, no readback comparison)
jtag_write_bits (chn, jtag_write_bits (chn,
&buf[datastart], // data to write &buf[datastart], // data to write
skipvfy << 3, // number of bytes to write skipvfy << 3, // number of bytes to write
0, // compare readback data with previously written, abort on mismatch 0, // compare readback data with previously written, abort on mismatch
0, // do not raise TMS at last bit 0, // do not raise TMS at last bit
prev); // 64 bits storage to verify configuration transmission prev); // 64 bits storage to verify configuration transmission
if ((r=jtag_write_bits (chn, if ((r=jtag_write_bits (chn,
&buf[datastart+skipvfy], &buf[datastart+skipvfy],
// (buf8i-(datastart+skipvfy)) << 3, // (buf8i-(datastart+skipvfy)) << 3,
(len-(datastart+skipvfy)) << 3, (len-(datastart+skipvfy)) << 3,
1, 1,
1, prev))<0) { 1, prev))<0) {
r= -r; r= -r;
i= (r>>8) -1 + (datastart+skipvfy); i= (r>>8) -1 + (datastart+skipvfy);
r &= 0xff; r &= 0xff;
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
local_irq_restore(flags); local_irq_restore(flags);
#endif #endif
set_pgm (chn, 1); set_pgm (chn, 1);
set_pgm (chn, 0); set_pgm (chn, 0);
// disable programmimg mode (nop for the 10353 FPGA) // disable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 0); set_pgm_mode(chn, 0);
dev_err(NULL,"**** Configuration failed at byte # %d (%x)****\n", (i-datastart),(i-datastart)); dev_err(NULL,"**** Configuration failed at byte # %d (%x)****\n", (i-datastart),(i-datastart));
dev_err(NULL,"**** r= %x, prev64=%x prev32=%x****\n", r,prev[1], prev[0]); dev_err(NULL,"**** r= %x, prev64=%x prev32=%x****\n", r,prev[1], prev[0]);
return -EFAULT; return -EFAULT;
} }
jtag_send(chn, 1, 1, 0 ); //step 11 - set UPDATE-DR state jtag_send(chn, 1, 1, 0 ); //step 11 - set UPDATE-DR state
jtag_send(chn, 1, 2, 0 ); //step 12 - set SELECT-IR state jtag_send(chn, 1, 2, 0 ); //step 12 - set SELECT-IR state
jtag_send(chn, 0, 2, 0 ); //step 13 - set SHIFT-IR state jtag_send(chn, 0, 2, 0 ); //step 13 - set SHIFT-IR state
jtag_send(chn, 0, 5, 0x30); //step 14 - start of JSTART ***NOW 6 bits *** jtag_send(chn, 0, 5, 0x30); //step 14 - start of JSTART ***NOW 6 bits ***
jtag_send(chn, 1, 1, 0 ); //step 15 - finish JSTART jtag_send(chn, 1, 1, 0 ); //step 15 - finish JSTART
jtag_send(chn, 1, 2, 0 ); //step 16 - set SELECT-DR state jtag_send(chn, 1, 2, 0 ); //step 16 - set SELECT-DR state
jtag_send(chn, 0, 0, 0 ); //step 17 - set SHIFT-DR , clock startup jtag_send(chn, 0, 0, 0 ); //step 17 - set SHIFT-DR , clock startup
jtag_send(chn, 0, 0, 0 ); //step 17a - (total >=12 clocks) jtag_send(chn, 0, 0, 0 ); //step 17a - (total >=12 clocks)
jtag_send(chn, 1, 2, 0 ); //step 18 - set UPDATE-DR state jtag_send(chn, 1, 2, 0 ); //step 18 - set UPDATE-DR state
jtag_send(chn, 0, 1, 0 ); //step 19 - set Run-Test-Idle state jtag_send(chn, 0, 1, 0 ); //step 19 - set Run-Test-Idle state
jtag_send(chn, 0, 0, 0 ); //step 19a - only here starts the sequence - adding 17b does not help (5 - sets done, 6 - releases outputs, 7 - releases reset) jtag_send(chn, 0, 0, 0 ); //step 19a - only here starts the sequence - adding 17b does not help (5 - sets done, 6 - releases outputs, 7 - releases reset)
jtag_send(chn, 0, 0, 0 ); //step 19b - one more? jtag_send(chn, 0, 0, 0 ); //step 19b - one more?
// ready or not - device should start now // ready or not - device should start now
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
local_irq_restore(flags); local_irq_restore(flags);
#endif #endif
//*************************** END OF NO INTERRUPS *********************** //*************************** END OF NO INTERRUPS ***********************
r=read_done(chn); r=read_done(chn);
// disable programmimg mode (nop for the 10353 FPGA) // disable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 0); set_pgm_mode(chn, 0);
if (r==0) { if (r==0) {
dev_err(NULL,"*** FPGA did not start after configuration ***\r\n"); dev_err(NULL,"*** FPGA did not start after configuration ***\r\n");
return -EFAULT; return -EFAULT;
} }
//D( udelay (100000);printk("\nJTAG_configure() OK!\r\n")); //D( udelay (100000);printk("\nJTAG_configure() OK!\r\n"));
D( mdelay (100);printk("\nJTAG_configure() OK!\r\n")); D( mdelay (100);printk("\nJTAG_configure() OK!\r\n"));
dev_info(NULL,"JTAG_configure() OK!\n"); dev_info(NULL,"JTAG_configure() OK!\n");
return 0; return 0;
} //int JTAG_configure } //int JTAG_configure
...@@ -1194,97 +1203,97 @@ int JTAG_configure (int chn, unsigned char * buf, int len) { ...@@ -1194,97 +1203,97 @@ int JTAG_configure (int chn, unsigned char * buf, int len) {
// enable access to JTAG pins. For sensor FPGA that is not possible w/o deprogramming the chip // enable access to JTAG pins. For sensor FPGA that is not possible w/o deprogramming the chip
// leaves in Run-Test-Idle state // leaves in Run-Test-Idle state
int JTAG_openChannel (int chn) { int JTAG_openChannel (int chn) {
dev_dbg(NULL, "JTAG_openChannel (%d)\n",chn); dev_dbg(NULL, "JTAG_openChannel (%d)\n",chn);
// enable programmimg mode (nop for the 10353 FPGA) // enable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 1); set_pgm_mode(chn, 1);
// for shared JTAG/data bus we need to de-program the chip to be able to read JTAG :-( // for shared JTAG/data bus we need to de-program the chip to be able to read JTAG :-(
switch (chn >> 2) { switch (chn >> 2) {
case JTAG_SENSOR_FPGA: case JTAG_SENSOR_FPGA:
// reset device // reset device
set_pgm (chn, 1); set_pgm (chn, 1);
set_pgm (chn, 0); set_pgm (chn, 0);
// wait INIT over - no init connected, just wait >2ms // wait INIT over - no init connected, just wait >2ms
//udelay (2500); //udelay (2500);
mdelay(3); mdelay(3);
break; break;
} }
jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state
jtag_send(chn, 0, 1, 0 ); // set Run-Test-Idle state jtag_send(chn, 0, 1, 0 ); // set Run-Test-Idle state
return 0; return 0;
} // int JTAG_openChannel (int chn) } // int JTAG_openChannel (int chn)
// //
int JTAG_resetChannel (int chn) { int JTAG_resetChannel (int chn) {
dev_dbg(NULL, "JTAG_resetChannel (%d)\n",chn); dev_dbg(NULL, "JTAG_resetChannel (%d)\n",chn);
jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state
// disable programmimg mode (nop for the 10353 FPGA) // disable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 0); // only for sensor FPGA set_pgm_mode(chn, 0); // only for sensor FPGA
return 0; return 0;
} // int JTAG_resetChannel (int chn) } // int JTAG_resetChannel (int chn)
int JTAG_readID (int chn, unsigned char * buf) { int JTAG_readID (int chn, unsigned char * buf) {
int i; int i;
unsigned long d1,d2=0; unsigned long d1,d2=0;
unsigned long * dp; unsigned long * dp;
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
unsigned long flags; unsigned long flags;
#endif #endif
// read dev id, user id // read dev id, user id
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE *********************** //*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE ***********************
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
local_irq_save(flags); local_irq_save(flags);
//local_irq_disable(); //local_irq_disable();
#endif #endif
// prepare JTAG // prepare JTAG
jtag_send(chn, 1, 5, 0 ); //step 1 - set Test-Logic-Reset state jtag_send(chn, 1, 5, 0 ); //step 1 - set Test-Logic-Reset state
jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state
jtag_send(chn, 1, 2, 0 ); //step 3 - set SELECT-IR state jtag_send(chn, 1, 2, 0 ); //step 3 - set SELECT-IR state
jtag_send(chn, 0, 2, 0 ); //step 4 - set SHIFT-IR state jtag_send(chn, 0, 2, 0 ); //step 4 - set SHIFT-IR state
jtag_send(chn, 0, 5, 0x90); //step 5 - start of IDCODE jtag_send(chn, 0, 5, 0x90); //step 5 - start of IDCODE
jtag_send(chn, 1, 1, 0 ); //step 6 - finish IDCODE jtag_send(chn, 1, 1, 0 ); //step 6 - finish IDCODE
jtag_send(chn, 1, 2, 0 ); //step 7 - set SELECT-DR state jtag_send(chn, 1, 2, 0 ); //step 7 - set SELECT-DR state
jtag_send(chn, 0, 2, 0 ); //step 8 - set CAPTURE-DR state jtag_send(chn, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn, jtag_write_bits (chn,
&buf[0], // data to write &buf[0], // data to write
32, // number of bits to write/read 32, // number of bits to write/read
0, // don't compare readback data with previously written 0, // don't compare readback data with previously written
1, 0) ; // raise TMS at last bit 1, 0) ; // raise TMS at last bit
jtag_send(chn, 1, 5, 0 ); //reset state machine to Test-Logic-Reset state jtag_send(chn, 1, 5, 0 ); //reset state machine to Test-Logic-Reset state
jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state
jtag_send(chn, 1, 2, 0 ); //step 3 - set SELECT-IR state jtag_send(chn, 1, 2, 0 ); //step 3 - set SELECT-IR state
jtag_send(chn, 0, 2, 0 ); //step 4 - set SHIFT-IR state jtag_send(chn, 0, 2, 0 ); //step 4 - set SHIFT-IR state
jtag_send(chn, 0, 5, 0x10); //step 5 - start of USERCODE jtag_send(chn, 0, 5, 0x10); //step 5 - start of USERCODE
jtag_send(chn, 1, 1, 0 ); //step 6 - finish USERCODE jtag_send(chn, 1, 1, 0 ); //step 6 - finish USERCODE
jtag_send(chn, 1, 2, 0 ); //step 7 - set SELECT-DR state jtag_send(chn, 1, 2, 0 ); //step 7 - set SELECT-DR state
jtag_send(chn, 0, 2, 0 ); //step 8 - set CAPTURE-DR state jtag_send(chn, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn, jtag_write_bits (chn,
&buf[4], // data to write &buf[4], // data to write
32, // number of bits to write/read 32, // number of bits to write/read
0, // don't compare readback data with previously written 0, // don't compare readback data with previously written
1,0) ; // raise TMS at last bit 1,0) ; // raise TMS at last bit
jtag_send(chn,1, 5, 0 ); //reset state machine to Test-Logic-Reset state jtag_send(chn,1, 5, 0 ); //reset state machine to Test-Logic-Reset state
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
local_irq_restore(flags); local_irq_restore(flags);
#endif #endif
//*************************** END OF NO INTERRUPS *********************** //*************************** END OF NO INTERRUPS ***********************
// swap all bits in ID and user fields // swap all bits in ID and user fields
dp = (unsigned long *) &buf[0]; dp = (unsigned long *) &buf[0];
d1= *dp; d1= *dp;
for (i=0;i<32;i++){ for (i=0;i<32;i++){
d2 = (d2 << 1) | (d1 & 1); d2 = (d2 << 1) | (d1 & 1);
d1 >>= 1; d1 >>= 1;
} }
*dp=d2; *dp=d2;
dp = (unsigned long *) &buf[4]; dp = (unsigned long *) &buf[4];
d1= *dp; d1= *dp;
for (i=0;i<32;i++){ for (i=0;i<32;i++){
d2 = (d2 << 1) | (d1 & 1); d2 = (d2 << 1) | (d1 & 1);
d1 >>= 1; d1 >>= 1;
} }
*dp=d2; *dp=d2;
D(for (i=0; i<8;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");} ); D(for (i=0; i<8;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");} );
data_modified=0; //************************************************* data_modified=0; //*************************************************
return 0; return 0;
} // int JTAG_readID (int chn, unsigned char * buf) } // int JTAG_readID (int chn, unsigned char * buf)
/* /*
...@@ -1293,47 +1302,47 @@ int JTAG_readID (int chn, unsigned char * buf) { ...@@ -1293,47 +1302,47 @@ int JTAG_readID (int chn, unsigned char * buf) {
*/ */
int JTAG_CAPTURE (int chn, unsigned char * buf, int len) { int JTAG_CAPTURE (int chn, unsigned char * buf, int len) {
int i; // only in debug int i; // only in debug
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
unsigned long flags; unsigned long flags;
#endif #endif
dev_dbg(NULL,"JTAG_CAPTURE(): buf=%p\n",buf); dev_dbg(NULL,"JTAG_CAPTURE(): buf=%p\n",buf);
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE *********************** //*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE ***********************
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
local_irq_save(flags); local_irq_save(flags);
//local_irq_disable(); //local_irq_disable();
#endif #endif
// prepare JTAG // prepare JTAG
// jtag_send(chn, 1, 5, 0 ); //step 1 - set Test-Logic-Reset state // jtag_send(chn, 1, 5, 0 ); //step 1 - set Test-Logic-Reset state
// jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state // jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state
jtag_send(chn, 1, 2, 0 ); //step 3 - set SELECT-IR state jtag_send(chn, 1, 2, 0 ); //step 3 - set SELECT-IR state
jtag_send(chn, 0, 2, 0 ); //step 4 - set SHIFT-IR state jtag_send(chn, 0, 2, 0 ); //step 4 - set SHIFT-IR state
jtag_send(chn, 0, 5, 0x80); //step 5 - start of SAMPLE (which bit goes first???) jtag_send(chn, 0, 5, 0x80); //step 5 - start of SAMPLE (which bit goes first???)
jtag_send(chn, 1, 1, 0 ); //step 6 - finish SAMPLE jtag_send(chn, 1, 1, 0 ); //step 6 - finish SAMPLE
jtag_send(chn, 1, 2, 0 ); //step 7 - set SELECT-DR state jtag_send(chn, 1, 2, 0 ); //step 7 - set SELECT-DR state
jtag_send(chn, 0, 2, 0 ); //step 8 - set CAPTURE-DR state jtag_send(chn, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn, jtag_write_bits (chn,
buf, // data to write buf, // data to write
len, // number of bits to read len, // number of bits to read
0, // don't compare readback data with previously written 0, // don't compare readback data with previously written
1,0) ; // raise TMS at last bit 1,0) ; // raise TMS at last bit
// D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); ); // D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); );
// D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); ); // D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); );
jtag_send(chn, 1, 1, 0 ); //step 9 - set UPDATE-DR state jtag_send(chn, 1, 1, 0 ); //step 9 - set UPDATE-DR state
// D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); ); // D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); );
// jtag_send(chn,1, 5, 0 ); //reset state machine to Test-Logic-Reset state // jtag_send(chn,1, 5, 0 ); //reset state machine to Test-Logic-Reset state
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
local_irq_restore(flags); local_irq_restore(flags);
#endif #endif
//*************************** END OF NO INTERRUPS *********************** //*************************** END OF NO INTERRUPS ***********************
dev_dbg(NULL, "\n"); dev_dbg(NULL, "\n");
for (i=0; i<((len+7)>>3) ;i++) { for (i=0; i<((len+7)>>3) ;i++) {
dev_dbg(NULL, "%3x ",(int) buf[i]); dev_dbg(NULL, "%3x ",(int) buf[i]);
if ((i & 0xf) == 0xf) dev_dbg(NULL, "\n"); if ((i & 0xf) == 0xf) dev_dbg(NULL, "\n");
} }
dev_dbg(NULL, "\n"); dev_dbg(NULL, "\n");
data_modified=0; data_modified=0;
return 0; return 0;
} // JTAG_CAPTURE (int chn, unsigned char * buf, int len) { } // JTAG_CAPTURE (int chn, unsigned char * buf, int len) {
...@@ -1345,62 +1354,62 @@ dev_dbg(NULL,"JTAG_CAPTURE(): buf=%p\n",buf); ...@@ -1345,62 +1354,62 @@ dev_dbg(NULL,"JTAG_CAPTURE(): buf=%p\n",buf);
*/ */
int JTAG_EXTEST (int chn, unsigned char * buf, int len) { int JTAG_EXTEST (int chn, unsigned char * buf, int len) {
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
unsigned long flags; unsigned long flags;
#endif #endif
int i; // only in debug int i; // only in debug
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
local_irq_save(flags); local_irq_save(flags);
//local_irq_disable(); //local_irq_disable();
#endif #endif
//D(printk("EXTEST: buf=%p, len=0x%x\n",buf,len)); //D(printk("EXTEST: buf=%p, len=0x%x\n",buf,len));
//D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); ); //D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); );
// jtag_send(chn, 1, 5, 0 ); //step 1 - set Test-Logic-Reset state // jtag_send(chn, 1, 5, 0 ); //step 1 - set Test-Logic-Reset state
// jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state // jtag_send(chn, 0, 1, 0 ); //step 2 - set Run-Test-Idle state
jtag_send(chn, 1, 2, 0 ); //step 3 - set SELECT-IR state jtag_send(chn, 1, 2, 0 ); //step 3 - set SELECT-IR state
jtag_send(chn, 0, 2, 0 ); //step 4 - set SHIFT-IR state jtag_send(chn, 0, 2, 0 ); //step 4 - set SHIFT-IR state
jtag_send(chn, 0, 5, 0xf0); //step 5 - start of EXTEST jtag_send(chn, 0, 5, 0xf0); //step 5 - start of EXTEST
jtag_send(chn, 1, 1, 0 ); //step 6 - finish EXTEST jtag_send(chn, 1, 1, 0 ); //step 6 - finish EXTEST
jtag_send(chn, 1, 2, 0 ); //step 7 - set SELECT-DR state jtag_send(chn, 1, 2, 0 ); //step 7 - set SELECT-DR state
jtag_send(chn, 0, 2, 0 ); //step 8 - set CAPTURE-DR state jtag_send(chn, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn, jtag_write_bits (chn,
buf, buf,
len, // number of bits to write len, // number of bits to write
0, // don't compare readback data with previously written 0, // don't compare readback data with previously written
1,0); // raise TMS at last bit 1,0); // raise TMS at last bit
jtag_send(chn, 1, 1, 0 ); //step 9 - set UPDATE-DR state jtag_send(chn, 1, 1, 0 ); //step 9 - set UPDATE-DR state
#ifdef JTAG_DISABLE_IRQ #ifdef JTAG_DISABLE_IRQ
local_irq_restore(flags); local_irq_restore(flags);
#endif #endif
// D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); ); // D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); );
return 0; return 0;
} //int JTAG_EXTEST (int chn, unsigned char * buf, int len) } //int JTAG_EXTEST (int chn, unsigned char * buf, int len)
static int __init fpga_jtag_init(void) { static int __init fpga_jtag_init(void) {
int i,res; int i,res;
res = register_chrdev(FPGA_JTAG_MAJOR, fpga_jtag_name, &fpga_jtag_fops); res = register_chrdev(DEV393_MAJOR(DEV393_JTAGS_CONF0), fpga_jtag_name, &fpga_jtag_fops);
if(res < 0) { if(res < 0) {
dev_err(NULL,"\nfpga_jtag_init: couldn't get a major number %d.\n",FPGA_JTAG_MAJOR); dev_err(NULL,"\nfpga_jtag_init: couldn't get a major number %d.\n",DEV393_MAJOR(DEV393_JTAGS_CONF0));
return res; return res;
} }
dev_dbg(NULL,FPGA_JTAG_DRIVER_NAME" - %d\n",FPGA_JTAG_MAJOR); dev_dbg(NULL,DEV393_NAME(DEV393_JTAGS_CONF0)" - %d\n",DEV393_MAJOR(DEV393_JTAGS_CONF0));
for (i=0;i<=FPGA_JTAG_MAXMINOR;i++) minors[i]=0; for (i=0;i<=FPGA_JTAG_MAXMINOR;i++) minors[i]=0;
initPortC(); initPortC();
dev_dbg(NULL, "elphel test %s: MAJOR %d", FPGA_JTAG_DRIVER_NAME, FPGA_JTAG_MAJOR); dev_dbg(NULL, "elphel test %s: MAJOR %d", DEV393_NAME(DEV393_JTAGS_CONF0), DEV393_MAJOR(DEV393_JTAGS_CONF0));
res = init_mmio_ptr(); res = init_mmio_ptr();
if (res < 0) if (res < 0)
return -ENOMEM; return -ENOMEM;
return 0; return 0;
} }
static void __exit fpga_jtag_exit(void) static void __exit fpga_jtag_exit(void)
{ {
unregister_chrdev(FPGA_JTAG_MAJOR, FPGA_JTAG_DRIVER_NAME); unregister_chrdev(DEV393_MAJOR(DEV393_JTAGS_CONF0), DEV393_NAME(DEV393_JTAGS_CONF0));
dev_dbg(NULL, "unregistering driver"); dev_dbg(NULL, "unregistering driver");
} }
module_exit(fpga_jtag_exit); module_exit(fpga_jtag_exit);
...@@ -1409,5 +1418,5 @@ module_exit(fpga_jtag_exit); ...@@ -1409,5 +1418,5 @@ module_exit(fpga_jtag_exit);
module_init(fpga_jtag_init); module_init(fpga_jtag_init);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>"); MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>");
MODULE_DESCRIPTION(FPGA_JTAG_DRIVER_NAME); MODULE_DESCRIPTION(FPGA_JTAG_DRIVER_DESCRIPTION);
...@@ -47,9 +47,10 @@ ...@@ -47,9 +47,10 @@
//#include <asm/delay.h> //#include <asm/delay.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/c313a.h> #include <uapi/elphel/c313a.h>
#include <uapi/elphel/exifa.h> #include <uapi/elphel/exifa.h>
#include <uapi/elphel/x393_devices.h>
//#include "fpgactrl.h" // defines port_csp0_adsensor_common.hdr, port_csp4_addr //#include "fpgactrl.h" // defines port_csp0_adsensor_common.hdr, port_csp4_addr
//#include "cc3x3.h" //#include "cc3x3.h"
//#include "x3x3.h" // hardware definitions //#include "x3x3.h" // hardware definitions
...@@ -117,7 +118,7 @@ ...@@ -117,7 +118,7 @@
/** /**
* driver name to display * driver name to display
*/ */
#define FRAMEPARS_DRIVER_NAME "Elphel (R) Model 393 Frame Parameters device driver" #define FRAMEPARS_DRIVER_DESCRIPTION "Elphel (R) Model 393 Frame Parameters device driver"
/* 393: sFrameParsAll is an array of 4per-port structures */ /* 393: sFrameParsAll is an array of 4per-port structures */
static struct framepars_all_t sFrameParsAll[SENSOR_PORTS] __attribute__ ((aligned(PAGE_SIZE))); ///< Sensor Parameters, currently 16 pages all and 2048 pages some, static struct static struct framepars_all_t sFrameParsAll[SENSOR_PORTS] __attribute__ ((aligned(PAGE_SIZE))); ///< Sensor Parameters, currently 16 pages all and 2048 pages some, static struct
...@@ -1067,10 +1068,10 @@ int framepars_open(struct inode *inode, struct file *filp) ...@@ -1067,10 +1068,10 @@ int framepars_open(struct inode *inode, struct file *filp)
privData->minor = MINOR(inode->i_rdev); privData->minor = MINOR(inode->i_rdev);
MDF1(printk(": minor=0x%x\n", privData->minor)); MDF1(printk(": minor=0x%x\n", privData->minor));
switch (privData->minor) { switch (privData->minor) {
case CMOSCAM_MINOR_FRAMEPARS_CHN_0: case DEV393_MINOR(DEV393_FRAMEPARS0):
case CMOSCAM_MINOR_FRAMEPARS_CHN_1: case DEV393_MINOR(DEV393_FRAMEPARS1):
case CMOSCAM_MINOR_FRAMEPARS_CHN_2: case DEV393_MINOR(DEV393_FRAMEPARS2):
case CMOSCAM_MINOR_FRAMEPARS_CHN_3: case DEV393_MINOR(DEV393_FRAMEPARS3):
inode->i_size = 0; //or return 8 - number of frame pages? inode->i_size = 0; //or return 8 - number of frame pages?
return 0; return 0;
default: default:
...@@ -1093,10 +1094,10 @@ int framepars_release(struct inode *inode, struct file *filp) ...@@ -1093,10 +1094,10 @@ int framepars_release(struct inode *inode, struct file *filp)
MDF1(printk(": minor=0x%x\n", p)); MDF1(printk(": minor=0x%x\n", p));
switch ( p ) { switch ( p ) {
case CMOSCAM_MINOR_FRAMEPARS_CHN_0: case DEV393_MINOR(DEV393_FRAMEPARS0):
case CMOSCAM_MINOR_FRAMEPARS_CHN_1: case DEV393_MINOR(DEV393_FRAMEPARS1):
case CMOSCAM_MINOR_FRAMEPARS_CHN_2: case DEV393_MINOR(DEV393_FRAMEPARS2):
case CMOSCAM_MINOR_FRAMEPARS_CHN_3: case DEV393_MINOR(DEV393_FRAMEPARS3):
break; break;
default: default:
return -EINVAL; //! do not need to free anything - "wrong number" return -EINVAL; //! do not need to free anything - "wrong number"
...@@ -1122,7 +1123,7 @@ loff_t framepars_lseek(struct file * file, loff_t offset, int orig) ...@@ -1122,7 +1123,7 @@ loff_t framepars_lseek(struct file * file, loff_t offset, int orig)
{ {
unsigned long target_frame; unsigned long target_frame;
struct framepars_pd * privData = (struct framepars_pd*) file -> private_data; struct framepars_pd * privData = (struct framepars_pd*) file -> private_data;
int sensor_port = privData -> minor - CMOSCAM_MINOR_FRAMEPARS_CHN_0; int sensor_port = privData -> minor - DEV393_MINOR(DEV393_FRAMEPARS0);
// struct framepars_t *framepars = aframepars[sensor_port]; // struct framepars_t *framepars = aframepars[sensor_port];
MDF1(printk(" offset=0x%x, orig=0x%x, sensor_port = %d\n", (int)offset, (int)orig, sensor_port)); MDF1(printk(" offset=0x%x, orig=0x%x, sensor_port = %d\n", (int)offset, (int)orig, sensor_port));
switch (orig) { switch (orig) {
...@@ -1223,7 +1224,7 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff ...@@ -1223,7 +1224,7 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff
struct frameparspair_t pars_static[256]; // will be sufficient for most calls struct frameparspair_t pars_static[256]; // will be sufficient for most calls
struct frameparspair_t * pars = pars_static; struct frameparspair_t * pars = pars_static;
struct framepars_pd * privData = (struct framepars_pd*)file->private_data; struct framepars_pd * privData = (struct framepars_pd*)file->private_data;
int sensor_port = privData -> minor - CMOSCAM_MINOR_FRAMEPARS_CHN_0; int sensor_port = privData -> minor - DEV393_MINOR(DEV393_FRAMEPARS0);
// struct framepars_t *framepars = aframepars[sensor_port]; // struct framepars_t *framepars = aframepars[sensor_port];
unsigned long frame = *off; // ************* NOTE: Never use file->f_pos in write() and read() !!! unsigned long frame = *off; // ************* NOTE: Never use file->f_pos in write() and read() !!!
int latency = -1; int latency = -1;
...@@ -1234,7 +1235,10 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff ...@@ -1234,7 +1235,10 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff
MDF1(printk(": file->f_pos=0x%x, *off=0x%x, count=0x%x\n", (int)file->f_pos, (int)*off, (int)count)); MDF1(printk(": file->f_pos=0x%x, *off=0x%x, count=0x%x\n", (int)file->f_pos, (int)*off, (int)count));
count &= ~7; // sizeof (struct frameparspair_t)==8 count &= ~7; // sizeof (struct frameparspair_t)==8
switch (privData->minor) { switch (privData->minor) {
case CMOSCAM_MINOR_FRAMEPARS: case DEV393_MINOR(DEV393_FRAMEPARS0):
case DEV393_MINOR(DEV393_FRAMEPARS1):
case DEV393_MINOR(DEV393_FRAMEPARS2):
case DEV393_MINOR(DEV393_FRAMEPARS3):
if (count > sizeof(pars_static)) // only allocate if static is not enough if (count > sizeof(pars_static)) // only allocate if static is not enough
pars = (struct frameparspair_t*)kmalloc(count, GFP_KERNEL); pars = (struct frameparspair_t*)kmalloc(count, GFP_KERNEL);
if (!pars) return -ENOMEM; if (!pars) return -ENOMEM;
...@@ -1296,11 +1300,14 @@ int framepars_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -1296,11 +1300,14 @@ int framepars_mmap(struct file *file, struct vm_area_struct *vma)
{ {
int result; int result;
struct framepars_pd * privData = (struct framepars_pd*)file->private_data; struct framepars_pd * privData = (struct framepars_pd*)file->private_data;
int sensor_port = privData -> minor - CMOSCAM_MINOR_FRAMEPARS_CHN_0; int sensor_port = privData -> minor - DEV393_MINOR(DEV393_FRAMEPARS0);
MDF1(printk(": minor=0x%x\n", privData->minor)); MDF1(printk(": minor=0x%x\n", privData->minor));
switch (privData->minor) { switch (privData->minor) {
case CMOSCAM_MINOR_FRAMEPARS: case DEV393_MINOR(DEV393_FRAMEPARS0):
case DEV393_MINOR(DEV393_FRAMEPARS1):
case DEV393_MINOR(DEV393_FRAMEPARS2):
case DEV393_MINOR(DEV393_FRAMEPARS3):
result = remap_pfn_range(vma, result = remap_pfn_range(vma,
vma->vm_start, vma->vm_start,
((unsigned long)virt_to_phys(&aframeparsall[sensor_port])) >> PAGE_SHIFT, // Should be page-aligned ((unsigned long)virt_to_phys(&aframeparsall[sensor_port])) >> PAGE_SHIFT, // Should be page-aligned
...@@ -1331,22 +1338,22 @@ int framepars_init(struct platform_device *pdev) ...@@ -1331,22 +1338,22 @@ int framepars_init(struct platform_device *pdev)
initMultiPars(sensor_port); // just clear - needs to be called again when sensor is recognized initMultiPars(sensor_port); // just clear - needs to be called again when sensor is recognized
} }
frameParsInitialized = 0; frameParsInitialized = 0;
res = register_chrdev(FRAMEPARS_MAJOR, "framepars_operations", &framepars_fops); res = register_chrdev(DEV393_MAJOR(DEV393_FRAMEPARS0), DEV393_NAME(DEV393_FRAMEPARS0), &framepars_fops);
if (res < 0) { if (res < 0) {
printk(KERN_ERR "\nframepars_init: couldn't get a major number %d.\n", FRAMEPARS_MAJOR); printk(KERN_ERR "\nframepars_init: couldn't get a major number %d.\n", DEV393_MAJOR(DEV393_FRAMEPARS0));
return res; return res;
} }
for (sensor_port = 0; sensor_port < SENSOR_PORTS; sensor_port++) { for (sensor_port = 0; sensor_port < SENSOR_PORTS; sensor_port++) {
init_waitqueue_head(&aframepars_wait_queue[sensor_port]); init_waitqueue_head(&aframepars_wait_queue[sensor_port]);
} }
dev_info(dev, "registered MAJOR: %d\n", FRAMEPARS_MAJOR); dev_info(dev, "registered MAJOR: %d\n", DEV393_MAJOR(DEV393_FRAMEPARS0));
return 0; return 0;
} }
int framepars_remove(struct platform_device *pdev) int framepars_remove(struct platform_device *pdev)
{ {
unregister_chrdev(FRAMEPARS_MAJOR, "framepars_operations"); unregister_chrdev(DEV393_MAJOR(DEV393_FRAMEPARS0), DEV393_NAME(DEV393_FRAMEPARS0));
return 0; return 0;
} }
...@@ -1361,7 +1368,7 @@ int framepars_remove(struct platform_device *pdev) ...@@ -1361,7 +1368,7 @@ int framepars_remove(struct platform_device *pdev)
// .probe = framepars_init, // .probe = framepars_init,
// .remove = framepars_remove, // .remove = framepars_remove,
// .driver = { // .driver = {
// .name = FRAMEPARS_DRIVER_NAME, // .name = DEV393_NAME(DEV393_FRAMEPARS0),
// .of_match_table = elphel393_framepars_of_match, // .of_match_table = elphel393_framepars_of_match,
// }, // },
//}; //};
...@@ -1370,4 +1377,5 @@ int framepars_remove(struct platform_device *pdev) ...@@ -1370,4 +1377,5 @@ int framepars_remove(struct platform_device *pdev)
// //
//MODULE_LICENSE("GPL"); //MODULE_LICENSE("GPL");
//MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>."); //MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
//MODULE_DESCRIPTION(X3X3_FRAMEPARS_DRIVER_NAME); //MODULE_DESCRIPTION(FRAMEPARS_DRIVER_DESCRIPTION);
//
...@@ -112,7 +112,7 @@ ...@@ -112,7 +112,7 @@
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <elphel/driver_numbers.h> #include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/c313a.h> #include <uapi/elphel/c313a.h>
#include <uapi/elphel/exifa.h> #include <uapi/elphel/exifa.h>
//#include "fpgactrl.h" // defines port_csp0_addr, port_csp4_addr //#include "fpgactrl.h" // defines port_csp0_addr, port_csp4_addr
...@@ -153,7 +153,7 @@ ...@@ -153,7 +153,7 @@
/** Combine color, sensor port and sub-channel into a single index /** Combine color, sensor port and sub-channel into a single index
* It is still possible to use "color" parameter in the range of 0..63 with port and channel set to 0 */ * It is still possible to use "color" parameter in the range of 0..63 with port and channel set to 0 */
#define PORT_CHN_COLOR(color,port,chn) (((color) & 0x3f) | ((((port) & 3 ) << 4)) | ((((chn) & 3 ) << 2))) #define PORT_CHN_COLOR(color,port,chn) (((color) & 0x3f) | ((((port) & 3 ) << 4)) | ((((chn) & 3 ) << 2)))
#define X3X3_GAMMAS_DRIVER_NAME "Elphel (R) Model 353 Gamma Tables device driver" #define X3X3_GAMMAS_DRIVER_DESCRIPTION "Elphel (R) Model 353 Gamma Tables device driver"
/** /**
* @brief number of different non-scaled tables in cache when it starts to overwrite non-scaled tables rather than scaled * @brief number of different non-scaled tables in cache when it starts to overwrite non-scaled tables rather than scaled
* \n TODO: use P_*? * \n TODO: use P_*?
...@@ -750,7 +750,7 @@ int gammas_open(struct inode *inode, struct file *file) { ...@@ -750,7 +750,7 @@ int gammas_open(struct inode *inode, struct file *file) {
privData-> minor=MINOR(inode->i_rdev); privData-> minor=MINOR(inode->i_rdev);
MDF10(printk("gammas_open, minor=0x%x\n",privData-> minor)); MDF10(printk("gammas_open, minor=0x%x\n",privData-> minor));
switch (privData-> minor) { switch (privData-> minor) {
case CMOSCAM_MINOR_GAMMAS : case DEV393_MINOR(DEV393_GAMMA) :
inode->i_size = GAMMA_FILE_SIZE; inode->i_size = GAMMA_FILE_SIZE;
privData-> scale= 0; privData-> scale= 0;
privData-> hash16=0; privData-> hash16=0;
...@@ -775,7 +775,7 @@ int gammas_release(struct inode *inode, struct file *file) { ...@@ -775,7 +775,7 @@ int gammas_release(struct inode *inode, struct file *file) {
int p = MINOR(inode->i_rdev); int p = MINOR(inode->i_rdev);
MDF10(printk("gammas_release, minor=0x%x\n",p)); MDF10(printk("gammas_release, minor=0x%x\n",p));
switch ( p ) { switch ( p ) {
case CMOSCAM_MINOR_GAMMAS : case DEV393_MINOR(DEV393_GAMMA) :
break; break;
default: default:
return -EINVAL; //! do not need to free anything - "wrong number" return -EINVAL; //! do not need to free anything - "wrong number"
...@@ -804,7 +804,7 @@ loff_t gammas_lseek (struct file * file, loff_t offset, int orig) { ...@@ -804,7 +804,7 @@ loff_t gammas_lseek (struct file * file, loff_t offset, int orig) {
struct gammas_pd * privData = (struct gammas_pd *) file->private_data; struct gammas_pd * privData = (struct gammas_pd *) file->private_data;
MDF10(printk("offset=0x%x, orig=0x%x, file->f_pos=0x%x\n",(int) offset, (int) orig, (int) file->f_pos)); MDF10(printk("offset=0x%x, orig=0x%x, file->f_pos=0x%x\n",(int) offset, (int) orig, (int) file->f_pos));
switch (privData->minor) { switch (privData->minor) {
case CMOSCAM_MINOR_GAMMAS : case DEV393_MINOR(DEV393_GAMMA) :
switch(orig) { switch(orig) {
case SEEK_SET: case SEEK_SET:
file->f_pos = offset; file->f_pos = offset;
...@@ -872,7 +872,7 @@ ssize_t gammas_write(struct file * file, ///< this file structure ...@@ -872,7 +872,7 @@ ssize_t gammas_write(struct file * file, ///< this file structure
unsigned short * gamma= data.gamma; unsigned short * gamma= data.gamma;
MDF10(printk(" file->f_pos=0x%x, *off=0x%x\n", (int) file->f_pos, (int) *off)); MDF10(printk(" file->f_pos=0x%x, *off=0x%x\n", (int) file->f_pos, (int) *off));
switch (privData->minor) { switch (privData->minor) {
case CMOSCAM_MINOR_GAMMAS : case DEV393_MINOR(DEV393_GAMMA) :
if (count>sizeof (data)) count = sizeof (data); if (count>sizeof (data)) count = sizeof (data);
if(count) { if(count) {
if(copy_from_user((char *) &data, buf, count)) return -EFAULT; if(copy_from_user((char *) &data, buf, count)) return -EFAULT;
...@@ -903,7 +903,7 @@ int gammas_mmap (struct file *file, struct vm_area_struct *vma) { ...@@ -903,7 +903,7 @@ int gammas_mmap (struct file *file, struct vm_area_struct *vma) {
struct gammas_pd * privData = (struct gammas_pd *) file->private_data; struct gammas_pd * privData = (struct gammas_pd *) file->private_data;
MDF10(printk("gammas_all_mmap, minor=0x%x\n",privData-> minor)); MDF10(printk("gammas_all_mmap, minor=0x%x\n",privData-> minor));
switch (privData->minor) { switch (privData->minor) {
case CMOSCAM_MINOR_GAMMAS : case DEV393_MINOR(DEV393_GAMMA) :
result=remap_pfn_range(vma, result=remap_pfn_range(vma,
vma->vm_start, vma->vm_start,
((unsigned long) virt_to_phys(gammas_p)) >> PAGE_SHIFT, // Should be page-aligned ((unsigned long) virt_to_phys(gammas_p)) >> PAGE_SHIFT, // Should be page-aligned
...@@ -922,19 +922,19 @@ int gammas_mmap (struct file *file, struct vm_area_struct *vma) { ...@@ -922,19 +922,19 @@ int gammas_mmap (struct file *file, struct vm_area_struct *vma) {
*/ */
static int __init gammas_init(void) { static int __init gammas_init(void) {
int res; int res;
printk ("Starting "X3X3_GAMMAS_DRIVER_NAME" - %d \n",GAMMAS_MAJOR); printk ("Starting "DEV393_NAME(DEV393_GAMMA)" - %d \n",DEV393_MAJOR(DEV393_GAMMA));
init_gammas(); init_gammas();
MDF10(printk("set_gamma_table (0, GAMMA_SCLALE_1, NULL, 0, 0)\n"); udelay (ELPHEL_DEBUG_DELAY)); MDF10(printk("set_gamma_table (0, GAMMA_SCLALE_1, NULL, 0, 0)\n"); udelay (ELPHEL_DEBUG_DELAY));
set_gamma_table (0, GAMMA_SCLALE_1, NULL, 0, 0, 0, 0); // maybe not needed to put linear to cache - it can be calculated as soon FPGA will be tried to be programmed with set_gamma_table (0, GAMMA_SCLALE_1, NULL, 0, 0, 0, 0); // maybe not needed to put linear to cache - it can be calculated as soon FPGA will be tried to be programmed with
// hash16==0 // hash16==0
res = register_chrdev(GAMMAS_MAJOR, "gamma_tables_operations", &gammas_fops); res = register_chrdev(DEV393_MAJOR(DEV393_GAMMA), DEV393_NAME(DEV393_GAMMA), &gammas_fops);
if(res < 0) { if(res < 0) {
printk(KERN_ERR "\ngammas_init: couldn't get a major number %d.\n",GAMMAS_MAJOR); printk(KERN_ERR "\ngammas_init: couldn't get a major number %d.\n",DEV393_MAJOR(DEV393_GAMMA));
return res; return res;
} }
// init_waitqueue_head(&gammas_wait_queue); // init_waitqueue_head(&gammas_wait_queue);
printk(X3X3_GAMMAS_DRIVER_NAME" - %d \n",GAMMAS_MAJOR); printk(DEV393_NAME(DEV393_GAMMA)" - %d \n",DEV393_MAJOR(DEV393_GAMMA));
return 0; return 0;
} }
...@@ -942,7 +942,7 @@ static int __init gammas_init(void) { ...@@ -942,7 +942,7 @@ static int __init gammas_init(void) {
module_init(gammas_init); module_init(gammas_init);
MODULE_LICENSE("GPLv3.0"); MODULE_LICENSE("GPLv3.0");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>."); MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
MODULE_DESCRIPTION(X3X3_GAMMAS_DRIVER_NAME); MODULE_DESCRIPTION(X3X3_GAMMAS_DRIVER_DESCRIPTION);
......
...@@ -106,7 +106,7 @@ ...@@ -106,7 +106,7 @@
#include <linux/dma-direction.h> #include <linux/dma-direction.h>
// ##include <asm/dma-mapping.h> // ##include <asm/dma-mapping.h>
#include <elphel/driver_numbers.h> #include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/c313a.h> #include <uapi/elphel/c313a.h>
#include <uapi/elphel/exifa.h> #include <uapi/elphel/exifa.h>
//#include "fpgactrl.h" // defines port_csp0_addr, port_csp4_addr //#include "fpgactrl.h" // defines port_csp0_addr, port_csp4_addr
...@@ -135,7 +135,7 @@ ...@@ -135,7 +135,7 @@
u32 (*fpga_hist_data)[SENSOR_PORTS][MAX_SENSORS][PARS_FRAMES][4][256]; ///< Array of histogram data, mapped to the memory wheer FPGA sends data u32 (*fpga_hist_data)[SENSOR_PORTS][MAX_SENSORS][PARS_FRAMES][4][256]; ///< Array of histogram data, mapped to the memory wheer FPGA sends data
dma_addr_t fpga_hist_phys; // physical address of the start of the received histogram data dma_addr_t fpga_hist_phys; // physical address of the start of the received histogram data
#define X3X3_HISTOGRAMS_DRIVER_NAME "Elphel (R) Model 353 Histograms device driver" #define X3X3_HISTOGRAMS_DRIVER_DESCRIPTION "Elphel (R) Model 353 Histograms device driver"
/** for each port and possible sensor subchannel provides index in combine histogram data */ /** for each port and possible sensor subchannel provides index in combine histogram data */
int histograms_map[SENSOR_PORTS][MAX_SENSORS]; int histograms_map[SENSOR_PORTS][MAX_SENSORS];
...@@ -463,7 +463,7 @@ int histograms_open(struct inode *inode, ///< inode ...@@ -463,7 +463,7 @@ int histograms_open(struct inode *inode, ///< inode
privData-> minor=MINOR(inode->i_rdev); privData-> minor=MINOR(inode->i_rdev);
MDF21(printk("minor=0x%x\n",privData-> minor)); MDF21(printk("minor=0x%x\n",privData-> minor));
switch (privData-> minor) { switch (privData-> minor) {
case CMOSCAM_MINOR_HISTOGRAMS : case DEV393_MINOR(DEV393_HISTOGRAM) :
inode->i_size = HISTOGRAMS_FILE_SIZE; inode->i_size = HISTOGRAMS_FILE_SIZE;
privData->frame=0xffffffff; privData->frame=0xffffffff;
privData->frame_index=-1; privData->frame_index=-1;
...@@ -490,7 +490,7 @@ int histograms_release (struct inode *inode, ///< inode ...@@ -490,7 +490,7 @@ int histograms_release (struct inode *inode, ///< inode
int p = MINOR(inode->i_rdev); int p = MINOR(inode->i_rdev);
MDF21(printk("minor=0x%x\n",p)); MDF21(printk("minor=0x%x\n",p));
switch ( p ) { switch ( p ) {
case CMOSCAM_MINOR_HISTOGRAMS : case DEV393_MINOR(DEV393_HISTOGRAM) :
break; break;
default: default:
return -EINVAL; //! do not need to free anything - "wrong number" return -EINVAL; //! do not need to free anything - "wrong number"
...@@ -535,7 +535,7 @@ loff_t histograms_lseek (struct file * file, ...@@ -535,7 +535,7 @@ loff_t histograms_lseek (struct file * file,
MDF21(printk("offset=0x%x, orig=0x%x\n",(int) offset, (int) orig)); MDF21(printk("offset=0x%x, orig=0x%x\n",(int) offset, (int) orig));
switch (privData->minor) { switch (privData->minor) {
case CMOSCAM_MINOR_HISTOGRAMS : case DEV393_MINOR(DEV393_HISTOGRAM) :
switch(orig) { switch(orig) {
case SEEK_CUR: // ignore offset case SEEK_CUR: // ignore offset
offset+=(privData-> wait_mode)? offset+=(privData-> wait_mode)?
...@@ -655,7 +655,7 @@ int histograms_mmap (struct file *file, struct vm_area_struct *vma) { ...@@ -655,7 +655,7 @@ int histograms_mmap (struct file *file, struct vm_area_struct *vma) {
struct histograms_pd * privData = (struct histograms_pd *) file->private_data; struct histograms_pd * privData = (struct histograms_pd *) file->private_data;
MDF21(printk("minor=0x%x\n",privData-> minor)); MDF21(printk("minor=0x%x\n",privData-> minor));
switch (privData->minor) { switch (privData->minor) {
case CMOSCAM_MINOR_HISTOGRAMS : case DEV393_MINOR(DEV393_HISTOGRAM) :
result=remap_pfn_range(vma, result=remap_pfn_range(vma,
vma->vm_start, vma->vm_start,
((unsigned long) virt_to_phys(histograms_p)) >> PAGE_SHIFT, // Should be page-aligned ((unsigned long) virt_to_phys(histograms_p)) >> PAGE_SHIFT, // Should be page-aligned
...@@ -676,15 +676,15 @@ static int __init histograms_init(void) { ...@@ -676,15 +676,15 @@ static int __init histograms_init(void) {
int res; int res;
// init_histograms(); // Not now??? Need to have list of channels // init_histograms(); // Not now??? Need to have list of channels
// Do it later, from the user space // Do it later, from the user space
res = register_chrdev(HISTOGRAMS_MAJOR, "gamma_tables_operations", &histograms_fops); res = register_chrdev(DEV393_MAJOR(DEV393_HISTOGRAM), "gamma_tables_operations", &histograms_fops);
if(res < 0) { if(res < 0) {
printk(KERN_ERR "histograms_init: couldn't get a major number %d.\n",HISTOGRAMS_MAJOR); printk(KERN_ERR "histograms_init: couldn't get a major number %d.\n",DEV393_MAJOR(DEV393_HISTOGRAM));
return res; return res;
} }
// init_waitqueue_head(&histograms_wait_queue); // init_waitqueue_head(&histograms_wait_queue);
init_waitqueue_head(&hist_y_wait_queue); // wait queue for the G1 histogram (used as Y) init_waitqueue_head(&hist_y_wait_queue); // wait queue for the G1 histogram (used as Y)
init_waitqueue_head(&hist_c_wait_queue); // wait queue for all the other (R,G2,B) histograms (color) init_waitqueue_head(&hist_c_wait_queue); // wait queue for all the other (R,G2,B) histograms (color)
printk(X3X3_HISTOGRAMS_DRIVER_NAME"\r\n"); printk(DEV393_NAME(DEV393_HISTOGRAM)"\n");
return 0; return 0;
} }
...@@ -692,4 +692,4 @@ static int __init histograms_init(void) { ...@@ -692,4 +692,4 @@ static int __init histograms_init(void) {
module_init(histograms_init); module_init(histograms_init);
MODULE_LICENSE("GPLv3.0"); MODULE_LICENSE("GPLv3.0");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>."); MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
MODULE_DESCRIPTION(X3X3_HISTOGRAMS_DRIVER_NAME); MODULE_DESCRIPTION(X3X3_HISTOGRAMS_DRIVER_DESCRIPTION);
...@@ -49,12 +49,13 @@ ...@@ -49,12 +49,13 @@
#include <linux/string.h> #include <linux/string.h>
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/uaccess.h> // copy_*_user #include <asm/uaccess.h> // copy_*_user
#include <elphel/driver_numbers.h>
#include <uapi/elphel/c313a.h> #include <uapi/elphel/c313a.h>
#include <elphel/elphel393-mem.h> #include <elphel/elphel393-mem.h>
#include "imu_log393.h" #include "imu_log393.h"
#include "x393.h" #include "x393.h"
#include "cci2c.h" #include "cci2c.h"
#include <uapi/elphel/x393_devices.h>
#if 0 #if 0
#define D(x) x #define D(x) x
...@@ -104,7 +105,7 @@ ...@@ -104,7 +105,7 @@
#endif #endif
#define RS232_RATE 19200 ///< RS232 bps #define RS232_RATE 19200 ///< RS232 bps
#define IMU_MODULE_DESCRIPTION "IMU logger for 10365 ext. board" #define IMU_MODULE_DESCRIPTION "IMU logger for 10365 ext. board"
#define LOGGER_DRIVER_NAME "imu_logger" //#define LOGGER_DRIVER_NAME "imu_logger"
#define IMU_MAXMINOR 10 #define IMU_MAXMINOR 10
#ifdef NC353 #ifdef NC353
...@@ -606,12 +607,12 @@ static int imu_open(struct inode *inode, struct file *filp) { ...@@ -606,12 +607,12 @@ static int imu_open(struct inode *inode, struct file *filp) {
D(printk("filp=%lx\r\n",(unsigned long)filp) ); D(printk("filp=%lx\r\n",(unsigned long)filp) );
switch ( p ) { switch ( p ) {
case LOGGER_CTL_MINOR: case DEV393_MINOR(DEV393_LOGGER_CTRL):
D1(printk(KERN_NOTICE "IMU_ctl_open\n")); D1(printk(KERN_NOTICE "IMU_ctl_open\n"));
inode->i_size=sizeof(wbuf); inode->i_size=sizeof(wbuf);
// nothing more here, after writing parameters should start imu (and dma), otherwise will use defaults on next open of /dev/imu // nothing more here, after writing parameters should start imu (and dma), otherwise will use defaults on next open of /dev/imu
break; break;
case LOGGER_MINOR : case DEV393_MINOR(DEV393_LOGGER) :
{ {
D1(printk(KERN_NOTICE "IMU_open\n")); D1(printk(KERN_NOTICE "IMU_open\n"));
inode->i_size=sizeof(wbuf); // only in write mode inode->i_size=sizeof(wbuf); // only in write mode
...@@ -668,8 +669,8 @@ static int imu_release(struct inode *inode, struct file *filp) { ...@@ -668,8 +669,8 @@ static int imu_release(struct inode *inode, struct file *filp) {
// int res=0; // int res=0;
int p = MINOR(inode->i_rdev); int p = MINOR(inode->i_rdev);
switch ( p ) { switch ( p ) {
case LOGGER_MINOR : case DEV393_MINOR(DEV393_LOGGER) :
case LOGGER_CTL_MINOR: case DEV393_MINOR(DEV393_LOGGER_CTRL):
printk(KERN_NOTICE "Closing IMU device, numBytesWritten=0x%llx, numBytesRead=0x%llx (only global pointer, does not include files opened in read mode)\n", numBytesWritten, numBytesRead); printk(KERN_NOTICE "Closing IMU device, numBytesWritten=0x%llx, numBytesRead=0x%llx (only global pointer, does not include files opened in read mode)\n", numBytesWritten, numBytesRead);
break; break;
default: return -EINVAL; default: return -EINVAL;
...@@ -687,8 +688,8 @@ static ssize_t imu_write(struct file * file, const char * buf, size_t count, lof ...@@ -687,8 +688,8 @@ static ssize_t imu_write(struct file * file, const char * buf, size_t count, lof
D(printk("imu_write: (int)file->private_data)= %x\r\n",((int)file->private_data))); D(printk("imu_write: (int)file->private_data)= %x\r\n",((int)file->private_data)));
// switch (((int *)file->private_data)[0]) { // switch (((int *)file->private_data)[0]) {
switch ((int) file->private_data) { switch ((int) file->private_data) {
case LOGGER_MINOR : case DEV393_MINOR(DEV393_LOGGER) :
case LOGGER_CTL_MINOR: case DEV393_MINOR(DEV393_LOGGER_CTRL):
if (!file->f_mode & FMODE_WRITE) { if (!file->f_mode & FMODE_WRITE) {
return -EINVAL; // readonly return -EINVAL; // readonly
} }
...@@ -722,8 +723,8 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) { ...@@ -722,8 +723,8 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) {
D(printk (" file=%x, offset=%llx (%d), orig=%x\r\n", (int) file, offset,(int) offset, (int) orig)); D(printk (" file=%x, offset=%llx (%d), orig=%x\r\n", (int) file, offset,(int) offset, (int) orig));
int p=(int)file->private_data; int p=(int)file->private_data;
switch (p) { switch (p) {
case LOGGER_MINOR: case DEV393_MINOR(DEV393_LOGGER):
case LOGGER_CTL_MINOR: case DEV393_MINOR(DEV393_LOGGER_CTRL):
switch (orig) { switch (orig) {
case SEEK_SET: case SEEK_SET:
file->f_pos = offset; file->f_pos = offset;
...@@ -783,7 +784,7 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) { ...@@ -783,7 +784,7 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) {
return (-EOVERFLOW); return (-EOVERFLOW);
} }
/** enable seeking beyond buffer - it now is absolute position in the data stream*/ /** enable seeking beyond buffer - it now is absolute position in the data stream*/
if ((p==LOGGER_CTL_MINOR) && (file->f_pos > sizeof(wbuf))) { if ((p==DEV393_MINOR(DEV393_LOGGER_CTRL)) && (file->f_pos > sizeof(wbuf))) {
printk(KERN_ERR "beyond end: minor=%d, file->f_pos=0x%llx\n", p, file->f_pos); printk(KERN_ERR "beyond end: minor=%d, file->f_pos=0x%llx\n", p, file->f_pos);
file->f_pos = sizeof(wbuf); file->f_pos = sizeof(wbuf);
return (-EOVERFLOW); return (-EOVERFLOW);
...@@ -811,7 +812,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of ...@@ -811,7 +812,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of
reg_bif_dma_r_ch1_stat ch1_stat; reg_bif_dma_r_ch1_stat ch1_stat;
#endif #endif
switch ((int)file->private_data) { switch ((int)file->private_data) {
case LOGGER_CTL_MINOR: case DEV393_MINOR(DEV393_LOGGER_CTRL):
// if (*off >= sizeof(wbuf)) return -EINVAL; // bigger than all // if (*off >= sizeof(wbuf)) return -EINVAL; // bigger than all
if (*off >= sizeof(wbuf)) return 0; // bigger than all if (*off >= sizeof(wbuf)) return 0; // bigger than all
if( (*off + count) > sizeof(wbuf)) { // truncate count if( (*off + count) > sizeof(wbuf)) { // truncate count
...@@ -826,7 +827,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of ...@@ -826,7 +827,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of
*off+=count; *off+=count;
return count; return count;
break; break;
case LOGGER_MINOR : case DEV393_MINOR(DEV393_LOGGER) :
#ifdef NC353 #ifdef NC353
updateNumBytesWritten(); updateNumBytesWritten();
#endif #endif
...@@ -944,13 +945,13 @@ static int logger_init(struct platform_device *pdev) ...@@ -944,13 +945,13 @@ static int logger_init(struct platform_device *pdev)
if (!match) if (!match)
return -EINVAL; return -EINVAL;
dev_dbg(dev, "Registering character device with name "LOGGER_DRIVER_NAME); dev_dbg(dev, "Registering character device with name "DEV393_NAME(DEV393_LOGGER));
res = register_chrdev(LOGGER_MAJOR, LOGGER_DRIVER_NAME, &imu_fops); res = register_chrdev(DEV393_MAJOR(DEV393_LOGGER), DEV393_NAME(DEV393_LOGGER), &imu_fops);
if(res < 0) { if(res < 0) {
dev_err(dev, "\nlogger_init: couldn't get a major number %d.\n ",LOGGER_MAJOR); dev_err(dev, "\nlogger_init: couldn't get a major number %d.\n ",DEV393_MAJOR(DEV393_LOGGER));
return res; return res;
} }
dev_info(dev,LOGGER_DRIVER_NAME"- %d\n",LOGGER_MAJOR); dev_info(dev,DEV393_NAME(DEV393_LOGGER)"- %d\n",DEV393_MAJOR(DEV393_LOGGER));
// Setup memory buffer from CMA // Setup memory buffer from CMA
logger_buffer = (u32 *) pElphel_buf->logger_vaddr; // must be page-aligned! logger_buffer = (u32 *) pElphel_buf->logger_vaddr; // must be page-aligned!
logger_size = pElphel_buf->logger_size << PAGE_SHIFT; logger_size = pElphel_buf->logger_size << PAGE_SHIFT;
...@@ -1236,7 +1237,7 @@ int x313_setDMA1Buffer(void) { ...@@ -1236,7 +1237,7 @@ int x313_setDMA1Buffer(void) {
static int logger_remove(struct platform_device *pdev) ///< [in] pointer to @e platform_device structure static int logger_remove(struct platform_device *pdev) ///< [in] pointer to @e platform_device structure
///< @return always 0 ///< @return always 0
{ {
unregister_chrdev(LOGGER_MAJOR, LOGGER_DRIVER_NAME); unregister_chrdev(DEV393_MAJOR(DEV393_LOGGER), DEV393_NAME(DEV393_LOGGER));
return 0; return 0;
} }
...@@ -1251,7 +1252,7 @@ static struct platform_driver elphel393_logger = { ...@@ -1251,7 +1252,7 @@ static struct platform_driver elphel393_logger = {
.probe = logger_init, .probe = logger_init,
.remove = logger_remove, .remove = logger_remove,
.driver = { .driver = {
.name = LOGGER_DRIVER_NAME, .name = DEV393_NAME(DEV393_LOGGER),
.of_match_table = elphel393_logger_of_match, .of_match_table = elphel393_logger_of_match,
}, },
}; };
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
//#include <asm/delay.h> //#include <asm/delay.h>
//#include <asm/uaccess.h> //#include <asm/uaccess.h>
#include <elphel/driver_numbers.h> #include <uapi/elphel/x393_devices.h>
#include <elphel/c313a.h> #include <elphel/c313a.h>
//#include <asm/elphel/fpgaconfa.h> //#include <asm/elphel/fpgaconfa.h>
#include <elphel/exifa.h> #include <elphel/exifa.h>
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
/** /**
* @brief driver name to display in log messages * @brief driver name to display in log messages
*/ */
#define IMAGEACQ_DRIVER_NAME "Elphel (R) Model 393 Image Acquisition device driver" #define IMAGEACQ_DRIVER_DESCRIPTION "Elphel (R) Model 393 Image Acquisition device driver"
/**@struct jpeg_ptr_t /**@struct jpeg_ptr_t
* @brief \e jpeg_ptr_t structure contains read and write pointers along with * @brief \e jpeg_ptr_t structure contains read and write pointers along with
...@@ -804,4 +804,4 @@ int image_acq_stop(struct platform_device *pdev) ...@@ -804,4 +804,4 @@ int image_acq_stop(struct platform_device *pdev)
//MODULE_LICENSE("GPL"); //MODULE_LICENSE("GPL");
//MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>."); //MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
//MODULE_DESCRIPTION(IMAGEACQ_DRIVER_NAME); //MODULE_DESCRIPTION(IMAGEACQ_DRIVER_DESCRIPTION);
...@@ -34,9 +34,9 @@ ...@@ -34,9 +34,9 @@
#include <asm/outercache.h> #include <asm/outercache.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/c313a.h> #include <uapi/elphel/c313a.h>
#include <uapi/elphel/exifa.h> #include <uapi/elphel/exifa.h>
//#include <uapi/elphel/x393_devices.h>
#include "framepars.h" #include "framepars.h"
#include "sensor_common.h" #include "sensor_common.h"
...@@ -52,8 +52,8 @@ ...@@ -52,8 +52,8 @@
#include <asm/delay.h> // just for usleep1000() #include <asm/delay.h> // just for usleep1000()
/** @brief Driver name to display in log messages.*/ /* Driver name to display in log messages.*/
#define IMAGEACQ_DRIVER_NAME "Elphel (R) Model 393 Image Acquisition device driver" //#define IMAGEACQ_DRIVER_DESCRIPTION "Elphel (R) Model 393 Image Acquisition device driver"
/** @brief The size in bytes of L2 cache invalidation area. This size must be aligned to cache line size. 16 kbytes seems to be good starting point.*/ /** @brief The size in bytes of L2 cache invalidation area. This size must be aligned to cache line size. 16 kbytes seems to be good starting point.*/
#define L2_INVAL_SIZE (32 * 1024) #define L2_INVAL_SIZE (32 * 1024)
...@@ -1031,4 +1031,4 @@ int legacy_i2c(int ports) ///< bitmask of the sensor ports to use ...@@ -1031,4 +1031,4 @@ int legacy_i2c(int ports) ///< bitmask of the sensor ports to use
//MODULE_LICENSE("GPL"); //MODULE_LICENSE("GPL");
//MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>."); //MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
//MODULE_DESCRIPTION(IMAGEACQ_DRIVER_NAME); //MODULE_DESCRIPTION(IMAGEACQ_DRIVER_DESCRIPTION);
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <elphel/driver_numbers.h> #include <uapi/elphel/x393_devices.h> // just driver name
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "x393.h" #include "x393.h"
#include "sensor_i2c.h" #include "sensor_i2c.h"
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
#define SYSFS_READONLY 0444 #define SYSFS_READONLY 0444
#define SYSFS_WRITEONLY 0222 #define SYSFS_WRITEONLY 0222
#define DRV_NAME "elphel_sensor_i2c" //#define DRV_NAME "elphel_sensor_i2c"
struct x393_i2c_device_list { struct x393_i2c_device_list {
x393_i2c_device_t i2c_dev; x393_i2c_device_t i2c_dev;
...@@ -1400,7 +1400,7 @@ static struct platform_driver elphel393_sensor_i2c = { ...@@ -1400,7 +1400,7 @@ static struct platform_driver elphel393_sensor_i2c = {
.probe = elphel393_sensor_i2c_probe, ///< Function executed on probe operation .probe = elphel393_sensor_i2c_probe, ///< Function executed on probe operation
.remove = elphel393_sensor_i2c_remove, ///< Function executed on remove operation .remove = elphel393_sensor_i2c_remove, ///< Function executed on remove operation
.driver = { ///< Driver specifications .driver = { ///< Driver specifications
.name = "elphel393-sensor-i2c", ///< driver name .name = DEV393_NAME(DEV393_I2C_SENSORS), ///< driver name
.owner = THIS_MODULE, ///< Driver owner .owner = THIS_MODULE, ///< Driver owner
.of_match_table = elphel393_sensor_i2c_of_match, ///< Device tree match data .of_match_table = elphel393_sensor_i2c_of_match, ///< Device tree match data
.pm = NULL, ///< No power management supported in this driver .pm = NULL, ///< No power management supported in this driver
......
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
#ifndef _X393_MACRO #ifndef _X393_MACRO
#define _X393_MACRO #define _X393_MACRO
#include <elphel/driver_numbers.h> #include <uapi/elphel/x393_devices.h>
/** @brief Resolution of current/OEF pointer in bits */ /** @brief Resolution of current/OEF pointer in bits */
#define OFFSET256_CNTR_RES 26 #define OFFSET256_CNTR_RES 26
...@@ -75,7 +76,7 @@ ...@@ -75,7 +76,7 @@
static inline unsigned int minor_to_chn(unsigned int minor, unsigned int *dev_type) static inline unsigned int minor_to_chn(unsigned int minor, unsigned int *dev_type)
{ {
if (dev_type != NULL) { if (dev_type != NULL) {
if ((minor & 0xf0) == CIRCBUF_MINOR || (minor & 0xf0) == HUFFMAN_MINOR || (minor & 0xf0) == JPEGHEAD_MINOR) if ((minor & 0xf0) == DEV393_MINOR(DEV393_CIRCBUF0) || (minor & 0xf0) == DEV393_MINOR(DEV393_HUFFMAN0) || (minor & 0xf0) == DEV393_MINOR(DEV393_JPEGHEAD0))
*dev_type = minor & 0xf0; *dev_type = minor & 0xf0;
else else
*dev_type = 0; *dev_type = 0;
......
...@@ -27,13 +27,13 @@ ...@@ -27,13 +27,13 @@
#include "x393.h" #include "x393.h"
#include "x393_videomem.h" #include "x393_videomem.h"
#include <elphel/driver_numbers.h>
#include <uapi/elphel/c313a.h> #include <uapi/elphel/c313a.h>
#include <uapi/elphel/x393_devices.h>
#define VIDEOMEM_MODULE_DESCRIPTION "Video buffer driver" #define VIDEOMEM_MODULE_DESCRIPTION "Video buffer driver"
#define VIDEOMEM_DRIVER_NAME "video_mem" //#define VIDEOMEM_DRIVER_NAME "video_mem"
static const struct of_device_id elphel393_videomem_of_match[]; static const struct of_device_id elphel393_videomem_of_match[];
static struct device *g_dev_ptr; ///< Global pointer to basic device structure. This pointer is used in debugfs output functions static struct device *g_dev_ptr; ///< Global pointer to basic device structure. This pointer is used in debugfs output functions
...@@ -542,10 +542,12 @@ static int videomem_probe(struct platform_device *pdev) ...@@ -542,10 +542,12 @@ static int videomem_probe(struct platform_device *pdev)
// Add sysfs modification // Add sysfs modification
dev_dbg(dev, "Registering character device with name "VIDEOMEM_DRIVER_NAME); dev_dbg(dev, "Registering character device with name "DEV393_NAME(DEV393_VIDEOMEM_RAW));
res = register_chrdev(VIDEOMEM_MAJOR, VIDEOMEM_DRIVER_NAME, &videomem_fops); // res = register_chrdev(VIDEOMEM_MAJOR, VIDEOMEM_DRIVER_NAME, &videomem_fops);
res = register_chrdev(DEV393_MAJOR(DEV393_VIDEOMEM_RAW), DEV393_NAME(DEV393_VIDEOMEM_RAW), &videomem_fops);
if(res < 0) { if(res < 0) {
dev_err(dev, "\videomem_probe: couldn't get a major number %d.\n ",VIDEOMEM_MAJOR); dev_err(dev, "\videomem_probe: couldn't get a major number %d.\n ",DEV393_MAJOR(DEV393_VIDEOMEM_RAW));
return res; return res;
} }
// Setup interrupt // Setup interrupt
...@@ -569,7 +571,7 @@ static int videomem_probe(struct platform_device *pdev) ...@@ -569,7 +571,7 @@ static int videomem_probe(struct platform_device *pdev)
static int videomem_remove(struct platform_device *pdev) ///< [in] pointer to @e platform_device structure static int videomem_remove(struct platform_device *pdev) ///< [in] pointer to @e platform_device structure
///< @return always 0 ///< @return always 0
{ {
unregister_chrdev(VIDEOMEM_MAJOR, VIDEOMEM_DRIVER_NAME); unregister_chrdev(DEV393_MAJOR(DEV393_VIDEOMEM_RAW), DEV393_NAME(DEV393_VIDEOMEM_RAW));
return 0; return 0;
} }
...@@ -585,7 +587,7 @@ static struct platform_driver elphel393_videomem = { ...@@ -585,7 +587,7 @@ static struct platform_driver elphel393_videomem = {
.probe = videomem_probe, .probe = videomem_probe,
.remove = videomem_remove, .remove = videomem_remove,
.driver = { .driver = {
.name = VIDEOMEM_DRIVER_NAME, .name = DEV393_NAME(DEV393_VIDEOMEM_RAW),
.of_match_table = elphel393_videomem_of_match, .of_match_table = elphel393_videomem_of_match,
}, },
}; };
......
/// driver_numbers.h /// driver_numbers.h
/// see packages/devices/elphel/Makefile - major numbers should match /// see packages/devices/elphel/Makefile - major numbers should match
/*
//#define CMOSCAM_MAJOR 126 #define LLL1 ("one", 2, 3, 4)
#define X3X3_EXIF_MAJOR 125 #define lll_first(n, ...) n
#define ELPHEL_MAJOR 126 #define lll_second(x,n, ...) n
#define STREAM_MAJOR 127 const char * ccc1 = lll_first LLL1;
#define FPGA_MAJOR 129 const int iii2 = lll_second LLL1;
#define FPGA_JTAG_MAJOR 132 #define xxx lll_first LLL1
#define FPGA_CLOCK_MAJOR 133 const char *ccc2 = xxx;
#define X3X3_I2C_MAJOR 134 */
#define CIRCBUF_MAJOR 135 //#define CMOSCAM_MAJOR 126
#define X3X3_EXIF_MAJOR 125 // DONE!
#define ELPHEL_MAJOR 126 // NOT Used
#define STREAM_MAJOR 127 // Not used (was in sensor_common.c, but no operations)
#define FPGA_MAJOR 129 // Not used in 393 - was for direct FP:GA access (register, tables, sdram) (/fpgaio, /fsdram, /fpga_tables)
// @$(MKNOD) -m 0666 $(DEV)/autoexp c 131 1 - was already rotten
#define FPGA_JTAG_MAJOR 132
#define FPGA_CLOCK_MAJOR 133
#define X3X3_I2C_MAJOR 134
#define CIRCBUF_MAJOR 135
//#define FRAMEPARS_MAJOR 136 //#define FRAMEPARS_MAJOR 136
#define FRAMEPARS_MAJOR 130 #define FRAMEPARS_MAJOR 130
#define GAMMAS_MAJOR 137 #define GAMMAS_MAJOR 137
#define HISTOGRAMS_MAJOR 138 #define HISTOGRAMS_MAJOR 138
//#define IMAGERAW_MAJOR 139 //#define IMAGERAW_MAJOR 139
#define IMAGERAW_MAJOR 131 #define IMAGERAW_MAJOR 131
#define IMAGEACQ_MAJOR 140 #define IMAGEACQ_MAJOR 140
#define LOGGER_MAJOR 141 #define LOGGER_MAJOR 141
#define VIDEOMEM_MAJOR 142 // implement raw access to memory and/or 16-bit image buffers over membridge interface #define VIDEOMEM_MAJOR 142 // implement raw access to memory and/or 16-bit image buffers over membridge interface
#define DETECT_SENSORS_MAJOR 143 // Maybe not needed? #define DETECT_SENSORS_MAJOR 143 // Maybe not needed?
/// MINORS /// MINORS
#define LOGGER_MINOR 1 #define LOGGER_MINOR 1
#define LOGGER_CTL_MINOR 2 #define LOGGER_CTL_MINOR 2
#define IMAGERAW_MINOR_FRAME 1 #define IMAGERAW_MINOR_FRAME 1
#define IMAGERAW_MINOR_FPN 2 #define IMAGERAW_MINOR_FPN 2
#define IMAGERAW_MINOR_UNLOCK 3 #define IMAGERAW_MINOR_UNLOCK 3
#define CIRCBUF_MINOR 0x20 #define CIRCBUF_MINOR 0x20
#define CIRCBUF_MINOR_CHN_0 0x20 #define CIRCBUF_MINOR_CHN_0 0x20
#define CIRCBUF_MINOR_CHN_1 0x21 #define CIRCBUF_MINOR_CHN_1 0x21
#define CIRCBUF_MINOR_CHN_2 0x22 #define CIRCBUF_MINOR_CHN_2 0x22
#define CIRCBUF_MINOR_CHN_3 0x23 #define CIRCBUF_MINOR_CHN_3 0x23
#define JPEGHEAD_MINOR 0x30 #define JPEGHEAD_MINOR 0x30
#define JPEGHEAD_MINOR_CHN_0 0x30 #define JPEGHEAD_MINOR_CHN_0 0x30
#define JPEGHEAD_MINOR_CHN_1 0x31 #define JPEGHEAD_MINOR_CHN_1 0x31
#define JPEGHEAD_MINOR_CHN_2 0x32 #define JPEGHEAD_MINOR_CHN_2 0x32
#define JPEGHEAD_MINOR_CHN_3 0x33 #define JPEGHEAD_MINOR_CHN_3 0x33
#define HUFFMAN_MINOR 0x40 #define HUFFMAN_MINOR 0x40
#define HUFFMAN_MINOR_CHN_0 0x40 #define HUFFMAN_MINOR_CHN_0 0x40
#define HUFFMAN_MINOR_CHN_1 0x41 #define HUFFMAN_MINOR_CHN_1 0x41
#define HUFFMAN_MINOR_CHN_2 0x42 #define HUFFMAN_MINOR_CHN_2 0x42
#define HUFFMAN_MINOR_CHN_3 0x43 #define HUFFMAN_MINOR_CHN_3 0x43
#define CMOSCAM_MINOR_FRAMEPARS_CHN_0 0x50 #define CMOSCAM_MINOR_FRAMEPARS_CHN_0 0x50
#define CMOSCAM_MINOR_FRAMEPARS_CHN_1 0x51 #define CMOSCAM_MINOR_FRAMEPARS_CHN_1 0x51
#define CMOSCAM_MINOR_FRAMEPARS_CHN_2 0x52 #define CMOSCAM_MINOR_FRAMEPARS_CHN_2 0x52
#define CMOSCAM_MINOR_FRAMEPARS_CHN_3 0x53 #define CMOSCAM_MINOR_FRAMEPARS_CHN_3 0x53
#define CMOSCAM_MINOR_RWTABLES 9 #define CMOSCAM_MINOR_RWTABLES 9
#define CMOSCAM_MINOR_CIRCBUF 11 #define CMOSCAM_MINOR_CIRCBUF 11
#define CMOSCAM_MINOR_HISTOGRAM 12 #define CMOSCAM_MINOR_HISTOGRAM 12
#define CMOSCAM_MINOR_JPEAGHEAD 13 #define CMOSCAM_MINOR_JPEAGHEAD 13
#define CMOSCAM_MINOR_GAMMA 14 #define CMOSCAM_MINOR_GAMMA 14
#define CMOSCAM_MINOR_FRAMEPARS 16 #define CMOSCAM_MINOR_FRAMEPARS 16
#define CMOSCAM_MINOR_GAMMAS 17 #define CMOSCAM_MINOR_GAMMAS 17
#define CMOSCAM_MINOR_HISTOGRAMS 18 #define CMOSCAM_MINOR_HISTOGRAMS 18
#define CMOSCAM_MINOR_IMAGEACQ 19 #define CMOSCAM_MINOR_IMAGEACQ 19
#define CMOSCAM_MINOR_HUFFMAN 20 #define CMOSCAM_MINOR_HUFFMAN 20
#define FPGACONF_MINOR_IORW 3 /* direct R/W FPGA registers */ #define FPGACONF_MINOR_IORW 3 ///< direct R/W FPGA registers
#define FPGACONF_MINOR_SDRAM 4 /* read/write SDRAM through PIO */ #define FPGACONF_MINOR_SDRAM 4 ///< read/write SDRAM through PIO
#define FPGACONF_MINOR_TABLES 6 /// Write FPGA tables directly #define FPGACONF_MINOR_TABLES 6 ///< Write FPGA tables directly
#define FPGA_CLOCK_MINOR 2 #define FPGA_CLOCK_MINOR 2
#define FPGA_CLOCK_MINOR_I2C 2 #define FPGA_CLOCK_MINOR_I2C 2
#define FPGA_CLOCK_MINOR_CLOCKS 3 #define FPGA_CLOCK_MINOR_CLOCKS 3
#define FPGA_JTAG_RESET_MINOR 0 // just close open files #define FPGA_JTAG_RESET_MINOR 0 // just close open files
#define FPGA_JTAG_RAW_MINOR 0 // just close open files #define FPGA_JTAG_RAW_MINOR 0 // just close open files
#define FPGA_JTAG_MINOR 1 #define FPGA_JTAG_MINOR 1
#define FPGA_SJTAG_MINOR 2 #define FPGA_SJTAG_MINOR 2
#define FPGA_AJTAG_MINOR 3 #define FPGA_AJTAG_MINOR 3
#define FPGA_JTAG_BOUNDARY_MINOR 5 // read/write boundary pins of the main FPGA #define FPGA_JTAG_BOUNDARY_MINOR 5 // read/write boundary pins of the main FPGA
#define FPGA_SJTAG_BOUNDARY_MINOR 6 // read/write boundary pins of the sensor board FPGA #define FPGA_SJTAG_BOUNDARY_MINOR 6 // read/write boundary pins of the sensor board FPGA
#define FPGA_AJTAG_BOUNDARY_MINOR 7 // read/write boundary pins of the aux board FPGA #define FPGA_AJTAG_BOUNDARY_MINOR 7 // read/write boundary pins of the aux board FPGA
#define FPGA_SJTAG_CHANNELS 4 // Number of sensor ports for JTAG #define FPGA_SJTAG_CHANNELS 4 // Number of sensor ports for JTAG
#define FPGA_SJTAG_MINOR_OFFSET 8 // Minors range start for the sensor port JTAG #define FPGA_SJTAG_MINOR_OFFSET 8 // Minors range start for the sensor port JTAG
#define FPGA_SJTAG_BOUNDARY_OFFSET 12 // Minors range start for the sensor port boundary #define FPGA_SJTAG_BOUNDARY_OFFSET 12 // Minors range start for the sensor port boundary
//#define X3X3_EXIF_EXIF 0 // read encoded Exif data (SEEK_END, //#define X3X3_EXIF_EXIF 0 // read encoded Exif data (SEEK_END,
//#define X3X3_EXIF_META 1 // write metadata, concurently opened files. All writes atomic //#define X3X3_EXIF_META 1 // write metadata, concurently opened files. All writes atomic
// control/setup devices // control/setup devices
#define X3X3_EXIF_TEMPLATE 2 // write Exif template #define X3X3_EXIF_TEMPLATE 2 // write Exif template
#define X3X3_EXIF_METADIR 3 // write metadata to Exif header translation (dir_table[MAX_EXIF_FIELDS]) #define X3X3_EXIF_METADIR 3 // write metadata to Exif header translation (dir_table[MAX_EXIF_FIELDS])
// those 2 files will disable exif_enable and exif_valid, truncate file size to file pointer on release. // those 2 files will disable exif_enable and exif_valid, truncate file size to file pointer on release.
#define X3X3_EXIF_TIME 4 // write today/tomorrow date (YYYY:MM:DD) and number of seconds at today/tomorrow #define X3X3_EXIF_TIME 4 // write today omorrow date (YYYY:MM:DD) and number of seconds at today omorrow
// midnight (00:00:00) in seconds from epoch (long, startting from LSB) // midnight (00:00:00) in seconds from epoch (long, startting from LSB)
#define X3X3_EXIF_EXIF_CHN_0 0x10 // read encoded Exif data (SEEK_END, #define X3X3_EXIF_EXIF_CHN_0 0x10 // read encoded Exif data (SEEK_END,
#define X3X3_EXIF_EXIF_CHN_1 0x11 // read encoded Exif data (SEEK_END, #define X3X3_EXIF_EXIF_CHN_1 0x11 // read encoded Exif data (SEEK_END,
#define X3X3_EXIF_EXIF_CHN_2 0x12 // read encoded Exif data (SEEK_END, #define X3X3_EXIF_EXIF_CHN_2 0x12 // read encoded Exif data (SEEK_END,
#define X3X3_EXIF_EXIF_CHN_3 0x13 // read encoded Exif data (SEEK_END, #define X3X3_EXIF_EXIF_CHN_3 0x13 // read encoded Exif data (SEEK_END,
#define X3X3_EXIF_META_CHN_0 0x20 // write metadata, concurently opened files. All writes atomic #define X3X3_EXIF_META_CHN_0 0x20 // write metadata, concurently opened files. All writes atomic
#define X3X3_EXIF_META_CHN_1 0x21 // write metadata, concurently opened files. All writes atomic #define X3X3_EXIF_META_CHN_1 0x21 // write metadata, concurently opened files. All writes atomic
#define X3X3_EXIF_META_CHN_2 0x22 // write metadata, concurently opened files. All writes atomic #define X3X3_EXIF_META_CHN_2 0x22 // write metadata, concurently opened files. All writes atomic
#define X3X3_EXIF_META_CHN_3 0x23 // write metadata, concurently opened files. All writes atomic #define X3X3_EXIF_META_CHN_3 0x23 // write metadata, concurently opened files. All writes atomic
...@@ -4,4 +4,5 @@ ...@@ -4,4 +4,5 @@
header-y += exifa.h header-y += exifa.h
header-y += c313a.h header-y += c313a.h
header-y += x393_devices.h
...@@ -120,6 +120,8 @@ ...@@ -120,6 +120,8 @@
#define MCPwrseq 0x200 #define MCPwrseq 0x200
#else #else
// Temporarily porting, to use only bus = 1 (GPS, IMU) // Temporarily porting, to use only bus = 1 (GPS, IMU)
// Moved to include/uapi/elphel/x393_devices.h
#if 0
#define X3X3_I2C_CTRL 0 ///< control/reset i2c #define X3X3_I2C_CTRL 0 ///< control/reset i2c
#define X3X3_I2C_8_AINC 1 ///< 8bit registers, autoincement while read/write #define X3X3_I2C_8_AINC 1 ///< 8bit registers, autoincement while read/write
#define X3X3_I2C_16_AINC 2 ///< 16bit registers, autoincement while read/write #define X3X3_I2C_16_AINC 2 ///< 16bit registers, autoincement while read/write
...@@ -128,6 +130,7 @@ ...@@ -128,6 +130,7 @@
#define X3X3_I2C_RAW 5 ///< 8bit registers, no address byte (just slave, then read/write byte(s) #define X3X3_I2C_RAW 5 ///< 8bit registers, no address byte (just slave, then read/write byte(s)
#define X3X3_I2C1_RAW 6 ///< 8bit registers, no address byte (just slave, then read/write byte(s) #define X3X3_I2C1_RAW 6 ///< 8bit registers, no address byte (just slave, then read/write byte(s)
#define X3X3_I2C_ENABLE 7 ///< enable(/protect) different I2C devices for different types of I2C accesses #define X3X3_I2C_ENABLE 7 ///< enable(/protect) different I2C devices for different types of I2C accesses
#endif
#define X3X3_I2C_ENABLE_RD 0 ///< bit 0 - enable i2c read #define X3X3_I2C_ENABLE_RD 0 ///< bit 0 - enable i2c read
#define X3X3_I2C_ENABLE_WR 1 ///< bit 1 - enable i2c write #define X3X3_I2C_ENABLE_WR 1 ///< bit 1 - enable i2c write
#define X3X3_I2C_ENABLE_RAW 2 ///< bit 2 - enable i2c raw (no address byte) #define X3X3_I2C_ENABLE_RAW 2 ///< bit 2 - enable i2c raw (no address byte)
...@@ -1478,7 +1481,7 @@ struct p_names_t { ...@@ -1478,7 +1481,7 @@ struct p_names_t {
#define LSEEK_HIST_WAIT_C 0x29 ///< set histogram waiting for the C (actually R, G2, B) histograms to become available - implies G1 too #define LSEEK_HIST_WAIT_C 0x29 ///< set histogram waiting for the C (actually R, G2, B) histograms to become available - implies G1 too
#define LSEEK_HIST_REQ_EN 0x2a ///< enable histogram request when reading histogram (safer, but may be not desirable in HDR mode) - default after opening #define LSEEK_HIST_REQ_EN 0x2a ///< enable histogram request when reading histogram (safer, but may be not desirable in HDR mode) - default after opening
#define LSEEK_HIST_REQ_DIS 0x2b ///< disable histogram request when reading histogram - will read latest available relying it is available #define LSEEK_HIST_REQ_DIS 0x2b ///< disable histogram request when reading histogram - will read latest available relying it is available
#define LSEEK_HIST_SET_CHN 0x30 ///< ..2F Select channel to wait for (4*port+subchannel) #define LSEEK_HIST_SET_CHN 0x30 ///< ..3F Select channel to wait for (4*port+subchannel)
#define LSEEK_HIST_NEEDED 0x10000 ///< set histogram "needed" mask - 0x10000..0x1ffff #define LSEEK_HIST_NEEDED 0x10000 ///< set histogram "needed" mask - 0x10000..0x1ffff
//#define LSEEK_HIST_WAIT_AE 0x2a ///< wait for autoexposure enabled //#define LSEEK_HIST_WAIT_AE 0x2a ///< wait for autoexposure enabled
......
/***************************************************************************//**
* @file x393_devices.h
* @brief Definitions of static device files, major and minor numbers
* and userland.
* @copyright Copyright 2002-2016 (C) Elphel, Inc.
* @par <b>License</b>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
#define DEV393_EXIF_TEMPLATE ("exif_template", "exif_elphel", 125, 2, "0666", "c") ///< write Exif template
#define DEV393_EXIF_METADIR ("exif_metadir", "exif_elphel", 125, 3, "0666", "c") ///< write metadata to Exif header translation (dir_table[MAX_EXIF_FIELDS])
#define DEV393_EXIF_TIME ("exif_time", "exif_elphel", 125, 4, "0666", "c") ///< write today/tomorrow date (YYYY:MM:DD) and number of seconds at today/tomorrow
///< midnight (00:00:00) in seconds from epoch (long, startting from LSB)
#define DEV393_EXIF0 ("exif_exif0", "exif_elphel", 125, 16, "0666", "c") ///< sensor port 0: read encoded Exif data (SEEK_END)
#define DEV393_EXIF1 ("exif_exif1", "exif_elphel", 125, 17, "0666", "c") ///< sensor port 1: read encoded Exif data (SEEK_END)
#define DEV393_EXIF2 ("exif_exif2", "exif_elphel", 125, 18, "0666", "c") ///< sensor port 2: read encoded Exif data (SEEK_END)
#define DEV393_EXIF3 ("exif_exif3", "exif_elphel", 125, 19, "0666", "c") ///< sensor port 3: read encoded Exif data (SEEK_END)
#define DEV393_EXIF_META0 ("exif_meta0", "exif_elphel", 125, 32, "0666", "c") ///< sensor port 0: write metadata, concurrently opened files. All writes atomic
#define DEV393_EXIF_META1 ("exif_meta1", "exif_elphel", 125, 33, "0666", "c") ///< sensor port 1: write metadata, concurrently opened files. All writes atomic
#define DEV393_EXIF_META2 ("exif_meta2", "exif_elphel", 125, 34, "0666", "c") ///< sensor port 2: write metadata, concurrently opened files. All writes atomic
#define DEV393_EXIF_META3 ("exif_meta3", "exif_elphel", 125, 35, "0666", "c") ///< sensor port 3: write metadata, concurrently opened files. All writes atomic
#define DEV393_FRAMEPARS0 ("frameparsall0","framepars_operations",125,80, "0666", "c") ///< Access frame parameters for channel 0 (schedule modification, read with mmap)
#define DEV393_FRAMEPARS1 ("frameparsall1","framepars_operations",125,81, "0666", "c") ///< Access frame parameters for channel 1 (schedule modification, read with mmap)
#define DEV393_FRAMEPARS2 ("frameparsall2","framepars_operations",125,82, "0666", "c") ///< Access frame parameters for channel 2 (schedule modification, read with mmap)
#define DEV393_FRAMEPARS3 ("frameparsall3","framepars_operations",125,83, "0666", "c") ///< Access frame parameters for channel 3 (schedule modification, read with mmap)
#define DEV393_JTAG_RESET ("fpgaresetjtag", "x393_jtag", 132, 0, "0666", "c") ///< Just close open files (same as jtagraw)
#define DEV393_JTAG_RAW ("jtagraw", "x393_jtag", 132, 0, "0666", "c") ///< Just close open files (same as jtagraw)
#define DEV393_JTAGS_CONF0 ("sfpgaconfjtag0", "x393_jtag", 132, 8, "0666", "c") ///< JTAG configure sensor port 0 FPGA
#define DEV393_JTAGS_CONF1 ("sfpgaconfjtag1", "x393_jtag", 132, 9, "0666", "c") ///< JTAG configure sensor port 1 FPGA
#define DEV393_JTAGS_CONF2 ("sfpgaconfjtag2", "x393_jtag", 132, 10, "0666", "c") ///< JTAG configure sensor port 2 FPGA
#define DEV393_JTAGS_CONF3 ("sfpgaconfjtag3", "x393_jtag", 132, 11, "0666", "c") ///< JTAG configure sensor port 3 FPGA
#define DEV393_JTAGS_BSCAN0 ("sfpgabscan0", "x393_jtag", 132, 12, "0666", "c") ///< JTAG boundary scan sensor port 0 FPGA
#define DEV393_JTAGS_BSCAN1 ("sfpgabscan1", "x393_jtag", 132, 13, "0666", "c") ///< JTAG boundary scan sensor port 1 FPGA
#define DEV393_JTAGS_BSCAN2 ("sfpgabscan2", "x393_jtag", 132, 14, "0666", "c") ///< JTAG boundary scan sensor port 2 FPGA
#define DEV393_JTAGS_BSCAN3 ("sfpgabscan3", "x393_jtag", 132, 15, "0666", "c") ///< JTAG boundary scan sensor port 3 FPGA
#define DEV393_I2C_CTRL ("xi2cctl", "fpga_xi2c", 134, 0, "0666", "c") ///< control/reset i2c
#define DEV393_I2C_8_AINC ("xi2c8", "fpga_xi2c", 134, 1, "0666", "c") ///< 8bit registers, autoincrement while read/write (NC393: Not used)
#define DEV393_I2C_16_AINC ("xi2c16", "fpga_xi2c", 134, 2, "0666", "c") ///< 16bit registers, autoincrement while read/write (NC393: Not used)
#define DEV393_I2C1_8_AINC ("xi2c8_aux", "fpga_xi2c", 134, 3, "0666", "c") ///< 8bit registers, autoincrement while read/write (bus 1)
#define DEV393_I2C1_16_AINC ("xi2c16_aux", "fpga_xi2c", 134, 4, "0666", "c") ///< 16bit registers, autoincrement while read/write (bus 1)
#define DEV393_I2C_RAW ("xi2craw", "fpga_xi2c", 134, 5, "0666", "c") ///< 8bit registers, no address byte (just slave, then read/write byte(s) (NC393: Not used)
#define DEV393_I2C1_RAW ("xi2craw_aux", "fpga_xi2c", 134, 6, "0666", "c") ///< 8bit registers, no address byte (just slave, then read/write byte(s) bus 1
#define DEV393_I2C_ENABLE ("xi2cenable", "fpga_xi2c", 134, 7, "0666", "c") ///< enable(/protect) different I2C devices for different types of I2C accesses
#define DEV393_CIRCBUF0 ("circbuf0", "circbuf", 135, 32, "0666", "c") ///< circbuf for channel 0
#define DEV393_CIRCBUF1 ("circbuf1", "circbuf", 135, 33, "0666", "c") ///< circbuf for channel 1
#define DEV393_CIRCBUF2 ("circbuf2", "circbuf", 135, 34, "0666", "c") ///< circbuf for channel 2
#define DEV393_CIRCBUF3 ("circbuf3", "circbuf", 135, 35, "0666", "c") ///< circbuf for channel 3
#define DEV393_JPEGHEAD0 ("jpeghead0", "circbuf", 135, 48, "0666", "c") ///< JPEG header for channel 0
#define DEV393_JPEGHEAD1 ("jpeghead1", "circbuf", 135, 49, "0666", "c") ///< JPEG header for channel 1
#define DEV393_JPEGHEAD2 ("jpeghead2", "circbuf", 135, 50, "0666", "c") ///< JPEG header for channel 2
#define DEV393_JPEGHEAD3 ("jpeghead3", "circbuf", 135, 51, "0666", "c") ///< JPEG header for channel 3
#define DEV393_HUFFMAN0 ("huffman0", "circbuf", 135, 64, "0666", "c") ///< Huffman table for channel 0
#define DEV393_HUFFMAN1 ("huffman1", "circbuf", 135, 65, "0666", "c") ///< Huffman table for channel 1
#define DEV393_HUFFMAN2 ("huffman2", "circbuf", 135, 66, "0666", "c") ///< Huffman table for channel 2
#define DEV393_HUFFMAN3 ("huffman3", "circbuf", 135, 67, "0666", "c") ///< Huffman table for channel 3
#define DEV393_GAMMA ("gamma_cache","gamma_tables_operations",137,17,"0666", "c") ///< Cache for calculated gamma tables (common for all ports/channels/colors)
#define DEV393_HISTOGRAM ("histogram_cache","histograms_operations",138,18,"0666","c") ///< Access to acquired/calculated histograms for all ports/channels/colors
#define DEV393_LOGGER ("imu", "imu_logger", 141, 1, "0666", "c") ///< IMU/GPS/images logs data access
#define DEV393_LOGGER_CTRL ("imu_ctl", "imu_logger", 141, 2, "0666", "c") ///< IMU/GPS/images logger control
// Video memory access uses a single (shared) membridge module, so device driver should have exclusive access
#define DEV393_VIDEOMEM_RAW ("videomem_raw", "video_mem", 142, 1, "0666", "c") ///< Raw access to video memory using membridge module (NC393: Not yet implemented)
#define DEV393_IMAGE_RAW ("image_raw", "video_mem", 142, 2, "0666", "c") ///< Access to raw (uncompressed) data in video memory, frame-organized
#define DEV393_DETECT_SENSORS ("detect_sensors", "detect_sensors",143, 1, "0666", "c") ///< Probably not needed, only sysfs is used
#define DEV393_I2C_SENSORS ("", "elphel393-sensor-i2c",-1, -1, "0666", "c") ///< Used only in sysfs, no character device (yet?)
#define _DEV393_PATH(n, ...) "/dev/"n
#define _DEV393_NAME(a,n, ...) n
#define _DEV393_MAJOR(a,b,n, ...) n
#define _DEV393_MINOR(a,b,c,n, ...) n
#define _DEV393_PERMISSIONS(a,b,c,d,n, ...) n
#define _DEV393_TYPE(a,b,c,d,e,n,...) n
#define DEV393_PATH(LIST) _DEV393_PATH LIST
#define DEV393_NAME(LIST) _DEV393_NAME LIST
#define DEV393_MAJOR(LIST) _DEV393_MAJOR LIST
#define DEV393_MINOR(LIST) _DEV393_MINOR LIST
#define DEV393_PERMISSIONS(LIST) _DEV393_PERMISSIONS LIST
#define DEV393_TYPE(LIST) _DEV393_TYPE LIST
char * aaa = DEV393_PATH(DEV393_HUFFMAN0);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment