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

merged with framepars

parents 923da644 809ae1e8
......@@ -299,5 +299,15 @@
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 @@
compatible = "elphel,klogger-393-1.00";
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 @@
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 @@
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 @@
#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/uaccess.h>
#include <uapi/elphel/x393_devices.h>
......@@ -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.
#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_CHANNELS 2 // number of i2c channels
......@@ -149,10 +156,12 @@
// 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
//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 int xi2c_initialized=0; // configure GPIO puins access at first command;
#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
......@@ -170,6 +179,7 @@ int i2c_restart(int n);
int i2c_stop(int n);
int i2c_outbyte(int n, unsigned char d);
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.
// 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;}
int i2s_running(void) {return i2c_hardware_on;}
#endif
#define i2c_ldelay(usecs) udelay(usecs)
/*
void i2c_ldelay(int dly){
while (dly--) {
__asm__ __volatile__("");
}
}
*/
// Low level i2c pin functions
......@@ -238,10 +251,31 @@ X313_I2C_CMD
#ifdef NC353
#define X313_PIOR(x) ((port_csp0_addr[X313__RA__IOPINS] >> X313_PIOR__##x ) & 1)
#else
#define X313_PIOR(x) ((x393_gpio_status().d32 >> X313_PIOR__##x ) & 1)
#define X313_PIOR(x) ((read_gpio() >> X313_PIOR__##x ) & 1)
#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 {
......@@ -264,6 +298,7 @@ int i2c_getbit(int n) {
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);
else return X313_PIOR(SDA1);
#endif
}
......@@ -341,9 +376,10 @@ void i2c_sda_strong (int n, int d) { // will also force sda enable
int i2c_start(int n) {
int i;
unsigned long flags;
test_init_GPIO();
local_irq_save(flags);
//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
// set SCL=1, release SDA, wait SCL high time and verify.
i2c_scl_1(n);
......@@ -375,7 +411,7 @@ int i2c_stop(int n) {
unsigned long flags;
local_irq_save(flags);
//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
i2c_sda_weak (n, 0);
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) {
unsigned long flags;
local_irq_save(flags);
//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
i2c_sda_weak (n, 1);
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) {
unsigned long flags;
local_irq_save(flags);
//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_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;
......@@ -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
i= (1-i2c_getbit(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);
return i;
}
......@@ -453,7 +489,7 @@ unsigned char i2c_inbyte(int n, int more) { // assumed SCL=0, SDA=X
unsigned long flags;
local_irq_save(flags);
//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
i2c_sda_weak (n, 1);
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
i2c_scl_0(n);
//TODO: (test next is OK - 2012-01-15)
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);
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
*#--------------------------------------------------------------------------*/
int i2c_writeData(int n, unsigned char theSlave, unsigned char *theData, int size, int stop) {
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
if ((error=i2c_start(n))) return error;
......@@ -529,7 +565,7 @@ int i2c_readData(int n, unsigned char theSlave, unsigned char *theData, int size
if ((error=i2c_restart(n))) return error;
}
/* 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)) {
i2c_stop(n);
......@@ -548,9 +584,9 @@ int i2c_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) {
unsigned char data[3];
int error=0;
D(printk("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]));
// D(printk("i2c_ioctl: ((int )file->private_data)= %x\n\r",(int)file->private_data));
dev_dbg(g_dev_ptr, "i2c_ioctl cmd= %x, arg= %x\n\r",cmd,(int) arg);
dev_dbg(g_dev_ptr, "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)= %x\n\r",(int)file->private_data);
if(_IOC_TYPE(cmd) != CMOSCAM_IOCTYPE) {
return -EINVAL;
}
......@@ -562,49 +598,49 @@ int i2c_ioctl(struct inode *inode, struct file *file,
return i2c_delays (arg);
case I2C_WRITEREG:
/* 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_ARGSLAVE(arg),
(int) I2C_ARGREG(arg),
(int) I2C_ARGVALUE(arg)));
(int) I2C_ARGVALUE(arg));
data[0]=I2C_ARGREG(arg);
data[1]=I2C_ARGVALUE(arg);
return -i2c_writeData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) & 0xfe, &data[0], 2, 1); // send stop
case I2C_READREG:
/* 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_ARGSLAVE(arg),
(int) I2C_ARGREG(arg)));
(int) I2C_ARGREG(arg));
data[0]=I2C_ARGREG(arg);
error=i2c_writeData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) & 0xfe, &data[0], 1, 0); // no stop
if (error) return -error;
error=i2c_readData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) | 0x01, &data[1], 1, 0); // will start with restart, not start
if (error) return -error;
D(printk("returned %d\n", data[1]));
dev_dbg(g_dev_ptr, "returned %d\n", data[1]);
return data[1];
case I2C_16_WRITEREG:
/* 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_ARGREG(arg),
(int) I2C_16_ARGVALUE(arg)));
(int) I2C_16_ARGVALUE(arg));
data[0]=I2C_16_ARGREG(arg);
data[1]=I2C_16_ARGVALUE_H(arg);
data[2]=I2C_16_ARGVALUE_L(arg);
return -i2c_writeData(0, I2C_16_ARGSLAVE(arg) & 0xfe, &data[0], 3, 1); // send stop
case I2C_16_READREG:
/* 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_ARGREG(arg)));
(int) 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
if (error) return -error;
error=i2c_readData(0, I2C_16_ARGSLAVE(arg) | 0x01, &data[1], 2, 0);
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];
default:
return -EINVAL;
......@@ -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 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 int __init xi2c_init(void);
static int xi2c_init (struct platform_device *pdev);
static struct file_operations xi2c_fops = {
owner: THIS_MODULE,
......@@ -678,9 +714,9 @@ int xi2c_open(struct inode *inode, struct file *filp) {
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;
D(printk("xi2c_open, minor=%d\n",p));
dev_dbg(g_dev_ptr, "xi2c_open, minor=%d\n",p);
inode->i_size=sizes[p];
if (bus>=0) inuse[bus] =1;
......@@ -736,7 +772,7 @@ static int xi2c_release(struct inode *inode, struct file *filp){
bus=-1;
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;
else if (p==DEV393_MINOR(DEV393_I2C_CTRL)) for (bus=0; bus < X3X3_I2C_CHANNELS; bus++) inuse[bus]=0;
// thisminor =0;
......@@ -802,12 +838,12 @@ static loff_t xi2c_lseek(struct file * file, loff_t offset, int orig) {
//!++++++++++++++++++++++++++++++++++++ read() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
int hardware_i2c_running;
unsigned long flags;
// int hardware_i2c_running;
// unsigned long flags;
unsigned long p;
int error;
p = *off;
char * bbitdelays= (char*) bitdelays;
p = *off;
int bus=0;
unsigned char * i2cbuf=&i2cbuf_all[0]; // initialize to keep compiler happy
unsigned char * userbuf=&i2cbuf[1];
......@@ -852,7 +888,7 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
slave_adr=(p >> 8) & 0xfe;
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
switch ((int)file->private_data) {
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) {
}
if ((en_bits & en_mask) ^ en_mask) {
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;
}
......@@ -965,18 +1001,17 @@ ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
default:
*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;
}
//!++++++++++++++++++++++++++++++++++++ write() ++++++++++++++++++++++++++++++++++++++++++++++++++++++
static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, loff_t *off) {
int hardware_i2c_running;
unsigned long flags;
// int hardware_i2c_running;
// unsigned long flags;
unsigned long p;
int error;
p = *off;
int bus=0;
char * bbitdelays= (char*) bitdelays;
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
int slave_adr;
int en_mask=0;
int en_bits=0;
p = *off;
// switch (((int *)file->private_data)[0]) {
switch ((int)file->private_data) {
......@@ -1013,7 +1049,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
slave_adr=(p >> 8) & 0xfe;
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
switch ((int)file->private_data) {
......@@ -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) {
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;
}
......@@ -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):
if (bus==0) {
error = -EINVAL;
#ifdef NC353
local_irq_save(flags); /// IRQ Off
hardware_i2c_running=i2s_running();
......@@ -1092,6 +1129,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
i2cbuf[0]=p & 0xff;
if (bus==0) {
error = -EINVAL;
#ifdef NC353
local_irq_save(flags); /// IRQ Off
hardware_i2c_running=i2s_running();
......@@ -1111,6 +1149,7 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
i2cbuf[0]=(p>>1) & 0xff;
if (bus==0) {
error = -EINVAL;
#ifdef NC353
local_irq_save(flags); /// IRQ Off
hardware_i2c_running=i2s_running();
......@@ -1140,13 +1179,192 @@ static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, lo
default:
*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;
}
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;
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);
if(res < 0) {
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) {
printk(X3X3_I2C_DRIVER_NAME" - %d, %d channels\n",DEV393_MAJOR(DEV393_I2C_CTRL),X3X3_I2C_CHANNELS);
// thisminor =0;
elphel393_xi2c_init_of(pdev);
bitdelays[0].scl_high=2; //! SCL high:
bitdelays[0].scl_low=2; //! SCL low:
bitdelays[0].slave2master=1; //! slave -> master
......@@ -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_scl=0x07; //! filter SCL read data by testing multiple times - currently just zero/non zero
//! bus 1 - increased by 1 measured for EEPROM
bitdelays[1].scl_high=3; //! SCL high:
bitdelays[1].scl_low=4; //! SCL low: with 2 -
bitdelays[1].slave2master=2; //! slave -> master
bitdelays[1].master2slave=2; //! master -> slave
bitdelays[1].filter_sda=0x07; //! 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].scl_high=2; //! SCL high: (was 3)
bitdelays[1].scl_low=2; //! SCL low: with 2 -
bitdelays[1].slave2master=1; //! slave -> master
bitdelays[1].master2slave=1; //! master -> slave
bitdelays[1].filter_sda=0x0; //! filter SDA 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++) {
inuse[i]=0;
......@@ -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_8 3 // bit 3 - enable i2c 8-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;
}
/* 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_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
MODULE_DESCRIPTION(X3X3_I2C_DRIVER_NAME);
......@@ -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)
{
int i;
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);
// Should never get here
......@@ -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)
{
int i;
int psch = get_channel_sub_from_name(attr);
int port = (psch>>4) &3;
int sub_chn = psch &3;
......@@ -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)
{
size_t len;
// size_t len;
char name[80];
int port = get_channel_from_name(attr);
int i, code, rslt;
if (sscanf(buf, "%79s", name, &len)){
int rslt;
if (sscanf(buf, "%79s", name)){
if ((rslt = set_detected_mux_code( port, get_code_by_name(name, DETECT_MUX)))<0)
return rslt;
......@@ -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)
{
size_t len;
// size_t len;
char name[80];
int psch = get_channel_sub_from_name(attr);
int port = (psch>>4) &3;
int sub_chn = psch &3;
int i, rslt;
if (sscanf(buf, "%79s", name, &len)){
int rslt;
if (sscanf(buf, "%79s", name)){
if ((rslt = set_detected_sensor_code(port, sub_chn, get_code_by_name(name, DETECT_SENSOR)))<0)
return rslt;
}
......
......@@ -501,7 +501,7 @@ loff_t exif_lseek (struct file * file, loff_t offset, int orig) {
int p=(int)file->private_data;
int thissize=minor_file_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);
// int sensor_port;
switch (orig) {
......@@ -548,10 +548,12 @@ loff_t exif_lseek (struct file * file, loff_t offset, int orig) {
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);
fp= dir_find_tag (offset);
if (fp < 0) return -EOVERFLOW; // tag is not in the directory
file->f_pos=fp;
break;
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);
break;
case DEV393_MINOR(DEV393_EXIF_TIME):
switch (offset) {
......@@ -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()?
unsigned long flags;
int disabled_err=0;
dev_dbg(g_devfp_ptr,"minor=0x%x\n", p);
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;
}
switch (p) {
......
......@@ -57,21 +57,21 @@
#include <uapi/elphel/x393_devices.h>
#if 0
#if 1
#define D(x) x
#define D0(x) x
#define MD7(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 D0(x) x
//#define MD7(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
#else
#define D(x)
#define D0(x)
#define MD7(x)
#define MD8(x)
#define MD12(x)
//#define D0(x)
//#define MD7(x)
//#define MD8(x)
//#define MD12(x)
#endif
#define D1(x) x
//#define D1(x) x
#define IS_103695_REV_A 1
......@@ -215,6 +215,11 @@
#define LSEEK_IMU_NEW 1 ///< start from the new data, discard buffer
#define LSEEK_IMU_STOP 2 ///< stop DMA1 and IMU
#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[]=
{ DFLT_PERIOD & 0xff, ( DFLT_PERIOD >> 8 ) & 0xff, ( DFLT_PERIOD >> 16) & 0xff, ( DFLT_PERIOD >> 24 ) & 0xff,
// {0,0,0,0, // period - off
......@@ -353,16 +358,17 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
x393_logger_data_t logger_data;
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]); });
if (which & WHICH_RESET) {
if (logger_is_dma_on()!=0) {
D(printk("Stopping DMA\n"));
dev_dbg(g_dev_ptr,"Stopping DMA\n");
logger_dma_stop();
}
D(printk("Resetting logger\n"));
dev_dbg(g_dev_ptr,"Resetting logger\n");
#ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_CONFIGURE_ADDR;
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
#endif
}
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
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;
#else
dev_dbg(g_dev_ptr,"Enabling I/O pins for IMU\n");
gpio_set_pins.d32 = 0;
gpio_set_pins.chn_c = 3; // enable
x393_gpio_set_pins(gpio_set_pins);
......@@ -385,23 +394,21 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
#endif
///TODO: add enabling via i2c (bus=1&raw=0x2300&data=0xfe)
//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
enable_IMU=(((config[0]>>23) & 1)?0xfd:0xff); // bit[0] - reset IMU
#else
enable_IMU=0xfe; // maybe we need to reset it here? bit [1]
#endif
i2c_writeData(1, // int n - bus (0 - to the sensor)
i2c_sa, // unsigned char theSlave,
&enable_IMU, //unsigned char *theData,
1, // int size,
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));
i2c_writeData(i2cbus, // int n - bus (0 - to the sensor)
i2c_sa, // unsigned char theSlave,
&enable_IMU, //unsigned char *theData,
1, // int size,
1); // int stop (send stop in the end)
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) {
D(printk("stopped IMU logger (set period=0)\n"));
dev_dbg(g_dev_ptr,"stopped IMU logger (set period=0)\n");
#ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_PERIOD_ADDR;
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
}
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
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_DIVISOR_ADDR;
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
#endif
}
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
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_RS232DIV_ADDR;
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
}
for (n=0;n<4;n++) {
nmea_format[32*n+27]=0; // just in case
D(printk("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,"Setting NMEA sentence format for $GP%s\n", &nmea_format[32*n]);
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;
for (i=2;i>=0;i--) {
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--) {
f<<=1;
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);
f=0;
nmea_fpga_frmt[n*4]=0;
......@@ -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+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[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]));
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]));
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]));
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]));
nmea_sel[10],nmea_sel[11],nmea_sel[12],nmea_sel[13],nmea_sel[14]);
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]);
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]);
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]);
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
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_NMEA_FORMAT_ADDR;
#else
......@@ -491,7 +498,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
logger_data.d32= nmea_sel[i];
x393_logger_data(logger_data);
#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++) {
#ifdef NC353
......@@ -500,12 +507,12 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
logger_data.d32= nmea_fpga_frmt[i];
x393_logger_data(logger_data);
#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) {
D(printk("Setting configuration= 0x%lx\n", config[0]));
dev_dbg(g_dev_ptr,"Setting configuration= 0x%lx\n", config[0]);
#ifdef NC353
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
......@@ -526,7 +533,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
#endif
for (i=X313_IMU_REGISTERS_OFFS; i< X313_IMU_NMEA_FORMAT_OFFS ;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
port_csp0_addr[X313_WA_IMU_DATA] = d;
#else
......@@ -536,7 +543,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
}
}
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
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_MESSAGE_ADDR;
#else
......@@ -544,7 +551,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
x393_logger_address(logger_address);
#endif
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
port_csp0_addr[X313_WA_IMU_DATA] = message[i];
#else
......@@ -556,7 +563,7 @@ static void set_logger_params(int which){ // 1 - program IOPINS, 2 - reset first
// setting IMU SPI period, turning it on
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
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_PERIOD_ADDR;
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
#endif
}
if (which & WHICH_EN_DMA) {
D(printk("Enabling DMA\n"));
dev_dbg(g_dev_ptr,"Enabling DMA\n");
/*!
TODO: (re)start DMA1 here !
*/
/// for now - init everything again?
if (logger_is_dma_on()!=0) {
D(printk("Stopping DMA\n"));
dev_dbg(g_dev_ptr,"Stopping DMA\n");
logger_dma_stop();
}
x313_dma1_init();
......@@ -582,7 +589,7 @@ TODO: (re)start DMA1 here !
}
if (which & WHICH_EN_LOGGER) {
D(printk("Enabling logger\n"));
dev_dbg(g_dev_ptr,"Enabling logger\n");
#ifdef NC353
port_csp0_addr[X313_WA_IMU_CTRL] = X313_IMU_CONFIGURE_ADDR;
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) {
int i;
// loff_t numBytesWritten;
D(printk("imu_open: minor=%x\r\n",p) );
D(printk("filp=%lx\r\n",(unsigned long)filp) );
dev_dbg(g_dev_ptr,"imu_open: minor=%x\n",p);
dev_dbg(g_dev_ptr,"filp=%lx\n",(unsigned long)filp);
switch ( p ) {
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);
// nothing more here, after writing parameters should start imu (and dma), otherwise will use defaults on next open of /dev/imu
break;
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
/// See if initialization is needed
if (logger_is_dma_on()==0) {
/// 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];
set_logger_params(WHICH_INIT |
WHICH_RESET |
......@@ -636,7 +643,7 @@ static int imu_open(struct inode *inode, struct file *filp) {
WHICH_EN_LOGGER );
numBytesRead=0;
} else {
D1(printk(KERN_NOTICE "Skipping IMU initialization\n"));
dev_dbg(g_dev_ptr, "Skipping IMU initialization\n");
#ifdef NC353
updateNumBytesWritten();
#endif
......@@ -648,7 +655,7 @@ static int imu_open(struct inode *inode, struct file *filp) {
#endif
{
// 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;
}
//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) {
switch ( p ) {
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);
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;
default: return -EINVAL;
}
D(printk("imu_release: done\r\n"));
dev_dbg(g_dev_ptr,"imu_release: done\n");
return 0;
}
......@@ -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 left;
int which=0;
// D(printk("imu_write: ((int *)file->private_data)[0]= %x\r\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)[0]= %x\n",((int *)file->private_data)[0]);
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) {
case DEV393_MINOR(DEV393_LOGGER) :
......@@ -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) {
D(printk (" file=%x, offset=%llx (%d), orig=%x\r\n", (int) file, offset,(int) offset, (int) orig));
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) {
case DEV393_MINOR(DEV393_LOGGER):
case DEV393_MINOR(DEV393_LOGGER_CTRL):
......@@ -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
return file->f_pos;
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 |
WHICH_RESET_SPI);
numBytesRead=0;
return file->f_pos;
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 |
WHICH_RESET_SPI |
WHICH_PERIOD |
......@@ -764,12 +771,12 @@ static loff_t imu_lseek(struct file * file, loff_t offset, int orig) {
}
break;
default:
printk(KERN_ERR "lseek: invalid orig=%d\n", orig);
dev_err(g_dev_ptr,"lseek: invalid orig=%d\n", orig);
return -EINVAL;
}
break;
default:
printk(KERN_ERR "lseek: invalid minor=%d\n", p);
dev_err(g_dev_ptr,"lseek: invalid minor=%d\n", p);
return -EINVAL;
/*
#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) {
}
/** truncate position */
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;
return (-EOVERFLOW);
}
/** 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))) {
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);
return (-EOVERFLOW);
}
......@@ -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;
err=copy_to_user(buf, &wbuf[*off], count);
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;
}
*off+=count;
......@@ -848,7 +855,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of
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
//TODO:Flush cache !!!!!!!!!!!!!!!!!!!!!!*********************************
......@@ -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)
err=copy_to_user(buf, &charDMABuf[byteIndexRead], (pe-byteIndexRead));
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;
}
......@@ -886,7 +893,7 @@ static ssize_t imu_read(struct file * file, char * buf, size_t count, loff_t *of
byteIndexRead=0;
}
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;
}
thisNumBytesRead+=leftToRead;
......@@ -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
stat = REG_RD(dma, regi_dma7, rw_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
//printk(" file->f_mode & FMODE_WRITE=0x%d\n",file->f_mode & FMODE_WRITE);
if (file->f_mode & FMODE_WRITE) numBytesRead=thisNumBytesRead;
// else *off=thisNumBytesRead;
*off=thisNumBytesRead; // always update
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;
default:
//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;
}
}
......@@ -937,6 +944,8 @@ static int logger_init(struct platform_device *pdev)
unsigned int irq;
int res;
struct device *dev = &pdev->dev;
g_dev_ptr = dev;
const struct of_device_id *match;
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)
/** 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
{
if (logger_fpga_configured && !force) return 0; // Already initialized
x393_status_ctrl_t logger_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_l= {.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
x393_mult_saxi_buf_address(mult_saxi_a, MULT_SAXI_CHN);
mult_saxi_l.addr32 = logger_size >> 2;
......@@ -1079,7 +1088,7 @@ int logger_is_dma_on(void) {
*/
int logger_dma_stop(void) {
dma_is_on=0;
MD12(printk("==========logger_dma_stop\n"));
dev_dbg(g_dev_ptr,"==========logger_dma_stop\n");
#ifdef NC353
port_csp0_addr[X313_WA_DMACR] = 0x20; // disable DMA1, dot't modify DMA0
EXT_DMA_1_STOP ; /// for testing - no reset DMA after acquisition
......@@ -1102,7 +1111,7 @@ void logger_dma_start(void) {
#ifdef NC353
unsigned long dai;
int i = 0;
MD12(printk("----------logger_dma_start\n"));
dev_dbg(g_dev_ptr,"----------logger_dma_start\n");
DMA_RESET(regi_dma7);
/// 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
......@@ -1137,8 +1146,8 @@ void logger_dma_start(void) {
///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!)
unsigned long x313_dma1_init(void) {
dma_is_on=0;
int rslt;
dma_is_on=0;
#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_bif_dma_rw_ch1_ctrl exdma_ctrl = {
......@@ -1169,22 +1178,22 @@ unsigned long x313_dma1_init(void) {
};
// just in case - free DMA channel (we are only using it here)
crisv32_free_dma(EXTDMA1_RX_DMA_NBR);
printk("Initializing DMA registers for EXTDMA1\n");
MD7(printk("x313_dma1_init(void)"));
dev_dbg(g_dev_ptr,"Initializing DMA registers for EXTDMA1\n");
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,
"imu data in from fpga",
DMA_VERBOSE_ON_ERROR,
0,
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) {
printk("failed\n");
dev_dbg(g_dev_ptr,"failed\n");
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
/// setup source of hsh2, hsh3
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) {
// TODO: make new global parameter?
// set_globalParam (G_CIRCBUFSIZE,CCAM__DMA_SIZE<<2); /// make it adjustable? TODO: initialize with others?
//*********************** 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;
return 0;
}
......
......@@ -44,7 +44,6 @@
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <linux/of_net.h>
#include <linux/platform_device.h>
#include <linux/sysfs.h>
#include <linux/list.h>
......
......@@ -1652,7 +1652,7 @@ struct p_names_t {
// make this structure common for sensors, add fields as needed
struct sensor_t {
struct __attribute__((__packed__)) sensor_t {
// sensor constants
unsigned long imageWidth; ///< nominal image width for final images
unsigned long imageHeight; ///< nominal image height for final images
......@@ -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_SCLALE_1 ( 1 << GAMMA_SCALE_SHIFT ) // gamma scale 1.0 - 0x400
struct gamma_stuct_t {
struct __attribute__((__packed__)) gamma_stuct_t {
union {
unsigned long hash32; /// fully identifies current table
struct {
......
......@@ -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
*/
struct exif_dir_table_t {
struct __attribute__((__packed__)) exif_dir_table_t {
union {
unsigned long ltag;// tag group and tag combined
struct {
......@@ -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(0x9291,2,"0 ") //original time sub-second length=10 9 ."\0"
///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 signffff; //! should be 0xffff - it will be a signature that JPEG data was not overwritten
unsigned long frame_length; //! frame length
};
struct meta_GPSInfo_t {
struct __attribute__((__packed__)) meta_GPSInfo_t {
unsigned char GPSLatitudeRef; //"N"/"S"
unsigned long GPSLatitude_deg_nom;
unsigned long GPSLatitude_deg_denom;
......@@ -142,7 +142,7 @@ struct meta_GPSInfo_t {
unsigned char GPSMeasureMode;
};
//hack - use
struct meta_CompassInfo_t {
struct __attribute__((__packed__)) meta_CompassInfo_t {
// unsigned char GPSImgDirectionRef; //"M"/"T" //0x10
unsigned long CompassDirection_nom; //0x11
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