os/linux-2.6-tag--devboard-R2_10-4/arch/cris/arch-v32/drivers/elphel/cxi2c.c

Go to the documentation of this file.
00001 /*!********************************************************************************
00002 *! FILE NAME  : cxi2c.c
00003 *! DESCRIPTION: I2c driver for FPGA communicating to sensors, software implementation
00004 *! Copyright (C) 2002-2007 Elphel, Inc.
00005 *! -----------------------------------------------------------------------------**
00006 *!
00007 *!  This program is free software: you can redistribute it and/or modify
00008 *!  it under the terms of the GNU General Public License as published by
00009 *!  the Free Software Foundation, either version 3 of the License, or
00010 *!  (at your option) any later version.
00011 *!
00012 *!  This program is distributed in the hope that it will be useful,
00013 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 *!  GNU General Public License for more details.
00016 *!
00017 *!  You should have received a copy of the GNU General Public License
00018 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 *! -----------------------------------------------------------------------------**
00020 *!  $Log: cxi2c.c,v $
00021 *!  Revision 1.7  2008/04/11 23:16:51  elphel
00022 *!  removed unneeded local_irq_disable() after local_irq_save_flags()
00023 *!
00024 *!  Revision 1.6  2008/03/16 01:25:15  elphel
00025 *!  increased default delays fro I2c bus 1 (EEPROM was not fast enough)
00026 *!
00027 *!  Revision 1.5  2008/02/18 20:02:34  elphel
00028 *!  added option to specify number of bytes to be actually written from device per read command (PHP feature fix)
00029 *!
00030 *!  Revision 1.4  2008/02/12 21:53:20  elphel
00031 *!  Modified I2c to support multiple buses, added raw access (no address registers) and per-slave protection bitmasks
00032 *!
00033 *!  Revision 1.3  2008/02/11 04:52:18  elphel
00034 *!  Modified I2C operations, added second bus to work with the 10369 (and future) board(s)
00035 *!
00036 *!  Revision 1.2  2007/10/16 23:18:31  elphel
00037 *!  added filtering I2C lines, r/w control of the I2C bit delays
00038 *!
00039 */
00040 
00041 /****************** INCLUDE FILES SECTION ***********************************/
00042 
00043 #include <linux/module.h>
00044 #include <linux/sched.h>
00045 #include <linux/slab.h>
00046 #include <linux/errno.h>
00047 #include <linux/kernel.h>
00048 #include <linux/fs.h>
00049 #include <linux/string.h>
00050 #include <linux/init.h>
00051 #include <linux/autoconf.h>
00052 
00053 #include <asm/system.h>
00054 //#include <asm/svinto.h>
00055 #include <asm/io.h>
00056 
00057 #include <asm/irq.h>
00058 
00059 #include <asm/delay.h>
00060 #include <asm/uaccess.h>
00061 #include <asm/elphel/c313a.h>
00062 
00063 #include "fpgactrl.h"  // defines port_csp0_addr, port_csp4_addr 
00064 
00065 #include "x3x3.h"
00066 #include "cc3x3.h"
00067 
00068 
00069 #include "cci2c.h"
00070 
00071 #define D(x)
00072 //#define D(x) printk("%s:%d:",__FILE__,__LINE__);x
00073 
00074 //#define PASSIVE_PULLUP y // Enable to remove active pullup on SCL SDA (just use pullup resistors)
00075 
00076 
00077 // implementing read/write/lseek for i2c - using a new major and several minors:
00078 // for 8 and 16 registers with and w/o autoincrement.
00079 // next minors - for less commomn i2c devices.
00080 // address space is considered to include 1 byte of register address and 7MSBs of slave address
00081 
00082 
00083 /****************** I2C DEFINITION SECTION *************************/
00084 #define CLOCK_LOW_TIME            8
00085 #define CLOCK_HIGH_TIME           8
00086 #define START_CONDITION_HOLD_TIME 8
00087 #define STOP_CONDITION_HOLD_TIME  8
00088 #define ENABLE_OUTPUT 0x01
00089 #define ENABLE_INPUT 0x00
00090 #define I2C_CLOCK_HIGH 1
00091 #define I2C_CLOCK_LOW 0
00092 #define I2C_DATA_HIGH 1
00093 #define I2C_DATA_LOW 0
00094 
00095 /* use the kernels delay routine */
00096 
00097 //#define i2c_delay(usecs) udelay(usecs)
00098 //#define i2c_delay(usecs) {}
00099 
00100 //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.
00101 
00102 #define i2c_delay(usecs) udelay(usecs)
00103 #define I2C_DELAY_SCALE 1
00104 //#define X3X3_I2C_MAXMINOR 4  //
00105 //#define X3X3_I2C_CHANNELS 2  // number of i2c channels
00106 
00107 //volatile unsigned long ccam_cr_shadow=0;
00108 extern volatile unsigned long ccam_cr_shadow;
00109 
00110 // currently delays are approximately  0.4usec+0.2usec*n and 0x01010000 works (~8usec/byte)
00111 // with deafult 20MHz pixel clock - 0x01010202, after clock is set to 48MHz 0x01010000 is enough
00113 /*
00114 struct i2c_timing_t {
00115         unsigned char scl_high; //0x02, //! SCL high:
00116         unsigned char scl_low;  //0x02, //! SCL low:
00117         unsigned char slave2master; //0x01, //! slave -> master
00118         unsigned char master2slave; //0x01, //! master -> slave
00119         unsigned char filter_sda;   //0x07, //! filter SDA read data by testing multiple times - currently just zero/non zero
00120         unsigned char filter_scl;  //0x07};//! filter SCL read data by testing multiple times - currently just zero/non zero 
00121 }
00122 */
00123 
00124 static struct i2c_timing_t bitdelays[X3X3_I2C_CHANNELS];
00125 
00126 /*
00127 static unsigned char bitdelays[6]= {0x02, //! SCL high:
00128                                     0x02, //! SCL low:
00129                                     0x01, //! slave -> master
00130                                     0x01, //! master -> slave
00131                                     0x07, //! filter SDA read data by testing multiple times - currently just zero/non zero
00132                                     0x07};//! filter SCL read data by testing multiple times - currently just zero/non zero 
00133 */
00134 
00135 
00136 
00137 
00138 void i2c_disable(int n);
00139 void i2c_dir_out(int n);
00140 void i2c_dir_in (int n);
00141 void i2c_scl_0  (int n);
00142 void i2c_scl_1  (int n);
00143 void i2c_sda    (int n, int d); /* d is checked against zero only, it does not need to be "1" */ 
00144 int i2c_getbit  (int n);
00145 int i2c_getscl(int n);                  /* just for i2c testing */
00146 int i2c_diagnose(int n);
00147 int i2c_start(int n);
00148 int i2c_restart(int n);
00149 int i2c_stop(int n);
00150 int i2c_outbyte(int n, unsigned char d);
00151 unsigned char i2c_inbyte(int n, int more);
00152 void i2c_sendack(int n, int ackn); // ackn= 1 - send ackn (low level), 0 - no ackn.
00153 
00154 int i2c_delays (unsigned long delays) { // will only change bus 0 this way
00155   unsigned long * bitdelays_long=(unsigned long *) bitdelays;
00156   if (delays !=0) bitdelays_long[0]=delays;
00157   return (int) bitdelays_long[0];
00158 }
00159 
00160 /* I2C functions */
00161 // redesign of i2c functions optimized for faster communications,
00162 // including FPGA <->FPGA transfers.
00163 // To make communications faster there are the following steps:
00164 // 1 - SCL is always driven by master - no waiting for the slave
00165 // 2 - SDA is actively driven high by the master (and expecting the same from the slave)
00166 //     SDA is driven high during SCL=0 when other party is known not to drive it low.
00167 // 3 - separate bus turn-over delays are added in addition to (shorter) bit delays
00168 // 4 - 4 delays are programmed as a single 32-bit word that can be changed to communicate with
00169 //     different slaves (i.e. FPGA and image sensor)
00170 /*
00171 #define x3x3_DELAY(x) {int iiii; for (iiii=0; iiii < (x); iiii++) X3X3_AFTERWRITE ; }
00172 I2C_DELAY_SCALE
00173     #define   X313_WA_IOPINS    0x70  // bits [13:12] selecte  of the source of the control word:
00174     SCL=EXT[0]
00175     SDA=EXT[1]
00176 */
00177 #define SCL1_0   0x1
00178 #define SCL1_OFF 0x3
00179 #define SDA1_0   0x4
00180 #define SDA1_OFF 0xc
00181 
00182 #ifdef PASSIVE_PULLUP
00183   #define SCL1_1   0x3  // same as off
00184   #define SDA1_1   0xc  // same as off
00185 #else
00186   #define SCL1_1   0x2
00187   #define SDA1_1   0x8
00188 #endif
00189 
00190 /*
00191 struct i2c_timing_t {
00192 0        unsigned char scl_high; //0x02, //! SCL high:
00193 1        unsigned char scl_low;  //0x02, //! SCL low:
00194 2        unsigned char slave2master; //0x01, //! slave -> master
00195 3        unsigned char master2slave; //0x01, //! master -> slave
00196 4        unsigned char filter_sda;   //0x07, //! filter SDA read data by testing multiple times - currently just zero/non zero
00197 5        unsigned char filter_scl;  //0x07};//! filter SCL read data by testing multiple times - currently just zero/non zero 
00198 }
00199 */
00201 int i2c_getbit(int n) {
00202   if (bitdelays[n].filter_sda)
00203            return n? (((X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1)) + (X313_PIOR(SDA1))) >> 2) :
00204                      (((X313_SR(SDA0)) + (X313_SR(SDA0)) + (X313_SR(SDA0)) + (X313_SR(SDA0)) + (X313_SR(SDA0)) + (X313_SR(SDA0)) + (X313_SR(SDA0))) >> 2) ;
00205   else     return n? X313_PIOR(SDA1) : X313_SR(SDA0);
00206 }
00207 
00208 int i2c_getscl(int n) {
00209   if (bitdelays[n].filter_scl)
00210            return n? (((X313_PIOR(SCL1)) + (X313_PIOR(SCL1)) + (X313_PIOR(SCL1)) + (X313_PIOR(SCL1)) + (X313_PIOR(SCL1)) + (X313_PIOR(SCL1)) + (X313_PIOR(SCL1))) >> 2) :
00211                      (((X313_SR(SCL0)) + (X313_SR(SCL0)) + (X313_SR(SCL0)) + (X313_SR(SCL0)) + (X313_SR(SCL0)) + (X313_SR(SCL0)) + (X313_SR(SCL0))) >> 2) ;
00212   else     return n? X313_PIOR(SCL1) : X313_SR(SCL0);
00213 }
00214 
00215 // faster inline replacements - need to have IRQs disabled
00216 inline void il_ccamCRAnd(unsigned long d) {
00217         port_csp0_addr[X313_WA_WCTL]= (ccam_cr_shadow &= d);
00218 }
00219 
00220 inline void il_ccamCROr(unsigned long d) {
00221         port_csp0_addr[X313_WA_WCTL]= (ccam_cr_shadow |= d);
00222 }
00223 
00224 inline void il_ccamCRAndOr(unsigned long d_and, unsigned long d_or) {
00225         ccam_cr_shadow &= d_and;
00226         port_csp0_addr[X313_WA_WCTL]= (ccam_cr_shadow |= d_or);
00227 }
00228 
00229 void i2c_scl_0(int n) {
00230 
00231    if (n) port_csp0_addr[X313_WA_IOPINS]=SCL1_0; // EXT[0] enabled, 0
00232    else   il_ccamCRAndOr(~X313_BITS(SCL0,1),X313_BITS(SCL0_EN,1)); // SCL= 0
00233  }
00234 
00235 void i2c_scl_1(int n) {
00236    if (n)  port_csp0_addr[X313_WA_IOPINS]=SCL1_1; // modified by ifdef PASSIVE_PULLUP
00237    else    il_ccamCROr (X313_BITS(SCL0,1) | X313_BITS(SCL0_EN,1)); // SCL=1
00238  }
00239 
00240 
00241 
00242 
00243 void i2c_sda_weak (int n, int d) {      // will also force sda enable
00244  if (n) {
00245    if (d) port_csp0_addr[X313_WA_IOPINS]=SDA1_OFF; // turn off SDA
00246    else   port_csp0_addr[X313_WA_IOPINS]=SDA1_0; // turn on SDA ==0
00247  } else {
00248    if (d) il_ccamCRAndOr(~X313_BITS(SDA0_EN,1), X313_BITS(SDA0,1)); // turn off SDA ==1 (just in case)
00249    else   il_ccamCRAndOr(~X313_BITS(SDA0,1),  X313_BITS(SDA0_EN,1)); // turn on SDA ==0
00250  }
00251 }
00252 
00253 void i2c_sda_strong (int n, int d) {    // will also force sda enable
00254  if (n) {
00255    if (d) port_csp0_addr[X313_WA_IOPINS]=SDA1_1; // modified by ifdef PASSIVE_PULLUP
00256    else   port_csp0_addr[X313_WA_IOPINS]=SDA1_0; // turn on SDA ==0
00257  } else {
00258    if (d) il_ccamCROr   ( X313_BITS(SDA0,1) | X313_BITS(SDA0_EN,1)); // turn on SDA ==1
00259    else   il_ccamCRAndOr(~X313_BITS(SDA0,1),  X313_BITS(SDA0_EN,1)); // turn on SDA ==0
00260  }
00261 }
00262 
00263 
00265 int     i2c_start(int n) {
00266    int i;
00267    unsigned long flags;
00268    local_irq_save(flags);
00269    //local_irq_disable();
00270   D(printk("i2c_start:  bus=%x\r\n", n));
00271 // both SCL and SDA are supposed to be high - no waiting is needed
00272 // set SCL=1, release SDA, wait SCL high time and verify.
00273    i2c_scl_1(n);
00274    i2c_sda_weak (n, 1);
00275    x3x3_DELAY(bitdelays[n].scl_high*I2C_DELAY_SCALE);
00276 // verify SDA is high
00277    if (!i2c_getbit(n)) { // try recovering by clocking SCL (8x slower)
00278      for (i=0; i<9; i++) {
00279        i2c_scl_0(n);
00280        x3x3_DELAY(bitdelays[n].scl_low * I2C_DELAY_SCALE*8);
00281        i2c_scl_1(n);
00282        x3x3_DELAY(bitdelays[n].scl_high * I2C_DELAY_SCALE*8);
00283       if (!i2c_getbit(n)) break;
00284      }
00285      if (!i2c_getbit(n)) {
00286        local_irq_restore(flags);
00287        return ERR_I2C_SDA_ST0; // error
00288      }
00289    }
00290    i2c_sda_weak (n, 0);
00291    x3x3_DELAY(bitdelays[n].scl_low*I2C_DELAY_SCALE); // technically it is SCL==1
00292    i2c_scl_0(n);
00293    local_irq_restore(flags);
00294    return 0;
00295 }
00296 
00297 // generate i2c stop condition
00298 int i2c_stop(int n) {
00299    unsigned long flags;
00300    local_irq_save(flags);
00301    //local_irq_disable();
00302   D(printk("i2c_stop:  bus=%x\r\n", n));
00303 // SCL=0, SDA - unknown. Wait for bus turnover
00304    i2c_sda_weak (n, 0);
00305    x3x3_DELAY(bitdelays[n].slave2master*I2C_DELAY_SCALE); // maybe not needed  as it is 1->0 transition
00306    x3x3_DELAY(bitdelays[n].scl_low*I2C_DELAY_SCALE); // regular SCL=0 delay
00307    i2c_scl_1(n);
00308    x3x3_DELAY(bitdelays[n].scl_high*I2C_DELAY_SCALE); // regular SCL=1 delay
00309    i2c_sda_strong (n, 1);
00310    x3x3_DELAY(bitdelays[n].scl_high*I2C_DELAY_SCALE); // regular SCL=1 delay
00311    i2c_sda_weak (n, 1);
00312    local_irq_restore(flags);
00313    return 0;
00314 }
00315 
00316 // generate i2c repeated start condition
00317 int     i2c_restart(int n) {
00318    unsigned long flags;
00319    local_irq_save(flags);
00320    //local_irq_disable();
00321   D(printk("i2c_restart:  bus=%x\r\n", n));
00322 // SCL=0, SDA - unknown. Wait for bus turnover
00323    i2c_sda_weak (n, 1);
00324    x3x3_DELAY(bitdelays[n].slave2master*I2C_DELAY_SCALE); // time for slave to release the bus
00325    i2c_sda_strong (n, 1);
00326    x3x3_DELAY(bitdelays[n].scl_low*I2C_DELAY_SCALE); // regular SCL=0 delay
00327    i2c_scl_1(n);
00328    i2c_sda_weak (n, 1);
00329    x3x3_DELAY(bitdelays[n].scl_high*I2C_DELAY_SCALE); // regular SCL=1 delay
00330    i2c_sda_weak (n, 0);
00331    x3x3_DELAY(bitdelays[n].scl_low*I2C_DELAY_SCALE); // technically it is SCL==1
00332    i2c_scl_0(n);
00333    local_irq_restore(flags);
00334    return 0;
00335 }
00336 
00337 // write a byte to the i2c interface , return acknowledge (active high, inverted from SDA line)
00338 int i2c_outbyte(int n, unsigned char d) { 
00339    int i;
00340    unsigned char x=d;   // make it non-destructive
00341    unsigned long flags;
00342    local_irq_save(flags);
00343    //local_irq_disable();
00344   D(printk("i2c_outbyte:  bus=%x byte=%x\r\n", n, x));
00345    i2c_sda_weak (n, 1);
00346    x3x3_DELAY(bitdelays[n].slave2master * I2C_DELAY_SCALE); // time for slave to release the bus
00347    for (i = 0; i < 8; i++) { // assumed to be with SCL=0;
00348       i2c_sda_strong (n,(x & 0x80));    // checks only on non-zero, so no need to '>>'
00349       x3x3_DELAY(bitdelays[n].scl_low * I2C_DELAY_SCALE); // SCL=0 delay
00350       i2c_scl_1(n);
00351       i2c_sda_weak (n,(x & 0x80));      // checks only on non-zero, so no need to '>>'
00352       x3x3_DELAY(bitdelays[n].scl_high * I2C_DELAY_SCALE); // regular SCL=1 delay
00353       i2c_scl_0(n);
00354       x <<= 1;
00355    }
00356 // prepare to read ACKN
00357    i2c_sda_weak (n, 1);
00358    x3x3_DELAY(bitdelays[n].master2slave * I2C_DELAY_SCALE); // master -> slave delay
00359    x3x3_DELAY(bitdelays[n].scl_low * I2C_DELAY_SCALE); // regular SCL=0 delay
00360    i2c_scl_1(n);
00361    x3x3_DELAY(bitdelays[n].scl_high * I2C_DELAY_SCALE); // regular SCL=1 delay
00362    i= (1-i2c_getbit(n));
00363    i2c_scl_0(n);
00364   D(printk("i2c_outbyte:  ACK=%x\r\n", i));
00365    local_irq_restore(flags);
00366    return i;
00367 }
00368 
00369 
00370 // read a byte from the i2c interface, send "more" bit (SDA=0 - more, SDA=1 - that's enough)
00371 
00372 unsigned char i2c_inbyte(int n, int more) { // assumed SCL=0, SDA=X
00373    unsigned char aBitByte = 0;
00374    int i;
00375    unsigned long flags;
00376    local_irq_save(flags);
00377    //local_irq_disable();
00378   D(printk("i2c_inbyte:  bus=%x\r\n", n));
00379 // prepare to read ACKN
00380    i2c_sda_weak (n, 1);
00381    x3x3_DELAY(bitdelays[n].master2slave * I2C_DELAY_SCALE); // master -> slave delay
00382 // read bits
00383    for (i = 0; i < 8; i++) {
00384      x3x3_DELAY(bitdelays[n].scl_low * I2C_DELAY_SCALE); // regular SCL=0 delay
00385      i2c_scl_1(n);
00386      x3x3_DELAY(bitdelays[n].scl_high * I2C_DELAY_SCALE); // regular SCL=1 delay
00387      aBitByte = (aBitByte << 1) | i2c_getbit(n);
00388      i2c_scl_0(n);
00389    }
00390 // send "more"
00391    i2c_sda_weak (n, more ? 0 : 1);
00392    x3x3_DELAY(bitdelays[n].slave2master * I2C_DELAY_SCALE); // time for slave to release the bus
00393    i2c_sda_strong (n, more ? 0 : 1);
00394    x3x3_DELAY(bitdelays[n].scl_low * I2C_DELAY_SCALE); // SCL=0 delay
00395    i2c_scl_1(n);
00396    i2c_sda_weak (n, more ? 0 : 1);
00397    x3x3_DELAY(bitdelays[n].scl_high * I2C_DELAY_SCALE); // regular SCL=1 delay
00398    i2c_scl_0(n);
00399   D(printk("i2c_inbyte:  data=%x\r\n", aBitByte));
00400    local_irq_restore(flags);
00401    return aBitByte;     // returns with SCL=0, SDA - OFF
00402 }
00403 
00404 
00405 /*#---------------------------------------------------------------------------
00406 *#
00407 *# FUNCTION NAME: i2c_writeData
00408 *#
00409 *# DESCRIPTION  : Writes a sequence of bytes to an I2C device
00410 *# removed retries, will add test-ready later as a separate function
00411 *# removed all "dummy stuff" - I never needed that
00412 *# added "stop" argument - don't send stop before read
00413 *#--------------------------------------------------------------------------*/
00414 int i2c_writeData(int n, unsigned char theSlave, unsigned char *theData, int size, int stop) {
00415    int i,error=0;
00416    D(printk("i2c_writeData:  bus=%x theSlave=%x data=%x %x size=%x\r\n", n, theSlave, theData[0], theData[1], size));
00417 
00418 // generate start condition, test bus
00419    if ((error=i2c_start(n))) return error;
00420 // send slave address, wait for ack 
00421    if(!i2c_outbyte(n,theSlave)) {
00422       i2c_stop(n);
00423       return ERR_I2C_BSY;       // device does not exist or not ready
00424    }
00425 // OK, now send theData verifying ACK goes after each byte
00426    for (i=0;i<size;i++) {
00427      if(!i2c_outbyte(n,theData[i])) {
00428        i2c_stop(n);
00429        return ERR_I2C_NACK;     // device failure
00430      }
00431    }
00432    if (stop) i2c_stop(n);
00433         return 0;
00434 }
00435 
00436 /*#---------------------------------------------------------------------------
00437 *#
00438 *# FUNCTION NAME: i2c_readData
00439 *#
00440 *# DESCRIPTION  : Reads a data from the i2c device, returns 0- OK, else - error code
00441 *#
00442 *#--------------------------------------------------------------------------*/
00443 
00444 int i2c_readData(int n, unsigned char theSlave, unsigned char *theData, int size, int start) {
00445    int i, error=0;
00446    if (start) {
00447      if ((error=i2c_start(n))) return error; 
00448    } else {
00449      if ((error=i2c_restart(n))) return error; 
00450    }
00451    /* send slave address, wait for ack */
00452    D(printk("i2c_readData:  bus=%x theSlave=%x size=%x start=%d\r\n", n, theSlave, size, start));
00453 
00454    if(!i2c_outbyte(n,theSlave)) {
00455       i2c_stop(n);
00456       return ERR_I2C_BSY;       // device does not exist or not ready
00457    }
00458    for (i=0;i<size;i++) {
00459       theData[i]=i2c_inbyte(n, (i<(size-1))); // last one should have no ackn !!!
00460    }
00461    i2c_stop(n);
00462    return 0;
00463 }
00464 
00465 extern int _353_io_board_present;
00466 
00467 /* Main device API. ioctl's to write or read to/from i2c registers.  */
00468 // for now - single register read/write only
00469 int i2c_ioctl(struct inode *inode, struct file *file,
00470     unsigned int cmd, unsigned long arg) {
00471     unsigned char data[3];
00472     int error=0;
00473    D(printk("i2c_ioctl cmd= %x, arg= %x\n\r",cmd,(int) arg));
00474    D(printk("i2c_ioctl:  ((int *)file->private_data)[0]= %x\n\r",((int *)file->private_data)[0]));
00475 //   D(printk("i2c_ioctl:  ((int )file->private_data)= %x\n\r",(int)file->private_data));
00476     if(_IOC_TYPE(cmd) != CMOSCAM_IOCTYPE) {
00477       return -EINVAL;
00478     }
00479 // #define I2C_DELAYS   0x0   /* read/write bit deleys for I2C */
00480 //int i2c_delays (unsigned long delays) {
00481 
00482    switch (_IOC_NR(cmd)) {
00483         case IO_EXT_BOARD_PRESENT: {
00484                 return _353_io_board_present;
00485         }
00486      case I2C_DELAYS:
00487        return i2c_delays (arg);
00488      case I2C_WRITEREG:
00489     /* write to an i2c slave */
00490     D(printk("i2cw bus=%d, slave=%d, reg=%d, value=%d\n", 
00491          (int) I2C_ARGBUS(arg),
00492          (int) I2C_ARGSLAVE(arg),
00493          (int) I2C_ARGREG(arg),
00494          (int) I2C_ARGVALUE(arg)));
00495        data[0]=I2C_ARGREG(arg);
00496        data[1]=I2C_ARGVALUE(arg);
00497        return -i2c_writeData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) & 0xfe, &data[0], 2, 1); // send stop
00498      case I2C_READREG:
00499     /* read from an i2c slave */
00500     D(printk("i2cr bus=%d, slave=%d, reg=%d ", 
00501          (int) I2C_ARGBUS(arg),
00502          (int) I2C_ARGSLAVE(arg),
00503          (int) I2C_ARGREG(arg)));
00504        data[0]=I2C_ARGREG(arg);
00505        error=i2c_writeData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) & 0xfe, &data[0], 1, 0); // no stop
00506        if (error) return -error;
00507        error=i2c_readData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) | 0x01, &data[1], 1, 0);  // will start with restart, not start
00508        if (error) return -error;
00509     D(printk("returned %d\n", data[1]));
00510        return data[1];
00511 
00512      case I2C_16_WRITEREG:
00513     /* write to an i2c slave */
00514     D(printk("i2c16w slave=%d, reg=%d, value=%d\n",
00515          (int) I2C_16_ARGSLAVE(arg),
00516          (int) I2C_16_ARGREG(arg),
00517          (int) I2C_16_ARGVALUE(arg)));
00518        data[0]=I2C_16_ARGREG(arg);
00519        data[1]=I2C_16_ARGVALUE_H(arg);
00520        data[2]=I2C_16_ARGVALUE_L(arg);
00521        return -i2c_writeData(0, I2C_16_ARGSLAVE(arg) & 0xfe, &data[0], 3, 1); // send stop
00522      case I2C_16_READREG:
00523     /* read from an i2c slave */
00524     D(printk("i2c16r slave=%d, reg=%d ",
00525          (int) I2C_16_ARGSLAVE(arg),
00526          (int) I2C_16_ARGREG(arg)));
00527        data[0]=I2C_16_ARGREG(arg);
00528        error=i2c_writeData(0, I2C_16_ARGSLAVE(arg) & 0xfe, &data[0], 1, 0); //no stop 
00529        if (error) return -error;
00530        error=i2c_readData(0, I2C_16_ARGSLAVE(arg) | 0x01, &data[1], 2, 0);
00531        if (error) return -error;
00532     D(printk("returned %d\n", (data[1]<<8)+data[2]));
00533        return (data[1]<<8)+data[2];
00534      default:
00535        return -EINVAL;
00536  }
00537  return 0;
00538 }
00539 
00540 /*
00541  * I2C as character devices
00542  *
00543  */
00544 
00545 
00546 
00547 //#define X3X3_I2C 134
00548 // minors (add more later - maybe different minors for different speed - set speed when opening)
00549 //#define X3X3_I2C_CTRL     0  // control/reset i2c
00550 //#define X3X3_I2C_8_AINC  1  // 8bit  registers, autoincement while read/write
00551 //#define X3X3_I2C_16_AINC 2  // 16bit registers, autoincement while read/write
00552 #define X3X3_I2C_DRIVER_NAME "Elphel (R) model 353 i2c character device driver"
00553 //#define X3X3_I2C_CHANNELS 2
00554 //#define X3X3_I2C_MAXMINOR 4  //
00555 
00556 #define  I2CBUFSIZE 8196
00557 //static unsigned char i2cbuf[256*256+1]; //actually usually much less
00558 static unsigned char i2c_enable[X3X3_I2C_CHANNELS*128]; //128 devices in a bus
00559 //static unsigned char i2cbuf_all[( X3X3_I2C_CHANNELS + 1 ) * I2CBUFSIZE];
00560 static unsigned char i2cbuf_all[ X3X3_I2C_CHANNELS + 1  * I2CBUFSIZE]; 
00561 static loff_t sizes[X3X3_I2C_MAXMINOR + 1];
00562 static int burst_sizes[X3X3_I2C_MAXMINOR + 1]; 
00563 static loff_t inuse[X3X3_I2C_CHANNELS];
00564 
00565 //static int thisminor =0;
00566 //static int thissize  =0;
00567 static int     xi2c_open   (struct inode *inode, struct file *filp);
00568 static int     xi2c_release(struct inode *inode, struct file *filp);
00569 static loff_t  xi2c_lseek  (struct file * file, loff_t offset, int orig);
00570 static ssize_t xi2c_write  (struct file * file, const char * buf, size_t count, loff_t *off);
00571 static ssize_t xi2c_read   (struct file * file, char * buf, size_t count, loff_t *off);
00572 static int __init xi2c_init(void);
00573 
00574 static struct file_operations xi2c_fops = {
00575         owner:    THIS_MODULE,
00576         open:     xi2c_open,
00577         release:  xi2c_release,
00578         read:     xi2c_read,
00579         write:    xi2c_write,
00580         llseek:   xi2c_lseek
00581 };
00582 
00584 
00585 int     xi2c_open(struct inode *inode, struct file *filp) {
00586    int p = MINOR(inode->i_rdev);
00587    int bus=-1;
00588    int * pd= (int *) &(filp->private_data);
00589    switch (p) {
00590      case X3X3_I2C_RAW:
00591      case X3X3_I2C_8_AINC :
00592      case X3X3_I2C_16_AINC :
00593        bus=0;
00594        break;
00595      case X3X3_I2C1_RAW:
00596      case X3X3_I2C1_8_AINC :
00597      case X3X3_I2C1_16_AINC :
00598        bus=1;
00599        break;
00600      case X3X3_I2C_ENABLE:
00601      case X3X3_I2C_CTRL : 
00602        bus=-1;
00603        break;
00604   }
00605 
00606    D(printk("xi2c_open, minor=%d\n",p));
00607    if ((bus>=0) && (inuse[bus] !=0)) return -EACCES;
00608    D(printk("xi2c_open, minor=%d\n",p));
00609    inode->i_size=sizes[p];
00610    if (bus>=0) inuse[bus] =1;
00611 
00612    switch ( p ) {
00613      case X3X3_I2C_RAW:
00614      case X3X3_I2C1_RAW:
00615      case X3X3_I2C_8_AINC :
00616      case X3X3_I2C1_8_AINC :
00617        inode->i_size=128*256;
00618        burst_sizes[p]=1; 
00619        break;
00620      case X3X3_I2C_16_AINC :
00621      case X3X3_I2C1_16_AINC : 
00622        inode->i_size=256*256;
00623        burst_sizes[p]=2; 
00624        break;
00625      case X3X3_I2C_CTRL : 
00626        inode->i_size=sizeof(bitdelays);
00627        break;
00628      case X3X3_I2C_ENABLE:
00629        inode->i_size=sizeof(i2c_enable);
00630        break;
00631      default:return -EINVAL;
00632    }
00633 //   thisminor=p;
00634 //   thissize=inode->i_size;
00635 //   filp->private_data = &thisminor;
00636 //   filp->private_data=p; // just a minor number
00637    pd[0]=p; // just a minor number
00638   return 0;
00639 }
00640 
00642 //static loff_t sizes[X3X3_I2C_MAXMINOR + 1];
00643 //static loff_t inuse[X3X3_I2C_CHANNELS];
00644 
00645 static int     xi2c_release(struct inode *inode, struct file *filp){
00646    int p = MINOR(inode->i_rdev);
00647    int bus=-1;
00648    switch (p) {
00649      case X3X3_I2C_RAW:
00650      case X3X3_I2C_8_AINC :
00651      case X3X3_I2C_16_AINC :
00652        bus=0;
00653        break;
00654      case X3X3_I2C1_RAW:
00655      case X3X3_I2C1_8_AINC :
00656      case X3X3_I2C1_16_AINC :
00657        bus=1;
00658        break;
00659      case X3X3_I2C_ENABLE:
00660      case X3X3_I2C_CTRL :
00661        bus=-1;
00662        break;
00663   }
00664   D(printk("xi2c_release, minor=%d\n",p));
00665   if (bus>=0) inuse[bus]=0;
00666   else if (p==X3X3_I2C_CTRL) for (bus=0; bus < X3X3_I2C_CHANNELS; bus++) inuse[bus]=0;
00667 //  thisminor =0;
00668   return 0;
00669 }
00670 
00672 static loff_t  xi2c_lseek(struct file * file, loff_t offset, int orig) {
00673 /*
00674  *  orig 0: position from begning of eeprom
00675  *  orig 1: relative from current position
00676  *  orig 2: position from last address
00677  */
00678    int p=(int)file->private_data;
00679    int thissize=sizes[p];
00680         switch (orig) {
00681         case SEEK_SET:
00682                 file->f_pos = offset;
00683                 break;
00684         case SEEK_CUR:
00685                 file->f_pos += offset;
00686                 break;
00687         case SEEK_END:
00688 
00689 //       burst_sizes[p]=2; //!fix for PHP read (always 8192) -> 2 bytes/read
00690 
00692       if (offset<=0) {
00693         file->f_pos = thissize + offset;
00694       } else {
00695         burst_sizes[p]=offset; 
00696       }
00697       break;
00698         default:
00699                 return -EINVAL;
00700         }
00701 //   switch (((int *)file->private_data)[0]) {
00702    switch (p) {
00703      case X3X3_I2C_RAW:
00704      case X3X3_I2C1_RAW:
00705        (file->f_pos) &= ~(0x7f); // zero out 7 MSBs
00706        break;
00707      case X3X3_I2C_16_AINC :
00708      case X3X3_I2C1_16_AINC : {
00709        if ((file->f_pos) & 1) (file->f_pos)++; // increment to the next (if odd) for 16-bit accesses
00710        break;
00711      }
00712    }
00713 
00714         /* truncate position */
00715         if (file->f_pos < 0) {
00716                 file->f_pos = 0;
00717                 return (-EOVERFLOW);
00718         }
00719 
00720         if (file->f_pos > thissize) {
00721                 file->f_pos = thissize;
00722                 return (-EOVERFLOW);
00723         }
00724         return (file->f_pos);
00725 }
00726 
00728 
00729 ssize_t xi2c_read(struct file * file, char * buf, size_t count, loff_t *off) {
00730   unsigned long p;
00731   int error;
00732   p = *off;
00733   char * bbitdelays= (char*) bitdelays;
00734   int bus=0;
00735   unsigned char * i2cbuf=&i2cbuf_all[0]; // initialize to keep compiler happy
00736   unsigned char * userbuf=&i2cbuf[1];
00737   int thissize=sizes[(int)file->private_data];
00738   int slave_adr;
00739   int en_mask=0;
00740   int en_bits=0;
00741 
00742 //  switch (((int *)file->private_data)[0]) {
00743   switch ((int)file->private_data) {
00744      case X3X3_I2C_RAW:
00745      case X3X3_I2C_8_AINC :
00746      case X3X3_I2C_16_AINC :
00747        bus=0;
00748        i2cbuf = &i2cbuf_all[0];
00749        break;
00750      case X3X3_I2C1_RAW:
00751      case X3X3_I2C1_8_AINC :
00752      case X3X3_I2C1_16_AINC :
00753        bus=1;
00754        i2cbuf = &i2cbuf_all[1*I2CBUFSIZE];
00755        break;
00756 //     case X3X3_I2C_CTRL :
00757 //       i2cbuf = &i2cbuf_all[X3X3_I2C_CHANNELS*I2CBUFSIZE];
00758   }
00759   userbuf=&i2cbuf[1];
00760 
00761 //  switch (((int *)file->private_data)[0]) {
00762   slave_adr=(p >> 7) & 0xfe;
00763   switch ((int)file->private_data) {
00764      case X3X3_I2C_RAW:
00765      case X3X3_I2C1_RAW:
00766      case X3X3_I2C_8_AINC :
00767      case X3X3_I2C1_8_AINC : 
00768        if (count == 8192) count=burst_sizes[(int)file->private_data]; 
00769        break;
00770      case X3X3_I2C_16_AINC :
00771      case X3X3_I2C1_16_AINC : 
00772        p&=0xfffffffe;
00773        if (count == 8192) count=burst_sizes[(int)file->private_data]; 
00774        if (count & 1) count++;
00775        slave_adr=(p >> 8) & 0xfe;
00776        break;
00777   }
00778   D(printk("xi2c_read (bus=%d) from 0x%x, count=%d\n", bus, (int) *off, (int) count));
00780   switch ((int)file->private_data) {
00781      case X3X3_I2C_RAW:
00782      case X3X3_I2C1_RAW:
00783        en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_RAW);
00784        break;
00785      case X3X3_I2C_8_AINC :
00786      case X3X3_I2C1_8_AINC : 
00787        en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_8);
00788        break;
00789      case X3X3_I2C_16_AINC :
00790      case X3X3_I2C1_16_AINC : 
00791        en_mask=(1 << X3X3_I2C_ENABLE_RD) | (1 <<X3X3_I2C_ENABLE_16);
00792        break;
00793   }
00794   switch ((int)file->private_data) {
00795      case X3X3_I2C_RAW:
00796      case X3X3_I2C_8_AINC :
00797      case X3X3_I2C_16_AINC :
00798        en_bits=i2c_enable[ slave_adr>>1 ];
00799        break;
00800      case X3X3_I2C1_RAW:
00801      case X3X3_I2C1_8_AINC : 
00802      case X3X3_I2C1_16_AINC : 
00803        en_bits=i2c_enable[(slave_adr>>1) + 128];
00804        break;
00805   }
00806   if ((en_bits & en_mask) ^ en_mask) {
00807      printk("tried disabed xi2c_read (bus=%d, slave=0x%x)\n", bus, slave_adr);
00808      D(printk("en_bits=0x%x, en_mask=0x%x (minor=%d)\n", (int) en_bits, (int) en_mask, (int)file->private_data));
00809      return -ENXIO;
00810   }
00811 
00812   if (p >= thissize)  return -EINVAL; // bigger than
00813   if( (p + count) > thissize) { // truncate count 
00814     count = thissize - p;
00815   }
00816   if( count > (I2CBUFSIZE-1)) { // should not happen i2cbuf is larger than maximal thissize
00817     count = I2CBUFSIZE-1;
00818   }
00819   if (count==0) return 0;
00820   switch ((int)file->private_data) {
00821      case X3X3_I2C_RAW:
00822      case X3X3_I2C1_RAW:
00823        i2cbuf[0]=p & 0xff;
00824        error=i2c_readData (bus, slave_adr | 0x01, &i2cbuf[1], count, 1);  // will start with start, not restart
00825        if (error) return -EINVAL;
00826        break;
00827      case X3X3_I2C_8_AINC :
00828      case X3X3_I2C1_8_AINC : 
00829        i2cbuf[0]=p & 0xff;
00830        error=i2c_writeData(bus,  slave_adr,         &i2cbuf[0], 1, 0); // no stop
00831        if (error) return -EINVAL;
00832        error=i2c_readData (bus, slave_adr | 0x01, &i2cbuf[1], count,0);  // will start with restart, not start
00833        if (error) return -EINVAL;
00834        break;
00835      case X3X3_I2C_16_AINC :
00836      case X3X3_I2C1_16_AINC : 
00837        i2cbuf[0]=(p>>1) & 0xff;
00838        error=i2c_writeData(bus,  slave_adr,         &i2cbuf[0], 1, 0); // no stop
00839        if (error) return -EINVAL;
00840        error=i2c_readData (bus, slave_adr | 0x01, &i2cbuf[1], count,0);  // will start with restart, not start
00841        if (error) return -EINVAL;
00842        break;
00843      case X3X3_I2C_CTRL : 
00844        userbuf=&bbitdelays[*off];
00845 //       memcpy(&i2cbuf[1],&bbitdelays[*off],count);
00846        break;
00847      case X3X3_I2C_ENABLE:
00848        userbuf=&i2c_enable[*off];
00849        break;
00850      default:return -EINVAL;
00851   }
00852 
00853 //  if (copy_to_user(buf,  &i2cbuf[1], count)) return -EFAULT;
00854   if (copy_to_user(buf,  userbuf, count)) return -EFAULT;
00855 
00857   switch ((int)file->private_data) {
00858      case X3X3_I2C_RAW:
00859      case X3X3_I2C1_RAW:
00860       *off &= ~(0x7f); // zero out 7 MSBs
00861        break;
00862      default:
00863       *off+=count;
00864   }
00865   D(printk("count= 0x%x, pos= 0x%x\n", (int) count, (int)*off));
00866   return count;
00867 }
00868 
00870 
00871 static ssize_t xi2c_write(struct file * file, const char * buf, size_t count, loff_t *off) {
00872   unsigned long p;
00873   int error;
00874   p = *off;
00875   int bus=0;
00876   char * bbitdelays= (char*) bitdelays;
00877   unsigned char * i2cbuf=&i2cbuf_all[0]; // initialize to keep compiler happy
00878   unsigned char * userbuf=&i2cbuf[1];
00879   int thissize=sizes[(int)file->private_data];
00880   int slave_adr;
00881   int en_mask=0;
00882   int en_bits=0;
00883 
00884 //  switch (((int *)file->private_data)[0]) {
00885   switch ((int)file->private_data) {
00886      case X3X3_I2C_RAW:
00887      case X3X3_I2C_8_AINC :
00888      case X3X3_I2C_16_AINC :
00889        bus=0;
00890        i2cbuf = &i2cbuf_all[0];
00891        break;
00892      case X3X3_I2C1_RAW:
00893      case X3X3_I2C1_8_AINC :
00894      case X3X3_I2C1_16_AINC :
00895        bus=1;
00896        i2cbuf = &i2cbuf_all[1*I2CBUFSIZE];
00897        break;
00898 //     case X3X3_I2C_CTRL :
00899 //       i2cbuf = &i2cbuf_all[X3X3_I2C_CHANNELS*I2CBUFSIZE];
00900   }
00901   userbuf=&i2cbuf[1];
00902   slave_adr=(p >> 7) & 0xfe;
00903   switch ((int)file->private_data) {
00904      case X3X3_I2C_16_AINC :
00905      case X3X3_I2C1_16_AINC :
00906        p&=0xfffffffe;
00907        if (count & 1) count++;
00908        slave_adr=(p >> 8) & 0xfe;
00909        break;
00910   }
00911   D(printk("xi2c_write (bus=%d) to 0x%x, count=%x\n", bus, (int) *off, (int) count));
00912 
00914   switch ((int)file->private_data) {
00915      case X3X3_I2C_RAW:
00916      case X3X3_I2C1_RAW:
00917        en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_RAW);
00918        break;
00919      case X3X3_I2C_8_AINC :
00920      case X3X3_I2C1_8_AINC : 
00921        en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_8);
00922        break;
00923      case X3X3_I2C_16_AINC :
00924      case X3X3_I2C1_16_AINC : 
00925        en_mask=(1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_16);
00926        break;
00927   }
00928   switch ((int)file->private_data) {
00929      case X3X3_I2C_RAW:
00930      case X3X3_I2C_8_AINC :
00931      case X3X3_I2C_16_AINC :
00932        en_bits=i2c_enable[ slave_adr>>1 ];
00933        break;
00934      case X3X3_I2C1_RAW:
00935      case X3X3_I2C1_8_AINC : 
00936      case X3X3_I2C1_16_AINC : 
00937        en_bits=i2c_enable[(slave_adr>>1) + 128];
00938        break;
00939   }
00940   if ((en_bits & en_mask) ^ en_mask) {
00941      printk("tried disabed xi2c_write (bus=%d, slave=0x%x)\n", bus, slave_adr);
00942      D(printk("en_bits=0x%x, en_mask=0x%x (minor=%d)\n", (int) en_bits, (int) en_mask, (int)file->private_data));
00943      return -ENXIO;
00944   }
00945 
00946   if (p >= thissize)  return -EINVAL; 
00947   if( (p + count) > thissize) { // truncate count 
00948     count = thissize - p;
00949   }
00950   if( count > (I2CBUFSIZE-1)) { // should not happen i2cbuf is larger than maximal thissize
00951     count = I2CBUFSIZE-1;
00952   }
00953   if (count==0) return 0;
00955   switch ((int)file->private_data) {
00956      case X3X3_I2C_CTRL : 
00957        userbuf=&bbitdelays[p];
00958        break;
00959      case X3X3_I2C_ENABLE:
00960        userbuf=&i2c_enable[p];
00961        break;
00962   }
00963 
00964 //  if (copy_from_user( &i2cbuf[1], buf, count)) return -EFAULT;
00965   if (copy_from_user( userbuf, buf, count)) return -EFAULT;
00966   switch ((int)file->private_data) {
00967      case X3X3_I2C_RAW:
00968      case X3X3_I2C1_RAW:
00969        error=i2c_writeData(bus, slave_adr,  &i2cbuf[1],count, 1); // send stop
00970        if (error) return -EINVAL;
00971        break;
00972      case X3X3_I2C_8_AINC :
00973      case X3X3_I2C1_8_AINC :
00974        i2cbuf[0]=p & 0xff;
00975        error=i2c_writeData(bus, slave_adr,  &i2cbuf[0],count+1, 1); // send stop
00976        if (error) return -EINVAL;
00977        break;
00978      case X3X3_I2C_16_AINC :
00979      case X3X3_I2C1_16_AINC :
00980        i2cbuf[0]=(p>>1) & 0xff;
00981        error=i2c_writeData(bus, slave_adr,  &i2cbuf[0],count+1, 1); // send stop
00982        if (error) return -EINVAL;
00983        break;
00984 //     case X3X3_I2C_CTRL :
00985 //       memcpy(&bbitdelays[*off],&i2cbuf[1],count);
00986 //       break;
00987      default:return -EINVAL;
00988    }
00989 //  *off+=count;
00991   switch ((int)file->private_data) {
00992      case X3X3_I2C_RAW:
00993      case X3X3_I2C1_RAW:
00994       *off &= ~(0x7f); // zero out 7 MSBs
00995        break;
00996      default:
00997       *off+=count;
00998   }
00999   D(printk("count= 0x%x, pos= 0x%x\n", (int) count, (int)*off));
01000   return count;
01001 }
01002 
01003 
01004 static int __init xi2c_init(void) {
01005    int i,res;
01006    res = register_chrdev(X3X3_I2C, "fpga_xi2c", &xi2c_fops);
01007    if(res < 0) {
01008      printk(KERN_ERR "xi2c_init: couldn't get a major number.\n");
01009      return res;
01010    }
01011    printk(X3X3_I2C_DRIVER_NAME", %d channels\r\n",X3X3_I2C_CHANNELS);
01012 //   thisminor =0;
01013 
01014    bitdelays[0].scl_high=2;      
01015    bitdelays[0].scl_low=2;       
01016    bitdelays[0].slave2master=1;  
01017    bitdelays[0].master2slave=1;  
01018    bitdelays[0].filter_sda=0x07; 
01019    bitdelays[0].filter_scl=0x07; 
01020 // bus 1 - increased by 1 measured fro EEPROM
01021    bitdelays[1].scl_high=3;      
01022    bitdelays[1].scl_low=4;       
01023    bitdelays[1].slave2master=2;  
01024    bitdelays[1].master2slave=2;  
01025    bitdelays[1].filter_sda=0x07; 
01026    bitdelays[1].filter_scl=0x07; 
01027 
01028    for (i=0; i<X3X3_I2C_CHANNELS;i++) {
01029      inuse[i]=0;
01030    }
01031    sizes[X3X3_I2C_CTRL]=     sizeof(bitdelays); // control/reset i2c
01032    sizes[X3X3_I2C_8_AINC]=   128*256;           // 8bit  registers, autoincement while read/write
01033    sizes[X3X3_I2C_16_AINC]=  256*256;           // 16bit registers, autoincement while read/write
01034    sizes[X3X3_I2C1_8_AINC]=  128*256;           // 8bit  registers, autoincement while read/write (bus 1)
01035    sizes[X3X3_I2C1_16_AINC]= 256*256;           // 16bit registers, autoincement while read/write (bus 1)
01036    sizes[X3X3_I2C_RAW]=      128*256;           // 8bit single register, 
01037    sizes[X3X3_I2C1_RAW]=     128*256;           // 8bit single register, 
01038    sizes[X3X3_I2C_ENABLE]=   sizeof(i2c_enable); // enable particular types of accesses for I2C devices
01040    for (i=0; i<X3X3_I2C_CHANNELS*128; i++) i2c_enable[i]=0xff;
01043    i2c_enable[0x90 >> 1]= (1 << X3X3_I2C_ENABLE_RD) | ( 1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_16); 
01044    i2c_enable[0xba >> 1]= (1 << X3X3_I2C_ENABLE_RD) | ( 1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_16); 
01045    i2c_enable[0x20 >> 1]= (1 << X3X3_I2C_ENABLE_RD) | ( 1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_16); 
01046 
01047    i2c_enable[128+(0x90 >> 1)]= (1 << X3X3_I2C_ENABLE_RD) | ( 1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_8); 
01048    i2c_enable[128+(0xa2 >> 1)]= (1 << X3X3_I2C_ENABLE_RD) | ( 1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_8); 
01049    i2c_enable[128+(0xa0 >> 1)]= (1 << X3X3_I2C_ENABLE_RD) | ( 0 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_8); 
01050    i2c_enable[128+(0x40 >> 1)]= (1 << X3X3_I2C_ENABLE_RD) | ( 1 << X3X3_I2C_ENABLE_WR) | (1 <<X3X3_I2C_ENABLE_RAW); 
01051 
01052 //#define X3X3_I2C_RAW        5  // 8bit  registers, no address byte (just slave, then read/write byte(s)
01053 //#define X3X3_I2C1_RAW       6  // 8bit  registers, no address byte (just slave, then read/write byte(s)
01054 //#define X3X3_I2C_ENABLE     7  // enable(/protect) different I2C devices for different types of I2C accesses
01055 //static unsigned char i2c_enable[X3X3_I2C_CHANNELS*128]; //128 devices in a bus
01056 //#define X3X3_I2C_ENABLE_RD   0 // bit 0 - enable i2c read
01057 //#define X3X3_I2C_ENABLE_WR   1 // bit 1 - enable i2c write
01058 //#define X3X3_I2C_ENABLE_RAW  2 // bit 2 - enable i2c raw (no address byte)
01059 //#define X3X3_I2C_ENABLE_8    3 // bit 3 - enable i2c 8-bit registers access
01060 //#define X3X3_I2C_ENABLE_16   4 // bit 4 - enable i2c 16-bit registers access
01061 
01062    return 0;
01063 }
01064 
01065 /* this makes sure that xi2c_init is called during boot */
01066 
01067 module_init(xi2c_init);
01068 MODULE_LICENSE("GPL");
01069 MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
01070 MODULE_DESCRIPTION(X3X3_I2C_DRIVER_NAME);

Generated on Thu Aug 7 16:19:00 2008 for elphel by  doxygen 1.5.1