Commit 50663cc1 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Adding sensor ports i2c driver

parent 3027f36c
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -6,6 +6,7 @@ obj-$(CONFIG_ELPHEL393) += elphel393-pwr.o
obj-$(CONFIG_ELPHEL393)           += elphel393-mem.o  
obj-$(CONFIG_ELPHEL393)           += elphel393-mem.o  
obj-$(CONFIG_ELPHELDRVONMICROZED) += elphel393-mem.o
obj-$(CONFIG_ELPHELDRVONMICROZED) += elphel393-mem.o
obj-$(CONFIG_ELPHEL393_INIT)      += elphel393-init.o   
obj-$(CONFIG_ELPHEL393_INIT)      += elphel393-init.o   

obj-$(CONFIG_ELPHEL393)           += x393.o
obj-$(CONFIG_ELPHEL393)           += sensor_i2c.o
fpgajtag-y := fpgajtag353.o x393.o 
fpgajtag-y := fpgajtag353.o x393.o 
obj-$(CONFIG_ELPHEL393_EXTERNAL)  += fpgajtag.o
obj-$(CONFIG_ELPHEL393_EXTERNAL)  += fpgajtag.o
 No newline at end of file
+60 −66
Original line number Original line Diff line number Diff line
@@ -223,8 +223,8 @@ static struct file_operations fpga_jtag_fops = {
//static int sens_num = 0;
//static int sens_num = 0;


// internal functions
// internal functions
loff_t fjtag_bitsize (int minor);
//loff_t fjtag_bitsize (int minor);
loff_t fjtag_bytesize (int minor);
//loff_t fjtag_bytesize (int minor);
int JTAG_channel(int minor);
int JTAG_channel(int minor);
void initPortC(void);
void initPortC(void);
void set_pgm_mode (int chn, int en);
void set_pgm_mode (int chn, int en);
@@ -484,7 +484,7 @@ static int fpga_jtag_release(struct inode *inode, struct file *filp) {
     case FPGA_AJTAG_BOUNDARY_MINOR :
     case FPGA_AJTAG_BOUNDARY_MINOR :
// "dirty"? Send to JTAG
// "dirty"? Send to JTAG
       if (JTAG_channels[chn].wp >0) {
       if (JTAG_channels[chn].wp >0) {
		   D(printk("fpga_jtag_release(), JTAG_channels[%d].wp = 0x%x",chn,JTAG_channels[chn].wp));
//		   D(printk("fpga_jtag_release(), JTAG_channels[%d].wp = 0x%x",chn,JTAG_channels[chn].wp));
    	   JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // size in bits
    	   JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // size in bits
       }
       }
       JTAG_resetChannel (chn);
       JTAG_resetChannel (chn);
@@ -544,7 +544,7 @@ static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t coun
       if (*off > size) return -EFAULT;
       if (*off > size) return -EFAULT;
       if ((*off + count) > size) count= (size - *off);
       if ((*off + count) > size) count= (size - *off);
       if (*off < JTAG_channels[chn].wp) {
       if (*off < JTAG_channels[chn].wp) {
 	     D(printk("fpga_jtag_write(), JTAG_channels[%d].wp = 0x%x",chn, JTAG_channels[chn].wp));
// 	     D(printk("fpga_jtag_write(), JTAG_channels[%d].wp = 0x%x",chn, JTAG_channels[chn].wp));
         JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // writing "before" causes EXTEST to fill in boundary scan register
         JTAG_EXTEST (chn, JTAG_channels[chn].dbuf, JTAG_channels[chn].bitsw); // writing "before" causes EXTEST to fill in boundary scan register
         JTAG_channels[chn].wdirty=0;
         JTAG_channels[chn].wdirty=0;
       }
       }
@@ -560,7 +560,7 @@ static ssize_t fpga_jtag_write(struct file * file, const char * buf, size_t coun
     default:               return -EINVAL;
     default:               return -EINVAL;
   }
   }
 dev_dbg(NULL, "fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size);
 dev_dbg(NULL, "fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size);
 D(printk("fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size));
 //D(printk("fpga_jtag_write end: p=%x,chn=%x, buf address=%lx count=%lx *offs=%lx, wp=%lx,size=0x%x\r\n", p, chn, (long) buf, (long) count, (long) *off, (long)JTAG_channels[chn].wp, (int) size));
   return count;
   return count;
}
}


@@ -756,11 +756,34 @@ inline x393_status_sens_io_t wait_sensio_status(int chn, u32 seq_num) // reducin
	return stat;
	return stat;
}
}


inline u32 read_tdo(int sens_num)
{
	x393_status_sens_io_t stat;
	x393_status_ctrl_t stat_ctrl;
    int i;
	stat_ctrl.d32 = 0;
	stat = x393_sensio_status(sens_num);
	stat_ctrl.seq_num = stat.seq_num + 1;
	stat_ctrl.mode = 1;
	set_x393_sensio_status_cntrl(stat_ctrl, sens_num);
	for (i = 0; i < 10; i++) {
		stat = x393_sensio_status(sens_num & 3); // sens_num);
		if (likely(stat.seq_num == stat_ctrl.seq_num)) {
			return stat.xfpgatdo;
		}
	}
	dev_err(NULL,"read_tdo(%d): failed to  get expected seq_num in 10 cycles, expected = 0x%x, got 0x%x\n",sens_num,stat_ctrl.seq_num, stat.seq_num);
	return stat.xfpgatdo;
}




// set FPGA in programming/JTAG mode (only for sensor board)
// set FPGA in programming/JTAG mode (only for sensor board)
// NOP for the main board FPGA configuration
// NOP for the main board FPGA configuration
void set_pgm_mode (int chn, int en) {
void set_pgm_mode (int chn, int en) {
	u32 seq_num;
	u32 seq_num;
	x393_sensio_jpag_t data;
	x393_sensio_jtag_t data;
	dev_dbg(NULL, "set_pgm_mode (%d,%d)\n",chn,en);
	dev_dbg(NULL, "set_pgm_mode (%d,%d)\n",chn,en);


	switch (chn >> 2) {
	switch (chn >> 2) {
@@ -768,16 +791,15 @@ void set_pgm_mode (int chn, int en) {
		//port_csp0_addr[X313_WA_SENSFPGA] = (en ? (3 << SFPGA_PGMEN_BIT): (SFPGA_RD_SENSPGMPIN | (2 << SFPGA_PGMEN_BIT))) | (2  << SFPGA_TCK_BIT); // turn off TCK (if not turned off already)
		//port_csp0_addr[X313_WA_SENSFPGA] = (en ? (3 << SFPGA_PGMEN_BIT): (SFPGA_RD_SENSPGMPIN | (2 << SFPGA_PGMEN_BIT))) | (2  << SFPGA_TCK_BIT); // turn off TCK (if not turned off already)


		/* ? SFPGA_RD_SENSPGMPIN */
		/* ? SFPGA_RD_SENSPGMPIN */
		data.d32 = 0;
		data.pgmen = (en) ? 1 : 0;
		data.pgmen = (en) ? 1 : 0;
		data.pgmen_set = 1;
		data.pgmen_set = 1;
		data.tck = 0;
		data.tck = 0;
		data.tck_set = 1;
		data.tck_set = 1;
		/* check status register */
		/* check status register */
//		seq_num = prep_sensio_status(sens_num);
		x393_sensio_jtag(data, chn & 3); // sens_num);
		x393_sensio_jtag(data, chn & 3); // sens_num);
		/* wait for status register update */
		/* wait for status register update */
//		wait_sensio_status(sens_num, seq_num);
		wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ; // Not needed here
//		x393_sensio_jtag(data, sens_num);
		break;
		break;
	}
	}
	udelay (2);
	udelay (2);
@@ -785,7 +807,7 @@ void set_pgm_mode (int chn, int en) {


void set_pgm (int chn, int pgmon) {
void set_pgm (int chn, int pgmon) {
	u32 seq_num;
	u32 seq_num;
	x393_sensio_jpag_t data;
	x393_sensio_jtag_t data;
	dev_dbg(NULL, "set_pgm (%d,%d)\n",chn,pgmon);
	dev_dbg(NULL, "set_pgm (%d,%d)\n",chn,pgmon);


	switch (chn >> 2) {
	switch (chn >> 2) {
@@ -800,9 +822,7 @@ void set_pgm (int chn, int pgmon) {
		//port_csp0_addr[X313_WA_SENSFPGA] = (2 | (pgmon & 1)) << SFPGA_PROG_BIT;
		//port_csp0_addr[X313_WA_SENSFPGA] = (2 | (pgmon & 1)) << SFPGA_PROG_BIT;
		data.prog= pgmon & 1;
		data.prog= pgmon & 1;
		data.prog_set = 1;
		data.prog_set = 1;
//		seq_num = prep_sensio_status(sens_num);
		x393_sensio_jtag(data, chn >> 2); // sens_num);
		x393_sensio_jtag(data, chn >> 2); // sens_num);
//		wait_sensio_status(sens_num, seq_num);
		break;
		break;
	case JTAG_AUX_FPGA:
	case JTAG_AUX_FPGA:
		break;
		break;
@@ -812,9 +832,8 @@ void set_pgm (int chn, int pgmon) {




int read_done (int chn) {
int read_done (int chn) {
	u32 seq_num;
	x393_status_sens_io_t stat;
	x393_status_sens_io_t stat;
	x393_sensio_jpag_t data;
	x393_sensio_jtag_t data;


	switch (chn >> 2) {
	switch (chn >> 2) {
#ifdef TEST_DISABLE_CODE
#ifdef TEST_DISABLE_CODE
@@ -825,9 +844,8 @@ int read_done (int chn) {
		//port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_DONE;
		//port_csp0_addr[X313_WA_SENSFPGA] = SFPGA_RD_DONE;
		//udelay (1);
		//udelay (1);
		//return (port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1 ;
		//return (port_csp0_addr[X313__RA__SENSFPGA] >> SFPGA_RD_BIT) & 1 ;
		seq_num = prep_sensio_status(chn & 3) ; // sens_num);

//		stat = x393_sensio_status(chn & 3) ; // sens_num);
		stat = wait_sensio_status(chn & 3, prep_sensio_status(chn & 3)) ;
		stat = wait_sensio_status(chn & 3, seq_num) ; // sens_num);
		return stat.xfpgadone;
		return stat.xfpgadone;
	case JTAG_AUX_FPGA:
	case JTAG_AUX_FPGA:
		return 0;
		return 0;
@@ -838,7 +856,7 @@ int read_done (int chn) {
//  send 1..8 bits through JTAG 
//  send 1..8 bits through JTAG 
int jtag_send (int chn, int tms, int len, int d) {
int jtag_send (int chn, int tms, int len, int d) {
	int sens_num = chn & 3;
	int sens_num = chn & 3;
	x393_sensio_jpag_t data;
	x393_sensio_jtag_t data;
	x393_status_sens_io_t stat;
	x393_status_sens_io_t stat;
	u32 seq_num;
	u32 seq_num;
	int i; //,m;
	int i; //,m;
@@ -882,11 +900,12 @@ int jtag_send (int chn, int tms, int len, int d) {
		}
		}
		port_csp0_addr[X313_WA_SENSFPGA] = (2  << SFPGA_TCK_BIT); // TCK=0
		port_csp0_addr[X313_WA_SENSFPGA] = (2  << SFPGA_TCK_BIT); // TCK=0
#endif /* TEST_DISABLE_CODE */
#endif /* TEST_DISABLE_CODE */
		data.d32 =     0;
		data.tck_set = 1;
		data.tck_set = 1;
		data.tms_set = 1;
		data.tms_set = 1;
		data.tdi_set = 1;
		data.tdi_set = 1;


		printk("jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\n", chn, tms,len,d);
		dev_dbg(NULL, "jtag_send(0x%x, 0x%x, 0x%x, 0x%x)\n", chn, tms,len,d);
		for ( ; i > 0; i--) {
		for ( ; i > 0; i--) {
			/* TCK = 0 - just a delay; is it really needed? */
			/* TCK = 0 - just a delay; is it really needed? */
			data.tck = 0;
			data.tck = 0;
@@ -897,31 +916,20 @@ int jtag_send (int chn, int tms, int len, int d) {


			x393_sensio_jtag(data, sens_num);
			x393_sensio_jtag(data, sens_num);
			/* repeat writel - just a delay; is it really needed? */
			/* repeat writel - just a delay; is it really needed? */
			x393_sensio_jtag(data, sens_num);
//			x393_sensio_jtag(data, sens_num);
			x393_sensio_jtag(data, sens_num);
			x393_sensio_jtag(data, sens_num);


			/* read TDO before TCK pulse */
			/* read TDO before TCK pulse */
			seq_num = prep_sensio_status(sens_num);
			r = (r << 1) +  read_tdo(sens_num); // may to need to read twice to increase delay?
			stat = wait_sensio_status(sens_num, seq_num); // get TDO (only where we need to wait status for here)

			// DEBUG: repeating read
			seq_num = prep_sensio_status(sens_num);
			stat = wait_sensio_status(sens_num, seq_num); // get TDO (only where we need to wait status for here)

			printk(" %08x", stat.d32);

			r = (r << 1) + (stat.xfpgatdo & 1);


			data.tck = 1;
			data.tck = 1;
			x393_sensio_jtag(data, sens_num);  // keep other signals, set TCK == 1
			x393_sensio_jtag(data, sens_num);  // keep other signals, set TCK == 1
			x393_sensio_jtag(data, sens_num);  // repeat if delay will be needed to increase length of the TCK signal
//			x393_sensio_jtag(data, sens_num);  // repeat if delay will be needed to increase length of the TCK signal


			data.tck = 0;
			data.tck = 0;
			x393_sensio_jtag(data, sens_num);
//			x393_sensio_jtag(data, sens_num);
			x393_sensio_jtag(data, sens_num);
		}
		}
		printk(" ---> %02x\n", r);
		x393_sensio_jtag(data, sens_num);
		dev_dbg(NULL, " ---> %02x\n", r);


		break;
		break;
	case JTAG_AUX_FPGA:
	case JTAG_AUX_FPGA:
@@ -948,9 +956,9 @@ int jtag_write_bits (int chn,
	int i,j;
	int i,j;
	int r=0;
	int r=0;
	int d,d0;
	int d,d0;
	u32 seq_num;
//	u32 seq_num;
	x393_status_sens_io_t stat;
	x393_status_sens_io_t stat;
	x393_sensio_jpag_t data;
	x393_sensio_jtag_t data;


	dev_dbg(NULL, "jtag_write_bits(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\r\n", (int) chn, (int) buf, len, check, last);
	dev_dbg(NULL, "jtag_write_bits(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\r\n", (int) chn, (int) buf, len, check, last);


@@ -1030,51 +1038,36 @@ int jtag_write_bits (int chn,
		port_csp0_addr[X313_WA_SENSFPGA] = (2  << SFPGA_TCK_BIT); // TCK=0
		port_csp0_addr[X313_WA_SENSFPGA] = (2  << SFPGA_TCK_BIT); // TCK=0
#endif /* TEST_DISABLE_CODE */
#endif /* TEST_DISABLE_CODE */
// Can be done once
// Can be done once
		data.d32 =     0;
		data.tck_set = 1;
		data.tck_set = 1;
		data.tms_set = 1;
		data.tms_set = 1;
		data.tdi_set = 1;
		data.tdi_set = 1;


		for (i = 0; len > 0; i++) {
		for (i = 0; len > 0; i++) {
			d0 = (d = buf[i]);
			d0 = (d = buf[i]);
			printk("jtag_write_bits(), i=0x%x ", i);
			dev_dbg(NULL,"jtag_write_bits(), i=0x%x ", i);

			for (j = 0; j < 8; j++) {
			for (j = 0; j < 8; j++) {
				/* TCK = 0 - just a delay; is it really needed? */
				data.tck = 0;
				if (len > 0) {
				if (len > 0) {
					if (len == 1 && last) data.tms = 1;
					data.tms = (len == 1 && last)? 1:0 ;
					else                  data.tms = 0;

					data.tdi = ((d <<= 1) >> 8) & 1;
					data.tdi = ((d <<= 1) >> 8) & 1;
					data.tck = 0;
					data.tck = 0;
					x393_sensio_jtag(data, sens_num);
					x393_sensio_jtag(data, sens_num);
					x393_sensio_jtag(data, sens_num); // repeat writel() if needed for delay
//					x393_sensio_jtag(data, sens_num); // repeat writel() if needed for delay
					x393_sensio_jtag(data, sens_num); // repeat writel() if needed for delay
					r = (r << 1) +  read_tdo(sens_num);
					x393_sensio_jtag(data, sens_num); // repeat writel() if needed for delay

					seq_num = prep_sensio_status(sens_num);
					stat = wait_sensio_status(sens_num, seq_num);

					seq_num = prep_sensio_status(sens_num);
					stat = wait_sensio_status(sens_num, seq_num);
					printk(" %d: %08x", j, stat.d32);

					r = (r << 1) + (stat.xfpgatdo & 1);

					data.tck = 1;
					data.tck = 1;
					x393_sensio_jtag(data, sens_num);
					x393_sensio_jtag(data, sens_num);
					x393_sensio_jtag(data, sens_num); // remove if no delay is needed
//					x393_sensio_jtag(data, sens_num); // remove if no delay is needed


					data.tck = 0;
					data.tck = 0;
					x393_sensio_jtag(data, sens_num);
					x393_sensio_jtag(data, sens_num);
					x393_sensio_jtag(data, sens_num);
//					x393_sensio_jtag(data, sens_num);
				} else {
				} else {
					r <<= 1;
					r <<= 1;
				}
				}
				len--;
				len--;
			}
			}
			buf[i] = r;
			buf[i] = r;
			printk(" ===> %02x\n", r);
			dev_dbg(NULL," ===> %02x\n", r);
			if (check && ((r ^ (prev[1]>>24)) & 0xff)) {
			if (check && ((r ^ (prev[1]>>24)) & 0xff)) {
				return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
				return -((r & 0xff) | ((i+1) << 8)); //readback mismatch
			}
			}
@@ -1241,6 +1234,7 @@ int JTAG_resetChannel (int chn) {
     jtag_send(chn, 1, 5, 0   ); // set Test-Logic-Reset state
     jtag_send(chn, 1, 5, 0   ); // set Test-Logic-Reset state
// disable programmimg mode (nop for the 10353 FPGA)
// disable programmimg mode (nop for the 10353 FPGA)
     set_pgm_mode(chn, 0); // only for sensor FPGA
     set_pgm_mode(chn, 0); // only for sensor FPGA
     return 0;
} // int JTAG_resetChannel (int chn)
} // int JTAG_resetChannel (int chn)


int JTAG_readID (int chn, unsigned char * buf)  {
int JTAG_readID (int chn, unsigned char * buf)  {
@@ -1319,7 +1313,7 @@ int i; // only in debug
#ifdef JTAG_DISABLE_IRQ
#ifdef JTAG_DISABLE_IRQ
  unsigned long flags;
  unsigned long flags;
#endif
#endif
D(printk("JTAG_CAPTURE(): buf=%p\n",buf));
dev_dbg(NULL,"JTAG_CAPTURE(): buf=%p\n",buf);
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE ***********************
//*************************** NOW DISABLE INTERRUPS FOR THE WHOLE JTAG SEQUENCE ***********************
#ifdef JTAG_DISABLE_IRQ
#ifdef JTAG_DISABLE_IRQ
     local_irq_save(flags);
     local_irq_save(flags);
@@ -1374,8 +1368,8 @@ int i; // only in debug
     local_irq_save(flags);
     local_irq_save(flags);
     //local_irq_disable();
     //local_irq_disable();
#endif
#endif
D(printk("EXTEST: buf=%p, len=0x%x\n",buf,len));
//D(printk("EXTEST: buf=%p, len=0x%x\n",buf,len));
D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); );
//D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); );


//     jtag_send(chn, 1, 5, 0   ); //step 1 - set Test-Logic-Reset state
//     jtag_send(chn, 1, 5, 0   ); //step 1 - set Test-Logic-Reset state
//     jtag_send(chn, 0, 1, 0   ); //step 2 - set Run-Test-Idle state
//     jtag_send(chn, 0, 1, 0   ); //step 2 - set Run-Test-Idle state
@@ -1395,7 +1389,7 @@ D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if
#ifdef JTAG_DISABLE_IRQ
#ifdef JTAG_DISABLE_IRQ
     local_irq_restore(flags);
     local_irq_restore(flags);
#endif
#endif
     D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); ); 
//     D(printk ("\n"); for (i=0; i<((len+7)>>3) ;i++) {printk("%3x ",(int) buf[i]); if ((i & 0xf) == 0xf) printk ("\n");}printk ("\n"); );


    return 0;
    return 0;
} //int JTAG_EXTEST (int chn, unsigned char * buf, int len)
} //int JTAG_EXTEST (int chn, unsigned char * buf, int len)
@@ -1430,6 +1424,6 @@ module_exit(fpga_jtag_exit);


module_init(fpga_jtag_init);
module_init(fpga_jtag_init);
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>");
MODULE_DESCRIPTION(FPGA_JTAG_DRIVER_NAME);
MODULE_DESCRIPTION(FPGA_JTAG_DRIVER_NAME);
+453 −0

File added.

Preview size limit exceeded, changes collapsed.

+89 −0
Original line number Original line Diff line number Diff line
/*******************************************************************************
* FILE NAME  : sensor_i2c.h
* DESCRIPTION: Interface to FPGA-based i2c sequencer for sensor ports
* Copyright 2016 (C) Elphel, Inc.
* -----------------------------------------------------------------------------*
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/

/* Reserve i2c page (1 of 256 for a sensor port)*/
int i2c_page_alloc(int chn);

/* Free i2c page */
void i2c_page_free(int chn, int page);

/* Set i2c table entry to raw data (will just overwrite tbl_mode = 2) */
void set_sensor_i2c_raw(int chn,
		                int page,   // index in lookup table
					    u32 data); // Bit delay - number of mclk periods in 1/4 of the SCL period

/* Set i2c table entry for write operation */
void set_sensor_i2c_wr(int chn,
		              int page,        // index in lookup table
					  int sa,          // slave address (7 bit)
					  int rah,         // High byte of the i2c register address
					  int num_bytes,   //Number of bytes to write (1..10)
					  int bit_delay); // Bit delay - number of mclk periods in 1/4 of the SCL period

/* Set i2c table entry for read operation */
void set_sensor_i2c_rd(int chn,
		              int page,          // index in lookup table
					  int two_byte_addr, // Number of address bytes (0 - one byte, 1 - two bytes)
					  int num_bytes,     // Number of bytes to read (1..8, 0 means 8)
					  int bit_delay);// Bit delay - number of mclk periods in 1/4 of the SCL period
/*
// Write i2c command to the i2c command sequencer
// I2C command sequencer, block of 16 DWORD slots for absolute frame numbers (modulo 16) and 15 slots for relative ones
// 0 - ASAP, 1 next frame, 14 -14-th next.
// Data written depends on context:
// 1 - I2C register write: index page (MSB), 3 payload bytes. Payload bytes are used according to table and sent
//     after the slave address and optional high address byte. Other bytes are sent in descending order (LSB- last).
//     If less than 4 bytes are programmed in the table the high bytes (starting with the one from the table) are
//     skipped.
//     If more than 4 bytes are programmed in the table for the page (high byte), one or two next 32-bit words
//     bypass the index table and all 4 bytes are considered payload ones. If less than 4 extra bytes are to be
//     sent for such extra word, only the lower bytes are sent.
//
// 2 - I2C register read: index page, slave address (8-bit, with lower bit 0) and one or 2 address bytes (as programmed
//     in the table. Slave address is always in byte 2 (bits 23:16), byte1 (high register address) is skipped if
//     read address in the table is programmed to be a single-byte one
 */

/* Write one or multiple DWORDs to i2c relative (modulo16) address. Use offs = 0 for immediate (ASAP) command */
/* Length of data is determined by the page data already preset */
int write_sensor_i2c_rel (int chn,
                          int offs, // 4 bits
                          u32 * data);

/* Same to absolute (modulo16) address */
int write_sensor_i2c_abs (int chn,
			 		      int offs, // 4 bits
						  u32 * data);

/* Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */
void  write_sensor_reg16  (int chn,
		                  int page, // page (8 bits)
                          int addr, // low 8 bits
	    				  u32 data); // 16 or 8-bit data (LSB aligned)

/* Initiate sensor i2c read in immediate mode (data itself has to be read from FIFO with read_sensor_i2c_fifo)*/
void  read_sensor_i2c  (int chn,
		               int page, // page (8 bits)
					   int sa7,  // 7-bit i2c slave address
                       int addr); // 8/16 bit address

/* Read next byte from the channel i2c FIFO. Return byte or -1 if no data available */
/* Sensor channel status should be in auto update mode (3) */
int read_sensor_i2c_fifo(int chn);
+2 −2
Original line number Original line Diff line number Diff line
/*******************************************************************************
/*******************************************************************************
 * File: x393.c
 * File: x393.c
 * Date: 2016-03-29  
 * Date: 2016-04-06  
 * Author: auto-generated file, see x393_export_c.py
 * Author: auto-generated file, see x393_export_c.py
 * Description: Functions definitions to access x393 hardware registers
 * Description: Functions definitions to access x393 hardware registers
 *******************************************************************************/
 *******************************************************************************/
@@ -174,7 +174,7 @@ void x393_sens_sync_late (x393_sens_sync
void                         x393_sensio_ctrl                    (x393_sensio_ctl_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1020 + 0x100 * sens_num));} // Configure sensor I/O port
void                         x393_sensio_ctrl                    (x393_sensio_ctl_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1020 + 0x100 * sens_num));} // Configure sensor I/O port
void                         set_x393_sensio_status_cntrl        (x393_status_ctrl_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1024 + 0x100 * sens_num));} // Set status control for SENSIO module
void                         set_x393_sensio_status_cntrl        (x393_status_ctrl_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1024 + 0x100 * sens_num));} // Set status control for SENSIO module
x393_status_ctrl_t           get_x393_sensio_status_cntrl        (int sens_num)      { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + (0x1024 + 0x100 * sens_num)); return d; }
x393_status_ctrl_t           get_x393_sensio_status_cntrl        (int sens_num)      { x393_status_ctrl_t d; d.d32 = readl(mmio_ptr + (0x1024 + 0x100 * sens_num)); return d; }
void                         x393_sensio_jtag                    (x393_sensio_jpag_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1028 + 0x100 * sens_num));} // Programming interface for multiplexer FPGA (with X393_SENSIO_STATUS)
void                         x393_sensio_jtag                    (x393_sensio_jtag_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1028 + 0x100 * sens_num));} // Programming interface for multiplexer FPGA (with X393_SENSIO_STATUS)
void                         set_x393_sensio_width               (x393_sensio_width_t d, int sens_num){writel(d.d32, mmio_ptr + (0x102c + 0x100 * sens_num));} // Set sensor line in pixels (0 - use line sync from the sensor)
void                         set_x393_sensio_width               (x393_sensio_width_t d, int sens_num){writel(d.d32, mmio_ptr + (0x102c + 0x100 * sens_num));} // Set sensor line in pixels (0 - use line sync from the sensor)
x393_sensio_width_t          get_x393_sensio_width               (int sens_num)      { x393_sensio_width_t d; d.d32 = readl(mmio_ptr + (0x102c + 0x100 * sens_num)); return d; }
x393_sensio_width_t          get_x393_sensio_width               (int sens_num)      { x393_sensio_width_t d; d.d32 = readl(mmio_ptr + (0x102c + 0x100 * sens_num)); return d; }
void                         set_x393_sensio_tim0                (x393_sensio_tim0_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1030 + 0x100 * sens_num));} // Sensor port i/o timing configuration, register 0
void                         set_x393_sensio_tim0                (x393_sensio_tim0_t d, int sens_num){writel(d.d32, mmio_ptr + (0x1030 + 0x100 * sens_num));} // Sensor port i/o timing configuration, register 0
Loading