Commit 56064cd8 authored by Andrey Filippov's avatar Andrey Filippov

merged with framepars

parents 923da644 809ae1e8
...@@ -299,5 +299,15 @@ ...@@ -299,5 +299,15 @@
klogger-393,buffer_size = <1048576>; klogger-393,buffer_size = <1048576>;
} ; } ;
/* i2c driver for the extension boards, such as imu, gps, etc */
elphel393_ext_i2c:elphel393-ext-i2c@0{
compatible = "elphel,elphel393-ext-i2c-1.00";
time_scl_high = <3>; /* SCL high duration (us) */
time_scl_low = <3>; /* SCL low duration (us) */
time_slave2master = <2>; /* slave -> master delay (us) */
time_master2slave = <2>; /* master -> slave delay (us) */
filter_sda = <7>; /* filter SDA read data by testing multiple times - currently just zero/non zero */
filter_scl = <7>; /* filter SCL read data by testing multiple times - currently just zero/non zero */
};
}; };
\ No newline at end of file
...@@ -298,6 +298,15 @@ ...@@ -298,6 +298,15 @@
compatible = "elphel,klogger-393-1.00"; compatible = "elphel,klogger-393-1.00";
klogger-393,buffer_size = <1048576>; klogger-393,buffer_size = <1048576>;
} ; } ;
/* i2c driver for the extension boards, such as imu, gps, etc */
elphel393_ext_i2c:elphel393-ext-i2c@0{
compatible = "elphel,elphel393-ext-i2c-1.00";
time_scl_high = <3>; /* SCL high duration (us) */
time_scl_low = <3>; /* SCL low duration (us) */
time_slave2master = <2>; /* slave -> master delay (us) */
time_master2slave = <2>; /* master -> slave delay (us) */
filter_sda = <7>; /* filter SDA read data by testing multiple times - currently just zero/non zero */
filter_scl = <7>; /* filter SCL read data by testing multiple times - currently just zero/non zero */
};
}; };
\ No newline at end of file
...@@ -299,5 +299,15 @@ ...@@ -299,5 +299,15 @@
klogger-393,buffer_size = <1048576>; klogger-393,buffer_size = <1048576>;
} ; } ;
/* i2c driver for the extension boards, such as imu, gps, etc */
elphel393_ext_i2c:elphel393-ext-i2c@0{
compatible = "elphel,elphel393-ext-i2c-1.00";
time_scl_high = <3>; /* SCL high duration (us) */
time_scl_low = <3>; /* SCL low duration (us) */
time_slave2master = <2>; /* slave -> master delay (us) */
time_master2slave = <2>; /* master -> slave delay (us) */
filter_sda = <7>; /* filter SDA read data by testing multiple times - currently just zero/non zero */
filter_scl = <7>; /* filter SCL read data by testing multiple times - currently just zero/non zero */
};
}; };
\ No newline at end of file
...@@ -299,5 +299,15 @@ ...@@ -299,5 +299,15 @@
klogger-393,buffer_size = <1048576>; klogger-393,buffer_size = <1048576>;
} ; } ;
/* i2c driver for the extension boards, such as imu, gps, etc */
elphel393_ext_i2c:elphel393-ext-i2c@0{
compatible = "elphel,elphel393-ext-i2c-1.00";
time_scl_high = <3>; /* SCL high duration (us) */
time_scl_low = <3>; /* SCL low duration (us) */
time_slave2master = <2>; /* slave -> master delay (us) */
time_master2slave = <2>; /* master -> slave delay (us) */
filter_sda = <7>; /* filter SDA read data by testing multiple times - currently just zero/non zero */
filter_scl = <7>; /* filter SCL read data by testing multiple times - currently just zero/non zero */
};
}; };
\ No newline at end of file
...@@ -94,6 +94,13 @@ ...@@ -94,6 +94,13 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <linux/platform_device.h> // For sysfs
#include <linux/of_device.h>
//#include <linux/of.h>
//#include <linux/of_fdt.h>
//#include <linux/of_net.h>
#include <linux/sysfs.h>
#include <asm/delay.h> #include <asm/delay.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <uapi/elphel/x393_devices.h> #include <uapi/elphel/x393_devices.h>
...@@ -139,7 +146,7 @@ ...@@ -139,7 +146,7 @@
//Just removing delays is absolutely wrong (does not work with other sensors) what can be done - replacing constants with some run-time value(s) and set them individually for different sensors. For now - I'll use the standard values again. //Just removing delays is absolutely wrong (does not work with other sensors) what can be done - replacing constants with some run-time value(s) and set them individually for different sensors. For now - I'll use the standard values again.
#define i2c_delay(usecs) udelay(usecs) #define i2c_delay(usecs) udelay(usecs)
#define I2C_DELAY_SCALE 1 #define I2C_DELAY_SCALE 1 // with I2C_DELAY_SCALE==1 SCL period is 900 KHz - using udelay?
//#define X3X3_I2C_MAXMINOR 4 // //#define X3X3_I2C_MAXMINOR 4 //
//#define X3X3_I2C_CHANNELS 2 // number of i2c channels //#define X3X3_I2C_CHANNELS 2 // number of i2c channels
...@@ -149,10 +156,12 @@ ...@@ -149,10 +156,12 @@
// currently delays are approximately 0.4usec+0.2usec*n and 0x01010000 works (~8usec/byte) // currently delays are approximately 0.4usec+0.2usec*n and 0x01010000 works (~8usec/byte)
// with deafult 20MHz pixel clock - 0x01010202, after clock is set to 48MHz 0x01010000 is enough // with deafult 20MHz pixel clock - 0x01010202, after clock is set to 48MHz 0x01010000 is enough
//TODO: Make delays independent for 2 channels? //TODO: Make delays independent for 2 channels?
static struct device *g_dev_ptr=NULL; ///< Global pointer to basic device structure. This pointer is used in debugfs output functions
static struct i2c_timing_t bitdelays[X3X3_I2C_CHANNELS]; static struct i2c_timing_t bitdelays[X3X3_I2C_CHANNELS];
static int xi2c_initialized=0; // configure GPIO puins access at first command;
#ifdef NC353 #ifdef NC353
static int i2c_hardware_on=0; // shadow register fro FPFA I@C controller static int i2c_hardware_on=0; // shadow register for FPFA I2C controller
#endif #endif
...@@ -170,6 +179,7 @@ int i2c_restart(int n); ...@@ -170,6 +179,7 @@ int i2c_restart(int n);
int i2c_stop(int n); int i2c_stop(int n);
int i2c_outbyte(int n, unsigned char d); int i2c_outbyte(int n, unsigned char d);
unsigned char i2c_inbyte(int n, int more); unsigned char i2c_inbyte(int n, int more);
static void test_init_GPIO(void);
//void i2c_sendack(int n, int ackn); // ackn= 1 - send ackn (low level), 0 - no ackn. //void i2c_sendack(int n, int ackn); // ackn= 1 - send ackn (low level), 0 - no ackn.
// the following functions should be called with IRQ off. Maybe will replace with FPGA register read // the following functions should be called with IRQ off. Maybe will replace with FPGA register read
...@@ -180,12 +190,15 @@ void i2c_run(void) {X3X3_I2C_RUN; i2c_hardware_on=1;} ...@@ -180,12 +190,15 @@ void i2c_run(void) {X3X3_I2C_RUN; i2c_hardware_on=1;}
int i2s_running(void) {return i2c_hardware_on;} int i2s_running(void) {return i2c_hardware_on;}
#endif #endif
#define i2c_ldelay(usecs) udelay(usecs)
/*
void i2c_ldelay(int dly){ void i2c_ldelay(int dly){
while (dly--) { while (dly--) {
__asm__ __volatile__(""); __asm__ __volatile__("");
} }
} }
*/
// Low level i2c pin functions // Low level i2c pin functions
...@@ -238,10 +251,31 @@ X313_I2C_CMD ...@@ -238,10 +251,31 @@ X313_I2C_CMD
#ifdef NC353 #ifdef NC353
#define X313_PIOR(x) ((port_csp0_addr[X313__RA__IOPINS] >> X313_PIOR__##x ) & 1) #define X313_PIOR(x) ((port_csp0_addr[X313__RA__IOPINS] >> X313_PIOR__##x ) & 1)
#else #else
#define X313_PIOR(x) ((x393_gpio_status().d32 >> X313_PIOR__##x ) & 1) #define X313_PIOR(x) ((read_gpio() >> X313_PIOR__##x ) & 1)
#endif #endif
u32 read_gpio(void)
{
x393_gpio_status_t gpio_status;
x393_status_ctrl_t stat_ctrl;
int i;
stat_ctrl.d32 = 0;
gpio_status = x393_gpio_status();
stat_ctrl.seq_num = gpio_status.seq_num + 1;
stat_ctrl.mode = 1;
set_x393_gpio_status_control(stat_ctrl);
for (i = 0; i < 10; i++) {
gpio_status = x393_gpio_status();
if (likely(gpio_status.seq_num == stat_ctrl.seq_num)) {
return gpio_status.d32 & 0x3ff; // lower 10 bits
}
}
dev_err(NULL,"read_gpio(): failed to get expected seq_num in 10 cycles, expected = 0x%x, got 0x%x\n",stat_ctrl.seq_num, gpio_status.seq_num);
return gpio_status.d32 & 0x3ff;
}
/* /*
struct i2c_timing_t { struct i2c_timing_t {
...@@ -264,6 +298,7 @@ int i2c_getbit(int n) { ...@@ -264,6 +298,7 @@ int i2c_getbit(int n) {
if (bitdelays[n].filter_sda) if (bitdelays[n].filter_sda)
return (((X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1))) >> 2); return (((X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1))) >> 2);
else return X313_PIOR(SDA1); else return X313_PIOR(SDA1);
#endif #endif
} }
...@@ -341,9 +376,10 @@ void i2c_sda_strong (int n, int d) { // will also force sda enable ...@@ -341,9 +376,10 @@ void i2c_sda_strong (int n, int d) { // will also force sda enable
int i2c_start(int n) { int i2c_start(int n) {
int i; int i;
unsigned long flags; unsigned long flags;
test_init_GPIO();
local_irq_save(flags); local_irq_save(flags);
//local_irq_disable(); //local_irq_disable();
D(printk("i2c_start: bus=%x\r\n", n)); dev_dbg(g_dev_ptr, "i2c_start: bus=%x\r\n", n);
// both SCL and SDA are supposed to be high - no waiting is needed // both SCL and SDA are supposed to be high - no waiting is needed
// set SCL=1, release SDA, wait SCL high time and verify. // set SCL=1, release SDA, wait SCL high time and verify.
i2c_scl_1(n); i2c_scl_1(n);
...@@ -375,7 +411,7 @@ int i2c_stop(int n) { ...@@ -375,7 +411,7 @@ int i2c_stop(int n) {
unsigned long flags; unsigned long flags;
local_irq_save(flags); local_irq_save(flags);
//local_irq_disable(); //local_irq_disable();
D(printk("i2c_stop: bus=%x\r\n", n)); dev_dbg(g_dev_ptr, "i2c_stop: bus=%x\r\n", n);
// SCL=0, SDA - unknown. Wait for bus turnover // SCL=0, SDA - unknown. Wait for bus turnover
i2c_sda_weak (n, 0); i2c_sda_weak (n, 0);
i2c_ldelay(bitdelays[n].slave2master*I2C_DELAY_SCALE); // maybe not needed as it is 1->0 transition i2c_ldelay(bitdelays[n].slave2master*I2C_DELAY_SCALE); // maybe not needed as it is 1->0 transition
...@@ -394,7 +430,7 @@ int i2c_restart(int n) { ...@@ -394,7 +430,7 @@ int i2c_restart(int n) {
unsigned long flags; unsigned long flags;
local_irq_save(flags); local_irq_save(flags);
//local_irq_disable(); //local_irq_disable();
D(printk("i2c_restart: bus=%x\r\n", n)); dev_dbg(g_dev_ptr, "i2c_restart: bus=%x\r\n", n);
// SCL=0, SDA - unknown. Wait for bus turnover // SCL=0, SDA - unknown. Wait for bus turnover
i2c_sda_weak (n, 1); i2c_sda_weak (n, 1);
i2c_ldelay(bitdelays[n].slave2master*I2C_DELAY_SCALE); // time for slave to release the bus i2c_ldelay(bitdelays[n].slave2master*I2C_DELAY_SCALE); // time for slave to release the bus
...@@ -417,7 +453,7 @@ int i2c_outbyte(int n, unsigned char d) { ...@@ -417,7 +453,7 @@ int i2c_outbyte(int n, unsigned char d) {
unsigned long flags; unsigned long flags;
local_irq_save(flags); local_irq_save(flags);
//local_irq_disable(); //local_irq_disable();
D(printk("i2c_outbyte: bus=%x byte=%x\r\n", n, x)); dev_dbg(g_dev_ptr, "i2c_outbyte: bus=%x byte=%x\r\n", n, x);
i2c_sda_weak (n, 1); i2c_sda_weak (n, 1);
i2c_ldelay(bitdelays[n].slave2master * I2C_DELAY_SCALE); // time for slave to release the bus i2c_ldelay(bitdelays[n].slave2master * I2C_DELAY_SCALE); // time for slave to release the bus
for (i = 0; i < 8; i++) { // assumed to be with SCL=0; for (i = 0; i < 8; i++) { // assumed to be with SCL=0;
...@@ -439,7 +475,7 @@ int i2c_outbyte(int n, unsigned char d) { ...@@ -439,7 +475,7 @@ int i2c_outbyte(int n, unsigned char d) {
i2c_ldelay(bitdelays[n].scl_high * I2C_DELAY_SCALE); // regular SCL=1 delay i2c_ldelay(bitdelays[n].scl_high * I2C_DELAY_SCALE); // regular SCL=1 delay
i= (1-i2c_getbit(n)); i= (1-i2c_getbit(n));
i2c_scl_0(n); i2c_scl_0(n);
D(printk("i2c_outbyte: ACK=%x\r\n", i)); dev_dbg(g_dev_ptr, "i2c_outbyte: ACK=%x\r\n", i);
local_irq_restore(flags); local_irq_restore(flags);
return i; return i;
} }
...@@ -453,7 +489,7 @@ unsigned char i2c_inbyte(int n, int more) { // assumed SCL=0, SDA=X ...@@ -453,7 +489,7 @@ unsigned char i2c_inbyte(int n, int more) { // assumed SCL=0, SDA=X
unsigned long flags; unsigned long flags;
local_irq_save(flags); local_irq_save(flags);
//local_irq_disable(); //local_irq_disable();
D(printk("i2c_inbyte: bus=%x\r\n", n)); dev_dbg(g_dev_ptr, "i2c_inbyte: bus=%x\r\n", n);
// prepare to read ACKN // prepare to read ACKN
i2c_sda_weak (n, 1); i2c_sda_weak (n, 1);
i2c_ldelay(bitdelays[n].master2slave * I2C_DELAY_SCALE); // master -> slave delay i2c_ldelay(bitdelays[n].master2slave * I2C_DELAY_SCALE); // master -> slave delay
...@@ -476,7 +512,7 @@ unsigned char i2c_inbyte(int n, int more) { // assumed SCL=0, SDA=X ...@@ -476,7 +512,7 @@ unsigned char i2c_inbyte(int n, int more) { // assumed SCL=0, SDA=X
i2c_scl_0(n); i2c_scl_0(n);
//TODO: (test next is OK - 2012-01-15) //TODO: (test next is OK - 2012-01-15)
i2c_sda_weak (n, 1); // release SDA byte i2c_sda_weak (n, 1); // release SDA byte
D(printk("i2c_inbyte: data=%x\r\n", aBitByte)); dev_dbg(g_dev_ptr, "i2c_inbyte: data=%x\r\n", aBitByte);
local_irq_restore(flags); local_irq_restore(flags);
return aBitByte; // returns with SCL=0, SDA - OFF return aBitByte; // returns with SCL=0, SDA - OFF
} }
...@@ -493,7 +529,7 @@ unsigned char i2c_inbyte(int n, int more) { // assumed SCL=0, SDA=X ...@@ -493,7 +529,7 @@ unsigned char i2c_inbyte(int n, int more) { // assumed SCL=0, SDA=X
*#--------------------------------------------------------------------------*/ *#--------------------------------------------------------------------------*/
int i2c_writeData(int n, unsigned char theSlave, unsigned char *theData, int size, int stop) { int i2c_writeData(int n, unsigned char theSlave, unsigned char *theData, int size, int stop) {
int i,error=0; int i,error=0;
D(printk("i2c_writeData: bus=%x theSlave=%x data=%x %x size=%x\r\n", n, theSlave, theData[0], theData[1], size)); dev_dbg(g_dev_ptr, "i2c_writeData: bus=%x theSlave=%x data=%x %x size=%x\r\n", n, theSlave, theData[0], theData[1], size);
// generate start condition, test bus // generate start condition, test bus
if ((error=i2c_start(n))) return error; if ((error=i2c_start(n))) return error;
...@@ -529,7 +565,7 @@ int i2c_readData(int n, unsigned char theSlave, unsigned char *theData, int size ...@@ -529,7 +565,7 @@ int i2c_readData(int n, unsigned char theSlave, unsigned char *theData, int size
if ((error=i2c_restart(n))) return error; if ((error=i2c_restart(n))) return error;
} }
/* send slave address, wait for ack */ /* send slave address, wait for ack */
D(printk("i2c_readData: bus=%x theSlave=%x size=%x start=%d\r\n", n, theSlave, size, start)); dev_dbg(g_dev_ptr, "i2c_readData: bus=%x theSlave=%x size=%x start=%d\r\n", n, theSlave, size, start);
if(!i2c_outbyte(n,theSlave)) { if(!i2c_outbyte(n,theSlave)) {
i2c_stop(n); i2c_stop(n);
...@@ -548,9 +584,9 @@ int i2c_ioctl(struct inode *inode, struct file *file, ...@@ -548,9 +584,9 @@ int i2c_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) { unsigned int cmd, unsigned long arg) {
unsigned char data[3]; unsigned char data[3];
int error=0; int error=0;
D(printk("i2c_ioctl cmd= %x, arg= %x\n\r",cmd,(int) arg)); dev_dbg(g_dev_ptr, "i2c_ioctl cmd= %x, arg= %x\n\r",cmd,(int) arg);
D(printk("i2c_ioctl: ((int *)file->private_data)[0]= %x\n\r",((int *)file->private_data)[0])); dev_dbg(g_dev_ptr, "i2c_ioctl: ((int *)file->private_data)[0]= %x\n\r",((int *)file->private_data)[0]);
// D(printk("i2c_ioctl: ((int )file->private_data)= %x\n\r",(int)file->private_data)); // dev_dbg(g_dev_ptr, "i2c_ioctl: ((int )file->private_data)= %x\n\r",(int)file->private_data);
if(_IOC_TYPE(cmd) != CMOSCAM_IOCTYPE) { if(_IOC_TYPE(cmd) != CMOSCAM_IOCTYPE) {
return -EINVAL; return -EINVAL;
} }
...@@ -562,49 +598,49 @@ int i2c_ioctl(struct inode *inode, struct file *file, ...@@ -562,49 +598,49 @@ int i2c_ioctl(struct inode *inode, struct file *file,
return i2c_delays (arg); return i2c_delays (arg);
case I2C_WRITEREG: case I2C_WRITEREG:
/* write to an i2c slave */ /* write to an i2c slave */
D(printk("i2cw bus=%d, slave=%d, reg=%d, value=%d\n", dev_dbg(g_dev_ptr, "i2cw bus=%d, slave=%d, reg=%d, value=%d\n",
(int) I2C_ARGBUS(arg), (int) I2C_ARGBUS(arg),
(int) I2C_ARGSLAVE(arg), (int) I2C_ARGSLAVE(arg),
(int) I2C_ARGREG(arg), (int) I2C_ARGREG(arg),
(int) I2C_ARGVALUE(arg))); (int) I2C_ARGVALUE(arg));
data[0]=I2C_ARGREG(arg); data[0]=I2C_ARGREG(arg);
data[1]=I2C_ARGVALUE(arg); data[1]=I2C_ARGVALUE(arg);
return -i2c_writeData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) & 0xfe, &data[0], 2, 1); // send stop return -i2c_writeData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) & 0xfe, &data[0], 2, 1); // send stop
case I2C_READREG: case I2C_READREG:
/* read from an i2c slave */ /* read from an i2c slave */
D(printk("i2cr bus=%d, slave=%d, reg=%d ", dev_dbg(g_dev_ptr, "i2cr bus=%d, slave=%d, reg=%d ",
(int) I2C_ARGBUS(arg), (int) I2C_ARGBUS(arg),
(int) I2C_ARGSLAVE(arg), (int) I2C_ARGSLAVE(arg),
(int) I2C_ARGREG(arg))); (int) I2C_ARGREG(arg));
data[0]=I2C_ARGREG(arg); data[0]=I2C_ARGREG(arg);
error=i2c_writeData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) & 0xfe, &data[0], 1, 0); // no stop error=i2c_writeData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) & 0xfe, &data[0], 1, 0); // no stop
if (error) return -error; if (error) return -error;
error=i2c_readData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) | 0x01, &data[1], 1, 0); // will start with restart, not start error=i2c_readData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) | 0x01, &data[1], 1, 0); // will start with restart, not start
if (error) return -error; if (error) return -error;
D(printk("returned %d\n", data[1])); dev_dbg(g_dev_ptr, "returned %d\n", data[1]);
return data[1]; return data[1];
case I2C_16_WRITEREG: case I2C_16_WRITEREG:
/* write to an i2c slave */ /* write to an i2c slave */
D(printk("i2c16w slave=%d, reg=%d, value=%d\n", dev_dbg(g_dev_ptr, "i2c16w slave=%d, reg=%d, value=%d\n",
(int) I2C_16_ARGSLAVE(arg), (int) I2C_16_ARGSLAVE(arg),
(int) I2C_16_ARGREG(arg), (int) I2C_16_ARGREG(arg),
(int) I2C_16_ARGVALUE(arg))); (int) I2C_16_ARGVALUE(arg));
data[0]=I2C_16_ARGREG(arg); data[0]=I2C_16_ARGREG(arg);
data[1]=I2C_16_ARGVALUE_H(arg); data[1]=I2C_16_ARGVALUE_H(arg);
data[2]=I2C_16_ARGVALUE_L(arg); data[2]=I2C_16_ARGVALUE_L(arg);
return -i2c_writeData(0, I2C_16_ARGSLAVE(arg) & 0xfe, &data[0], 3, 1); // send stop return -i2c_writeData(0, I2C_16_ARGSLAVE(arg) & 0xfe, &data[0], 3, 1); // send stop
case I2C_16_READREG: case I2C_16_READREG:
/* read from an i2c slave */ /* read from an i2c slave */
D(printk("i2c16r slave=%d, reg=%d ", dev_dbg(g_dev_ptr, "i2c16r slave=%d, reg=%d ",
(int) I2C_16_ARGSLAVE(arg), (int) I2C_16_ARGSLAVE(arg),
(int) I2C_16_ARGREG(arg))); (int) I2C_16_ARGREG(arg));
data[0]=I2C_16_ARGREG(arg); data[0]=I2C_16_ARGREG(arg);
error=i2c_writeData(0, I2C_16_ARGSLAVE(arg) & 0xfe, &data[0], 1, 0); //no stop error=i2c_writeData(0, I2C_16_ARGSLAVE(arg) & 0xfe, &data[0], 1, 0); //no stop
if (error) return -error; if (error) return -error;
error=i2c_readData(0, I2C_16_ARGSLAVE(arg) | 0x01, &data[1], 2, 0); error=i2c_readData(0, I2C_16_ARGSLAVE(arg) | 0x01, &data[1], 2, 0);
if (error) return -error; if (error) return -error;
D(printk("returned %d\n", (data[1]<<8)+data[2])); dev_dbg(g_dev_ptr, "returned %d\n", (data[1]<<8)+data[2]);
return (data[1]<<8)+data[2]; return (data[1]<<8)+data[2];
default: default:
return -EINVAL; return -EINVAL;
...@@ -644,7 +680,7 @@ static int xi2c_release(struct inode *inode, struct file *filp); ...@@ -644,7 +680,7 @@ static int xi2c_release(struct inode *inode, struct file *filp);
static loff_t xi2c_lseek (struct file * file, loff_t offset, int orig); static loff_t xi2c_lseek (struct file * file, loff_t offset, int orig);
static ssize_t xi2c_write (struct file * file, const char * buf, size_t count, loff_t *off); static ssize_t xi2c_write (struct file * file, const char * buf, size_t count, loff_t *off);
static ssize_t xi2c_read (struct file * file, char * buf, size_t count, loff_t *off); static ssize_t xi2c_read (struct file * file, char * buf, size_t count, loff_t *off);
static int __init xi2c_init(void); static int xi2c_init (struct platform_device *pdev);
static struct file_operations xi2c_fops = { static struct file_operations xi2c_fops = {
owner: THIS_MODULE, owner: THIS_MODULE,
...@@ -678,9 +714,9 @@ int xi2c_open(struct inode *inode, struct file *filp) { ...@@ -678,9 +714,9 @@ int xi2c_open(struct inode *inode, struct file *filp) {
break; break;
} }
D(printk("xi2c_open, minor=%d\n",p)); dev_dbg(g_dev_ptr, "xi2c_open, minor=%d\n",p);
if ((bus>=0) && (inuse[bus] !=0)) return -EACCES; if ((bus>=0) && (inuse[bus] !=0)) return -EACCES;
D(printk("xi2c_open, minor=%d\n",p)); dev_dbg(g_dev_ptr, "xi2c_open, minor=%d\n",p);
inode->i_size=sizes[p]; inode->i_size=sizes[p];
if (bus>=0) inuse[bus] =1; if (bus>=0) inuse[bus] =1;
...@@ -736,7 +772,7 @@ static int xi2c_release(struct inode *inode, struct file *filp){ ...@@ -736,7 +772,7 @@ static int xi2c_release(struct inode *inode, struct file *filp){
bus=-1; bus=-1;
break; break;
} }
D(printk("xi2c_release, minor=%d\n",p)); dev_dbg(g_dev_ptr, "xi2c_release, minor=%d\n",p);
if (bus>=0) inuse[bus]=0; if (bus>=0) inuse[bus]=0;
else if (p==DEV393_MINOR(DEV393_I2C_CTRL)) for (bus=0; bus < X3X3_I2C_CHANNELS; bus++) inuse[bus]=0; else if (p==DEV393_MINOR(DEV393_I2C_CTRL)) for (bus=0; bus < X3X3_I2C_CHANNELS; bus++) inuse[bus]=0;
// thisminor =0; // thisminor =0;
...@@ -802,12 +838,12 @@ static loff_t xi2c_lseek(struct file * file, loff_t offset, int orig) { ...@@ -802,12 +838,12 @@ static loff_t xi2c_lseek(struct file * file, loff_t offset, int orig) {
//!++++++++++++++++++++++++++++++++++++ read() ++++++++++++++++++++++++++++++++++++++++++++++++++++++ //!++++++++++++++++++++++++++++++++++++ read() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) { ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
int hardware_i2c_running; // int hardware_i2c_running;
unsigned long flags; // unsigned long flags;
unsigned long p; unsigned long p;
int error; int error;
p = *off;
char * bbitdelays= (char*) bitdelays; char * bbitdelays= (char*) bitdelays;
p = *off;
int bus=0; int bus=0;
unsigned char * i2cbuf=&i2cbuf_all[0]; // initialize to keep compiler happy unsigned char * i2cbuf=&i2cbuf_all[0]; // initialize to keep compiler happy
unsigned char * userbuf=&i2cbuf[1]; unsigned char * userbuf=&i2cbuf[1];
...@@ -852,7 +888,7 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) { ...@@ -852,7 +888,7 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
slave_adr=(p >> 8) & 0xfe; slave_adr=(p >> 8) & 0xfe;
break; break;
} }
D(printk("xi2c_read (bus=%d) from 0x%x, count=%d\n", bus, (int) *off, (int) count)); dev_dbg(g_dev_ptr, "xi2c_read (bus=%d) from 0x%x, count=%d\n", bus, (int) *off, (int) count);
//! Verify if this slave is enabled for the I2C operation requested //! Verify if this slave is enabled for the I2C operation requested
switch ((int)file->private_data) { switch ((int)file->private_data) {
case DEV393_MINOR(DEV393_I2C_RAW): case DEV393_MINOR(DEV393_I2C_RAW):
...@@ -882,7 +918,7 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) { ...@@ -882,7 +918,7 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
} }
if ((en_bits & en_mask) ^ en_mask) { if ((en_bits & en_mask) ^ en_mask) {
printk("tried disabled xi2c_read (bus=%d, slave=0x%x)\n", bus, slave_adr); printk("tried disabled xi2c_read (bus=%d, slave=0x%x)\n", bus, slave_adr);
D(printk("en_bits=0x%x, en_mask=0x%x (minor=%d)\n", (int) en_bits, (int) en_mask, (int)file->private_data)); dev_dbg(g_dev_ptr, "en_bits=0x%x, en_mask=0x%x (minor=%d)\n", (int) en_bits, (int) en_mask, (int)file->private_data);
return -ENXIO; return -ENXIO;
} }
...@@ -965,18 +1001,17 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) { ...@@ -965,18 +1001,17 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
default: default:
*off+=count; *off+=count;
} }
D(printk("count= 0x%x, pos= 0x%x\n", (int) count, (int)*off)); dev_dbg(g_dev_ptr, "count= 0x%x, pos= 0x%x\n", (int) count, (int)*off);
return count; return count;
} }
//!++++++++++++++++++++++++++++++++++++ write() ++++++++++++++++++++++++++++++++++++++++++++++++++++++ //!++++++++++++++++++++++++++++++++++++ write() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, loff_t *off) { static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, loff_t *off) {
int hardware_i2c_running; // int hardware_i2c_running;
unsigned long flags; // unsigned long flags;
unsigned long p; unsigned long p;
int error; int error;
p = *off;
int bus=0; int bus=0;
char * bbitdelays= (char*) bitdelays; char * bbitdelays= (char*) bitdelays;
unsigned char * i2cbuf=&i2cbuf_all[0]; // initialize to keep compiler happy unsigned char * i2cbuf=&i2cbuf_all[0]; // initialize to keep compiler happy
...@@ -985,6 +1020,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -985,6 +1020,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
int slave_adr; int slave_adr;
int en_mask=0; int en_mask=0;
int en_bits=0; int en_bits=0;
p = *off;
// switch (((int *)file->private_data)[0]) { // switch (((int *)file->private_data)[0]) {
switch ((int)file->private_data) { switch ((int)file->private_data) {
...@@ -1013,7 +1049,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1013,7 +1049,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
slave_adr=(p >> 8) & 0xfe; slave_adr=(p >> 8) & 0xfe;
break; break;
} }
D(printk("xi2c_write (bus=%d) to 0x%x, count=%x\n", bus, (int) *off, (int) count)); dev_dbg(g_dev_ptr, "xi2c_write (bus=%d) to 0x%x, count=%x\n", bus, (int) *off, (int) count);
//! Verify if this slave is enabled for the I2C operation requested //! Verify if this slave is enabled for the I2C operation requested
switch ((int)file->private_data) { switch ((int)file->private_data) {
...@@ -1044,7 +1080,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1044,7 +1080,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
} }
if ((en_bits & en_mask) ^ en_mask) { if ((en_bits & en_mask) ^ en_mask) {
printk("tried disabed xi2c_write (bus=%d, slave=0x%x)\n", bus, slave_adr); printk("tried disabed xi2c_write (bus=%d, slave=0x%x)\n", bus, slave_adr);
D(printk("en_bits=0x%x, en_mask=0x%x (minor=%d)\n", (int) en_bits, (int) en_mask, (int)file->private_data)); dev_dbg(g_dev_ptr, "en_bits=0x%x, en_mask=0x%x (minor=%d)\n", (int) en_bits, (int) en_mask, (int)file->private_data);
return -ENXIO; return -ENXIO;
} }
...@@ -1073,6 +1109,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1073,6 +1109,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
case DEV393_MINOR(DEV393_I2C1_RAW): case DEV393_MINOR(DEV393_I2C1_RAW):
if (bus==0) { if (bus==0) {
error = -EINVAL;
#ifdef NC353 #ifdef NC353
local_irq_save(flags); /// IRQ Off local_irq_save(flags); /// IRQ Off
hardware_i2c_running=i2s_running(); hardware_i2c_running=i2s_running();
...@@ -1092,6 +1129,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1092,6 +1129,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
i2cbuf[0]=p & 0xff; i2cbuf[0]=p & 0xff;
if (bus==0) { if (bus==0) {
error = -EINVAL;
#ifdef NC353 #ifdef NC353
local_irq_save(flags); /// IRQ Off local_irq_save(flags); /// IRQ Off
hardware_i2c_running=i2s_running(); hardware_i2c_running=i2s_running();
...@@ -1111,6 +1149,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1111,6 +1149,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
i2cbuf[0]=(p>>1) & 0xff; i2cbuf[0]=(p>>1) & 0xff;
if (bus==0) { if (bus==0) {
error = -EINVAL;
#ifdef NC353 #ifdef NC353
local_irq_save(flags); /// IRQ Off local_irq_save(flags); /// IRQ Off
hardware_i2c_running=i2s_running(); hardware_i2c_running=i2s_running();
...@@ -1140,13 +1179,192 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo ...@@ -1140,13 +1179,192 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
default: default:
*off+=count; *off+=count;
} }
D(printk("count= 0x%x, pos= 0x%x\n", (int) count, (int)*off)); dev_dbg(g_dev_ptr, "count= 0x%x, pos= 0x%x\n", (int) count, (int)*off);
return count;
}
/** Test if GPIO pins are not initialized, and do it if not (can nolt initialize at driver init as bitstream has to be loaded) */
static void test_init_GPIO(void)
{
x393_gpio_set_pins_t gpio_set_pins = {.d32 = 0};
if (xi2c_initialized) return;
gpio_set_pins.soft = 3; // Enable software control of GPIO pins
x393_gpio_set_pins (gpio_set_pins);
xi2c_initialized=1;
}
// TODO: Add sysfs interface here
#define SYSFS_PERMISSIONS 0644 /* default permissions for sysfs files */
#define SYSFS_READONLY 0444
#define SYSFS_WRITEONLY 0222
static ssize_t show_scl_high(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf,"%d\n", bitdelays[1].scl_high);
}
static ssize_t store_scl_high(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int d;
if (!sscanf(buf, "%u", &d)) {
return - EINVAL;
}
bitdelays[1].scl_high = (unsigned char) d;
return count;
}
static ssize_t show_scl_low(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf,"%d\n", bitdelays[1].scl_low);
}
static ssize_t store_scl_low(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int d;
if (!sscanf(buf, "%u", &d)) {
return - EINVAL;
}
bitdelays[1].scl_low = (unsigned char) d;
return count;
}
static ssize_t show_slave2master(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf,"%d\n", bitdelays[1].slave2master);
}
static ssize_t store_slave2master(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int d;
if (!sscanf(buf, "%u", &d)) {
return - EINVAL;
}
bitdelays[1].slave2master = (unsigned char) d;
return count;
}
static ssize_t show_master2slave(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf,"%d\n", bitdelays[1].master2slave);
}
static ssize_t store_master2slave(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int d;
if (!sscanf(buf, "%u", &d)) {
return - EINVAL;
}
bitdelays[1].master2slave = (unsigned char) d;
return count; return count;
} }
static ssize_t show_filter_sda(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf,"%d\n", bitdelays[1].filter_sda);
}
static ssize_t store_filter_sda(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int d;
if (!sscanf(buf, "%u", &d)) {
return - EINVAL;
}
bitdelays[1].filter_sda = (unsigned char) d;
return count;
}
static ssize_t show_filter_scl(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf,"%d\n", bitdelays[1].filter_scl);
}
static ssize_t store_filter_scl(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int d;
if (!sscanf(buf, "%u", &d)) {
return - EINVAL;
}
bitdelays[1].filter_scl = (unsigned char) d;
return count;
}
static DEVICE_ATTR(time_scl_high, SYSFS_PERMISSIONS, show_scl_high, store_scl_high);
static DEVICE_ATTR(time_scl_low, SYSFS_PERMISSIONS, show_scl_low, store_scl_low);
static DEVICE_ATTR(time_slave2master, SYSFS_PERMISSIONS, show_slave2master, store_slave2master);
static DEVICE_ATTR(time_master2slave, SYSFS_PERMISSIONS, show_master2slave, store_master2slave);
static DEVICE_ATTR(filter_sda, SYSFS_PERMISSIONS, show_filter_sda, store_filter_sda);
static DEVICE_ATTR(filter_scl, SYSFS_PERMISSIONS, show_filter_scl, store_filter_scl);
static struct attribute *root_dev_attrs[] = {
&dev_attr_time_scl_high.attr,
&dev_attr_time_scl_low.attr,
&dev_attr_time_slave2master.attr,
&dev_attr_time_master2slave.attr,
&dev_attr_filter_sda.attr,
&dev_attr_filter_scl.attr,
NULL
};
static const struct attribute_group dev_attr_root_group = {
.attrs = root_dev_attrs,
.name = NULL,
};
static int elphel393_ext_i2c_sysfs_register(struct platform_device *pdev)
{
int retval=0;
struct device *dev = &pdev->dev;
if (&dev->kobj) {
if (((retval = sysfs_create_group(&dev->kobj, &dev_attr_root_group)))<0) return retval;
}
return retval;
}
// Add device tree support (known devices?)
static const struct of_device_id elphel393_ext_i2c_of_match[] = {
{ .compatible = "elphel,elphel393-ext-i2c-1.00" },
{ /* end of list */ }
};
static int elphel393_xi2c_init_of(struct platform_device *pdev) ///< Platform device structure for this driver
{
const struct of_device_id *match;
struct device_node *node;
struct device *dev = &pdev->dev;
match = of_match_device(elphel393_ext_i2c_of_match, dev);
if (!match)
return -EINVAL;
static int __init xi2c_init(void) { node = of_find_node_by_name(NULL, "elphel393-ext-i2c");
if (!node)
{
pr_err("elphel393-ext-i2c: No device tree node found\n");
return -ENODEV;
}
bitdelays[1].scl_high = be32_to_cpup((__be32 *)of_get_property(node, "time_scl_high", NULL));
bitdelays[1].scl_low = be32_to_cpup((__be32 *)of_get_property(node, "time_scl_low", NULL));
bitdelays[1].slave2master = be32_to_cpup((__be32 *)of_get_property(node, "time_slave2master", NULL));
bitdelays[1].master2slave = be32_to_cpup((__be32 *)of_get_property(node, "time_master2slave", NULL));
bitdelays[1].filter_sda = be32_to_cpup((__be32 *)of_get_property(node, "filter_sda", NULL));
bitdelays[1].filter_scl = be32_to_cpup((__be32 *)of_get_property(node, "filter_scl", NULL));
return 0;
}
int xi2c_init(struct platform_device *pdev)
{
int i,res; int i,res;
struct device *dev = &pdev->dev;
elphel393_ext_i2c_sysfs_register(pdev);
dev_info(dev, DEV393_NAME(DEV393_I2C_CTRL)": registered sysfs\n");
g_dev_ptr = dev;
res = register_chrdev(DEV393_MAJOR(DEV393_I2C_CTRL), DEV393_NAME(DEV393_I2C_CTRL), &xi2c_fops); res = register_chrdev(DEV393_MAJOR(DEV393_I2C_CTRL), DEV393_NAME(DEV393_I2C_CTRL), &xi2c_fops);
if(res < 0) { if(res < 0) {
printk(KERN_ERR "\nxi2c_init: couldn't get a major number %d.\n",DEV393_MAJOR(DEV393_I2C_CTRL)); printk(KERN_ERR "\nxi2c_init: couldn't get a major number %d.\n",DEV393_MAJOR(DEV393_I2C_CTRL));
...@@ -1155,6 +1373,8 @@ static int __init xi2c_init(void) { ...@@ -1155,6 +1373,8 @@ static int __init xi2c_init(void) {
printk(X3X3_I2C_DRIVER_NAME" - %d, %d channels\n",DEV393_MAJOR(DEV393_I2C_CTRL),X3X3_I2C_CHANNELS); printk(X3X3_I2C_DRIVER_NAME" - %d, %d channels\n",DEV393_MAJOR(DEV393_I2C_CTRL),X3X3_I2C_CHANNELS);
// thisminor =0; // thisminor =0;
elphel393_xi2c_init_of(pdev);
bitdelays[0].scl_high=2; //! SCL high: bitdelays[0].scl_high=2; //! SCL high:
bitdelays[0].scl_low=2; //! SCL low: bitdelays[0].scl_low=2; //! SCL low:
bitdelays[0].slave2master=1; //! slave -> master bitdelays[0].slave2master=1; //! slave -> master
...@@ -1162,12 +1382,14 @@ static int __init xi2c_init(void) { ...@@ -1162,12 +1382,14 @@ static int __init xi2c_init(void) {
bitdelays[0].filter_sda=0x07; //! filter SDA read data by testing multiple times - currently just zero/non zero bitdelays[0].filter_sda=0x07; //! filter SDA read data by testing multiple times - currently just zero/non zero
bitdelays[0].filter_scl=0x07; //! filter SCL read data by testing multiple times - currently just zero/non zero bitdelays[0].filter_scl=0x07; //! filter SCL read data by testing multiple times - currently just zero/non zero
//! bus 1 - increased by 1 measured for EEPROM //! bus 1 - increased by 1 measured for EEPROM
bitdelays[1].scl_high=3; //! SCL high: bitdelays[1].scl_high=2; //! SCL high: (was 3)
bitdelays[1].scl_low=4; //! SCL low: with 2 - bitdelays[1].scl_low=2; //! SCL low: with 2 -
bitdelays[1].slave2master=2; //! slave -> master bitdelays[1].slave2master=1; //! slave -> master
bitdelays[1].master2slave=2; //! master -> slave bitdelays[1].master2slave=1; //! master -> slave
bitdelays[1].filter_sda=0x07; //! filter SDA read data by testing multiple times - currently just zero/non zero bitdelays[1].filter_sda=0x0; //! filter SDA read data by testing multiple times - currently just zero/non zero
bitdelays[1].filter_scl=0x07; //! filter SCL read data by testing multiple times - currently just zero/non zero bitdelays[1].filter_scl=0x0; //! filter SCL read data by testing multiple times - currently just zero/non zero
elphel393_xi2c_init_of(pdev); // may return negative errors
for (i=0; i<X3X3_I2C_CHANNELS;i++) { for (i=0; i<X3X3_I2C_CHANNELS;i++) {
inuse[i]=0; inuse[i]=0;
...@@ -1244,13 +1466,33 @@ static int __init xi2c_init(void) { ...@@ -1244,13 +1466,33 @@ static int __init xi2c_init(void) {
//#define X3X3_I2C_ENABLE_RAW 2 // bit 2 - enable i2c raw (no address byte) //#define X3X3_I2C_ENABLE_RAW 2 // bit 2 - enable i2c raw (no address byte)
//#define X3X3_I2C_ENABLE_8 3 // bit 3 - enable i2c 8-bit registers access //#define X3X3_I2C_ENABLE_8 3 // bit 3 - enable i2c 8-bit registers access
//#define X3X3_I2C_ENABLE_16 4 // bit 4 - enable i2c 16-bit registers access //#define X3X3_I2C_ENABLE_16 4 // bit 4 - enable i2c 16-bit registers access
xi2c_initialized=0; // configure GPIO puins access at first command;
return 0;
}
//-------------------------------
int xi2c_remove(struct platform_device *pdev)
{
unregister_chrdev(DEV393_MAJOR(DEV393_I2C_CTRL), DEV393_NAME(DEV393_I2C_CTRL));
return 0; return 0;
} }
/* this makes sure that xi2c_init is called during boot */ MODULE_DEVICE_TABLE(of, elphel393_ext_i2c_of_match);
static struct platform_driver elphel393_ext_i2c = {
.probe = xi2c_init,
.remove = xi2c_remove,
.driver = {
.name = DEV393_NAME(DEV393_I2C_CTRL),
.of_match_table = elphel393_ext_i2c_of_match,
},
};
module_platform_driver(elphel393_ext_i2c);
module_init(xi2c_init);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>."); MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
MODULE_DESCRIPTION(X3X3_I2C_DRIVER_NAME); MODULE_DESCRIPTION(X3X3_I2C_DRIVER_NAME);
...@@ -246,7 +246,6 @@ static int get_channel_sub_from_name(struct device_attribute *attr) ///< Linux k ...@@ -246,7 +246,6 @@ static int get_channel_sub_from_name(struct device_attribute *attr) ///< Linux k
static ssize_t show_port_mux(struct device *dev, struct device_attribute *attr, char *buf) static ssize_t show_port_mux(struct device *dev, struct device_attribute *attr, char *buf)
{ {
int i;
const char * name = get_name_by_code(get_detected_mux_code(get_channel_from_name(attr)), DETECT_MUX); const char * name = get_name_by_code(get_detected_mux_code(get_channel_from_name(attr)), DETECT_MUX);
if (name) return sprintf(buf,"%s\n", name); if (name) return sprintf(buf,"%s\n", name);
// Should never get here // Should never get here
...@@ -254,7 +253,6 @@ static ssize_t show_port_mux(struct device *dev, struct device_attribute *attr, ...@@ -254,7 +253,6 @@ static ssize_t show_port_mux(struct device *dev, struct device_attribute *attr,
} }
static ssize_t show_sensor(struct device *dev, struct device_attribute *attr, char *buf) static ssize_t show_sensor(struct device *dev, struct device_attribute *attr, char *buf)
{ {
int i;
int psch = get_channel_sub_from_name(attr); int psch = get_channel_sub_from_name(attr);
int port = (psch>>4) &3; int port = (psch>>4) &3;
int sub_chn = psch &3; int sub_chn = psch &3;
...@@ -265,11 +263,11 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *attr, ch ...@@ -265,11 +263,11 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *attr, ch
} }
static ssize_t store_port_mux(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) static ssize_t store_port_mux(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
size_t len; // size_t len;
char name[80]; char name[80];
int port = get_channel_from_name(attr); int port = get_channel_from_name(attr);
int i, code, rslt; int rslt;
if (sscanf(buf, "%79s", name, &len)){ if (sscanf(buf, "%79s", name)){
if ((rslt = set_detected_mux_code( port, get_code_by_name(name, DETECT_MUX)))<0) if ((rslt = set_detected_mux_code( port, get_code_by_name(name, DETECT_MUX)))<0)
return rslt; return rslt;
...@@ -278,13 +276,13 @@ static ssize_t store_port_mux(struct device *dev, struct device_attribute *attr, ...@@ -278,13 +276,13 @@ static ssize_t store_port_mux(struct device *dev, struct device_attribute *attr,
} }
static ssize_t store_sensor(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) static ssize_t store_sensor(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
size_t len; // size_t len;
char name[80]; char name[80];
int psch = get_channel_sub_from_name(attr); int psch = get_channel_sub_from_name(attr);
int port = (psch>>4) &3; int port = (psch>>4) &3;
int sub_chn = psch &3; int sub_chn = psch &3;
int i, rslt; int rslt;
if (sscanf(buf, "%79s", name, &len)){ if (sscanf(buf, "%79s", name)){
if ((rslt = set_detected_sensor_code(port, sub_chn, get_code_by_name(name, DETECT_SENSOR)))<0) if ((rslt = set_detected_sensor_code(port, sub_chn, get_code_by_name(name, DETECT_SENSOR)))<0)
return rslt; return rslt;
} }
......
...@@ -501,7 +501,7 @@ loff_t exif_lseek (struct file * file, loff_t offset, int orig) { ...@@ -501,7 +501,7 @@ loff_t exif_lseek (struct file * file, loff_t offset, int orig) {
int p=(int)file->private_data; int p=(int)file->private_data;
int thissize=minor_file_size(p); int thissize=minor_file_size(p);
int maxsize=minor_max_size(p); int maxsize=minor_max_size(p);
// int fp; int fp;
dev_dbg(g_devfp_ptr,"exif_lseek, minor=%d, offset = 0x%llx, orig=%d\n",p,offset,orig); dev_dbg(g_devfp_ptr,"exif_lseek, minor=%d, offset = 0x%llx, orig=%d\n",p,offset,orig);
// int sensor_port; // int sensor_port;
switch (orig) { switch (orig) {
...@@ -548,7 +548,9 @@ loff_t exif_lseek (struct file * file, loff_t offset, int orig) { ...@@ -548,7 +548,9 @@ loff_t exif_lseek (struct file * file, loff_t offset, int orig) {
case DEV393_MINOR(DEV393_EXIF_META1): case DEV393_MINOR(DEV393_EXIF_META1):
case DEV393_MINOR(DEV393_EXIF_META2): case DEV393_MINOR(DEV393_EXIF_META2):
case DEV393_MINOR(DEV393_EXIF_META3): case DEV393_MINOR(DEV393_EXIF_META3):
file->f_pos=offset*sizeof(struct exif_dir_table_t); fp= dir_find_tag (offset);
if (fp < 0) return -EOVERFLOW; // tag is not in the directory
file->f_pos=fp;
break; break;
case DEV393_MINOR(DEV393_EXIF_METADIR): case DEV393_MINOR(DEV393_EXIF_METADIR):
file->f_pos=offset*sizeof(struct exif_dir_table_t); file->f_pos=offset*sizeof(struct exif_dir_table_t);
...@@ -602,8 +604,11 @@ ssize_t exif_write (struct file * file, const char * buf, size_t count, loff ...@@ -602,8 +604,11 @@ ssize_t exif_write (struct file * file, const char * buf, size_t count, loff
char tmp[MAX_EXIF_SIZE]; //! Or is it possible to disable IRQ while copy_from_user()? char tmp[MAX_EXIF_SIZE]; //! Or is it possible to disable IRQ while copy_from_user()?
unsigned long flags; unsigned long flags;
int disabled_err=0; int disabled_err=0;
dev_dbg(g_devfp_ptr,"minor=0x%x\n", p);
if ((*off+count)>maxsize) { if ((*off+count)>maxsize) {
dev_warn(g_devfp_ptr,"%s:%d: Data (0x%x) does not fit into 0x%x bytes\n",__FILE__,__LINE__, (int) (*off+count), maxsize); // dev_warn(g_devfp_ptr,"%s:%d: Data (0x%x) does not fit into 0x%x bytes\n",__FILE__,__LINE__, (int) (*off+count), maxsize);
dev_dbg(g_devfp_ptr,"Data (0x%x) does not fit into 0x%x bytes, minor = 0x%x\n",(int) (*off+count), maxsize, p);
return -EOVERFLOW; return -EOVERFLOW;
} }
switch (p) { switch (p) {
......
...@@ -57,21 +57,21 @@ ...@@ -57,21 +57,21 @@
#include <uapi/elphel/x393_devices.h> #include <uapi/elphel/x393_devices.h>
#if 0 #if 1
#define D(x) x #define D(x) x
#define D0(x) x //#define D0(x) x
#define MD7(x) printk("%s:%d:",__FILE__,__LINE__);x //#define MD7(x) printk("%s:%d:",__FILE__,__LINE__);x
#define MD8(x) printk("%s:%d:",__FILE__,__LINE__);x //#define MD8(x) printk("%s:%d:",__FILE__,__LINE__);x
#define MD12(x) printk("%s:%d:",__FILE__,__LINE__);x //#define MD12(x) printk("%s:%d:",__FILE__,__LINE__);x
#else #else
#define D(x) #define D(x)
#define D0(x) //#define D0(x)
#define MD7(x) //#define MD7(x)
#define MD8(x) //#define MD8(x)
#define MD12(x) //#define MD12(x)
#endif #endif
#define D1(x) x //#define D1(x) x
#define IS_103695_REV_A 1 #define IS_103695_REV_A 1
...@@ -215,6 +215,11 @@ ...@@ -215,6 +215,11 @@
#define LSEEK_IMU_NEW 1 ///< start from the new data, discard buffer #define LSEEK_IMU_NEW 1 ///< start from the new data, discard buffer
#define LSEEK_IMU_STOP 2 ///< stop DMA1 and IMU #define LSEEK_IMU_STOP 2 ///< stop DMA1 and IMU
#define LSEEK_IMU_START 3 ///< start IMU and DMA1 (do not modify parameters) #define LSEEK_IMU_START 3 ///< start IMU and DMA1 (do not modify parameters)
static struct device *g_dev_ptr=NULL; ///< Global pointer to basic device structure. This pointer is used in debugfs output functions
const int i2cbus = 1;
static unsigned char dflt_wbuf[]= static unsigned char dflt_wbuf[]=
{ DFLT_PERIOD & 0xff, ( DFLT_PERIOD >> 8 ) & 0xff, ( DFLT_PERIOD >> 16) & 0xff, ( DFLT_PERIOD >> 24 ) & 0xff, { DFLT_PERIOD & 0xff, ( DFLT_PERIOD >> 8 ) & 0xff, ( DFLT_PERIOD >> 16) & 0xff, ( DFLT_PERIOD >> 24 ) & 0xff,
// {0,0,0,0, // period - off // {0,0,0,0, // period - off
...@@ -353,16 +358,17 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -353,16 +358,17 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
x393_logger_data_t logger_data; x393_logger_data_t logger_data;
x393_gpio_set_pins_t gpio_set_pins; x393_gpio_set_pins_t gpio_set_pins;
D(int i2c_err=0;) // D(int i2c_err=0;)
int i2c_err=0;
D(for (i=0; i< sizeof (wbuf); i++ ) { if ((i & 0x1f)==0) printk("\n %03x",i); printk(" %02x",(int) wbuf[i]); }); D(for (i=0; i< sizeof (wbuf); i++ ) { if ((i & 0x1f)==0) printk("\n %03x",i); printk(" %02x",(int) wbuf[i]); });
if (which & WHICH_RESET) { if (which & WHICH_RESET) {
if (logger_is_dma_on()!=0) { if (logger_is_dma_on()!=0) {
D(printk("Stopping DMA\n")); dev_dbg(g_dev_ptr,"Stopping DMA\n");
logger_dma_stop(); logger_dma_stop();
} }
D(printk("Resetting logger\n")); dev_dbg(g_dev_ptr,"Resetting logger\n");
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_CONFIGURE_ADDR; port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_CONFIGURE_ADDR;
port_csp0_addr[X313_WA_IMU_DATA] = IMU_CONF(RST_CONF,1); port_csp0_addr[X313_WA_IMU_DATA] = IMU_CONF(RST_CONF,1);
...@@ -374,10 +380,13 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -374,10 +380,13 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
#endif #endif
} }
if (which & WHICH_INIT) { if (which & WHICH_INIT) {
D(printk("Enabling I/O pins for IMU, written 0x%x to 0x%x\n", (int) X313_WA_IOPINS_EN_IMU, (int) X313_WA_IOPINS)); unsigned char i2c_sa= PCA9500_PP_ADDR+((config[0]>>23) & 0xe);
unsigned char enable_IMU=0xfe; // maybe we need to reset it here? bit [1]
#ifdef NC353 #ifdef NC353
dev_dbg(g_dev_ptr,"Enabling I/O pins for IMU, written 0x%x to 0x%x\n", (int) X313_WA_IOPINS_EN_IMU, (int) X313_WA_IOPINS);
port_csp0_addr[X313_WA_IOPINS] = X313_WA_IOPINS_EN_IMU; port_csp0_addr[X313_WA_IOPINS] = X313_WA_IOPINS_EN_IMU;
#else #else
dev_dbg(g_dev_ptr,"Enabling I/O pins for IMU\n");
gpio_set_pins.d32 = 0; gpio_set_pins.d32 = 0;
gpio_set_pins.chn_c = 3; // enable gpio_set_pins.chn_c = 3; // enable
x393_gpio_set_pins(gpio_set_pins); x393_gpio_set_pins(gpio_set_pins);
...@@ -385,23 +394,21 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -385,23 +394,21 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
#endif #endif
///TODO: add enabling via i2c (bus=1&raw=0x2300&data=0xfe) ///TODO: add enabling via i2c (bus=1&raw=0x2300&data=0xfe)
//PCA9500_PP_ADDR //PCA9500_PP_ADDR
unsigned char i2c_sa= PCA9500_PP_ADDR+((config[0]>>23) & 0xe);
unsigned char enable_IMU=0xfe; // maybe we need to reset it here? bit [1]
#if IS_103695_REV_A #if IS_103695_REV_A
enable_IMU=(((config[0]>>23) & 1)?0xfd:0xff); // bit[0] - reset IMU enable_IMU=(((config[0]>>23) & 1)?0xfd:0xff); // bit[0] - reset IMU
#else #else
enable_IMU=0xfe; // maybe we need to reset it here? bit [1] enable_IMU=0xfe; // maybe we need to reset it here? bit [1]
#endif #endif
i2c_writeData(1, // int n - bus (0 - to the sensor) i2c_writeData(i2cbus, // int n - bus (0 - to the sensor)
i2c_sa, // unsigned char theSlave, i2c_sa, // unsigned char theSlave,
&enable_IMU, //unsigned char *theData, &enable_IMU, //unsigned char *theData,
1, // int size, 1, // int size,
1); // int stop (send stop in the end) 1); // int stop (send stop in the end)
D(printk("Sent i2c command in raw mode - address=0x%x, data=0x%x, result=0x%x\n",(int)i2c_sa, (int) enable_IMU, i2c_err)); dev_dbg(g_dev_ptr,"Sent i2c command in raw mode - address=0x%x, data=0x%x, result=0x%x\n",(int)i2c_sa, (int) enable_IMU, i2c_err);
} }
if (which & WHICH_RESET_SPI) { if (which & WHICH_RESET_SPI) {
D(printk("stopped IMU logger (set period=0)\n")); dev_dbg(g_dev_ptr,"stopped IMU logger (set period=0)\n");
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_PERIOD_ADDR; port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_PERIOD_ADDR;
port_csp0_addr[X313_WA_IMU_DATA] = 0; // reset IMU port_csp0_addr[X313_WA_IMU_DATA] = 0; // reset IMU
...@@ -414,7 +421,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -414,7 +421,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
} }
if (which & WHICH_DIVISOR) { if (which & WHICH_DIVISOR) {
D(printk("IMU clock divisor= %ld\n", divisor[0])); dev_dbg(g_dev_ptr,"IMU clock divisor= %ld\n", divisor[0]);
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_DIVISOR_ADDR; port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_DIVISOR_ADDR;
port_csp0_addr[X313_WA_IMU_DATA] = divisor[0]-1; port_csp0_addr[X313_WA_IMU_DATA] = divisor[0]-1;
...@@ -426,7 +433,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -426,7 +433,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
#endif #endif
} }
if (which & WHICH_RS232DIV) { if (which & WHICH_RS232DIV) {
D(printk("RS232 clock divisor= %ld\n", rs232_div[0])); dev_dbg(g_dev_ptr,"RS232 clock divisor= %ld\n", rs232_div[0]);
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_RS232DIV_ADDR; port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_RS232DIV_ADDR;
port_csp0_addr[X313_WA_IMU_DATA] = rs232_div[0]-1; port_csp0_addr[X313_WA_IMU_DATA] = rs232_div[0]-1;
...@@ -446,19 +453,19 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -446,19 +453,19 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
} }
for (n=0;n<4;n++) { for (n=0;n<4;n++) {
nmea_format[32*n+27]=0; // just in case nmea_format[32*n+27]=0; // just in case
D(printk("Setting NMEA sentence format for $GP%s\n", &nmea_format[32*n])); dev_dbg(g_dev_ptr,"Setting NMEA sentence format for $GP%s\n", &nmea_format[32*n]);
D(printk("(0x%x, 0x%x, 0x%x\n",(int) nmea_format[32*n],(int) nmea_format[32*n+1],(int) nmea_format[32*n+2])); dev_dbg(g_dev_ptr,"(0x%x, 0x%x, 0x%x\n",(int) nmea_format[32*n],(int) nmea_format[32*n+1],(int) nmea_format[32*n+2]);
f=0; f=0;
for (i=2;i>=0;i--) { for (i=2;i>=0;i--) {
b=nmea_format[32*n+i]; /// first 3 letters in each sentence b=nmea_format[32*n+i]; /// first 3 letters in each sentence
D(printk("n=%d, i=%d, b=0x%x\n", n,i,b)); dev_dbg(g_dev_ptr,"n=%d, i=%d, b=0x%x\n", n,i,b);
for (j=4; j>=0; j--) { for (j=4; j>=0; j--) {
f<<=1; f<<=1;
if ((b & (1<<j))!=0) f++; if ((b & (1<<j))!=0) f++;
} }
} }
D(printk("n=%d, f=0x%x\n", n,f)); dev_dbg(g_dev_ptr,"n=%d, f=0x%x\n", n,f);
for (i=0;i<15;i++) if ((f & (1<<i))!=0) nmea_sel[i] |= (1<<n); for (i=0;i<15;i++) if ((f & (1<<i))!=0) nmea_sel[i] |= (1<<n);
f=0; f=0;
nmea_fpga_frmt[n*4]=0; nmea_fpga_frmt[n*4]=0;
...@@ -471,13 +478,13 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -471,13 +478,13 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
nmea_fpga_frmt[n*4+2]=(f>> 8)&0xff; nmea_fpga_frmt[n*4+2]=(f>> 8)&0xff;
nmea_fpga_frmt[n*4+3]=(f>>16)&0xff; nmea_fpga_frmt[n*4+3]=(f>>16)&0xff;
} }
D(printk("Selection data is %x%x%x%x%x%x%x%x%x%x%x%x%x%x%x\n", nmea_sel[0],nmea_sel[1],nmea_sel[2], dev_dbg(g_dev_ptr,"Selection data is %x%x%x%x%x%x%x%x%x%x%x%x%x%x%x\n", nmea_sel[0],nmea_sel[1],nmea_sel[2],
nmea_sel[3],nmea_sel[4],nmea_sel[5],nmea_sel[6],nmea_sel[7],nmea_sel[8],nmea_sel[9], nmea_sel[3],nmea_sel[4],nmea_sel[5],nmea_sel[6],nmea_sel[7],nmea_sel[8],nmea_sel[9],
nmea_sel[10],nmea_sel[11],nmea_sel[12],nmea_sel[13],nmea_sel[14])); nmea_sel[10],nmea_sel[11],nmea_sel[12],nmea_sel[13],nmea_sel[14]);
D(printk("Format data for sentence 1 is %02x %02x %02x %02x\n", nmea_fpga_frmt[ 0],nmea_fpga_frmt[ 1],nmea_fpga_frmt[ 2],nmea_fpga_frmt[ 3])); dev_dbg(g_dev_ptr,"Format data for sentence 1 is %02x %02x %02x %02x\n", nmea_fpga_frmt[ 0],nmea_fpga_frmt[ 1],nmea_fpga_frmt[ 2],nmea_fpga_frmt[ 3]);
D(printk("Format data for sentence 2 is %02x %02x %02x %02x\n", nmea_fpga_frmt[ 4],nmea_fpga_frmt[ 5],nmea_fpga_frmt[ 6],nmea_fpga_frmt[ 7])); dev_dbg(g_dev_ptr,"Format data for sentence 2 is %02x %02x %02x %02x\n", nmea_fpga_frmt[ 4],nmea_fpga_frmt[ 5],nmea_fpga_frmt[ 6],nmea_fpga_frmt[ 7]);
D(printk("Format data for sentence 3 is %02x %02x %02x %02x\n", nmea_fpga_frmt[ 8],nmea_fpga_frmt[ 9],nmea_fpga_frmt[10],nmea_fpga_frmt[11])); dev_dbg(g_dev_ptr,"Format data for sentence 3 is %02x %02x %02x %02x\n", nmea_fpga_frmt[ 8],nmea_fpga_frmt[ 9],nmea_fpga_frmt[10],nmea_fpga_frmt[11]);
D(printk("Format data for sentence 4 is %02x %02x %02x %02x\n", nmea_fpga_frmt[12],nmea_fpga_frmt[13],nmea_fpga_frmt[14],nmea_fpga_frmt[15])); dev_dbg(g_dev_ptr,"Format data for sentence 4 is %02x %02x %02x %02x\n", nmea_fpga_frmt[12],nmea_fpga_frmt[13],nmea_fpga_frmt[14],nmea_fpga_frmt[15]);
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_NMEA_FORMAT_ADDR; port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_NMEA_FORMAT_ADDR;
#else #else
...@@ -491,7 +498,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -491,7 +498,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
logger_data.d32= nmea_sel[i]; logger_data.d32= nmea_sel[i];
x393_logger_data(logger_data); x393_logger_data(logger_data);
#endif #endif
D(printk("Loading imu fpga register 0x%x with 0x%x\n", X313_IMU_NMEA_FORMAT_ADDR+i, nmea_sel[i] )); dev_dbg(g_dev_ptr,"Loading imu fpga register 0x%x with 0x%x\n", X313_IMU_NMEA_FORMAT_ADDR+i, nmea_sel[i] );
} }
for (i=0;i<16;i++) { for (i=0;i<16;i++) {
#ifdef NC353 #ifdef NC353
...@@ -500,12 +507,12 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -500,12 +507,12 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
logger_data.d32= nmea_fpga_frmt[i]; logger_data.d32= nmea_fpga_frmt[i];
x393_logger_data(logger_data); x393_logger_data(logger_data);
#endif #endif
D(printk("Loading imu fpga register 0x%x with 0x%x\n", X313_IMU_NMEA_FORMAT_ADDR+i+16, nmea_fpga_frmt[i] )); dev_dbg(g_dev_ptr,"Loading imu fpga register 0x%x with 0x%x\n", X313_IMU_NMEA_FORMAT_ADDR+i+16, nmea_fpga_frmt[i] );
} }
} }
if (which & WHICH_CONFIG) { if (which & WHICH_CONFIG) {
D(printk("Setting configuration= 0x%lx\n", config[0])); dev_dbg(g_dev_ptr,"Setting configuration= 0x%lx\n", config[0]);
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_CONFIGURE_ADDR; port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_CONFIGURE_ADDR;
port_csp0_addr[X313_WA_IMU_DATA] =(config[0] & 0xffffff); // MSB used for the i2c slave addr of the 10365 port_csp0_addr[X313_WA_IMU_DATA] =(config[0] & 0xffffff); // MSB used for the i2c slave addr of the 10365
...@@ -526,7 +533,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -526,7 +533,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
#endif #endif
for (i=X313_IMU_REGISTERS_OFFS; i< X313_IMU_NMEA_FORMAT_OFFS ;i++) { for (i=X313_IMU_REGISTERS_OFFS; i< X313_IMU_NMEA_FORMAT_OFFS ;i++) {
d=wbuf[i]; d=wbuf[i];
D(printk("%d: logging IMU register with 0x%lx\n", (i-X313_IMU_REGISTERS_OFFS+1),d)); dev_dbg(g_dev_ptr,"%d: logging IMU register with 0x%lx\n", (i-X313_IMU_REGISTERS_OFFS+1),d);
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_IMU_DATA] = d; port_csp0_addr[X313_WA_IMU_DATA] = d;
#else #else
...@@ -536,7 +543,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -536,7 +543,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
} }
} }
if (which & WHICH_MESSAGE) { if (which & WHICH_MESSAGE) {
D(printk("Setting odometer message %56s\n", (char *) message)); dev_dbg(g_dev_ptr,"Setting odometer message %56s\n", (char *) message);
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_MESSAGE_ADDR; port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_MESSAGE_ADDR;
#else #else
...@@ -544,7 +551,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -544,7 +551,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
x393_logger_address(logger_address); x393_logger_address(logger_address);
#endif #endif
for (i=0; i<(((sizeof(wbuf)-X313_IMU_MESSAGE_OFFS))>>2);i++) { for (i=0; i<(((sizeof(wbuf)-X313_IMU_MESSAGE_OFFS))>>2);i++) {
D(printk("%d: message 4 bytes= 0x%x\n", i+1,(int) message[i])); dev_dbg(g_dev_ptr,"%d: message 4 bytes= 0x%x\n", i+1,(int) message[i]);
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_IMU_DATA] = message[i]; port_csp0_addr[X313_WA_IMU_DATA] = message[i];
#else #else
...@@ -556,7 +563,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -556,7 +563,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
// setting IMU SPI period, turning it on // setting IMU SPI period, turning it on
if (which & WHICH_PERIOD) { if (which & WHICH_PERIOD) {
D(printk("IMU cycle period= %ld\n", period[0])); dev_dbg(g_dev_ptr,"IMU cycle period= %ld\n", period[0]);
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_PERIOD_ADDR; port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_PERIOD_ADDR;
port_csp0_addr[X313_WA_IMU_DATA] = period[0]; port_csp0_addr[X313_WA_IMU_DATA] = period[0];
...@@ -568,13 +575,13 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first ...@@ -568,13 +575,13 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
#endif #endif
} }
if (which & WHICH_EN_DMA) { if (which & WHICH_EN_DMA) {
D(printk("Enabling DMA\n")); dev_dbg(g_dev_ptr,"Enabling DMA\n");
/*! /*!
TODO: (re)start DMA1 here ! TODO: (re)start DMA1 here !
*/ */
/// for now - init everything again? /// for now - init everything again?
if (logger_is_dma_on()!=0) { if (logger_is_dma_on()!=0) {
D(printk("Stopping DMA\n")); dev_dbg(g_dev_ptr,"Stopping DMA\n");
logger_dma_stop(); logger_dma_stop();
} }
x313_dma1_init(); x313_dma1_init();
...@@ -582,7 +589,7 @@ TODO: (re)start DMA1 here ! ...@@ -582,7 +589,7 @@ TODO: (re)start DMA1 here !
} }
if (which & WHICH_EN_LOGGER) { if (which & WHICH_EN_LOGGER) {
D(printk("Enabling logger\n")); dev_dbg(g_dev_ptr,"Enabling logger\n");
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_CONFIGURE_ADDR; port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_CONFIGURE_ADDR;
port_csp0_addr[X313_WA_IMU_DATA] = IMU_CONF(RST_CONF,0); port_csp0_addr[X313_WA_IMU_DATA] = IMU_CONF(RST_CONF,0);
...@@ -603,24 +610,24 @@ static int imu_open(struct inode *inode, struct file *filp) { ...@@ -603,24 +610,24 @@ static int imu_open(struct inode *inode, struct file *filp) {
int i; int i;
// loff_t numBytesWritten; // loff_t numBytesWritten;
D(printk("imu_open: minor=%x\r\n",p) ); dev_dbg(g_dev_ptr,"imu_open: minor=%x\n",p);
D(printk("filp=%lx\r\n",(unsigned long)filp) ); dev_dbg(g_dev_ptr,"filp=%lx\n",(unsigned long)filp);
switch ( p ) { switch ( p ) {
case DEV393_MINOR(DEV393_LOGGER_CTRL): case DEV393_MINOR(DEV393_LOGGER_CTRL):
D1(printk(KERN_NOTICE "IMU_ctl_open\n")); dev_dbg(g_dev_ptr,"IMU_ctl_open\n");
inode->i_size=sizeof(wbuf); inode->i_size=sizeof(wbuf);
// nothing more here, after writing parameters should start imu (and dma), otherwise will use defaults on next open of /dev/imu // nothing more here, after writing parameters should start imu (and dma), otherwise will use defaults on next open of /dev/imu
break; break;
case DEV393_MINOR(DEV393_LOGGER) : case DEV393_MINOR(DEV393_LOGGER) :
{ {
D1(printk(KERN_NOTICE "IMU_open\n")); dev_dbg(g_dev_ptr,"IMU_open\n");
inode->i_size=sizeof(wbuf); // only in write mode inode->i_size=sizeof(wbuf); // only in write mode
/// See if initialization is needed /// See if initialization is needed
if (logger_is_dma_on()==0) { if (logger_is_dma_on()==0) {
/// copy defaults /// copy defaults
D1(printk(KERN_NOTICE "Initializing IMU\n")); dev_dbg(g_dev_ptr,"Initializing IMU\n");
for (i=0;i<sizeof(wbuf);i++) wbuf[i]=dflt_wbuf[i]; for (i=0;i<sizeof(wbuf);i++) wbuf[i]=dflt_wbuf[i];
set_logger_params(WHICH_INIT | set_logger_params(WHICH_INIT |
WHICH_RESET | WHICH_RESET |
...@@ -636,7 +643,7 @@ static int imu_open(struct inode *inode, struct file *filp) { ...@@ -636,7 +643,7 @@ static int imu_open(struct inode *inode, struct file *filp) {
WHICH_EN_LOGGER ); WHICH_EN_LOGGER );
numBytesRead=0; numBytesRead=0;
} else { } else {
D1(printk(KERN_NOTICE "Skipping IMU initialization\n")); dev_dbg(g_dev_ptr, "Skipping IMU initialization\n");
#ifdef NC353 #ifdef NC353
updateNumBytesWritten(); updateNumBytesWritten();
#endif #endif
...@@ -648,7 +655,7 @@ static int imu_open(struct inode *inode, struct file *filp) { ...@@ -648,7 +655,7 @@ static int imu_open(struct inode *inode, struct file *filp) {
#endif #endif
{ {
// alternatively - open at lower pointer? // alternatively - open at lower pointer?
D1(printk(KERN_ERR "DMA1 buffer overrun (numBytesWritten=0x%llx, numBytesRead=0x%llx, resetting numBytesRead\n", numBytesWritten, numBytesRead)); dev_err(g_dev_ptr,"DMA1 buffer overrun (numBytesWritten=0x%llx, numBytesRead=0x%llx, resetting numBytesRead\n", numBytesWritten, numBytesRead);
numBytesRead=numBytesWritten; numBytesRead=numBytesWritten;
} }
//printk("imu opened in R/W mode, (numBytesWritten=0x%x, numBytesRead=0x%x\n", numBytesWritten, numBytesRead); //printk("imu opened in R/W mode, (numBytesWritten=0x%x, numBytesRead=0x%x\n", numBytesWritten, numBytesRead);
...@@ -671,11 +678,11 @@ static int imu_release(struct inode *inode, struct file *filp) { ...@@ -671,11 +678,11 @@ static int imu_release(struct inode *inode, struct file *filp) {
switch ( p ) { switch ( p ) {
case DEV393_MINOR(DEV393_LOGGER) : case DEV393_MINOR(DEV393_LOGGER) :
case DEV393_MINOR(DEV393_LOGGER_CTRL): 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); dev_dbg(g_dev_ptr,"Closing IMU device, numBytesWritten=0x%llx, numBytesRead=0x%llx (only global pointer, does not include files opened in read mode)\n", numBytesWritten, numBytesRead);
break; break;
default: return -EINVAL; default: return -EINVAL;
} }
D(printk("imu_release: done\r\n")); dev_dbg(g_dev_ptr,"imu_release: done\n");
return 0; return 0;
} }
...@@ -684,8 +691,8 @@ static ssize_t imu_write(struct file * file, const char * buf, size_t count, lof ...@@ -684,8 +691,8 @@ static ssize_t imu_write(struct file * file, const char * buf, size_t count, lof
unsigned long p=*off; unsigned long p=*off;
unsigned long left; unsigned long left;
int which=0; int which=0;
// D(printk("imu_write: ((int *)file->private_data)[0]= %x\r\n",((int *)file->private_data)[0])); // dev_dbg(g_dev_ptr,"imu_write: ((int *)file->private_data)[0]= %x\n",((int *)file->private_data)[0]);
D(printk("imu_write: (int)file->private_data)= %x\r\n",((int)file->private_data))); dev_dbg(g_dev_ptr,"imu_write: (int)file->private_data)= %x\n",((int)file->private_data));
// switch (((int *)file->private_data)[0]) { // switch (((int *)file->private_data)[0]) {
switch ((int) file->private_data) { switch ((int) file->private_data) {
case DEV393_MINOR(DEV393_LOGGER) : case DEV393_MINOR(DEV393_LOGGER) :
...@@ -720,8 +727,8 @@ static ssize_t imu_write(struct file * file, const char * buf, size_t count, lof ...@@ -720,8 +727,8 @@ static ssize_t imu_write(struct file * file, const char * buf, size_t count, lof
} }
static loff_t imu_lseek(struct file * file, loff_t offset, int orig) { 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; int p=(int)file->private_data;
dev_dbg(g_dev_ptr," file=%x, offset=%llx (%d), orig=%x\n", (int) file, offset,(int) offset, (int) orig);
switch (p) { switch (p) {
case DEV393_MINOR(DEV393_LOGGER): case DEV393_MINOR(DEV393_LOGGER):
case DEV393_MINOR(DEV393_LOGGER_CTRL): case DEV393_MINOR(DEV393_LOGGER_CTRL):
...@@ -745,14 +752,14 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) { ...@@ -745,14 +752,14 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) {
// numBytesRead=(int) port_csp0_addr[X313_RA_IMU_COUNT]<<6; //numBytesWritten // numBytesRead=(int) port_csp0_addr[X313_RA_IMU_COUNT]<<6; //numBytesWritten
return file->f_pos; return file->f_pos;
case LSEEK_IMU_STOP: case LSEEK_IMU_STOP:
D(printk("got LSEEK_IMU_STOP\n")); dev_dbg(g_dev_ptr,"got LSEEK_IMU_STOP\n");
set_logger_params(WHICH_RESET | set_logger_params(WHICH_RESET |
WHICH_RESET_SPI); WHICH_RESET_SPI);
numBytesRead=0; numBytesRead=0;
return file->f_pos; return file->f_pos;
case LSEEK_IMU_START: case LSEEK_IMU_START:
D(printk("got LSEEK_IMU_START\n")); dev_dbg(g_dev_ptr,"got LSEEK_IMU_START\n");
set_logger_params(WHICH_RESET | set_logger_params(WHICH_RESET |
WHICH_RESET_SPI | WHICH_RESET_SPI |
WHICH_PERIOD | WHICH_PERIOD |
...@@ -764,12 +771,12 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) { ...@@ -764,12 +771,12 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) {
} }
break; break;
default: default:
printk(KERN_ERR "lseek: invalid orig=%d\n", orig); dev_err(g_dev_ptr,"lseek: invalid orig=%d\n", orig);
return -EINVAL; return -EINVAL;
} }
break; break;
default: default:
printk(KERN_ERR "lseek: invalid minor=%d\n", p); dev_err(g_dev_ptr,"lseek: invalid minor=%d\n", p);
return -EINVAL; return -EINVAL;
/* /*
#define LSEEK_IMU_STOP 1 // stop DMA1 and IMU #define LSEEK_IMU_STOP 1 // stop DMA1 and IMU
...@@ -779,13 +786,13 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) { ...@@ -779,13 +786,13 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) {
} }
/** truncate position */ /** truncate position */
if (file->f_pos < 0) { if (file->f_pos < 0) {
printk(KERN_ERR "negative position: minor=%d, file->f_pos=0x%llx\n", p, file->f_pos); dev_err(g_dev_ptr,"negative position: minor=%d, file->f_pos=0x%llx\n", p, file->f_pos);
file->f_pos = 0; file->f_pos = 0;
return (-EOVERFLOW); return (-EOVERFLOW);
} }
/** enable seeking beyond buffer - it now is absolute position in the data stream*/ /** enable seeking beyond buffer - it now is absolute position in the data stream*/
if ((p==DEV393_MINOR(DEV393_LOGGER_CTRL)) && (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); dev_err(g_dev_ptr,"beyond end: minor=%d, file->f_pos=0x%llx\n", p, file->f_pos);
file->f_pos = sizeof(wbuf); file->f_pos = sizeof(wbuf);
return (-EOVERFLOW); return (-EOVERFLOW);
} }
...@@ -821,7 +828,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of ...@@ -821,7 +828,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of
if (count==0) return 0; if (count==0) return 0;
err=copy_to_user(buf, &wbuf[*off], count); err=copy_to_user(buf, &wbuf[*off], count);
if (err) { if (err) {
printk(KERN_ERR "0. tried to copy 0x%x bytes to offset 0x%llx, result=0x%x\n", count, *off,err); dev_err(g_dev_ptr,"0. tried to copy 0x%x bytes to offset 0x%llx, result=0x%x\n", count, *off,err);
return -EFAULT; return -EFAULT;
} }
*off+=count; *off+=count;
...@@ -848,7 +855,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of ...@@ -848,7 +855,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of
if (idbg>0) { if (idbg>0) {
D(printk ("slept %d times (%d usec)\n", idbg, (int) (*sleep * idbg))); dev_dbg(g_dev_ptr,"slept %d times (%d usec)\n", idbg, (int) (*sleep * idbg));
} }
// now read what is available (and required), roll over the buffer (if needed), copy data and advance numReadBytes // now read what is available (and required), roll over the buffer (if needed), copy data and advance numReadBytes
//TODO:Flush cache !!!!!!!!!!!!!!!!!!!!!!********************************* //TODO:Flush cache !!!!!!!!!!!!!!!!!!!!!!*********************************
...@@ -872,7 +879,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of ...@@ -872,7 +879,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of
/// copy all (or first part) /// copy all (or first part)
err=copy_to_user(buf, &charDMABuf[byteIndexRead], (pe-byteIndexRead)); err=copy_to_user(buf, &charDMABuf[byteIndexRead], (pe-byteIndexRead));
if (err) { if (err) {
printk(KERN_ERR "1. tried to copy 0x%x bytes to offset 0x%llx, result=0x%x\n", count, *off,err); dev_err(g_dev_ptr,"1. tried to copy 0x%x bytes to offset 0x%llx, result=0x%x\n", count, *off,err);
return -EFAULT; return -EFAULT;
} }
...@@ -886,7 +893,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of ...@@ -886,7 +893,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of
byteIndexRead=0; byteIndexRead=0;
} }
if (err) { if (err) {
printk(KERN_ERR "2. tried to copy 0x%x bytes to offset 0x%llx, result=0x%x\n", count, *off,err); dev_err(g_dev_ptr,"2. tried to copy 0x%x bytes to offset 0x%llx, result=0x%x\n", count, *off,err);
return -EFAULT; return -EFAULT;
} }
thisNumBytesRead+=leftToRead; thisNumBytesRead+=leftToRead;
...@@ -895,19 +902,19 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of ...@@ -895,19 +902,19 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of
//Is it just for debug //Is it just for debug
stat = REG_RD(dma, regi_dma7, rw_stat); stat = REG_RD(dma, regi_dma7, rw_stat);
ch1_stat= REG_RD(bif_dma, regi_bif_dma, r_ch1_stat); ch1_stat= REG_RD(bif_dma, regi_bif_dma, r_ch1_stat);
D(printk ("count=0x%x, thisNumBytesRead=0x%llx, numBytesWritten=0x%llx, stat.buf=0x%x, stat.mode=%x, ch1.run=%x ch1.cnt=0x%x\n", (int) count, thisNumBytesRead, numBytesWritten, (int) stat.buf,(int) stat.mode, (int) ch1_stat.run, (int) ch1_stat.cnt )); dev_dbg(g_dev_ptr,"count=0x%x, thisNumBytesRead=0x%llx, numBytesWritten=0x%llx, stat.buf=0x%x, stat.mode=%x, ch1.run=%x ch1.cnt=0x%x\n", (int) count, thisNumBytesRead, numBytesWritten, (int) stat.buf,(int) stat.mode, (int) ch1_stat.run, (int) ch1_stat.cnt );
#endif #endif
//printk(" file->f_mode & FMODE_WRITE=0x%d\n",file->f_mode & FMODE_WRITE); //printk(" file->f_mode & FMODE_WRITE=0x%d\n",file->f_mode & FMODE_WRITE);
if (file->f_mode & FMODE_WRITE) numBytesRead=thisNumBytesRead; if (file->f_mode & FMODE_WRITE) numBytesRead=thisNumBytesRead;
// else *off=thisNumBytesRead; // else *off=thisNumBytesRead;
*off=thisNumBytesRead; // always update *off=thisNumBytesRead; // always update
if (count<0) { if (count<0) {
printk(KERN_ERR "Count is negative ( 0x%x)\n", count); dev_err(g_dev_ptr,"Count is negative ( 0x%x)\n", count);
} }
return count; return count;
default: default:
//printk(" Wrong minor=0x%x\n",((int *)file->private_data)[0]); //printk(" Wrong minor=0x%x\n",((int *)file->private_data)[0]);
printk(KERN_ERR " Wrong minor=0x%x\n",(int)file->private_data); dev_dbg(g_dev_ptr," Wrong minor=0x%x\n",(int)file->private_data);
return -EINVAL; return -EINVAL;
} }
} }
...@@ -937,6 +944,8 @@ static int logger_init(struct platform_device *pdev) ...@@ -937,6 +944,8 @@ static int logger_init(struct platform_device *pdev)
unsigned int irq; unsigned int irq;
int res; int res;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
g_dev_ptr = dev;
const struct of_device_id *match; const struct of_device_id *match;
const char *logger_irq_names[4] = {"mult_saxi_0", "mult_saxi_1", "mult_saxi_2", "mult_saxi_3"}; const char *logger_irq_names[4] = {"mult_saxi_0", "mult_saxi_1", "mult_saxi_2", "mult_saxi_3"};
...@@ -978,12 +987,12 @@ static int logger_init(struct platform_device *pdev) ...@@ -978,12 +987,12 @@ static int logger_init(struct platform_device *pdev)
/** Initialize FPGA DMA engine for the logger. Obviously requires bitstream to be loaded. */ /** Initialize FPGA DMA engine for the logger. Obviously requires bitstream to be loaded. */
int logger_init_fpga(int force) ///< if 0, only do if not already initialized int logger_init_fpga(int force) ///< if 0, only do if not already initialized
{ {
if (logger_fpga_configured && !force) return 0; // Already initialized
x393_status_ctrl_t logger_status_ctrl= {.d32 = 0}; x393_status_ctrl_t logger_status_ctrl= {.d32 = 0};
x393_status_ctrl_t mult_saxi_status_ctrl= {.d32 = 0}; x393_status_ctrl_t mult_saxi_status_ctrl= {.d32 = 0};
x393_mult_saxi_al_t mult_saxi_a= {.d32=0}; x393_mult_saxi_al_t mult_saxi_a= {.d32=0};
x393_mult_saxi_al_t mult_saxi_l= {.d32=0}; x393_mult_saxi_al_t mult_saxi_l= {.d32=0};
x393_mult_saxi_irqlen_t mult_saxi_irqlen= {.d32=0}; x393_mult_saxi_irqlen_t mult_saxi_irqlen= {.d32=0};
if (logger_fpga_configured && !force) return 0; // Already initialized
mult_saxi_a.addr32 = logger_phys >> 2; // in DWORDs mult_saxi_a.addr32 = logger_phys >> 2; // in DWORDs
x393_mult_saxi_buf_address(mult_saxi_a, MULT_SAXI_CHN); x393_mult_saxi_buf_address(mult_saxi_a, MULT_SAXI_CHN);
mult_saxi_l.addr32 = logger_size >> 2; mult_saxi_l.addr32 = logger_size >> 2;
...@@ -1079,7 +1088,7 @@ int logger_is_dma_on(void) { ...@@ -1079,7 +1088,7 @@ int logger_is_dma_on(void) {
*/ */
int logger_dma_stop(void) { int logger_dma_stop(void) {
dma_is_on=0; dma_is_on=0;
MD12(printk("==========logger_dma_stop\n")); dev_dbg(g_dev_ptr,"==========logger_dma_stop\n");
#ifdef NC353 #ifdef NC353
port_csp0_addr[X313_WA_DMACR] = 0x20; // disable DMA1, dot't modify DMA0 port_csp0_addr[X313_WA_DMACR] = 0x20; // disable DMA1, dot't modify DMA0
EXT_DMA_1_STOP ; /// for testing - no reset DMA after acquisition EXT_DMA_1_STOP ; /// for testing - no reset DMA after acquisition
...@@ -1102,7 +1111,7 @@ void logger_dma_start(void) { ...@@ -1102,7 +1111,7 @@ void logger_dma_start(void) {
#ifdef NC353 #ifdef NC353
unsigned long dai; unsigned long dai;
int i = 0; int i = 0;
MD12(printk("----------logger_dma_start\n")); dev_dbg(g_dev_ptr,"----------logger_dma_start\n");
DMA_RESET(regi_dma7); DMA_RESET(regi_dma7);
/// need to restore pointers after previous stop DMA - maybe later move there? /// need to restore pointers after previous stop DMA - maybe later move there?
for(dai = 0; dai < CCAM_DMA1_SIZE; dai += DMA_CHUNK) { /// DMA_CHUNK==0x4000 for(dai = 0; dai < CCAM_DMA1_SIZE; dai += DMA_CHUNK) { /// DMA_CHUNK==0x4000
...@@ -1137,8 +1146,8 @@ void logger_dma_start(void) { ...@@ -1137,8 +1146,8 @@ void logger_dma_start(void) {
///dma0 is using external dma 3 (input) with dma channel 9 ///dma0 is using external dma 3 (input) with dma channel 9
///dma1 (this) is using external dma 1 (input) with dma channel 7 (shared with async. serial 0, so do not use DMA there!) ///dma1 (this) is using external dma 1 (input) with dma channel 7 (shared with async. serial 0, so do not use DMA there!)
unsigned long x313_dma1_init(void) { unsigned long x313_dma1_init(void) {
dma_is_on=0;
int rslt; int rslt;
dma_is_on=0;
#ifdef NC353 #ifdef NC353
reg_dma_rw_cfg cfg = {.en = regk_dma_yes}; // if disabled - will be busy and hang on attemt of DMA_WR_CMD reg_dma_rw_cfg cfg = {.en = regk_dma_yes}; // if disabled - will be busy and hang on attemt of DMA_WR_CMD
reg_bif_dma_rw_ch1_ctrl exdma_ctrl = { reg_bif_dma_rw_ch1_ctrl exdma_ctrl = {
...@@ -1169,22 +1178,22 @@ unsigned long x313_dma1_init(void) { ...@@ -1169,22 +1178,22 @@ unsigned long x313_dma1_init(void) {
}; };
// just in case - free DMA channel (we are only using it here) // just in case - free DMA channel (we are only using it here)
crisv32_free_dma(EXTDMA1_RX_DMA_NBR); crisv32_free_dma(EXTDMA1_RX_DMA_NBR);
printk("Initializing DMA registers for EXTDMA1\n"); dev_dbg(g_dev_ptr,"Initializing DMA registers for EXTDMA1\n");
MD7(printk("x313_dma1_init(void)")); dev_dbg(g_dev_ptr,"x313_dma1_init(void)");
D0(printk ("before crisv32_request_dma\n"); udelay (500000)); dev_dbg(g_dev_ptr,"before crisv32_request_dma\n"); udelay (500000);
rslt = crisv32_request_dma(EXTDMA1_RX_DMA_NBR, rslt = crisv32_request_dma(EXTDMA1_RX_DMA_NBR,
"imu data in from fpga", "imu data in from fpga",
DMA_VERBOSE_ON_ERROR, DMA_VERBOSE_ON_ERROR,
0, 0,
dma_ext1); dma_ext1);
D0(printk ("after crisv32_request_dma - result=%d\n",rslt); udelay(500000)); dev_dbg(g_dev_ptr,"after crisv32_request_dma - result=%d\n",rslt); udelay(500000);
if(rslt) { if(rslt) {
printk("failed\n"); dev_dbg(g_dev_ptr,"failed\n");
crisv32_free_dma(EXTDMA1_RX_DMA_NBR); crisv32_free_dma(EXTDMA1_RX_DMA_NBR);
printk(KERN_CRIT "Can't allocate external dma port for compressed data in from fpga"); dev_dbg(g_dev_ptr,"Can't allocate external dma port for compressed data in from fpga");
} else { /// dma channel 7 allocated for ext dma 1 } else { /// dma channel 7 allocated for ext dma 1
/// setup source of hsh2, hsh3 /// setup source of hsh2, hsh3
REG_WR(bif_dma, regi_bif_dma, rw_pin2_cfg, exdma_pin2); /// just in case - turn hsh2 off REG_WR(bif_dma, regi_bif_dma, rw_pin2_cfg, exdma_pin2); /// just in case - turn hsh2 off
...@@ -1224,7 +1233,7 @@ int x313_setDMA1Buffer(void) { ...@@ -1224,7 +1233,7 @@ int x313_setDMA1Buffer(void) {
// TODO: make new global parameter? // TODO: make new global parameter?
// set_globalParam (G_CIRCBUFSIZE,CCAM__DMA_SIZE<<2); /// make it adjustable? TODO: initialize with others? // set_globalParam (G_CIRCBUFSIZE,CCAM__DMA_SIZE<<2); /// make it adjustable? TODO: initialize with others?
//*********************** TEMPORARY ******************************** //*********************** TEMPORARY ********************************
MD8(printk ("filling DMA1 buffer with natural numbers - just test \n")); dev_dbg(g_dev_ptr,"filling DMA1 buffer with natural numbers - just test \n");
for(dai = 0; dai < CCAM_DMA1_SIZE; dai++) logger_buffer[dai] = dai; for(dai = 0; dai < CCAM_DMA1_SIZE; dai++) logger_buffer[dai] = dai;
return 0; return 0;
} }
......
...@@ -44,7 +44,6 @@ ...@@ -44,7 +44,6 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_fdt.h> #include <linux/of_fdt.h>
#include <linux/of_net.h> #include <linux/of_net.h>
#include <linux/platform_device.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/list.h> #include <linux/list.h>
......
...@@ -1652,7 +1652,7 @@ struct p_names_t { ...@@ -1652,7 +1652,7 @@ struct p_names_t {
// make this structure common for sensors, add fields as needed // make this structure common for sensors, add fields as needed
struct sensor_t { struct __attribute__((__packed__)) sensor_t {
// sensor constants // sensor constants
unsigned long imageWidth; ///< nominal image width for final images unsigned long imageWidth; ///< nominal image width for final images
unsigned long imageHeight; ///< nominal image height for final images unsigned long imageHeight; ///< nominal image height for final images
...@@ -1789,7 +1789,7 @@ struct i2c_timing_t { ...@@ -1789,7 +1789,7 @@ struct i2c_timing_t {
#define GAMMA_SCALE_SHIFT 10 // when scaling - shift right by GAMMA_SCALE_SHIFT (treat scale as 6.10) #define GAMMA_SCALE_SHIFT 10 // when scaling - shift right by GAMMA_SCALE_SHIFT (treat scale as 6.10)
#define GAMMA_SCLALE_1 ( 1 << GAMMA_SCALE_SHIFT ) // gamma scale 1.0 - 0x400 #define GAMMA_SCLALE_1 ( 1 << GAMMA_SCALE_SHIFT ) // gamma scale 1.0 - 0x400
struct gamma_stuct_t { struct __attribute__((__packed__)) gamma_stuct_t {
union { union {
unsigned long hash32; /// fully identifies current table unsigned long hash32; /// fully identifies current table
struct { struct {
......
...@@ -43,7 +43,7 @@ or Rational or else. The generated Exif header copies that variable fileds on to ...@@ -43,7 +43,7 @@ or Rational or else. The generated Exif header copies that variable fileds on to
The compressed data buffer is stored in "meta pages", one per frame The compressed data buffer is stored in "meta pages", one per frame
*/ */
struct exif_dir_table_t { struct __attribute__((__packed__)) exif_dir_table_t {
union { union {
unsigned long ltag;// tag group and tag combined unsigned long ltag;// tag group and tag combined
struct { struct {
...@@ -112,13 +112,13 @@ struct exif_dir_table_t { ...@@ -112,13 +112,13 @@ struct exif_dir_table_t {
// array(0x9003,2,"2001:06:21 12:00:00","len"=> 20), //date/time original time created, always use 20 bytes (19 ."\0") // array(0x9003,2,"2001:06:21 12:00:00","len"=> 20), //date/time original time created, always use 20 bytes (19 ."\0")
// array(0x9291,2,"0 ") //original time sub-second length=10 9 ."\0" // array(0x9291,2,"0 ") //original time sub-second length=10 9 ."\0"
///move back to interframe_params_t? ///move back to interframe_params_t?
struct frame_exif_t { struct __attribute__((__packed__)) frame_exif_t {
unsigned short meta_index; //! index of the linked meta page unsigned short meta_index; //! index of the linked meta page
unsigned short signffff; //! should be 0xffff - it will be a signature that JPEG data was not overwritten unsigned short signffff; //! should be 0xffff - it will be a signature that JPEG data was not overwritten
unsigned long frame_length; //! frame length unsigned long frame_length; //! frame length
}; };
struct meta_GPSInfo_t { struct __attribute__((__packed__)) meta_GPSInfo_t {
unsigned char GPSLatitudeRef; //"N"/"S" unsigned char GPSLatitudeRef; //"N"/"S"
unsigned long GPSLatitude_deg_nom; unsigned long GPSLatitude_deg_nom;
unsigned long GPSLatitude_deg_denom; unsigned long GPSLatitude_deg_denom;
...@@ -142,7 +142,7 @@ struct meta_GPSInfo_t { ...@@ -142,7 +142,7 @@ struct meta_GPSInfo_t {
unsigned char GPSMeasureMode; unsigned char GPSMeasureMode;
}; };
//hack - use //hack - use
struct meta_CompassInfo_t { struct __attribute__((__packed__)) meta_CompassInfo_t {
// unsigned char GPSImgDirectionRef; //"M"/"T" //0x10 // unsigned char GPSImgDirectionRef; //"M"/"T" //0x10
unsigned long CompassDirection_nom; //0x11 unsigned long CompassDirection_nom; //0x11
unsigned long CompassDirection_denom; unsigned long CompassDirection_denom;
......
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