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 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <asm/uaccess.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/c313a.h>
#include <elphel/elphel393-mem.h>
......@@ -47,7 +47,7 @@
#include "x393_helpers.h"
/** @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 */
wait_queue_head_t circbuf_wait_queue;
......@@ -115,13 +115,13 @@ int circbuf_all_open(struct inode *inode, struct file *filp)
minor_to_chn(minor, &dev_type);
switch (dev_type) {
case CIRCBUF_MINOR:
case DEV393_MINOR(DEV393_CIRCBUF0):
res = circbuf_open(inode, filp);
break;
case JPEGHEAD_MINOR:
case DEV393_MINOR(DEV393_JPEGHEAD0):
res = jpeghead_open(inode, filp);
break;
case HUFFMAN_MINOR:
case DEV393_MINOR(DEV393_HUFFMAN0):
res = huffman_open(inode, filp);
break;
default:
......@@ -146,13 +146,13 @@ int circbuf_all_release(struct inode *inode, struct file *filp)
minor_to_chn(minor, &dev_type);
switch (dev_type) {
case CIRCBUF_MINOR:
case DEV393_MINOR(DEV393_CIRCBUF0):
// res=circbuf_release(inode,filp);
break;
case JPEGHEAD_MINOR:
case DEV393_MINOR(DEV393_JPEGHEAD0):
// res=jpeghead_release(inode,filp);
break;
case HUFFMAN_MINOR:
case DEV393_MINOR(DEV393_HUFFMAN0):
// res=huffman_release(inode,filp);
break;
default:
......@@ -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);
switch (dev_type) {
case CIRCBUF_MINOR:
case DEV393_MINOR(DEV393_CIRCBUF0):
return circbuf_lseek(file, offset, orig);
case JPEGHEAD_MINOR:
case DEV393_MINOR(DEV393_JPEGHEAD0):
if (orig == SEEK_END && offset > 0) {
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];
}
return jpeghead_lseek(file, offset, orig, fp);
case HUFFMAN_MINOR:
case DEV393_MINOR(DEV393_HUFFMAN0):
return huffman_lseek(file, offset, orig);
default:
return -EINVAL;
......@@ -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);
switch (dev_type) {
case CIRCBUF_MINOR:
case DEV393_MINOR(DEV393_CIRCBUF0):
return circbuf_read(file, buf, count, off);
case JPEGHEAD_MINOR:
case DEV393_MINOR(DEV393_JPEGHEAD0):
return jpeghead_read(file, buf, count, off);
case HUFFMAN_MINOR:
case DEV393_MINOR(DEV393_HUFFMAN0):
return huffman_read(file, buf, count, off);
default:
return -EINVAL;
......@@ -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);
switch (dev_type) {
case CIRCBUF_MINOR:
case DEV393_MINOR(DEV393_CIRCBUF0):
return circbuf_write (file, buf, count, off);
case JPEGHEAD_MINOR:
case DEV393_MINOR(DEV393_JPEGHEAD0):
// no method for this module
return -EINVAL;
case HUFFMAN_MINOR:
case DEV393_MINOR(DEV393_HUFFMAN0):
return huffman_write (file, buf, count, off);
default:
return -EINVAL;
......@@ -268,7 +268,7 @@ int circbuf_all_mmap(struct file *file, struct vm_area_struct *vma)
minor_to_chn(minor, &dev_type);
switch (dev_type) {
case CIRCBUF_MINOR:
case DEV393_MINOR(DEV393_CIRCBUF0):
return circbuf_mmap(file, vma);
default:
return -EINVAL;
......@@ -292,7 +292,7 @@ unsigned int circbuf_all_poll(struct file *file, poll_table *wait)
minor_to_chn(minor, &dev_type);
switch (dev_type) {
case CIRCBUF_MINOR:
case DEV393_MINOR(DEV393_CIRCBUF0):
return circbuf_poll(file, wait);
default:
return 0;
......@@ -963,12 +963,12 @@ static int circbuf_all_init(struct platform_device *pdev)
return -EINVAL;
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) {
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;
}
dev_info(dev, "registered MAJOR: %d\n", CIRCBUF_MAJOR);
dev_info(dev, "registered MAJOR: %d\n", DEV393_MAJOR(DEV393_CIRCBUF0));
res = jpeghead_init(pdev);
if (res < 0) {
......@@ -1002,7 +1002,7 @@ static int circbuf_all_init(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;
}
......@@ -1017,7 +1017,7 @@ static struct platform_driver elphel393_circbuf = {
.probe = circbuf_all_init,
.remove = circbuf_remove,
.driver = {
.name = CIRCBUF_DRIVER_NAME,
.name = DEV393_NAME(DEV393_CIRCBUF0),
.of_match_table = elphel393_circbuf_of_match,
},
};
......@@ -1026,4 +1026,4 @@ module_platform_driver(elphel393_circbuf);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
MODULE_DESCRIPTION(CIRCBUF_DRIVER_NAME);
MODULE_DESCRIPTION(DEV393_NAME(DEV393_CIRCBUF0));
......@@ -96,7 +96,7 @@
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/c313a.h>
#include "x393.h"
......@@ -621,9 +621,9 @@ int i2c_ioctl(struct inode *inode, struct file *file,
//#define X3X3_I2C 134
// minors (add more later - maybe different minors for different speed - set speed when opening)
//#define X3X3_I2C_CTRL 0 // control/reset i2c
//#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 DEV393_MINOR(DEV393_I2C_CTRL) 0 // control/reset i2c
//#define DEV393_MINOR(DEV393_I2C_8_AINC) 1 // 8bit 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_CHANNELS 2
//#define X3X3_I2C_MAXMINOR 4 //
......@@ -662,18 +662,18 @@ int xi2c_open(struct inode *inode, struct file *filp) {
int bus=-1;
int * pd= (int *) &(filp->private_data);
switch (p) {
case X3X3_I2C_RAW:
case X3X3_I2C_8_AINC :
case X3X3_I2C_16_AINC :
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
bus=0;
break;
case X3X3_I2C1_RAW:
case X3X3_I2C1_8_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C1_RAW):
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
bus=1;
break;
case X3X3_I2C_ENABLE:
case X3X3_I2C_CTRL :
case DEV393_MINOR(DEV393_I2C_ENABLE):
case DEV393_MINOR(DEV393_I2C_CTRL) :
bus=-1;
break;
}
......@@ -685,22 +685,22 @@ int xi2c_open(struct inode *inode, struct file *filp) {
if (bus>=0) inuse[bus] =1;
switch ( p ) {
case X3X3_I2C_RAW:
case X3X3_I2C1_RAW:
case X3X3_I2C_8_AINC :
case X3X3_I2C1_8_AINC :
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C1_RAW):
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
inode->i_size=128*256;
burst_sizes[p]=1; //!fix for PHP read (always 8192) -> 1 byte/read
break;
case X3X3_I2C_16_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
inode->i_size=256*256;
burst_sizes[p]=2; //!fix for PHP read (always 8192) -> 2 bytes/read
break;
case X3X3_I2C_CTRL :
case DEV393_MINOR(DEV393_I2C_CTRL) :
inode->i_size=sizeof(bitdelays);
break;
case X3X3_I2C_ENABLE:
case DEV393_MINOR(DEV393_I2C_ENABLE):
inode->i_size=sizeof(i2c_enable);
break;
default:return -EINVAL;
......@@ -721,24 +721,24 @@ static int xi2c_release(struct inode *inode, struct file *filp){
int p = MINOR(inode->i_rdev);
int bus=-1;
switch (p) {
case X3X3_I2C_RAW:
case X3X3_I2C_8_AINC :
case X3X3_I2C_16_AINC :
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
bus=0;
break;
case X3X3_I2C1_RAW:
case X3X3_I2C1_8_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C1_RAW):
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
bus=1;
break;
case X3X3_I2C_ENABLE:
case X3X3_I2C_CTRL :
case DEV393_MINOR(DEV393_I2C_ENABLE):
case DEV393_MINOR(DEV393_I2C_CTRL) :
bus=-1;
break;
}
D(printk("xi2c_release, minor=%d\n",p));
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;
return 0;
}
......@@ -775,12 +775,12 @@ static loff_t xi2c_lseek(struct file * file, loff_t offset, int orig) {
}
// switch (((int *)file->private_data)[0]) {
switch (p) {
case X3X3_I2C_RAW:
case X3X3_I2C1_RAW:
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C1_RAW):
(file->f_pos) &= ~(0x7f); // zero out 7 MSBs
break;
case X3X3_I2C_16_AINC :
case X3X3_I2C1_16_AINC : {
case DEV393_MINOR(DEV393_I2C_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
break;
}
......@@ -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) {
case X3X3_I2C_RAW:
case X3X3_I2C_8_AINC :
case X3X3_I2C_16_AINC :
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
bus=0;
i2cbuf = &i2cbuf_all[0];
break;
case X3X3_I2C1_RAW:
case X3X3_I2C1_8_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C1_RAW):
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
bus=1;
i2cbuf = &i2cbuf_all[1*I2CBUFSIZE];
break;
// case X3X3_I2C_CTRL :
// case DEV393_MINOR(DEV393_I2C_CTRL) :
// i2cbuf = &i2cbuf_all[X3X3_I2C_CHANNELS*I2CBUFSIZE];
}
userbuf=&i2cbuf[1];
......@@ -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]) {
slave_adr=(p >> 7) & 0xfe;
switch ((int)file->private_data) {
case X3X3_I2C_RAW:
case X3X3_I2C1_RAW:
case X3X3_I2C_8_AINC :
case X3X3_I2C1_8_AINC :
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C1_RAW):
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
if (count == 8192) count=burst_sizes[(int)file->private_data]; //! PHP "feature" fix
break;
case X3X3_I2C_16_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
p&=0xfffffffe;
if (count == 8192) count=burst_sizes[(int)file->private_data]; //! PHP "feature" fix
if (count & 1) count++;
......@@ -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));
//! Verify if this slave is enabled for the I2C operation requested
switch ((int)file->private_data) {
case X3X3_I2C_RAW:
case X3X3_I2C1_RAW:
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C1_RAW):
en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_RAW);
break;
case X3X3_I2C_8_AINC :
case X3X3_I2C1_8_AINC :
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_8);
break;
case X3X3_I2C_16_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_16);
break;
}
switch ((int)file->private_data) {
case X3X3_I2C_RAW:
case X3X3_I2C_8_AINC :
case X3X3_I2C_16_AINC :
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
en_bits=i2c_enable[ slave_adr>>1 ];
break;
case X3X3_I2C1_RAW:
case X3X3_I2C1_8_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C1_RAW):
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
en_bits=i2c_enable[(slave_adr>>1) + 128];
break;
}
......@@ -895,14 +895,14 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
}
if (count==0) return 0;
switch ((int)file->private_data) {
case X3X3_I2C_RAW:
case X3X3_I2C1_RAW:
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C1_RAW):
i2cbuf[0]=p & 0xff;
error=i2c_readData (bus, slave_adr | 0x01, &i2cbuf[1], count, 1); // will start with start, not restart
if (error) return -EINVAL;
break;
case X3X3_I2C_8_AINC :
case X3X3_I2C1_8_AINC :
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
i2cbuf[0]=p & 0xff;
if (bus==0) {
......@@ -922,8 +922,8 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
if (error) return -EINVAL;
break;
case X3X3_I2C_16_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
i2cbuf[0]=(p>>1) & 0xff;
if (bus==0) {
......@@ -943,11 +943,11 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
if (error) return -EINVAL;
break;
case X3X3_I2C_CTRL :
case DEV393_MINOR(DEV393_I2C_CTRL) :
userbuf=&bbitdelays[*off];
// memcpy(&i2cbuf[1],&bbitdelays[*off],count);
break;
case X3X3_I2C_ENABLE:
case DEV393_MINOR(DEV393_I2C_ENABLE):
userbuf=&i2c_enable[*off];
break;
default:return -EINVAL;
......@@ -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
switch ((int)file->private_data) {
case X3X3_I2C_RAW:
case X3X3_I2C1_RAW:
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C1_RAW):
*off &= ~(0x7f); // zero out 7 MSBs
break;
default:
......@@ -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) {
case X3X3_I2C_RAW:
case X3X3_I2C_8_AINC :
case X3X3_I2C_16_AINC :
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
bus=0;
i2cbuf = &i2cbuf_all[0];
break;
case X3X3_I2C1_RAW:
case X3X3_I2C1_8_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C1_RAW):
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
bus=1;
i2cbuf = &i2cbuf_all[1*I2CBUFSIZE];
break;
// case X3X3_I2C_CTRL :
// case DEV393_MINOR(DEV393_I2C_CTRL) :
// i2cbuf = &i2cbuf_all[X3X3_I2C_CHANNELS*I2CBUFSIZE];
}
userbuf=&i2cbuf[1];
slave_adr=(p >> 7) & 0xfe;
switch ((int)file->private_data) {
case X3X3_I2C_16_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
p&=0xfffffffe;
if (count & 1) count++;
slave_adr=(p >> 8) & 0xfe;
......@@ -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
switch ((int)file->private_data) {
case X3X3_I2C_RAW:
case X3X3_I2C1_RAW:
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C1_RAW):
en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_RAW);
break;
case X3X3_I2C_8_AINC :
case X3X3_I2C1_8_AINC :
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_8);
break;
case X3X3_I2C_16_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_16);
break;
}
switch ((int)file->private_data) {
case X3X3_I2C_RAW:
case X3X3_I2C_8_AINC :
case X3X3_I2C_16_AINC :
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
en_bits=i2c_enable[ slave_adr>>1 ];
break;
case X3X3_I2C1_RAW:
case X3X3_I2C1_8_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C1_RAW):
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
en_bits=i2c_enable[(slave_adr>>1) + 128];
break;
}
......@@ -1058,10 +1058,10 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
if (count==0) return 0;
//!only for control files that write directly to static arrays, no buffering
switch ((int)file->private_data) {
case X3X3_I2C_CTRL :
case DEV393_MINOR(DEV393_I2C_CTRL) :
userbuf=&bbitdelays[p];
break;
case X3X3_I2C_ENABLE:
case DEV393_MINOR(DEV393_I2C_ENABLE):
userbuf=&i2c_enable[p];
break;
}
......@@ -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( userbuf, buf, count)) return -EFAULT;
switch ((int)file->private_data) {
case X3X3_I2C_RAW:
case X3X3_I2C1_RAW:
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C1_RAW):
if (bus==0) {
#ifdef NC353
......@@ -1087,8 +1087,8 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
if (error) return -EINVAL;
break;
case X3X3_I2C_8_AINC :
case X3X3_I2C1_8_AINC :
case DEV393_MINOR(DEV393_I2C_8_AINC) :
case DEV393_MINOR(DEV393_I2C1_8_AINC) :
i2cbuf[0]=p & 0xff;
if (bus==0) {
......@@ -1106,8 +1106,8 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
if (error) return -EINVAL;
break;
case X3X3_I2C_16_AINC :
case X3X3_I2C1_16_AINC :
case DEV393_MINOR(DEV393_I2C_16_AINC) :
case DEV393_MINOR(DEV393_I2C1_16_AINC) :
i2cbuf[0]=(p>>1) & 0xff;
if (bus==0) {
......@@ -1125,7 +1125,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
if (error) return -EINVAL;
break;
// case X3X3_I2C_CTRL :
// case DEV393_MINOR(DEV393_I2C_CTRL) :
// memcpy(&bbitdelays[*off],&i2cbuf[1],count);
// break;
default:return -EINVAL;
......@@ -1133,8 +1133,8 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
// *off+=count;
//! do not increment pointer for raw accesses
switch ((int)file->private_data) {
case X3X3_I2C_RAW:
case X3X3_I2C1_RAW:
case DEV393_MINOR(DEV393_I2C_RAW):
case DEV393_MINOR(DEV393_I2C1_RAW):
*off &= ~(0x7f); // zero out 7 MSBs
break;
default:
......@@ -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) {
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) {
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;
}
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;
bitdelays[0].scl_high=2; //! SCL high:
......@@ -1172,14 +1172,14 @@ static int __init xi2c_init(void) {
for (i=0; i<X3X3_I2C_CHANNELS;i++) {
inuse[i]=0;
}
sizes[X3X3_I2C_CTRL]= sizeof(bitdelays); // control/reset i2c
sizes[X3X3_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[X3X3_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[X3X3_I2C_RAW]= 128*256; // 8bit single register,
sizes[X3X3_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_CTRL)]= sizeof(bitdelays); // control/reset i2c
sizes[DEV393_MINOR(DEV393_I2C_8_AINC)]= 128*256; // 8bit registers, autoincement while read/write
sizes[DEV393_MINOR(DEV393_I2C_16_AINC)]= 256*256; // 16bit registers, autoincement while read/write
sizes[DEV393_MINOR(DEV393_I2C1_8_AINC)]= 128*256; // 8bit 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[DEV393_MINOR(DEV393_I2C_RAW)]= 128*256; // 8bit single register,
sizes[DEV393_MINOR(DEV393_I2C1_RAW)]= 128*256; // 8bit single register,
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
for (i=0; i<X3X3_I2C_CHANNELS*128; i++) i2c_enable[i]=0xff;
//! now protect known devices from undesired/unintended accesses:
......@@ -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_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_I2C1_RAW) 6 // 8bit registers, no address byte (just slave, then read/write byte(s)
//#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
//#define X3X3_I2C_ENABLE_RD 0 // bit 0 - enable i2c read
//#define X3X3_I2C_ENABLE_WR 1 // bit 1 - enable i2c write
......
......@@ -31,15 +31,13 @@
#include <linux/fs.h>
#include "x393.h"
//#include "x393_detect_sensors.h"
#include <elphel/driver_numbers.h>
#include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/c313a.h>
#include "mt9x001.h"
#include "multi10359.h"
#include "detect_sensors.h"
#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"
struct sensor_port_config_t
{
......@@ -359,31 +357,39 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev)
///< @return 0 on success, or negative error.
{
const char * config_string;
// struct x393_i2c_device_list * dl;
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_attribute *new_attr;
// struct device *dev =&pdev->dev;
int num_ports, port, num_sub, sub_chn;
if (node) {
if (num_ports > SENSOR_PORTS)
num_ports = SENSOR_PORTS;
config_string = of_get_property(node, OF_PREFIX_NAME",ports", NULL); // &len);
num_ports = sscanf(config_string,"%79s %79s %79s %79s", names[0], names[1], names[2], names[3]);
for (port = 0; port < num_ports; port++){
set_detected_mux_code(port, get_code_by_name(names[sub_chn], DETECT_MUX));
config_string = of_get_property(node, OF_PREFIX_NAME",port-mux", NULL); // &len);
pr_info ("Mux config_string = %s (was looking for '%s')\n",config_string, OF_PREFIX_NAME",port-mux");
if (config_string) {
num_ports = sscanf(config_string,"%79s %79s %79s %79s", names[0], names[1], names[2], names[3]);
if (num_ports > SENSOR_PORTS)
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");
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++){
if (of_property_read_string_index(node, OF_PREFIX_NAME",sensors", port, &config_string)) {
pr_err("%s: No data for selected port\n", __func__);
BUG();
}
num_sub = sscanf(config_string,"%79s %79s %79s %79s", names[0], names[1], names[2], names[3]);
for (sub_chn = 0; sub_chn < num_sub; sub_chn++){
set_detected_sensor_code(port, sub_chn, get_code_by_name(names[sub_chn], DETECT_SENSOR));
pr_info ("Sensor config_string = %s\n",config_string);
if (config_string) {
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)
// pSensorPortConfig = sensorPortConfig;
elphel393_detect_sensors_sysfs_register(pdev);
pr_info ("Registered sysfs for detect_sensors");
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);
return -EINVAL;
return -EINVAL;
}
detect_sensors_init_of(pdev);
// dev_dbg(dev, "Registering character device with name "DETECT_SENSORS_DRIVER_NAME);
// res = register_chrdev(DETECT_SENSORS_MAJOR, DETECT_SENSORS_DRIVER_NAME, &detect_sensors_fops);
// dev_dbg(dev, "Registering character device with name "DEV393_NAME(DEV393_DETECT_SENSORS));
// res = register_chrdev(DETECT_SENSORS_MAJOR, DEV393_NAME(DEV393_DETECT_SENSORS), &detect_sensors_fops);
// if(res < 0) {
// dev_err(dev, "\nlogger_init: couldn't get a major number %d.\n ",DETECT_SENSORS_MAJOR);
// return res;
......@@ -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
///< @return always 0
{
// unregister_chrdev(DETECT_SENSORS_MAJOR, DETECT_SENSORS_DRIVER_NAME);
// unregister_chrdev(DETECT_SENSORS_MAJOR, DEV393_NAME(DEV393_DETECT_SENSORS));
return 0;
}
......@@ -442,7 +449,7 @@ static int elphel393_detect_sensors_sysfs_register(struct platform_device *pdev)
.probe = detect_sensors_probe,
.remove = detect_sensors_remove,
.driver = {
.name = DETECT_SENSORS_DRIVER_NAME,
.name = DEV393_NAME(DEV393_DETECT_SENSORS),
.of_match_table = elphel393_detect_sensors_of_match,
},
};
......
......@@ -39,9 +39,9 @@
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/c313a.h>
#include <uapi/elphel/exifa.h>
#include <uapi/elphel/x393_devices.h>
//#include "fpgactrl.h" // defines port_csp0_addr, port_csp4_addr
//
......@@ -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);
//#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
switch (minor) {
case X3X3_EXIF_TEMPLATE:
return exif_template_size;
case X3X3_EXIF_EXIF_CHN_0:
case X3X3_EXIF_EXIF_CHN_1:
case X3X3_EXIF_EXIF_CHN_2:
case X3X3_EXIF_EXIF_CHN_3:
sensor_port = minor - X3X3_EXIF_EXIF_CHN_0;
case DEV393_MINOR(DEV393_EXIF0):
case DEV393_MINOR(DEV393_EXIF1):
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
sensor_port = minor - DEV393_MINOR(DEV393_EXIF0);
return aexif_enabled[sensor_port]? (exif_template_size * (MAX_EXIF_FRAMES+1)):0;
case X3X3_EXIF_META_CHN_0:
case X3X3_EXIF_META_CHN_1:
case X3X3_EXIF_META_CHN_2:
case X3X3_EXIF_META_CHN_3:
sensor_port = minor - X3X3_EXIF_META_CHN_0;
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
case DEV393_MINOR(DEV393_EXIF_META3):
sensor_port = minor - DEV393_MINOR(DEV393_EXIF_META0);
return aexif_meta_size[sensor_port];
case X3X3_EXIF_METADIR:
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
switch (minor) {
case X3X3_EXIF_TEMPLATE:
return MAX_EXIF_SIZE;
case X3X3_EXIF_EXIF_CHN_0:
case X3X3_EXIF_EXIF_CHN_1:
case X3X3_EXIF_EXIF_CHN_2:
case X3X3_EXIF_EXIF_CHN_3:
case DEV393_MINOR(DEV393_EXIF0):
case DEV393_MINOR(DEV393_EXIF1):
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
return MAX_EXIF_SIZE * (MAX_EXIF_FRAMES+1);
case X3X3_EXIF_META_CHN_0:
case X3X3_EXIF_META_CHN_1:
case X3X3_EXIF_META_CHN_2:
case X3X3_EXIF_META_CHN_3:
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
case DEV393_MINOR(DEV393_EXIF_META3):
return MAX_EXIF_SIZE;
case X3X3_EXIF_METADIR:
return MAX_EXIF_FIELDS * sizeof(struct exif_dir_table_t);
......@@ -430,14 +430,14 @@ static int exif_open(struct inode *inode, struct file *filp) {
int p = MINOR(inode->i_rdev);
int * pd= (int *) &(filp->private_data);
switch (p) {
case X3X3_EXIF_EXIF_CHN_0:
case X3X3_EXIF_EXIF_CHN_1:
case X3X3_EXIF_EXIF_CHN_2:
case X3X3_EXIF_EXIF_CHN_3:
case X3X3_EXIF_META_CHN_0:
case X3X3_EXIF_META_CHN_1:
case X3X3_EXIF_META_CHN_2:
case X3X3_EXIF_META_CHN_3:
case DEV393_MINOR(DEV393_EXIF0):
case DEV393_MINOR(DEV393_EXIF1):
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
case DEV393_MINOR(DEV393_EXIF_META3):
case X3X3_EXIF_TEMPLATE:
case X3X3_EXIF_METADIR:
case X3X3_EXIF_TIME:
......@@ -457,15 +457,15 @@ static int exif_release(struct inode *inode, struct file *filp){
int p = MINOR(inode->i_rdev);
int * pd= (int *) &(filp->private_data);
switch (p) {
case X3X3_EXIF_EXIF_CHN_0:
case X3X3_EXIF_EXIF_CHN_1:
case X3X3_EXIF_EXIF_CHN_2:
case X3X3_EXIF_EXIF_CHN_3:
case DEV393_MINOR(DEV393_EXIF0):
case DEV393_MINOR(DEV393_EXIF1):
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
break;
case X3X3_EXIF_META_CHN_0:
case X3X3_EXIF_META_CHN_1:
case X3X3_EXIF_META_CHN_2:
case X3X3_EXIF_META_CHN_3:
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
case DEV393_MINOR(DEV393_EXIF_META3):
break;
case X3X3_EXIF_TEMPLATE:
break;
......@@ -521,11 +521,11 @@ static loff_t exif_lseek (struct file * file, loff_t offset, int orig) {
default:return -EINVAL;
}
break;
case X3X3_EXIF_EXIF_CHN_0:
case X3X3_EXIF_EXIF_CHN_1:
case X3X3_EXIF_EXIF_CHN_2:
case X3X3_EXIF_EXIF_CHN_3:
// sensor_port = p - X3X3_EXIF_EXIF_CHN_0;
case DEV393_MINOR(DEV393_EXIF0):
case DEV393_MINOR(DEV393_EXIF1):
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
// sensor_port = p - DEV393_MINOR(DEV393_EXIF0);
if (offset > MAX_EXIF_FRAMES) return -EOVERFLOW; //larger than buffer
// file->f_pos=exif_meta_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) {
if (fp < 0) return -EOVERFLOW; // tag is not in the directory
file->f_pos=fp;
break;
case X3X3_EXIF_META_CHN_0:
case X3X3_EXIF_META_CHN_1:
case X3X3_EXIF_META_CHN_2:
case X3X3_EXIF_META_CHN_3:
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
case DEV393_MINOR(DEV393_EXIF_META3):
file->f_pos=offset*sizeof(struct exif_dir_table_t);
break;
case X3X3_EXIF_TIME:
......@@ -609,11 +609,11 @@ static ssize_t exif_write (struct file * file, const char * buf, size_t coun
cp= (char *) &exif_time;
if (copy_from_user(&cp[*off], buf, count)) return -EFAULT;
break;
case X3X3_EXIF_META_CHN_0:
case X3X3_EXIF_META_CHN_1:
case X3X3_EXIF_META_CHN_2:
case X3X3_EXIF_META_CHN_3:
sensor_port = p - X3X3_EXIF_META_CHN_0;
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
case DEV393_MINOR(DEV393_EXIF_META3):
sensor_port = p - DEV393_MINOR(DEV393_EXIF_META0);
if (copy_from_user(tmp, buf, count)) return -EFAULT;
local_irq_save(flags);
//local_irq_disable();
......@@ -625,10 +625,10 @@ static ssize_t exif_write (struct file * file, const char * buf, size_t coun
count=0;
}
break;
case X3X3_EXIF_EXIF_CHN_0:
case X3X3_EXIF_EXIF_CHN_1:
case X3X3_EXIF_EXIF_CHN_2:
case X3X3_EXIF_EXIF_CHN_3:
case DEV393_MINOR(DEV393_EXIF0):
case DEV393_MINOR(DEV393_EXIF1):
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
return -EINVAL; // no writing - read only
break;
default:return -EINVAL;
......@@ -673,19 +673,19 @@ static ssize_t exif_read (struct file * file, char * buf, size_t count, lof
cp= (char *) &exif_time;
if (copy_to_user(buf, &cp[*off], count)) return -EFAULT;
break;
case X3X3_EXIF_META_CHN_0:
case X3X3_EXIF_META_CHN_1:
case X3X3_EXIF_META_CHN_2:
case X3X3_EXIF_META_CHN_3:
sensor_port = p - X3X3_EXIF_META_CHN_0;
case DEV393_MINOR(DEV393_EXIF_META0):
case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2):
case DEV393_MINOR(DEV393_EXIF_META3):
sensor_port = p - DEV393_MINOR(DEV393_EXIF_META0);
if (!aexif_enabled[sensor_port]) return 0;
if (copy_to_user(buf, &ameta_buffer[sensor_port][*off], count)) return -EFAULT;
break;
case X3X3_EXIF_EXIF_CHN_0:// generates exif data by merging exif_template with the selected meta_buffer page
case X3X3_EXIF_EXIF_CHN_1:
case X3X3_EXIF_EXIF_CHN_2:
case X3X3_EXIF_EXIF_CHN_3:
sensor_port = p - X3X3_EXIF_EXIF_CHN_0;
case DEV393_MINOR(DEV393_EXIF0):// generates exif data by merging exif_template with the selected meta_buffer page
case DEV393_MINOR(DEV393_EXIF1):
case DEV393_MINOR(DEV393_EXIF2):
case DEV393_MINOR(DEV393_EXIF3):
sensor_port = p - DEV393_MINOR(DEV393_EXIF0);
//will truncate by the end of current page
if (!aexif_enabled[sensor_port]) return 0;
i=((int) *off) / exif_template_size;
......@@ -716,16 +716,16 @@ static ssize_t exif_read (struct file * file, char * buf, size_t count, lof
static int __init exif_init(void) {
int res;
res = register_chrdev(X3X3_EXIF_MAJOR, "Exif", &exif_fops);
res = register_chrdev(DEV393_MAJOR(DEV393_EXIF0), "Exif", &exif_fops);
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;
}
printk(X3X3_EXIF_DRIVER_NAME" - %d\n",X3X3_EXIF_MAJOR);
printk(DEV393_NAME(DEV393_EXIF0)" - %d\n",DEV393_MAJOR(DEV393_EXIF0));
return 0;
}
module_init(exif_init);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
MODULE_DESCRIPTION(X3X3_EXIF_DRIVER_NAME);
MODULE_DESCRIPTION(X3X3_EXIF_DRIVER_DESCRIPTION);
/**************************************************************************//**
* @file fpgajtag353.c
* @brief TBD
* @copyright Copyright 2002-20016 (C) Elphel, Inc.
* 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/>.
* @par <b>License</b>*
*/
* @file fpgajtag353.c
* @brief TBD
* @copyright Copyright 2002-20016 (C) Elphel, Inc.
* 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/>.
* @par <b>License</b>*
*/
#undef DEBUG
/****************** INCLUDE FILES SECTION ***********************************/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/ioport.h> // needed?
#include <linux/ioport.h> // needed?
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/fs.h>
......@@ -39,7 +39,9 @@
//#include <asm/system.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
......@@ -70,7 +72,7 @@ port C 353:
5 - DONE (in)
6 - RSTBTN
7 - PGM (out)
*/
*/
#define FPGAJTAG_TDO_BIT 0
#define FPGAJTAG_TDI_BIT 1
#define FPGAJTAG_TMS_BIT 2
......@@ -81,20 +83,19 @@ port C 353:
#ifndef XC2S300E_BITSIZE
#define XC3S1000_BITSIZE 3223488
#define XC3S1200E_BITSIZE 3841189
#define XC3S1200E_BOUNDARY_SIZE 772
#define XC3S1000_BITSIZE 3223488
#define XC3S1200E_BITSIZE 3841189
#define XC3S1200E_BOUNDARY_SIZE 772
// #define XC3S1200E_BOUNDARY_SIZE 812
#define FJTAG_BUF_SIZE 0x77000
#define FJTAG_MAX_HEAD 0x1000
#define FJTAG_RAW_WSIZE 0x40000 // shared with bitstream buffer
#define FJTAG_RAW_RSIZE 0x30000 // shared with bitstream buffer
#define FJTAG_IDSIZE 0x40 // bits - ID and User
#define FJTAG_BUF_SIZE 0x77000
#define FJTAG_MAX_HEAD 0x1000
#define FJTAG_RAW_WSIZE 0x40000 // shared with bitstream buffer
#define FJTAG_RAW_RSIZE 0x30000 // shared with bitstream buffer
#define FJTAG_IDSIZE 0x40 // bits - ID and User
#endif
//#define FPGA_JTAG_DRIVER_NAME "Elphel (R) model 353 FPGA (Xilinx (R) XC3S1200E) configuration driver"
#define FPGA_JTAG_DRIVER_NAME "Elphel (R) model 393 FPGA (Xilinx (R) XC3S1200E) configuration driver"
#define FPGA_JTAG_DRIVER_DESCRIPTION "Elphel (R) model 393 FPGA (Xilinx (R) XC3S1200E) configuration driver"
#define FPGA_JTAG_MAXMINOR 16 // 10
......@@ -105,8 +106,8 @@ port C 353:
//#define JTAG_NCHANNELS 4
#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_CHANNELS 4 // Number of sensor ports for JTAG
//#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_MODE_CLOSED 0 // JTAG channel is closed
......@@ -119,15 +120,15 @@ port C 353:
// configuration and raw minors use whole buffer, ID and boundary can be opened at the same time
struct JTAG_channel_t {
int mode; // 0..5 -JTAG_MODE_CLOSED...JTAG_MODE_EXTEST
unsigned char * dbuf; // data buffer (shared, boundary mode use different parts)
int sizew; // byte size that can be written
int sizer; // byte size that can be read
int bitsw; // bit size to be written
int bitsr; // bit size to be read
int wp; // byte pointer for file write
int rp; // byte pointer for file read
int wdirty; // some data is buffered but not yet sent out in EXTEST mode
int mode; // 0..5 -JTAG_MODE_CLOSED...JTAG_MODE_EXTEST
unsigned char * dbuf; // data buffer (shared, boundary mode use different parts)
int sizew; // byte size that can be written
int sizer; // byte size that can be read
int bitsw; // bit size to be written
int bitsr; // bit size to be read
int wp; // byte pointer for file write
int rp; // byte pointer for file read
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 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
static int __init fpga_jtag_init(void);
static struct file_operations fpga_jtag_fops = {
owner: THIS_MODULE,
open: fpga_jtag_open,
release: fpga_jtag_release,
llseek: fpga_jtag_lseek,
read: fpga_jtag_read,
write: fpga_jtag_write
owner: THIS_MODULE,
open: fpga_jtag_open,
release: fpga_jtag_release,
llseek: fpga_jtag_lseek,
read: fpga_jtag_read,
write: fpga_jtag_write
};
//static int sens_num = 0;
......@@ -178,11 +179,11 @@ void set_pgm (int chn, int pgmon);
int read_done (int chn);
int jtag_send (int chn, int tms, int len, int d);
int jtag_write_bits (int chn,
unsigned char *buf, // data to write
int len, // number of bytes to write
int check, // compare readback data with previously written, abort on mismatch
int last, // output last bit with TMS=1
int prev[2]); // if null - don't use
unsigned char *buf, // data to write
int len, // number of bytes to write
int check, // compare readback data with previously written, abort on mismatch
int last, // output last bit with TMS=1
int prev[2]); // if null - don't use
int JTAG_configure (int chn, unsigned char * buf, int len);
int JTAG_readID (int chn, unsigned char * buf);
int JTAG_openChannel (int chn);
......@@ -195,13 +196,16 @@ int JTAG_process_raw(void);
int JTAG_channel(int minor) {
if ((minor >= FPGA_SJTAG_MINOR_OFFSET) && (minor < (FPGA_SJTAG_MINOR_OFFSET + FPGA_SJTAG_CHANNELS)))
return (minor - FPGA_SJTAG_MINOR_OFFSET) + (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
switch (minor) {
case FPGA_JTAG_RESET_MINOR : // same as RAW
if ((minor >= DEV393_MINOR(DEV393_JTAGS_CONF0)) && (minor < (DEV393_MINOR(DEV393_JTAGS_CONF0) + SENSOR_PORTS)))
return (minor - DEV393_MINOR(DEV393_JTAGS_CONF0)) + (JTAG_SENSOR_FPGA << 2);
if ((minor >= DEV393_MINOR(DEV393_JTAGS_BSCAN0)) && (minor < (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + SENSOR_PORTS)))
return (minor - DEV393_MINOR(DEV393_JTAGS_BSCAN0)) + (JTAG_SENSOR_FPGA << 2);
// maybe will never be used
#ifdef NC353
switch (minor) {
case DEV393_MINOR(DEV393_JTAG_RESET) : // same as RAW
return JTAG_RAW << 2;
case FPGA_JTAG_MINOR:
case FPGA_JTAG_BOUNDARY_MINOR:
......@@ -212,8 +216,9 @@ int JTAG_channel(int minor) {
case FPGA_AJTAG_MINOR:
case FPGA_AJTAG_BOUNDARY_MINOR:
return JTAG_AUX_FPGA << 2;
}
return 0;
}
#endif
return 0;
}
static int raw_fifo_w_wp;
static int raw_fifo_w_rp;
......@@ -245,204 +250,208 @@ void set_pgm (int chn, int pgmon);
#define JTAG_RAW_WAIT 0x80
void JTAG_push_raw (int b) {
raw_fifo_r[raw_fifo_r_wp++]=b;
if (raw_fifo_r_wp > FJTAG_RAW_RSIZE) raw_fifo_r_wp-=FJTAG_RAW_RSIZE;
raw_fifo_r[raw_fifo_r_wp++]=b;
if (raw_fifo_r_wp > FJTAG_RAW_RSIZE) raw_fifo_r_wp-=FJTAG_RAW_RSIZE;
}
// TODO: Not updated for 393. Is it needed?
int JTAG_process_raw(void) {
unsigned char b0, b1;
while (raw_fifo_w_rp != (raw_fifo_w_wp & ~1)) {
b0=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 (b1 == JTAG_RAW_SETCHN) { // set channel number
raw_chn = b0;
if (raw_chn>=JTAG_NCHANNELS) raw_chn=0; //illegal channel
JTAG_push_raw (raw_chn);
} else if (raw_chn) { // ignore commands until the JTAG channel number is specified
if ((b1 & 0xf0) == JTAG_RAW_SEND) { // send JTAG data
JTAG_push_raw (jtag_send(raw_chn, (b1 >> 3) & 1, b1 & 7, (int) b0 ));
} else if ((b1 & 0x80) == JTAG_RAW_WAIT) { // delay
/* possible bug here, udelay is used for delays less then 2 ms */
udelay(((b1 & 0x7f) <<8) + b0);
JTAG_push_raw (0x80);
} else switch (b1) {
case JTAG_RAW_DEACT:
set_pgm_mode (raw_chn, 0);
JTAG_push_raw (0x0);
break;
case JTAG_RAW_ACT:
set_pgm_mode (raw_chn, 1);
JTAG_push_raw (0x0);
break;
case JTAG_RAW_PGMOFF:
set_pgm (raw_chn, 0);
JTAG_push_raw (read_done(raw_chn));
break; // was missing for 353
case JTAG_RAW_PGMON:
set_pgm (raw_chn, 1);
JTAG_push_raw (0xf0);
break;
default:
JTAG_push_raw (0xff);
}
} else { // make output always be 1 byte for 2 bytes input
JTAG_push_raw (0xf0);
} // end of if (raw_chn) /else
} // while (raw_fifo_w_rp != (raw_fifo_w_wp & ~1))
return 0; // will think of return value later
unsigned char b0, b1;
while (raw_fifo_w_rp != (raw_fifo_w_wp & ~1)) {
b0=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 (b1 == JTAG_RAW_SETCHN) { // set channel number
raw_chn = b0;
if (raw_chn>=JTAG_NCHANNELS) raw_chn=0; //illegal channel
JTAG_push_raw (raw_chn);
} else if (raw_chn) { // ignore commands until the JTAG channel number is specified
if ((b1 & 0xf0) == JTAG_RAW_SEND) { // send JTAG data
JTAG_push_raw (jtag_send(raw_chn, (b1 >> 3) & 1, b1 & 7, (int) b0 ));
} else if ((b1 & 0x80) == JTAG_RAW_WAIT) { // delay
/* possible bug here, udelay is used for delays less then 2 ms */
udelay(((b1 & 0x7f) <<8) + b0);
JTAG_push_raw (0x80);
} else switch (b1) {
case JTAG_RAW_DEACT:
set_pgm_mode (raw_chn, 0);
JTAG_push_raw (0x0);
break;
case JTAG_RAW_ACT:
set_pgm_mode (raw_chn, 1);
JTAG_push_raw (0x0);
break;
case JTAG_RAW_PGMOFF:
set_pgm (raw_chn, 0);
JTAG_push_raw (read_done(raw_chn));
break; // was missing for 353
case JTAG_RAW_PGMON:
set_pgm (raw_chn, 1);
JTAG_push_raw (0xf0);
break;
default:
JTAG_push_raw (0xff);
}
} else { // make output always be 1 byte for 2 bytes input
JTAG_push_raw (0xf0);
} // end of if (raw_chn) /else
} // while (raw_fifo_w_rp != (raw_fifo_w_wp & ~1))
return 0; // will think of return value later
}
//returns 0 if all channels closed
//
int JTAG_whatopen(void) {
int i,r=0;
for (i=0;i<JTAG_NCHANNELS;i++) r |= 1 << JTAG_channels[i].mode;
return r;
int i,r=0;
for (i=0;i<JTAG_NCHANNELS;i++) r |= 1 << JTAG_channels[i].mode;
return r;
}
//++++++++++++++++++++++++++++++++++++ open() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
static int fpga_jtag_open(struct inode *inode, struct file *filp) {
int i;
// int res;
int p = MINOR(inode->i_rdev);
int chn= JTAG_channel(p);
//reg_intr_vect_rw_mask intr_mask;
//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);
switch ( p ) {
case FPGA_JTAG_RESET_MINOR : // same as RAW
for (i=1; i<JTAG_NCHANNELS; i++) JTAG_channels[i].mode=JTAG_MODE_CLOSED;
JTAG_channels[chn].mode=JTAG_MODE_RAW;
JTAG_channels[chn].sizew = FJTAG_RAW_WSIZE;
JTAG_channels[chn].sizer = FJTAG_RAW_RSIZE;
JTAG_channels[chn].wp = 0;
JTAG_channels[chn].rp = 0; // will read IDs if actually read
raw_fifo_w_wp=0;
raw_fifo_w_rp=0;
raw_fifo_r_wp=0;
raw_fifo_r_rp=0;
raw_chn=0;
break;
case FPGA_JTAG_MINOR :
// 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].dbuf = &bitstream_data[0];
// JTAG_channels[chn].sizew = FJTAG_BUF_SIZE;
// JTAG_channels[chn].sizer = FJTAG_IDSIZE >> 3;
// JTAG_channels[chn].wp = 0;
// JTAG_channels[chn].rp = 0; // will read IDs if actually read
int i;
// int res;
int p = MINOR(inode->i_rdev);
int chn= JTAG_channel(p);
//reg_intr_vect_rw_mask intr_mask;
//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);
switch ( p ) {
case DEV393_MINOR(DEV393_JTAG_RESET) : // same as RAW
for (i=1; i<JTAG_NCHANNELS; i++) JTAG_channels[i].mode=JTAG_MODE_CLOSED;
JTAG_channels[chn].mode=JTAG_MODE_RAW;
JTAG_channels[chn].sizew = FJTAG_RAW_WSIZE;
JTAG_channels[chn].sizer = FJTAG_RAW_RSIZE;
JTAG_channels[chn].wp = 0;
JTAG_channels[chn].rp = 0; // will read IDs if actually read
raw_fifo_w_wp=0;
raw_fifo_w_rp=0;
raw_fifo_r_wp=0;
raw_fifo_r_rp=0;
raw_chn=0;
break;
// case FPGA_JTAG_MINOR :
// 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].dbuf = &bitstream_data[0];
// JTAG_channels[chn].sizew = FJTAG_BUF_SIZE;
// JTAG_channels[chn].sizer = FJTAG_IDSIZE >> 3;
// JTAG_channels[chn].wp = 0;
// JTAG_channels[chn].rp = 0; // will read IDs if actually read
#ifdef TEST_DISABLE_CODE
fpga_state &= ~FPGA_STATE_LOADED; // is it still used?
fpga_state &= ~FPGA_STATE_SDRAM_INIT; // not needed
// disable camera interrupts here (while reprogramming FPGA could generate stray interrupts;
/* Disable external interrupts.. */
intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
intr_mask.ext = 0;
REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
fpga_state &= ~FPGA_STATE_LOADED; // is it still used?
fpga_state &= ~FPGA_STATE_SDRAM_INIT; // not needed
// disable camera interrupts here (while reprogramming FPGA could generate stray interrupts;
/* Disable external interrupts.. */
intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
intr_mask.ext = 0;
REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
#endif /* TEST_DISABLE_CODE */
// printk ("Camera interrupts disabled\r\n");
// break;
// fall through
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1):
case (FPGA_SJTAG_MINOR_OFFSET + 2):
case (FPGA_SJTAG_MINOR_OFFSET + 3):
case FPGA_SJTAG_MINOR :
case FPGA_AJTAG_MINOR :
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].dbuf = &bitstream_data[0];
JTAG_channels[chn].sizew = FJTAG_BUF_SIZE;
JTAG_channels[chn].sizer = FJTAG_IDSIZE >> 3;
JTAG_channels[chn].wp = 0;
JTAG_channels[chn].rp = 0; // will read IDs if actually read
JTAG_channels[chn].bitsw = XC3S1200E_BITSIZE; // bit size to be written
JTAG_channels[chn].bitsr= FJTAG_IDSIZE;
JTAG_openChannel (chn); // configure channel access, reset JTAG and to RUN-TEST/IDLE state
break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3):
case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR :
if ( JTAG_whatopen() & 0x46) return -EACCES; // none of the channels could be open for program/id/raw when opening this file
if ( JTAG_channels[chn].mode != JTAG_MODE_CLOSED) return -EACCES; // already open
JTAG_channels[chn].mode = JTAG_MODE_BOUNDARY;
JTAG_channels[chn].sizew = (XC3S1200E_BOUNDARY_SIZE+7) >> 3;
JTAG_channels[chn].sizer = (XC3S1200E_BOUNDARY_SIZE+7) >> 3;
JTAG_channels[chn].dbuf = &bitstream_data[JTAG_channels[chn].sizew * chn];
JTAG_channels[chn].wp = 0;
JTAG_channels[chn].rp = 0; // will read IDs if actually read
JTAG_channels[chn].bitsw = XC3S1200E_BOUNDARY_SIZE; // bit size to be written
JTAG_channels[chn].bitsr= XC3S1200E_BOUNDARY_SIZE;
JTAG_openChannel (chn); // configure channel access, reset JTAG and to RUN-TEST/IDLE state
break;
default: return -EINVAL;
}
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);
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);
JTAG_channels[chn].wdirty=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;
// printk ("Camera interrupts disabled\r\n");
// break;
// fall through
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 0): // ugly, fix
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 1):
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 2):
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 3):
#ifdef NC353
case FPGA_SJTAG_MINOR :
case FPGA_AJTAG_MINOR :
#endif
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].dbuf = &bitstream_data[0];
JTAG_channels[chn].sizew = FJTAG_BUF_SIZE;
JTAG_channels[chn].sizer = FJTAG_IDSIZE >> 3;
JTAG_channels[chn].wp = 0;
JTAG_channels[chn].rp = 0; // will read IDs if actually read
JTAG_channels[chn].bitsw = XC3S1200E_BITSIZE; // bit size to be written
JTAG_channels[chn].bitsr= FJTAG_IDSIZE;
JTAG_openChannel (chn); // configure channel access, reset JTAG and to RUN-TEST/IDLE state
break;
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 0):
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 1):
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 2):
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 3):
#ifdef NC353
case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR :
#endif
if ( JTAG_whatopen() & 0x46) return -EACCES; // none of the channels could be open for program/id/raw when opening this file
if ( JTAG_channels[chn].mode != JTAG_MODE_CLOSED) return -EACCES; // already open
JTAG_channels[chn].mode = JTAG_MODE_BOUNDARY;
JTAG_channels[chn].sizew = (XC3S1200E_BOUNDARY_SIZE+7) >> 3;
JTAG_channels[chn].sizer = (XC3S1200E_BOUNDARY_SIZE+7) >> 3;
JTAG_channels[chn].dbuf = &bitstream_data[JTAG_channels[chn].sizew * chn];
JTAG_channels[chn].wp = 0;
JTAG_channels[chn].rp = 0; // will read IDs if actually read
JTAG_channels[chn].bitsw = XC3S1200E_BOUNDARY_SIZE; // bit size to be written
JTAG_channels[chn].bitsr= XC3S1200E_BOUNDARY_SIZE;
JTAG_openChannel (chn); // configure channel access, reset JTAG and to RUN-TEST/IDLE state
break;
default: return -EINVAL;
}
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);
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);
JTAG_channels[chn].wdirty=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() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
static int fpga_jtag_release(struct inode *inode, struct file *filp) {
int res=0;
int p = MINOR(inode->i_rdev);
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);
switch ( p ) {
case FPGA_JTAG_RESET_MINOR : // same as RAW - do nothing, raw code should do it on it's own
break;
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1):
case (FPGA_SJTAG_MINOR_OFFSET + 2):
case (FPGA_SJTAG_MINOR_OFFSET + 3):
case FPGA_JTAG_MINOR :
case FPGA_SJTAG_MINOR :
case FPGA_AJTAG_MINOR :
if (JTAG_channels[chn].wp > 0) { // anything written?
res=JTAG_configure (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].wp);
JTAG_resetChannel (chn);
if ((res >=0) & (chn == JTAG_MAIN_FPGA)) {
// read FPGA model number/revision and OR it with current state
//fpga_state = (fpga_state & ~0xffff) | (port_csp0_addr[X313__RA__MODEL] & 0xffff);
}
} else JTAG_resetChannel (chn); /// reset initializing in any case:
//if (chn == JTAG_MAIN_FPGA) fpga_state &=~FPGA_STATE_INITIALIZED;
break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3):
case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR :
// "dirty"? Send to JTAG
if (JTAG_channels[chn].wp >0) {
// 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_resetChannel (chn);
break;
int res=0;
int p = MINOR(inode->i_rdev);
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);
switch ( p ) {
case DEV393_MINOR(DEV393_JTAG_RESET) : // same as RAW - do nothing, raw code should do it on it's own
break;
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 0): // ugly, fix
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 1):
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 2):
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 3):
// case FPGA_JTAG_MINOR :
// case FPGA_SJTAG_MINOR :
// case FPGA_AJTAG_MINOR :
if (JTAG_channels[chn].wp > 0) { // anything written?
res=JTAG_configure (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].wp);
JTAG_resetChannel (chn);
if ((res >=0) & (chn == JTAG_MAIN_FPGA)) {
// read FPGA model number/revision and OR it with current state
//fpga_state = (fpga_state & ~0xffff) | (port_csp0_addr[X313__RA__MODEL] & 0xffff);
}
} else JTAG_resetChannel (chn); /// reset initializing in any case:
//if (chn == JTAG_MAIN_FPGA) fpga_state &=~FPGA_STATE_INITIALIZED;
break;
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 0):
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 1):
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 2):
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 3):
// case FPGA_JTAG_BOUNDARY_MINOR :
// case FPGA_SJTAG_BOUNDARY_MINOR :
// case FPGA_AJTAG_BOUNDARY_MINOR :
// "dirty"? Send to JTAG
if (JTAG_channels[chn].wp >0) {
// 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_resetChannel (chn);
break;
default: return -EINVAL;
}
minors[p]=0;
JTAG_channels[chn].mode=JTAG_MODE_CLOSED;
//D(printk("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);
return (res<0)?res:0;
}
minors[p]=0;
JTAG_channels[chn].mode=JTAG_MODE_CLOSED;
//D(printk("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);
return (res<0)?res:0;
}
......@@ -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)
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 chn= JTAG_channel(p);
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);
switch (p) {
case FPGA_JTAG_RESET_MINOR : // same as RAW - do nothing, raw code should do it on it's own
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 (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
} else {
if (copy_from_user(&raw_fifo_w[raw_fifo_w_wp],buf,count)) return -EFAULT; // read count
}
raw_fifo_w_wp+=count;
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
break;
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1):
case (FPGA_SJTAG_MINOR_OFFSET + 2):
case (FPGA_SJTAG_MINOR_OFFSET + 3):
case FPGA_JTAG_MINOR :
case FPGA_SJTAG_MINOR :
case FPGA_AJTAG_MINOR : // read configuration data to buffer
if (*off > size) return -EFAULT;
if ((*off + count) > size) count= (size - *off);
if (copy_from_user(&(JTAG_channels[chn].dbuf[*off]),buf,count)) return -EFAULT;
*off+=count;
if (*off > JTAG_channels[chn].wp) JTAG_channels[chn].wp= *off;
break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3):
case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR :
if (*off > size) return -EFAULT;
if ((*off + count) > size) count= (size - *off);
if (*off < 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_channels[chn].wdirty=0;
}
if (copy_from_user(&(JTAG_channels[chn].dbuf[*off]),buf,count)) return -EFAULT;
*off+=count;
JTAG_channels[chn].wp= *off; // before rolling over
if (*off >= size) {
*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].wdirty=1;
break;
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);
//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;
int p = ((int *)file->private_data)[0];
int chn= JTAG_channel(p);
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);
switch (p) {
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 ((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[0],&buf[size-raw_fifo_w_wp],count+raw_fifo_w_wp-size)) return -EFAULT; // read head
} else {
if (copy_from_user(&raw_fifo_w[raw_fifo_w_wp],buf,count)) return -EFAULT; // read count
}
raw_fifo_w_wp+=count;
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
break;
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 0): // ugly, fix
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 1):
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 2):
case (DEV393_MINOR(DEV393_JTAGS_CONF0) + 3):
// case FPGA_JTAG_MINOR :
// case FPGA_SJTAG_MINOR :
// case FPGA_AJTAG_MINOR : // read configuration data to buffer
if (*off > size) return -EFAULT;
if ((*off + count) > size) count= (size - *off);
if (copy_from_user(&(JTAG_channels[chn].dbuf[*off]),buf,count)) return -EFAULT;
*off+=count;
if (*off > JTAG_channels[chn].wp) JTAG_channels[chn].wp= *off;
break;
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 0):
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 1):
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 2):
case (DEV393_MINOR(DEV393_JTAGS_BSCAN0) + 3):
// case FPGA_JTAG_BOUNDARY_MINOR :
// case FPGA_SJTAG_BOUNDARY_MINOR :
// case FPGA_AJTAG_BOUNDARY_MINOR :
if (*off > size) return -EFAULT;
if ((*off + count) > size) count= (size - *off);
if (*off < 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_channels[chn].wdirty=0;
}
if (copy_from_user(&(JTAG_channels[chn].dbuf[*off]),buf,count)) return -EFAULT;
*off+=count;
JTAG_channels[chn].wp= *off; // before rolling over
if (*off >= size) {
*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].wdirty=1;
break;
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);
//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;
}
//++++++++++++++++++++++++++++++++++++ read() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
ssize_t fpga_jtag_read(struct file * file, char * buf, size_t count, loff_t *off) {
int p = ((int *)file->private_data)[0];
int chn= JTAG_channel(p);
size_t size = JTAG_channels[chn].sizer;
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);
switch (p) {
case FPGA_JTAG_RESET_MINOR : // 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);
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 (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
} else {
if (copy_to_user(buf,&raw_fifo_w[raw_fifo_w_wp],count)) return -EFAULT; // read count
}
raw_fifo_r_rp+=count;
if (raw_fifo_r_rp > size) raw_fifo_r_rp -= size;
break;
case (FPGA_SJTAG_MINOR_OFFSET + 0): // ugly, fix
case (FPGA_SJTAG_MINOR_OFFSET + 1):
case (FPGA_SJTAG_MINOR_OFFSET + 2):
case (FPGA_SJTAG_MINOR_OFFSET + 3):
case FPGA_JTAG_MINOR :
case FPGA_SJTAG_MINOR :
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
JTAG_channels[chn].mode=JTAG_MODE_RDID;
JTAG_readID (chn, JTAG_channels[chn].dbuf);
}
if (*off > size) return -EFAULT;
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);
if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT;
*off+=count;
JTAG_channels[chn].rp= *off;
break;
case (FPGA_SJTAG_BOUNDARY_OFFSET + 0):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 1):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 2):
case (FPGA_SJTAG_BOUNDARY_OFFSET + 3):
case FPGA_JTAG_BOUNDARY_MINOR :
case FPGA_SJTAG_BOUNDARY_MINOR :
case FPGA_AJTAG_BOUNDARY_MINOR :
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_channels[chn].wdirty=0;
}
// (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))) {
JTAG_CAPTURE (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsr);
}
if (*off > size) return -EFAULT;
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);
if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT;
*off+=count;
JTAG_channels[chn].rp= *off; // before rolling over
if (*off >= size) {
*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
break;
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);
return count;
int p = ((int *)file->private_data)[0];
int chn= JTAG_channel(p);
size_t size = JTAG_channels[chn].sizer;
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);
switch (p) {
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);
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 (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
} else {
if (copy_to_user(buf,&raw_fifo_w[raw_fifo_w_wp],count)) return -EFAULT; // read count
}
raw_fifo_r_rp+=count;
if (raw_fifo_r_rp > size) raw_fifo_r_rp -= size;
break;
case DEV393_MINOR(DEV393_JTAGS_CONF0): // ugly, fix
case DEV393_MINOR(DEV393_JTAGS_CONF1):
case DEV393_MINOR(DEV393_JTAGS_CONF2):
case DEV393_MINOR(DEV393_JTAGS_CONF3):
// case FPGA_JTAG_MINOR :
// case FPGA_SJTAG_MINOR :
// 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
JTAG_channels[chn].mode=JTAG_MODE_RDID;
JTAG_readID (chn, JTAG_channels[chn].dbuf);
}
if (*off > size) return -EFAULT;
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);
if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT;
*off+=count;
JTAG_channels[chn].rp= *off;
break;
case DEV393_MINOR(DEV393_JTAGS_BSCAN0):
case DEV393_MINOR(DEV393_JTAGS_BSCAN1):
case DEV393_MINOR(DEV393_JTAGS_BSCAN2):
case DEV393_MINOR(DEV393_JTAGS_BSCAN3):
// case FPGA_JTAG_BOUNDARY_MINOR :
// case FPGA_SJTAG_BOUNDARY_MINOR :
// case FPGA_AJTAG_BOUNDARY_MINOR :
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_channels[chn].wdirty=0;
}
// (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))) {
JTAG_CAPTURE (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsr);
}
if (*off > size) return -EFAULT;
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);
if (copy_to_user(buf,&(JTAG_channels[chn].dbuf[*off]),count)) return -EFAULT;
*off+=count;
JTAG_channels[chn].rp= *off; // before rolling over
if (*off >= size) {
*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
break;
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);
return count;
}
//++++++++++++++++++++++++++++++++++++ lseek() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
static loff_t fpga_jtag_lseek(struct file * file, loff_t offset, int orig) {
/*
* orig 0: position from begning of
* orig 1: relative from current position
* orig 2: position from last address
*/
int p = ((int *)file->private_data)[0];
int chn= JTAG_channel(p);
size_t size;
if (chn==JTAG_RAW) {
size=raw_fifo_r_wp-raw_fifo_r_rp;
if (size<0) size+=FJTAG_RAW_RSIZE;
} else size = JTAG_channels[chn].sizew;
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);
switch (orig) {
case 0:
file->f_pos = offset;
break;
case 1:
file->f_pos += offset;
break;
case 2:
file->f_pos = size + offset;
break;
default:
return -EINVAL;
}
/* truncate position */
if (file->f_pos < 0) {
file->f_pos = 0;
return (-EOVERFLOW);
}
if (file->f_pos > size) {
file->f_pos = size;
return (-EOVERFLOW);
}
dev_dbg(NULL,"fpga_jtag_lseek, file->f_pos= 0x%x\n", (int) file->f_pos);
return (file->f_pos);
/*
* orig 0: position from begning of
* orig 1: relative from current position
* orig 2: position from last address
*/
int p = ((int *)file->private_data)[0];
int chn= JTAG_channel(p);
size_t size;
if (chn==JTAG_RAW) {
size=raw_fifo_r_wp-raw_fifo_r_rp;
if (size<0) size+=FJTAG_RAW_RSIZE;
} else size = JTAG_channels[chn].sizew;
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);
switch (orig) {
case 0:
file->f_pos = offset;
break;
case 1:
file->f_pos += offset;
break;
case 2:
file->f_pos = size + offset;
break;
default:
return -EINVAL;
}
/* truncate position */
if (file->f_pos < 0) {
file->f_pos = 0;
return (-EOVERFLOW);
}
if (file->f_pos > size) {
file->f_pos = size;
return (-EOVERFLOW);
}
dev_dbg(NULL,"fpga_jtag_lseek, file->f_pos= 0x%x\n", (int) file->f_pos);
return (file->f_pos);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Initialize GPIOs of the CPU to access JTAG/programming of the main FPGA
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;
#ifdef TEST_DISABLE_CODE
reg_pinmux_rw_pc_iop pinmux_c_iop;
......@@ -650,98 +659,98 @@ void initPortC(void) {
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);
// 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.data &= ~0xff;
pc_dout.data |= PC_DOUT_INITIAL;
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.oe &= ~( (1 << FPGAJTAG_TDO_BIT) |
(1 << FPGAJTAG_DONE_BIT) |
(1 << FPGAJTAG_RSTBTN_BIT));
(1 << FPGAJTAG_DONE_BIT) |
(1 << FPGAJTAG_RSTBTN_BIT));
pc_oe.oe |= ( (1 << FPGAJTAG_TDI_BIT) |
(1 << FPGAJTAG_TMS_BIT) |
(1 << FPGAJTAG_TCK_BIT) |
(1 << FPGAJTAG_PGM_BIT));
(1 << FPGAJTAG_TMS_BIT) |
(1 << FPGAJTAG_TCK_BIT) |
(1 << FPGAJTAG_PGM_BIT));
REG_WR(gio, regi_gio, rw_pc_oe, pc_oe);
#endif /* TEST_DISABLE_CODE */
}
inline u32 prep_sensio_status(int sens_num)
{
x393_status_sens_io_t stat;
x393_status_ctrl_t stat_ctrl;
stat_ctrl.d32 = 0;
stat = x393_sensio_status(sens_num);
stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 1;
set_x393_sensio_status_cntrl(stat_ctrl, 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
x393_status_sens_io_t stat;
x393_status_ctrl_t stat_ctrl;
stat_ctrl.d32 = 0;
stat = x393_sensio_status(sens_num);
stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 1;
set_x393_sensio_status_cntrl(stat_ctrl, 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
}
inline x393_status_sens_io_t wait_sensio_status(int chn, u32 seq_num) // reducing number of hardware reads
{
int i;
int ret = 0;
x393_status_sens_io_t stat;
// dev_dbg(NULL, "waiting for seq_num = %d, chn = %d", seq_num, chn);
for (i = 0; i < 10; i++) {
stat = x393_sensio_status(chn & 3); // sens_num);
if (stat.seq_num == seq_num) {
ret = -1;
if (i)
dev_dbg(NULL, "seq_num = %d received after %d wait cycles", seq_num, i);
break;
}
}
// return ret;
return stat;
int i;
int ret = 0;
x393_status_sens_io_t stat;
// dev_dbg(NULL, "waiting for seq_num = %d, chn = %d", seq_num, chn);
for (i = 0; i < 10; i++) {
stat = x393_sensio_status(chn & 3); // sens_num);
if (stat.seq_num == seq_num) {
ret = -1;
if (i)
dev_dbg(NULL, "seq_num = %d received after %d wait cycles", seq_num, i);
break;
}
}
// return ret;
return stat;
}
inline u32 read_tdo(int sens_num)
{
x393_status_sens_io_t stat;
x393_status_ctrl_t stat_ctrl;
x393_status_sens_io_t stat;
x393_status_ctrl_t stat_ctrl;
int i;
stat_ctrl.d32 = 0;
stat = x393_sensio_status(sens_num);
stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 1;
set_x393_sensio_status_cntrl(stat_ctrl, sens_num);
for (i = 0; i < 10; i++) {
stat = x393_sensio_status(sens_num & 3); // sens_num);
if (likely(stat.seq_num == stat_ctrl.seq_num)) {
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);
return stat.xfpgatdo;
stat_ctrl.d32 = 0;
stat = x393_sensio_status(sens_num);
stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 1;
set_x393_sensio_status_cntrl(stat_ctrl, sens_num);
for (i = 0; i < 10; i++) {
stat = x393_sensio_status(sens_num & 3); // sens_num);
if (likely(stat.seq_num == stat_ctrl.seq_num)) {
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);
return stat.xfpgatdo;
}
// read last 8 TDO bits, shifted at rising edge of TCL
inline u32 read_tdo_byte(int sens_num)
{
x393_status_sens_io_t stat;
x393_status_ctrl_t stat_ctrl;
x393_status_sens_io_t stat;
x393_status_ctrl_t stat_ctrl;
int i;
stat_ctrl.d32 = 0;
stat = x393_sensio_status(sens_num);
stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 1;
set_x393_sensio_status_cntrl(stat_ctrl, sens_num);
for (i = 0; i < 10; i++) {
stat = x393_sensio_status(sens_num & 3); // sens_num);
if (likely(stat.seq_num == stat_ctrl.seq_num)) {
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);
return stat.xfpgatdo_byte;
stat_ctrl.d32 = 0;
stat = x393_sensio_status(sens_num);
stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 1;
set_x393_sensio_status_cntrl(stat_ctrl, sens_num);
for (i = 0; i < 10; i++) {
stat = x393_sensio_status(sens_num & 3); // sens_num);
if (likely(stat.seq_num == stat_ctrl.seq_num)) {
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);
return stat.xfpgatdo_byte;
}
......@@ -749,167 +758,167 @@ inline u32 read_tdo_byte(int sens_num)
// set FPGA in programming/JTAG mode (only for sensor board)
// NOP for the main board FPGA configuration
void set_pgm_mode (int chn, int en) {
u32 seq_num;
x393_sensio_jtag_t data;
dev_dbg(NULL, "set_pgm_mode (%d,%d)\n",chn,en);
switch (chn >> 2) {
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)
/* ? SFPGA_RD_SENSPGMPIN */
data.d32 = 0;
data.pgmen = (en) ? 1 : 0;
data.pgmen_set = 1;
data.tck = 0;
data.tck_set = 1;
/* check status register */
x393_sensio_jtag(data, chn & 3); // sens_num);
/* wait for status register update */
wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ; // Not needed here
break;
}
udelay (2);
u32 seq_num;
x393_sensio_jtag_t data;
dev_dbg(NULL, "set_pgm_mode (%d,%d)\n",chn,en);
switch (chn >> 2) {
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)
/* ? SFPGA_RD_SENSPGMPIN */
data.d32 = 0;
data.pgmen = (en) ? 1 : 0;
data.pgmen_set = 1;
data.tck = 0;
data.tck_set = 1;
/* check status register */
x393_sensio_jtag(data, chn & 3); // sens_num);
/* wait for status register update */
wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ; // Not needed here
break;
}
udelay (2);
}
void set_pgm (int chn, int pgmon) {
u32 seq_num;
x393_sensio_jtag_t data;
dev_dbg(NULL, "set_pgm (%d,%d)\n",chn,pgmon);
u32 seq_num;
x393_sensio_jtag_t data;
dev_dbg(NULL, "set_pgm (%d,%d)\n",chn,pgmon);
switch (chn >> 2) {
case JTAG_MAIN_FPGA:
switch (chn >> 2) {
case JTAG_MAIN_FPGA:
#ifdef TEST_DISABLE_CODE
if (pgmon) pc_dout.data &= ~0x80; // set PGM low (active)
else pc_dout.data |= 0x80; // set PGM high (inactive)
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout); // extend low?
if (pgmon) pc_dout.data &= ~0x80; // set PGM low (active)
else pc_dout.data |= 0x80; // set PGM high (inactive)
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout); // extend low?
#endif /* TEST_DISABLE_CODE */
break;
case JTAG_SENSOR_FPGA:
//port_csp0_addr[X313_WA_SENSFPGA] = (2 | (pgmon & 1)) << SFPGA_PROG_BIT;
data.prog= pgmon & 1;
data.prog_set = 1;
x393_sensio_jtag(data, chn >> 2); // sens_num);
break;
case JTAG_AUX_FPGA:
break;
}
udelay (2);
break;
case JTAG_SENSOR_FPGA:
//port_csp0_addr[X313_WA_SENSFPGA] = (2 | (pgmon & 1)) << SFPGA_PROG_BIT;
data.prog= pgmon & 1;
data.prog_set = 1;
x393_sensio_jtag(data, chn >> 2); // sens_num);
break;
case JTAG_AUX_FPGA:
break;
}
udelay (2);
}
int read_done (int chn) {
x393_status_sens_io_t stat;
x393_sensio_jtag_t data;
x393_status_sens_io_t stat;
x393_sensio_jtag_t data;
switch (chn >> 2) {
switch (chn >> 2) {
#ifdef TEST_DISABLE_CODE
case JTAG_MAIN_FPGA:
return ((((REG_RD(gio, regi_gio, r_pc_din)).data & 0x20)==0) ? 0 : 1 );
case JTAG_MAIN_FPGA:
return ((((REG_RD(gio, regi_gio, r_pc_din)).data & 0x20)==0) ? 0 : 1 );
#endif //* TEST_DISABLE_CODE */
case JTAG_SENSOR_FPGA:
//port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_DONE;
//udelay (1);
//return (port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1 ;
stat = wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ;
return stat.xfpgadone;
case JTAG_AUX_FPGA:
return 0;
}
return 0; // just in case
case JTAG_SENSOR_FPGA:
//port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_DONE;
//udelay (1);
//return (port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1 ;
stat = wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ;
return stat.xfpgadone;
case JTAG_AUX_FPGA:
return 0;
}
return 0; // just in case
}
// send 1..8 bits through JTAG
int jtag_send (int chn, int tms, int len, int d) {
int sens_num = chn & 3;
x393_sensio_jtag_t data;
x393_status_sens_io_t stat;
// u32 seq_num;
int i, bm = 0; //,m;
int r=0;
int d0;
i = len & 7;
if (i==0) i=8;
d &= 0xff;
d0=d;
dev_dbg(NULL, "jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\r\n", chn, tms,len,d);
switch (chn >> 2) {
case JTAG_MAIN_FPGA:
int sens_num = chn & 3;
x393_sensio_jtag_t data;
x393_status_sens_io_t stat;
// u32 seq_num;
int i, bm = 0; //,m;
int r=0;
int d0;
i = len & 7;
if (i==0) i=8;
d &= 0xff;
d0=d;
dev_dbg(NULL, "jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\r\n", chn, tms,len,d);
switch (chn >> 2) {
case JTAG_MAIN_FPGA:
#ifdef TEST_DISABLE_CODE
pc_dout.data &= ~0x0e;
pc_dout.data |= (tms & 1) << FPGAJTAG_TMS_BIT;
for (;i>0;i--){
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);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data |= (1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data &= ~(1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
}
pc_dout.data &= ~0x0e;
pc_dout.data |= (tms & 1) << FPGAJTAG_TMS_BIT;
for (;i>0;i--){
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);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data |= (1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data &= ~(1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
}
#endif /* TEST_DISABLE_CODE */
break;
case JTAG_SENSOR_FPGA:
break;
case JTAG_SENSOR_FPGA:
#ifdef TEST_DISABLE_CODE
port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_TDO;
udelay (1); // wait MUX
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 | (tms & 1)) << SFPGA_TMS_BIT) |
(((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_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] = (3 << SFPGA_TCK_BIT); // TCK=1
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
port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_TDO;
udelay (1); // wait MUX
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 | (tms & 1)) << SFPGA_TMS_BIT) |
(((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_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] = (3 << SFPGA_TCK_BIT); // TCK=1
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
#endif /* TEST_DISABLE_CODE */
data.d32 = 0;
data.tck_set = 1;
data.tms_set = 1;
data.tdi_set = 1;
data.d32 = 0;
data.tck_set = 1;
data.tms_set = 1;
data.tdi_set = 1;
dev_dbg(NULL, "jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\n", chn, tms,len,d);
for ( ; i > 0; i--) {
/* TCK = 0 - just a delay; is it really needed? */
data.tck = 0;
dev_dbg(NULL, "jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\n", chn, tms,len,d);
for ( ; i > 0; i--) {
/* TCK = 0 - just a delay; is it really needed? */
data.tck = 0;
data.tms = tms & 1;
data.tdi = ((d <<= 1) >> 8) & 1;
data.tck = 0;
data.tms = tms & 1;
data.tdi = ((d <<= 1) >> 8) & 1;
data.tck = 0;
x393_sensio_jtag(data, sens_num);
/* repeat writel - just a delay; is it really needed? */
// x393_sensio_jtag(data, sens_num);
x393_sensio_jtag(data, sens_num);
/* repeat writel - just a delay; is it really needed? */
// x393_sensio_jtag(data, sens_num);
/* read TDO before TCK pulse */
/* read TDO before TCK pulse */
#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
bm = (bm <<1 ) | 1;
bm = (bm <<1 ) | 1;
#endif
data.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
data.tck = 0;
// x393_sensio_jtag(data, sens_num);
}
x393_sensio_jtag(data, sens_num);
data.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
data.tck = 0;
// x393_sensio_jtag(data, sens_num);
}
x393_sensio_jtag(data, sens_num);
#ifdef PARALLEL_JTAG
r = read_tdo_byte(sens_num) & bm;
r = read_tdo_byte(sens_num) & bm;
#endif
// x393_sensio_jtag(data, sens_num);
dev_dbg(NULL, " ---> %02x\n", r);
break;
case JTAG_AUX_FPGA:
break;
}
return r;
// x393_sensio_jtag(data, sens_num);
dev_dbg(NULL, " ---> %02x\n", r);
break;
case JTAG_AUX_FPGA:
break;
}
return r;
}
//====================================
......@@ -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.
int jtag_write_bits (int chn,
unsigned char *buf, // data to write
int len, // number of bits to write
int check, // compare readback data with previously written, abort on mismatch
int last, // output last bit with TMS=1
int prev[2]) // if null - don't use
unsigned char *buf, // data to write
int len, // number of bits to write
int check, // compare readback data with previously written, abort on mismatch
int last, // output last bit with TMS=1
int prev[2]) // if null - don't use
{
int sens_num = chn & 3;
int i,j;
int r = 0;
int bm = 0;
int d,d0;
// u32 seq_num;
x393_status_sens_io_t stat;
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);
switch (chn >> 2) {
case JTAG_MAIN_FPGA: //TODO: save some cycles like for FPGA_SJTAG_MINOR
int sens_num = chn & 3;
int i,j;
int r = 0;
int bm = 0;
int d,d0;
// u32 seq_num;
x393_status_sens_io_t stat;
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);
switch (chn >> 2) {
case JTAG_MAIN_FPGA: //TODO: save some cycles like for FPGA_SJTAG_MINOR
#ifdef TEST_DISABLE_CODE
for (i=0; len>0;i++) {
pc_dout.data &= ~0x0e;
d0=(d=buf[i]);
for (j=0;j<8;j++) {
//D(printk("i=%x, j=%x, len=%x, d=%x ",i,j,len,d));
if (len>0) {
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);
else pc_dout.data = (pc_dout.data & ~0x0a) | (((d<<=1)>>7) & 2);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data |= (1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data &= ~(1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
} else r= (r<<1);
len--;
//D(printk(", r=%x\r\n",r));
}
buf[i]=r; // read back in-place
if (check && ((r ^ (prev[1] >> 24)) & 0xff)) {
return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
}
if (prev) {
// prev64= (prev64<<8) | ((prev32>>24) & 0xff);
// prev32= (prev32<<8) | (d0 & 0xff);
prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 0xff);
prev[0]= (prev[0]<<8) | (d0 & 0xff);
}
}
for (i=0; len>0;i++) {
pc_dout.data &= ~0x0e;
d0=(d=buf[i]);
for (j=0;j<8;j++) {
//D(printk("i=%x, j=%x, len=%x, d=%x ",i,j,len,d));
if (len>0) {
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);
else pc_dout.data = (pc_dout.data & ~0x0a) | (((d<<=1)>>7) & 2);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data |= (1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
pc_dout.data &= ~(1 << FPGAJTAG_TCK_BIT);
REG_WR(gio, regi_gio, rw_pc_dout, pc_dout);
} else r= (r<<1);
len--;
//D(printk(", r=%x\r\n",r));
}
buf[i]=r; // read back in-place
if (check && ((r ^ (prev[1] >> 24)) & 0xff)) {
return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
}
if (prev) {
// prev64= (prev64<<8) | ((prev32>>24) & 0xff);
// prev32= (prev32<<8) | (d0 & 0xff);
prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 0xff);
prev[0]= (prev[0]<<8) | (d0 & 0xff);
}
}
#endif /* TEST_DISABLE_CODE */
break;
case JTAG_SENSOR_FPGA:
break;
case JTAG_SENSOR_FPGA:
#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()
udelay (1); // wait MUX
for (i=0; len>0;i++) {
d0=(d=buf[i]);
for (j=0;j<8;j++) {
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay
if (len>0) {
if ((len==1) && last) port_csp0_addr[X313_WA_SENSFPGA] =
(3 << SFPGA_TMS_BIT) |
(((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_BIT) |
(2 << SFPGA_TMS_BIT) |
(2 << SFPGA_TCK_BIT) ;
else port_csp0_addr[X313_WA_SENSFPGA] =
(((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_BIT) |
(2 << SFPGA_TMS_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] = (3 << SFPGA_TCK_BIT); // TCK=1
// add delays here if long cable?
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
} else r= (r<<1);
len--;
}
buf[i]=r; // read back in-place
if (check && ((r ^ (prev[1]>>24)) & 0xff)) {
return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
}
if (prev) {
// prev64= (prev64<<8) | ((prev32>>24) & 0xff);
// prev32= (prev32<<8) | (d0 & 0xff);
prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 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] = SFPGA_RD_TDO; // just in case, it should be in that mode when calling jtag_write_bits()
udelay (1); // wait MUX
for (i=0; len>0;i++) {
d0=(d=buf[i]);
for (j=0;j<8;j++) {
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0 - just a delay
if (len>0) {
if ((len==1) && last) port_csp0_addr[X313_WA_SENSFPGA] =
(3 << SFPGA_TMS_BIT) |
(((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_BIT) |
(2 << SFPGA_TMS_BIT) |
(2 << SFPGA_TCK_BIT) ;
else port_csp0_addr[X313_WA_SENSFPGA] =
(((((d<<=1)>>8) & 1) | 2) << SFPGA_TDI_BIT) |
(2 << SFPGA_TMS_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] = (3 << SFPGA_TCK_BIT); // TCK=1
// add delays here if long cable?
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
} else r= (r<<1);
len--;
}
buf[i]=r; // read back in-place
if (check && ((r ^ (prev[1]>>24)) & 0xff)) {
return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
}
if (prev) {
// prev64= (prev64<<8) | ((prev32>>24) & 0xff);
// prev32= (prev32<<8) | (d0 & 0xff);
prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 0xff);
prev[0]= (prev[0]<<8) | (d0 & 0xff);
}
}
port_csp0_addr[X313_WA_SENSFPGA] = (2 << SFPGA_TCK_BIT); // TCK=0
#endif /* TEST_DISABLE_CODE */
// Can be done once
data.d32 = 0;
data.tck_set = 1;
data.tms_set = 1;
data.tdi_set = 1;
for (i = 0; len > 0; i++) {
d0 = (d = buf[i]);
dev_dbg(NULL,"jtag_write_bits(), i=0x%x ", i);
bm = 0;
for (j = 0; j < 8; j++) {
if (len > 0) {
data.tms = (len == 1 && last)? 1:0 ;
data.tdi = ((d <<= 1) >> 8) & 1;
data.tck = 0;
x393_sensio_jtag(data, sens_num);
// Can be done once
data.d32 = 0;
data.tck_set = 1;
data.tms_set = 1;
data.tdi_set = 1;
for (i = 0; len > 0; i++) {
d0 = (d = buf[i]);
dev_dbg(NULL,"jtag_write_bits(), i=0x%x ", i);
bm = 0;
for (j = 0; j < 8; j++) {
if (len > 0) {
data.tms = (len == 1 && last)? 1:0 ;
data.tdi = ((d <<= 1) >> 8) & 1;
data.tck = 0;
x393_sensio_jtag(data, sens_num);
#ifndef PARALLEL_JTAG
r = (r << 1) + read_tdo(sens_num);
r = (r << 1) + read_tdo(sens_num);
#else
bm = (bm <<1 ) | 1;
bm = (bm <<1 ) | 1;
#endif
data.tck = 1;
x393_sensio_jtag(data, sens_num);
data.tck = 0;
x393_sensio_jtag(data, sens_num);
} else {
r <<= 1;
}
len--;
}
data.tck = 1;
x393_sensio_jtag(data, sens_num);
data.tck = 0;
x393_sensio_jtag(data, sens_num);
} else {
r <<= 1;
}
len--;
}
#ifdef PARALLEL_JTAG
r = read_tdo_byte(sens_num) & bm;
if (unlikely(len < 0)){
r <<= -len;
}
r = read_tdo_byte(sens_num) & bm;
if (unlikely(len < 0)){
r <<= -len;
}
#endif
buf[i] = r;
dev_dbg(NULL," ===> %02x\n", r);
if (check && ((r ^ (prev[1]>>24)) & 0xff)) {
return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
}
if (prev) {
prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 0xff);
prev[0]= (prev[0]<<8) | (d0 & 0xff);
}
}
break;
case JTAG_AUX_FPGA:
break;
}
return 0;
buf[i] = r;
dev_dbg(NULL," ===> %02x\n", r);
if (check && ((r ^ (prev[1]>>24)) & 0xff)) {
return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
}
if (prev) {
prev[1]= (prev[1]<<8) | ((prev[0]>>24) & 0xff);
prev[0]= (prev[0]<<8) | (d0 & 0xff);
}
}
break;
case JTAG_AUX_FPGA:
break;
}
return 0;
}
int JTAG_configure (int chn, unsigned char * buf, int len) {
int datastart, i, j ,r;
//static int prev32;
//static int prev64;
int prev[2];
int datastart, i, j ,r;
//static int prev32;
//static int prev64;
int prev[2];
#ifdef JTAG_DISABLE_IRQ
unsigned long flags;
unsigned long flags;
#endif
const unsigned char sync[]={0xff,0xff,0xff,0xff,0xaa,0x99,0x55,0x66};
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);
// all the programming goes here...
// find sync:
datastart=-1;
for (i=0;i<(FJTAG_MAX_HEAD-8);i++) {
j=0;
while ((j<8) && (buf[i+j]==sync[j])) j++;
if (j==8) {
datastart=i;
break;
const unsigned char sync[]={0xff,0xff,0xff,0xff,0xaa,0x99,0x55,0x66};
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);
// all the programming goes here...
// find sync:
datastart=-1;
for (i=0;i<(FJTAG_MAX_HEAD-8);i++) {
j=0;
while ((j<8) && (buf[i+j]==sync[j])) j++;
if (j==8) {
datastart=i;
break;
}
}
}
if (datastart<0) {
dev_err(NULL,"Bitstream not found - bad file\r\n");
return -EFAULT;
}
// check for right bitstream length
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,"header size - %d, data size - %d\r\n",datastart, len-datastart);
return -EFAULT;
}
// enable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 1);
// reset device
set_pgm (chn, 1);
//udelay (1000); // needed?
mdelay(1);
set_pgm (chn, 0);
// wait INIT over - no init connected, just wait >2ms
//udelay (2500);
mdelay(3);
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE PROGRAMMING CYCLE ***********************
//D( udelay (100000);printk("JTAG_configure(): IRQ off!\r\n"); udelay (100000););
D( mdelay (100);printk("JTAG_configure(): IRQ off!\r\n"); mdelay (100););
if (datastart<0) {
dev_err(NULL,"Bitstream not found - bad file\r\n");
return -EFAULT;
}
// check for right bitstream length
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,"header size - %d, data size - %d\r\n",datastart, len-datastart);
return -EFAULT;
}
// enable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 1);
// reset device
set_pgm (chn, 1);
//udelay (1000); // needed?
mdelay(1);
set_pgm (chn, 0);
// wait INIT over - no init connected, just wait >2ms
//udelay (2500);
mdelay(3);
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE PROGRAMMING CYCLE ***********************
//D( udelay (100000);printk("JTAG_configure(): IRQ off!\r\n"); udelay (100000););
D( mdelay (100);printk("JTAG_configure(): IRQ off!\r\n"); mdelay (100););
#ifdef JTAG_DISABLE_IRQ
local_irq_save(flags);
//local_irq_disable();
local_irq_save(flags);
//local_irq_disable();
#endif
// prepare JTAG
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, 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, 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, 2, 0 ); //step 7 - set SELECT-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)
jtag_write_bits (chn,
&buf[datastart], // data to write
skipvfy << 3, // number of bytes to write
0, // compare readback data with previously written, abort on mismatch
0, // do not raise TMS at last bit
prev); // 64 bits storage to verify configuration transmission
if ((r=jtag_write_bits (chn,
&buf[datastart+skipvfy],
// (buf8i-(datastart+skipvfy)) << 3,
(len-(datastart+skipvfy)) << 3,
1,
1, prev))<0) {
r= -r;
i= (r>>8) -1 + (datastart+skipvfy);
r &= 0xff;
// prepare JTAG
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, 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, 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, 2, 0 ); //step 7 - set SELECT-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)
jtag_write_bits (chn,
&buf[datastart], // data to write
skipvfy << 3, // number of bytes to write
0, // compare readback data with previously written, abort on mismatch
0, // do not raise TMS at last bit
prev); // 64 bits storage to verify configuration transmission
if ((r=jtag_write_bits (chn,
&buf[datastart+skipvfy],
// (buf8i-(datastart+skipvfy)) << 3,
(len-(datastart+skipvfy)) << 3,
1,
1, prev))<0) {
r= -r;
i= (r>>8) -1 + (datastart+skipvfy);
r &= 0xff;
#ifdef JTAG_DISABLE_IRQ
local_irq_restore(flags);
local_irq_restore(flags);
#endif
set_pgm (chn, 1);
set_pgm (chn, 0);
// disable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 0);
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]);
return -EFAULT;
}
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, 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, 1, 1, 0 ); //step 15 - finish JSTART
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 17a - (total >=12 clocks)
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, 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?
// ready or not - device should start now
set_pgm (chn, 1);
set_pgm (chn, 0);
// disable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 0);
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]);
return -EFAULT;
}
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, 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, 1, 1, 0 ); //step 15 - finish JSTART
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 17a - (total >=12 clocks)
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, 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?
// ready or not - device should start now
#ifdef JTAG_DISABLE_IRQ
local_irq_restore(flags);
local_irq_restore(flags);
#endif
//*************************** END OF NO INTERRUPS ***********************
r=read_done(chn);
// disable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 0);
if (r==0) {
dev_err(NULL,"*** FPGA did not start after configuration ***\r\n");
return -EFAULT;
}
//D( udelay (100000);printk("\nJTAG_configure() OK!\r\n"));
D( mdelay (100);printk("\nJTAG_configure() OK!\r\n"));
dev_info(NULL,"JTAG_configure() OK!\n");
return 0;
//*************************** END OF NO INTERRUPS ***********************
r=read_done(chn);
// disable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 0);
if (r==0) {
dev_err(NULL,"*** FPGA did not start after configuration ***\r\n");
return -EFAULT;
}
//D( udelay (100000);printk("\nJTAG_configure() OK!\r\n"));
D( mdelay (100);printk("\nJTAG_configure() OK!\r\n"));
dev_info(NULL,"JTAG_configure() OK!\n");
return 0;
} //int JTAG_configure
......@@ -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
// leaves in Run-Test-Idle state
int JTAG_openChannel (int chn) {
dev_dbg(NULL, "JTAG_openChannel (%d)\n",chn);
// enable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 1);
// for shared JTAG/data bus we need to de-program the chip to be able to read JTAG :-(
switch (chn >> 2) {
case JTAG_SENSOR_FPGA:
// reset device
set_pgm (chn, 1);
set_pgm (chn, 0);
// wait INIT over - no init connected, just wait >2ms
//udelay (2500);
mdelay(3);
break;
}
jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state
jtag_send(chn, 0, 1, 0 ); // set Run-Test-Idle state
return 0;
dev_dbg(NULL, "JTAG_openChannel (%d)\n",chn);
// enable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 1);
// for shared JTAG/data bus we need to de-program the chip to be able to read JTAG :-(
switch (chn >> 2) {
case JTAG_SENSOR_FPGA:
// reset device
set_pgm (chn, 1);
set_pgm (chn, 0);
// wait INIT over - no init connected, just wait >2ms
//udelay (2500);
mdelay(3);
break;
}
jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state
jtag_send(chn, 0, 1, 0 ); // set Run-Test-Idle state
return 0;
} // int JTAG_openChannel (int chn)
//
int JTAG_resetChannel (int chn) {
dev_dbg(NULL, "JTAG_resetChannel (%d)\n",chn);
jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state
// disable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 0); // only for sensor FPGA
return 0;
dev_dbg(NULL, "JTAG_resetChannel (%d)\n",chn);
jtag_send(chn, 1, 5, 0 ); // set Test-Logic-Reset state
// disable programmimg mode (nop for the 10353 FPGA)
set_pgm_mode(chn, 0); // only for sensor FPGA
return 0;
} // int JTAG_resetChannel (int chn)
int JTAG_readID (int chn, unsigned char * buf) {
int i;
unsigned long d1,d2=0;
unsigned long * dp;
int i;
unsigned long d1,d2=0;
unsigned long * dp;
#ifdef JTAG_DISABLE_IRQ
unsigned long flags;
unsigned long flags;
#endif
// read dev id, user id
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE ***********************
// read dev id, user id
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE ***********************
#ifdef JTAG_DISABLE_IRQ
local_irq_save(flags);
//local_irq_disable();
local_irq_save(flags);
//local_irq_disable();
#endif
// prepare JTAG
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, 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, 5, 0x90); //step 5 - start of 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, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn,
&buf[0], // data to write
32, // number of bits to write/read
0, // don't compare readback data with previously written
1, 0) ; // raise TMS at last bit
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, 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, 5, 0x10); //step 5 - start of 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, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn,
&buf[4], // data to write
32, // number of bits to write/read
0, // don't compare readback data with previously written
1,0) ; // raise TMS at last bit
jtag_send(chn,1, 5, 0 ); //reset state machine to Test-Logic-Reset state
// prepare JTAG
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, 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, 5, 0x90); //step 5 - start of 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, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn,
&buf[0], // data to write
32, // number of bits to write/read
0, // don't compare readback data with previously written
1, 0) ; // raise TMS at last bit
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, 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, 5, 0x10); //step 5 - start of 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, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn,
&buf[4], // data to write
32, // number of bits to write/read
0, // don't compare readback data with previously written
1,0) ; // raise TMS at last bit
jtag_send(chn,1, 5, 0 ); //reset state machine to Test-Logic-Reset state
#ifdef JTAG_DISABLE_IRQ
local_irq_restore(flags);
local_irq_restore(flags);
#endif
//*************************** END OF NO INTERRUPS ***********************
// swap all bits in ID and user fields
dp = (unsigned long *) &buf[0];
d1= *dp;
for (i=0;i<32;i++){
//*************************** END OF NO INTERRUPS ***********************
// swap all bits in ID and user fields
dp = (unsigned long *) &buf[0];
d1= *dp;
for (i=0;i<32;i++){
d2 = (d2 << 1) | (d1 & 1);
d1 >>= 1;
}
*dp=d2;
dp = (unsigned long *) &buf[4];
d1= *dp;
for (i=0;i<32;i++){
}
*dp=d2;
dp = (unsigned long *) &buf[4];
d1= *dp;
for (i=0;i<32;i++){
d2 = (d2 << 1) | (d1 & 1);
d1 >>= 1;
}
*dp=d2;
D(for (i=0; i<8;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");} );
data_modified=0; //*************************************************
return 0;
}
*dp=d2;
D(for (i=0; i<8;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");} );
data_modified=0; //*************************************************
return 0;
} // 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 i; // only in debug
int i; // only in debug
#ifdef JTAG_DISABLE_IRQ
unsigned long flags;
unsigned long flags;
#endif
dev_dbg(NULL,"JTAG_CAPTURE(): buf=%p\n",buf);
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE ***********************
dev_dbg(NULL,"JTAG_CAPTURE(): buf=%p\n",buf);
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE ***********************
#ifdef JTAG_DISABLE_IRQ
local_irq_save(flags);
//local_irq_disable();
local_irq_save(flags);
//local_irq_disable();
#endif
// prepare JTAG
// 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, 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, 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, 2, 0 ); //step 7 - set SELECT-DR state
jtag_send(chn, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn,
buf, // data to write
len, // number of bits to read
0, // don't compare readback data with previously written
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"); );
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"); );
// jtag_send(chn,1, 5, 0 ); //reset state machine to Test-Logic-Reset state
// prepare JTAG
// 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, 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, 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, 2, 0 ); //step 7 - set SELECT-DR state
jtag_send(chn, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn,
buf, // data to write
len, // number of bits to read
0, // don't compare readback data with previously written
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"); );
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"); );
// jtag_send(chn,1, 5, 0 ); //reset state machine to Test-Logic-Reset state
#ifdef JTAG_DISABLE_IRQ
local_irq_restore(flags);
local_irq_restore(flags);
#endif
//*************************** END OF NO INTERRUPS ***********************
dev_dbg(NULL, "\n");
for (i=0; i<((len+7)>>3) ;i++) {
dev_dbg(NULL, "%3x ",(int) buf[i]);
if ((i & 0xf) == 0xf) dev_dbg(NULL, "\n");
}
dev_dbg(NULL, "\n");
data_modified=0;
return 0;
//*************************** END OF NO INTERRUPS ***********************
dev_dbg(NULL, "\n");
for (i=0; i<((len+7)>>3) ;i++) {
dev_dbg(NULL, "%3x ",(int) buf[i]);
if ((i & 0xf) == 0xf) dev_dbg(NULL, "\n");
}
dev_dbg(NULL, "\n");
data_modified=0;
return 0;
} // JTAG_CAPTURE (int chn, unsigned char * buf, int len) {
......@@ -1345,62 +1354,62 @@ dev_dbg(NULL,"JTAG_CAPTURE(): buf=%p\n",buf);
*/
int JTAG_EXTEST (int chn, unsigned char * buf, int len) {
#ifdef JTAG_DISABLE_IRQ
unsigned long flags;
unsigned long flags;
#endif
int i; // only in debug
int i; // only in debug
#ifdef JTAG_DISABLE_IRQ
local_irq_save(flags);
//local_irq_disable();
local_irq_save(flags);
//local_irq_disable();
#endif
//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"); );
// 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, 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, 5, 0xf0); //step 5 - start of 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, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn,
buf,
len, // number of bits to write
0, // don't compare readback data with previously written
1,0); // raise TMS at last bit
//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"); );
// 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, 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, 5, 0xf0); //step 5 - start of 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, 0, 2, 0 ); //step 8 - set CAPTURE-DR state
jtag_write_bits (chn,
buf,
len, // number of bits to write
0, // don't compare readback data with previously written
1,0); // raise TMS at last bit
jtag_send(chn, 1, 1, 0 ); //step 9 - set UPDATE-DR state
#ifdef JTAG_DISABLE_IRQ
local_irq_restore(flags);
local_irq_restore(flags);
#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;
} //int JTAG_EXTEST (int chn, unsigned char * buf, int len)
static int __init fpga_jtag_init(void) {
int i,res;
res = register_chrdev(FPGA_JTAG_MAJOR, fpga_jtag_name, &fpga_jtag_fops);
if(res < 0) {
dev_err(NULL,"\nfpga_jtag_init: couldn't get a major number %d.\n",FPGA_JTAG_MAJOR);
return res;
}
dev_dbg(NULL,FPGA_JTAG_DRIVER_NAME" - %d\n",FPGA_JTAG_MAJOR);
for (i=0;i<=FPGA_JTAG_MAXMINOR;i++) minors[i]=0;
initPortC();
dev_dbg(NULL, "elphel test %s: MAJOR %d", FPGA_JTAG_DRIVER_NAME, FPGA_JTAG_MAJOR);
res = init_mmio_ptr();
if (res < 0)
return -ENOMEM;
return 0;
int i,res;
res = register_chrdev(DEV393_MAJOR(DEV393_JTAGS_CONF0), fpga_jtag_name, &fpga_jtag_fops);
if(res < 0) {
dev_err(NULL,"\nfpga_jtag_init: couldn't get a major number %d.\n",DEV393_MAJOR(DEV393_JTAGS_CONF0));
return res;
}
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;
initPortC();
dev_dbg(NULL, "elphel test %s: MAJOR %d", DEV393_NAME(DEV393_JTAGS_CONF0), DEV393_MAJOR(DEV393_JTAGS_CONF0));
res = init_mmio_ptr();
if (res < 0)
return -ENOMEM;
return 0;
}
static void __exit fpga_jtag_exit(void)
{
unregister_chrdev(FPGA_JTAG_MAJOR, FPGA_JTAG_DRIVER_NAME);
dev_dbg(NULL, "unregistering driver");
unregister_chrdev(DEV393_MAJOR(DEV393_JTAGS_CONF0), DEV393_NAME(DEV393_JTAGS_CONF0));
dev_dbg(NULL, "unregistering driver");
}
module_exit(fpga_jtag_exit);
......@@ -1409,5 +1418,5 @@ module_exit(fpga_jtag_exit);
module_init(fpga_jtag_init);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>");
MODULE_DESCRIPTION(FPGA_JTAG_DRIVER_NAME);
MODULE_DESCRIPTION(FPGA_JTAG_DRIVER_DESCRIPTION);
......@@ -47,9 +47,10 @@
//#include <asm/delay.h>
#include <asm/uaccess.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/c313a.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 "cc3x3.h"
//#include "x3x3.h" // hardware definitions
......@@ -117,7 +118,7 @@
/**
* 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 */
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)
privData->minor = MINOR(inode->i_rdev);
MDF1(printk(": minor=0x%x\n", privData->minor));
switch (privData->minor) {
case CMOSCAM_MINOR_FRAMEPARS_CHN_0:
case CMOSCAM_MINOR_FRAMEPARS_CHN_1:
case CMOSCAM_MINOR_FRAMEPARS_CHN_2:
case CMOSCAM_MINOR_FRAMEPARS_CHN_3:
case DEV393_MINOR(DEV393_FRAMEPARS0):
case DEV393_MINOR(DEV393_FRAMEPARS1):
case DEV393_MINOR(DEV393_FRAMEPARS2):
case DEV393_MINOR(DEV393_FRAMEPARS3):
inode->i_size = 0; //or return 8 - number of frame pages?
return 0;
default:
......@@ -1093,10 +1094,10 @@ int framepars_release(struct inode *inode, struct file *filp)
MDF1(printk(": minor=0x%x\n", p));
switch ( p ) {
case CMOSCAM_MINOR_FRAMEPARS_CHN_0:
case CMOSCAM_MINOR_FRAMEPARS_CHN_1:
case CMOSCAM_MINOR_FRAMEPARS_CHN_2:
case CMOSCAM_MINOR_FRAMEPARS_CHN_3:
case DEV393_MINOR(DEV393_FRAMEPARS0):
case DEV393_MINOR(DEV393_FRAMEPARS1):
case DEV393_MINOR(DEV393_FRAMEPARS2):
case DEV393_MINOR(DEV393_FRAMEPARS3):
break;
default:
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)
{
unsigned long target_frame;
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];
MDF1(printk(" offset=0x%x, orig=0x%x, sensor_port = %d\n", (int)offset, (int)orig, sensor_port));
switch (orig) {
......@@ -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 = pars_static;
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];
unsigned long frame = *off; // ************* NOTE: Never use file->f_pos in write() and read() !!!
int latency = -1;
......@@ -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));
count &= ~7; // sizeof (struct frameparspair_t)==8
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
pars = (struct frameparspair_t*)kmalloc(count, GFP_KERNEL);
if (!pars) return -ENOMEM;
......@@ -1296,11 +1300,14 @@ int framepars_mmap(struct file *file, struct vm_area_struct *vma)
{
int result;
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));
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,
vma->vm_start,
((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)
initMultiPars(sensor_port); // just clear - needs to be called again when sensor is recognized
}
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) {
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;
}
for (sensor_port = 0; sensor_port < SENSOR_PORTS; 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;
}
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;
}
......@@ -1361,7 +1368,7 @@ int framepars_remove(struct platform_device *pdev)
// .probe = framepars_init,
// .remove = framepars_remove,
// .driver = {
// .name = FRAMEPARS_DRIVER_NAME,
// .name = DEV393_NAME(DEV393_FRAMEPARS0),
// .of_match_table = elphel393_framepars_of_match,
// },
//};
......@@ -1370,4 +1377,5 @@ int framepars_remove(struct platform_device *pdev)
//
//MODULE_LICENSE("GPL");
//MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
//MODULE_DESCRIPTION(X3X3_FRAMEPARS_DRIVER_NAME);
//MODULE_DESCRIPTION(FRAMEPARS_DRIVER_DESCRIPTION);
//
......@@ -112,7 +112,7 @@
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/x393_devices.h>
#include <uapi/elphel/c313a.h>
#include <uapi/elphel/exifa.h>
//#include "fpgactrl.h" // defines port_csp0_addr, port_csp4_addr
......@@ -153,7 +153,7 @@
/** 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 */
#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
* \n TODO: use P_*?
......@@ -750,7 +750,7 @@ int gammas_open(struct inode *inode, struct file *file) {
privData-> minor=MINOR(inode->i_rdev);
MDF10(printk("gammas_open, minor=0x%x\n",privData-> minor));
switch (privData-> minor) {
case CMOSCAM_MINOR_GAMMAS :
case DEV393_MINOR(DEV393_GAMMA) :
inode->i_size = GAMMA_FILE_SIZE;
privData-> scale= 0;
privData-> hash16=0;
......@@ -775,7 +775,7 @@ int gammas_release(struct inode *inode, struct file *file) {
int p = MINOR(inode->i_rdev);
MDF10(printk("gammas_release, minor=0x%x\n",p));
switch ( p ) {
case CMOSCAM_MINOR_GAMMAS :
case DEV393_MINOR(DEV393_GAMMA) :
break;
default:
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) {
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));
switch (privData->minor) {
case CMOSCAM_MINOR_GAMMAS :
case DEV393_MINOR(DEV393_GAMMA) :
switch(orig) {
case SEEK_SET:
file->f_pos = offset;
......@@ -872,7 +872,7 @@ ssize_t gammas_write(struct file * file, ///< this file structure
unsigned short * gamma= data.gamma;
MDF10(printk(" file->f_pos=0x%x, *off=0x%x\n", (int) file->f_pos, (int) *off));
switch (privData->minor) {
case CMOSCAM_MINOR_GAMMAS :
case DEV393_MINOR(DEV393_GAMMA) :
if (count>sizeof (data)) count = sizeof (data);
if(count) {
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) {
struct gammas_pd * privData = (struct gammas_pd *) file->private_data;
MDF10(printk("gammas_all_mmap, minor=0x%x\n",privData-> minor));
switch (privData->minor) {
case CMOSCAM_MINOR_GAMMAS :
case DEV393_MINOR(DEV393_GAMMA) :
result=remap_pfn_range(vma,
vma->vm_start,
((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) {
*/
static int __init gammas_init(void) {
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();
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
// 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) {
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;
}
// 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;
}
......@@ -942,7 +942,7 @@ static int __init gammas_init(void) {
module_init(gammas_init);
MODULE_LICENSE("GPLv3.0");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
MODULE_DESCRIPTION(X3X3_GAMMAS_DRIVER_NAME);
MODULE_DESCRIPTION(X3X3_GAMMAS_DRIVER_DESCRIPTION);
......
......@@ -106,7 +106,7 @@
#include <linux/dma-direction.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/exifa.h>
//#include "fpgactrl.h" // defines port_csp0_addr, port_csp4_addr
......@@ -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
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 */
int histograms_map[SENSOR_PORTS][MAX_SENSORS];
......@@ -463,7 +463,7 @@ int histograms_open(struct inode *inode, ///< inode
privData-> minor=MINOR(inode->i_rdev);
MDF21(printk("minor=0x%x\n",privData-> minor));
switch (privData-> minor) {
case CMOSCAM_MINOR_HISTOGRAMS :
case DEV393_MINOR(DEV393_HISTOGRAM) :
inode->i_size = HISTOGRAMS_FILE_SIZE;
privData->frame=0xffffffff;
privData->frame_index=-1;
......@@ -490,7 +490,7 @@ int histograms_release (struct inode *inode, ///< inode
int p = MINOR(inode->i_rdev);
MDF21(printk("minor=0x%x\n",p));
switch ( p ) {
case CMOSCAM_MINOR_HISTOGRAMS :
case DEV393_MINOR(DEV393_HISTOGRAM) :
break;
default:
return -EINVAL; //! do not need to free anything - "wrong number"
......@@ -535,7 +535,7 @@ loff_t histograms_lseek (struct file * file,
MDF21(printk("offset=0x%x, orig=0x%x\n",(int) offset, (int) orig));
switch (privData->minor) {
case CMOSCAM_MINOR_HISTOGRAMS :
case DEV393_MINOR(DEV393_HISTOGRAM) :
switch(orig) {
case SEEK_CUR: // ignore offset
offset+=(privData-> wait_mode)?
......@@ -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;
MDF21(printk("minor=0x%x\n",privData-> minor));
switch (privData->minor) {
case CMOSCAM_MINOR_HISTOGRAMS :
case DEV393_MINOR(DEV393_HISTOGRAM) :
result=remap_pfn_range(vma,
vma->vm_start,
((unsigned long) virt_to_phys(histograms_p)) >> PAGE_SHIFT, // Should be page-aligned
......@@ -676,15 +676,15 @@ static int __init histograms_init(void) {
int res;
// init_histograms(); // Not now??? Need to have list of channels
// 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) {
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;
}
// 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_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;
}
......@@ -692,4 +692,4 @@ static int __init histograms_init(void) {
module_init(histograms_init);
MODULE_LICENSE("GPLv3.0");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
MODULE_DESCRIPTION(X3X3_HISTOGRAMS_DRIVER_NAME);
MODULE_DESCRIPTION(X3X3_HISTOGRAMS_DRIVER_DESCRIPTION);
......@@ -49,12 +49,13 @@
#include <linux/string.h>
#include <asm/delay.h>
#include <asm/uaccess.h> // copy_*_user
#include <elphel/driver_numbers.h>
#include <uapi/elphel/c313a.h>
#include <elphel/elphel393-mem.h>
#include "imu_log393.h"
#include "x393.h"
#include "cci2c.h"
#include <uapi/elphel/x393_devices.h>
#if 0
#define D(x) x
......@@ -104,7 +105,7 @@
#endif
#define RS232_RATE 19200 ///< RS232 bps
#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
#ifdef NC353
......@@ -606,12 +607,12 @@ static int imu_open(struct inode *inode, struct file *filp) {
D(printk("filp=%lx\r\n",(unsigned long)filp) );
switch ( p ) {
case LOGGER_CTL_MINOR:
case DEV393_MINOR(DEV393_LOGGER_CTRL):
D1(printk(KERN_NOTICE "IMU_ctl_open\n"));
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
break;
case LOGGER_MINOR :
case DEV393_MINOR(DEV393_LOGGER) :
{
D1(printk(KERN_NOTICE "IMU_open\n"));
inode->i_size=sizeof(wbuf); // only in write mode
......@@ -668,8 +669,8 @@ static int imu_release(struct inode *inode, struct file *filp) {
// int res=0;
int p = MINOR(inode->i_rdev);
switch ( p ) {
case LOGGER_MINOR :
case LOGGER_CTL_MINOR:
case DEV393_MINOR(DEV393_LOGGER) :
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);
break;
default: return -EINVAL;
......@@ -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)));
// switch (((int *)file->private_data)[0]) {
switch ((int) file->private_data) {
case LOGGER_MINOR :
case LOGGER_CTL_MINOR:
case DEV393_MINOR(DEV393_LOGGER) :
case DEV393_MINOR(DEV393_LOGGER_CTRL):
if (!file->f_mode & FMODE_WRITE) {
return -EINVAL; // readonly
}
......@@ -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));
int p=(int)file->private_data;
switch (p) {
case LOGGER_MINOR:
case LOGGER_CTL_MINOR:
case DEV393_MINOR(DEV393_LOGGER):
case DEV393_MINOR(DEV393_LOGGER_CTRL):
switch (orig) {
case SEEK_SET:
file->f_pos = offset;
......@@ -783,7 +784,7 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) {
return (-EOVERFLOW);
}
/** 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);
file->f_pos = sizeof(wbuf);
return (-EOVERFLOW);
......@@ -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;
#endif
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 0; // bigger than all
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
*off+=count;
return count;
break;
case LOGGER_MINOR :
case DEV393_MINOR(DEV393_LOGGER) :
#ifdef NC353
updateNumBytesWritten();
#endif
......@@ -944,13 +945,13 @@ static int logger_init(struct platform_device *pdev)
if (!match)
return -EINVAL;
dev_dbg(dev, "Registering character device with name "LOGGER_DRIVER_NAME);
res = register_chrdev(LOGGER_MAJOR, LOGGER_DRIVER_NAME, &imu_fops);
dev_dbg(dev, "Registering character device with name "DEV393_NAME(DEV393_LOGGER));
res = register_chrdev(DEV393_MAJOR(DEV393_LOGGER), DEV393_NAME(DEV393_LOGGER), &imu_fops);
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;
}
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
logger_buffer = (u32 *) pElphel_buf->logger_vaddr; // must be page-aligned!
logger_size = pElphel_buf->logger_size << PAGE_SHIFT;
......@@ -1236,7 +1237,7 @@ int x313_setDMA1Buffer(void) {
static int logger_remove(struct platform_device *pdev) ///< [in] pointer to @e platform_device structure
///< @return always 0
{
unregister_chrdev(LOGGER_MAJOR, LOGGER_DRIVER_NAME);
unregister_chrdev(DEV393_MAJOR(DEV393_LOGGER), DEV393_NAME(DEV393_LOGGER));
return 0;
}
......@@ -1251,7 +1252,7 @@ static struct platform_driver elphel393_logger = {
.probe = logger_init,
.remove = logger_remove,
.driver = {
.name = LOGGER_DRIVER_NAME,
.name = DEV393_NAME(DEV393_LOGGER),
.of_match_table = elphel393_logger_of_match,
},
};
......
......@@ -52,7 +52,7 @@
//#include <asm/delay.h>
//#include <asm/uaccess.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/x393_devices.h>
#include <elphel/c313a.h>
//#include <asm/elphel/fpgaconfa.h>
#include <elphel/exifa.h>
......@@ -78,7 +78,7 @@
/**
* @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
* @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)
//MODULE_LICENSE("GPL");
//MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
//MODULE_DESCRIPTION(IMAGEACQ_DRIVER_NAME);
//MODULE_DESCRIPTION(IMAGEACQ_DRIVER_DESCRIPTION);
......@@ -34,9 +34,9 @@
#include <asm/outercache.h>
#include <asm/cacheflush.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/c313a.h>
#include <uapi/elphel/exifa.h>
//#include <uapi/elphel/x393_devices.h>
#include "framepars.h"
#include "sensor_common.h"
......@@ -52,8 +52,8 @@
#include <asm/delay.h> // just for usleep1000()
/** @brief Driver name to display in log messages.*/
#define IMAGEACQ_DRIVER_NAME "Elphel (R) Model 393 Image Acquisition device driver"
/* Driver name to display in log messages.*/
//#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.*/
#define L2_INVAL_SIZE (32 * 1024)
......@@ -1031,4 +1031,4 @@ int legacy_i2c(int ports) ///< bitmask of the sensor ports to use
//MODULE_LICENSE("GPL");
//MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
//MODULE_DESCRIPTION(IMAGEACQ_DRIVER_NAME);
//MODULE_DESCRIPTION(IMAGEACQ_DRIVER_DESCRIPTION);
......@@ -30,7 +30,7 @@
#include <linux/jiffies.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <elphel/driver_numbers.h>
#include <uapi/elphel/x393_devices.h> // just driver name
#include <asm/uaccess.h>
#include "x393.h"
#include "sensor_i2c.h"
......@@ -52,7 +52,7 @@
#define SYSFS_READONLY 0444
#define SYSFS_WRITEONLY 0222
#define DRV_NAME "elphel_sensor_i2c"
//#define DRV_NAME "elphel_sensor_i2c"
struct x393_i2c_device_list {
x393_i2c_device_t i2c_dev;
......@@ -1400,7 +1400,7 @@ static struct platform_driver elphel393_sensor_i2c = {
.probe = elphel393_sensor_i2c_probe, ///< Function executed on probe operation
.remove = elphel393_sensor_i2c_remove, ///< Function executed on remove operation
.driver = { ///< Driver specifications
.name = "elphel393-sensor-i2c", ///< driver name
.name = DEV393_NAME(DEV393_I2C_SENSORS), ///< driver name
.owner = THIS_MODULE, ///< Driver owner
.of_match_table = elphel393_sensor_i2c_of_match, ///< Device tree match data
.pm = NULL, ///< No power management supported in this driver
......
......@@ -19,7 +19,8 @@
#ifndef _X393_MACRO
#define _X393_MACRO
#include <elphel/driver_numbers.h>
#include <uapi/elphel/x393_devices.h>
/** @brief Resolution of current/OEF pointer in bits */
#define OFFSET256_CNTR_RES 26
......@@ -75,7 +76,7 @@
static inline unsigned int minor_to_chn(unsigned int minor, unsigned int *dev_type)
{
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;
else
*dev_type = 0;
......
......@@ -27,13 +27,13 @@
#include "x393.h"
#include "x393_videomem.h"
#include <elphel/driver_numbers.h>
#include <uapi/elphel/c313a.h>
#include <uapi/elphel/x393_devices.h>
#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 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)
// Add sysfs modification
dev_dbg(dev, "Registering character device with name "VIDEOMEM_DRIVER_NAME);
res = register_chrdev(VIDEOMEM_MAJOR, VIDEOMEM_DRIVER_NAME, &videomem_fops);
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(DEV393_MAJOR(DEV393_VIDEOMEM_RAW), DEV393_NAME(DEV393_VIDEOMEM_RAW), &videomem_fops);
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;
}
// Setup interrupt
......@@ -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
///< @return always 0
{
unregister_chrdev(VIDEOMEM_MAJOR, VIDEOMEM_DRIVER_NAME);
unregister_chrdev(DEV393_MAJOR(DEV393_VIDEOMEM_RAW), DEV393_NAME(DEV393_VIDEOMEM_RAW));
return 0;
}
......@@ -585,7 +587,7 @@ static struct platform_driver elphel393_videomem = {
.probe = videomem_probe,
.remove = videomem_remove,
.driver = {
.name = VIDEOMEM_DRIVER_NAME,
.name = DEV393_NAME(DEV393_VIDEOMEM_RAW),
.of_match_table = elphel393_videomem_of_match,
},
};
......
/// driver_numbers.h
/// see packages/devices/elphel/Makefile - major numbers should match
//#define CMOSCAM_MAJOR 126
#define X3X3_EXIF_MAJOR 125
#define ELPHEL_MAJOR 126
#define STREAM_MAJOR 127
#define FPGA_MAJOR 129
#define FPGA_JTAG_MAJOR 132
#define FPGA_CLOCK_MAJOR 133
#define X3X3_I2C_MAJOR 134
#define CIRCBUF_MAJOR 135
/*
#define LLL1 ("one", 2, 3, 4)
#define lll_first(n, ...) n
#define lll_second(x,n, ...) n
const char * ccc1 = lll_first LLL1;
const int iii2 = lll_second LLL1;
#define xxx lll_first LLL1
const char *ccc2 = xxx;
*/
//#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 130
#define GAMMAS_MAJOR 137
#define HISTOGRAMS_MAJOR 138
#define FRAMEPARS_MAJOR 130
#define GAMMAS_MAJOR 137
#define HISTOGRAMS_MAJOR 138
//#define IMAGERAW_MAJOR 139
#define IMAGERAW_MAJOR 131
#define IMAGEACQ_MAJOR 140
#define LOGGER_MAJOR 141
#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 IMAGERAW_MAJOR 131
#define IMAGEACQ_MAJOR 140
#define LOGGER_MAJOR 141
#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?
/// MINORS
#define LOGGER_MINOR 1
#define LOGGER_CTL_MINOR 2
#define IMAGERAW_MINOR_FRAME 1
#define IMAGERAW_MINOR_FPN 2
#define IMAGERAW_MINOR_UNLOCK 3
#define CIRCBUF_MINOR 0x20
#define CIRCBUF_MINOR_CHN_0 0x20
#define CIRCBUF_MINOR_CHN_1 0x21
#define CIRCBUF_MINOR_CHN_2 0x22
#define CIRCBUF_MINOR_CHN_3 0x23
#define JPEGHEAD_MINOR 0x30
#define JPEGHEAD_MINOR_CHN_0 0x30
#define JPEGHEAD_MINOR_CHN_1 0x31
#define JPEGHEAD_MINOR_CHN_2 0x32
#define JPEGHEAD_MINOR_CHN_3 0x33
#define HUFFMAN_MINOR 0x40
#define HUFFMAN_MINOR_CHN_0 0x40
#define HUFFMAN_MINOR_CHN_1 0x41
#define HUFFMAN_MINOR_CHN_2 0x42
#define HUFFMAN_MINOR_CHN_3 0x43
#define LOGGER_MINOR 1
#define LOGGER_CTL_MINOR 2
#define IMAGERAW_MINOR_FRAME 1
#define IMAGERAW_MINOR_FPN 2
#define IMAGERAW_MINOR_UNLOCK 3
#define CIRCBUF_MINOR 0x20
#define CIRCBUF_MINOR_CHN_0 0x20
#define CIRCBUF_MINOR_CHN_1 0x21
#define CIRCBUF_MINOR_CHN_2 0x22
#define CIRCBUF_MINOR_CHN_3 0x23
#define JPEGHEAD_MINOR 0x30
#define JPEGHEAD_MINOR_CHN_0 0x30
#define JPEGHEAD_MINOR_CHN_1 0x31
#define JPEGHEAD_MINOR_CHN_2 0x32
#define JPEGHEAD_MINOR_CHN_3 0x33
#define HUFFMAN_MINOR 0x40
#define HUFFMAN_MINOR_CHN_0 0x40
#define HUFFMAN_MINOR_CHN_1 0x41
#define HUFFMAN_MINOR_CHN_2 0x42
#define HUFFMAN_MINOR_CHN_3 0x43
#define CMOSCAM_MINOR_FRAMEPARS_CHN_0 0x50
#define CMOSCAM_MINOR_FRAMEPARS_CHN_1 0x51
#define CMOSCAM_MINOR_FRAMEPARS_CHN_2 0x52
#define CMOSCAM_MINOR_FRAMEPARS_CHN_3 0x53
#define CMOSCAM_MINOR_RWTABLES 9
#define CMOSCAM_MINOR_CIRCBUF 11
#define CMOSCAM_MINOR_HISTOGRAM 12
#define CMOSCAM_MINOR_JPEAGHEAD 13
#define CMOSCAM_MINOR_GAMMA 14
#define CMOSCAM_MINOR_FRAMEPARS 16
#define CMOSCAM_MINOR_GAMMAS 17
#define CMOSCAM_MINOR_HISTOGRAMS 18
#define CMOSCAM_MINOR_IMAGEACQ 19
#define CMOSCAM_MINOR_HUFFMAN 20
#define FPGACONF_MINOR_IORW 3 /* direct R/W FPGA registers */
#define FPGACONF_MINOR_SDRAM 4 /* read/write SDRAM through PIO */
#define FPGACONF_MINOR_TABLES 6 /// Write FPGA tables directly
#define CMOSCAM_MINOR_RWTABLES 9
#define CMOSCAM_MINOR_CIRCBUF 11
#define CMOSCAM_MINOR_HISTOGRAM 12
#define CMOSCAM_MINOR_JPEAGHEAD 13
#define CMOSCAM_MINOR_GAMMA 14
#define CMOSCAM_MINOR_FRAMEPARS 16
#define CMOSCAM_MINOR_GAMMAS 17
#define CMOSCAM_MINOR_HISTOGRAMS 18
#define CMOSCAM_MINOR_IMAGEACQ 19
#define CMOSCAM_MINOR_HUFFMAN 20
#define FPGACONF_MINOR_IORW 3 ///< direct R/W FPGA registers
#define FPGACONF_MINOR_SDRAM 4 ///< read/write SDRAM through PIO
#define FPGACONF_MINOR_TABLES 6 ///< Write FPGA tables directly
#define FPGA_CLOCK_MINOR 2
#define FPGA_CLOCK_MINOR_I2C 2
#define FPGA_CLOCK_MINOR_CLOCKS 3
#define FPGA_CLOCK_MINOR 2
#define FPGA_CLOCK_MINOR_I2C 2
#define FPGA_CLOCK_MINOR_CLOCKS 3
#define FPGA_JTAG_RESET_MINOR 0 // just close open files
#define FPGA_JTAG_RAW_MINOR 0 // just close open files
#define FPGA_JTAG_MINOR 1
#define FPGA_SJTAG_MINOR 2
#define FPGA_AJTAG_MINOR 3
#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_AJTAG_BOUNDARY_MINOR 7 // read/write boundary pins of the aux board FPGA
#define FPGA_JTAG_RESET_MINOR 0 // just close open files
#define FPGA_JTAG_RAW_MINOR 0 // just close open files
#define FPGA_JTAG_MINOR 1
#define FPGA_SJTAG_MINOR 2
#define FPGA_AJTAG_MINOR 3
#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_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_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_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_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_META 1 // write metadata, concurently opened files. All writes atomic
//#define X3X3_EXIF_EXIF 0 // read encoded Exif data (SEEK_END,
//#define X3X3_EXIF_META 1 // write metadata, concurently opened files. All writes atomic
// control/setup devices
#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_TEMPLATE 2 // write Exif template
#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.
#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)
#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_2 0x12 // 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_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_3 0x23 // write metadata, concurently opened files. All writes atomic
#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_2 0x12 // 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_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_3 0x23 // write metadata, concurently opened files. All writes atomic
......@@ -4,4 +4,5 @@
header-y += exifa.h
header-y += c313a.h
header-y += x393_devices.h
......@@ -120,6 +120,8 @@
#define MCPwrseq 0x200
#else
// 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_8_AINC 1 ///< 8bit registers, autoincement while read/write
#define X3X3_I2C_16_AINC 2 ///< 16bit registers, autoincement while read/write
......@@ -128,6 +130,7 @@
#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_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_WR 1 ///< bit 1 - enable i2c write
#define X3X3_I2C_ENABLE_RAW 2 ///< bit 2 - enable i2c raw (no address byte)
......@@ -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_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_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_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