00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
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
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"
00064
00065 #include "x3x3.h"
00066 #include "cc3x3.h"
00067
00068
00069 #include "cci2c.h"
00070
00071 #define D(x)
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
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
00096
00097
00098
00099
00100
00101
00102 #define i2c_delay(usecs) udelay(usecs)
00103 #define I2C_DELAY_SCALE 1
00104
00105
00106
00107
00108 extern volatile unsigned long ccam_cr_shadow;
00109
00110
00111
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 static struct i2c_timing_t bitdelays[X3X3_I2C_CHANNELS];
00125
00126
00127
00128
00129
00130
00131
00132
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);
00144 int i2c_getbit (int n);
00145 int i2c_getscl(int n);
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);
00153
00154 int i2c_delays (unsigned long delays) {
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
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
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
00192
00193
00194
00195
00196
00197
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
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;
00232 else il_ccamCRAndOr(~X313_BITS(SCL0,1),X313_BITS(SCL0_EN,1));
00233 }
00234
00235 void i2c_scl_1(int n) {
00236 if (n) port_csp0_addr[X313_WA_IOPINS]=SCL1_1;
00237 else il_ccamCROr (X313_BITS(SCL0,1) | X313_BITS(SCL0_EN,1));
00238 }
00239
00240
00241
00242
00243 void i2c_sda_weak (int n, int d) {
00244 if (n) {
00245 if (d) port_csp0_addr[X313_WA_IOPINS]=SDA1_OFF;
00246 else port_csp0_addr[X313_WA_IOPINS]=SDA1_0;
00247 } else {
00248 if (d) il_ccamCRAndOr(~X313_BITS(SDA0_EN,1), X313_BITS(SDA0,1));
00249 else il_ccamCRAndOr(~X313_BITS(SDA0,1), X313_BITS(SDA0_EN,1));
00250 }
00251 }
00252
00253 void i2c_sda_strong (int n, int d) {
00254 if (n) {
00255 if (d) port_csp0_addr[X313_WA_IOPINS]=SDA1_1;
00256 else port_csp0_addr[X313_WA_IOPINS]=SDA1_0;
00257 } else {
00258 if (d) il_ccamCROr ( X313_BITS(SDA0,1) | X313_BITS(SDA0_EN,1));
00259 else il_ccamCRAndOr(~X313_BITS(SDA0,1), X313_BITS(SDA0_EN,1));
00260 }
00261 }
00262
00263
00265 int i2c_start(int n) {
00266 int i;
00267 unsigned long flags;
00268 local_irq_save(flags);
00269
00270 D(printk("i2c_start: bus=%x\r\n", n));
00271
00272
00273 i2c_scl_1(n);
00274 i2c_sda_weak (n, 1);
00275 x3x3_DELAY(bitdelays[n].scl_high*I2C_DELAY_SCALE);
00276
00277 if (!i2c_getbit(n)) {
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;
00288 }
00289 }
00290 i2c_sda_weak (n, 0);
00291 x3x3_DELAY(bitdelays[n].scl_low*I2C_DELAY_SCALE);
00292 i2c_scl_0(n);
00293 local_irq_restore(flags);
00294 return 0;
00295 }
00296
00297
00298 int i2c_stop(int n) {
00299 unsigned long flags;
00300 local_irq_save(flags);
00301
00302 D(printk("i2c_stop: bus=%x\r\n", n));
00303
00304 i2c_sda_weak (n, 0);
00305 x3x3_DELAY(bitdelays[n].slave2master*I2C_DELAY_SCALE);
00306 x3x3_DELAY(bitdelays[n].scl_low*I2C_DELAY_SCALE);
00307 i2c_scl_1(n);
00308 x3x3_DELAY(bitdelays[n].scl_high*I2C_DELAY_SCALE);
00309 i2c_sda_strong (n, 1);
00310 x3x3_DELAY(bitdelays[n].scl_high*I2C_DELAY_SCALE);
00311 i2c_sda_weak (n, 1);
00312 local_irq_restore(flags);
00313 return 0;
00314 }
00315
00316
00317 int i2c_restart(int n) {
00318 unsigned long flags;
00319 local_irq_save(flags);
00320
00321 D(printk("i2c_restart: bus=%x\r\n", n));
00322
00323 i2c_sda_weak (n, 1);
00324 x3x3_DELAY(bitdelays[n].slave2master*I2C_DELAY_SCALE);
00325 i2c_sda_strong (n, 1);
00326 x3x3_DELAY(bitdelays[n].scl_low*I2C_DELAY_SCALE);
00327 i2c_scl_1(n);
00328 i2c_sda_weak (n, 1);
00329 x3x3_DELAY(bitdelays[n].scl_high*I2C_DELAY_SCALE);
00330 i2c_sda_weak (n, 0);
00331 x3x3_DELAY(bitdelays[n].scl_low*I2C_DELAY_SCALE);
00332 i2c_scl_0(n);
00333 local_irq_restore(flags);
00334 return 0;
00335 }
00336
00337
00338 int i2c_outbyte(int n, unsigned char d) {
00339 int i;
00340 unsigned char x=d;
00341 unsigned long flags;
00342 local_irq_save(flags);
00343
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);
00347 for (i = 0; i < 8; i++) {
00348 i2c_sda_strong (n,(x & 0x80));
00349 x3x3_DELAY(bitdelays[n].scl_low * I2C_DELAY_SCALE);
00350 i2c_scl_1(n);
00351 i2c_sda_weak (n,(x & 0x80));
00352 x3x3_DELAY(bitdelays[n].scl_high * I2C_DELAY_SCALE);
00353 i2c_scl_0(n);
00354 x <<= 1;
00355 }
00356
00357 i2c_sda_weak (n, 1);
00358 x3x3_DELAY(bitdelays[n].master2slave * I2C_DELAY_SCALE);
00359 x3x3_DELAY(bitdelays[n].scl_low * I2C_DELAY_SCALE);
00360 i2c_scl_1(n);
00361 x3x3_DELAY(bitdelays[n].scl_high * I2C_DELAY_SCALE);
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
00371
00372 unsigned char i2c_inbyte(int n, int more) {
00373 unsigned char aBitByte = 0;
00374 int i;
00375 unsigned long flags;
00376 local_irq_save(flags);
00377
00378 D(printk("i2c_inbyte: bus=%x\r\n", n));
00379
00380 i2c_sda_weak (n, 1);
00381 x3x3_DELAY(bitdelays[n].master2slave * I2C_DELAY_SCALE);
00382
00383 for (i = 0; i < 8; i++) {
00384 x3x3_DELAY(bitdelays[n].scl_low * I2C_DELAY_SCALE);
00385 i2c_scl_1(n);
00386 x3x3_DELAY(bitdelays[n].scl_high * I2C_DELAY_SCALE);
00387 aBitByte = (aBitByte << 1) | i2c_getbit(n);
00388 i2c_scl_0(n);
00389 }
00390
00391 i2c_sda_weak (n, more ? 0 : 1);
00392 x3x3_DELAY(bitdelays[n].slave2master * I2C_DELAY_SCALE);
00393 i2c_sda_strong (n, more ? 0 : 1);
00394 x3x3_DELAY(bitdelays[n].scl_low * I2C_DELAY_SCALE);
00395 i2c_scl_1(n);
00396 i2c_sda_weak (n, more ? 0 : 1);
00397 x3x3_DELAY(bitdelays[n].scl_high * I2C_DELAY_SCALE);
00398 i2c_scl_0(n);
00399 D(printk("i2c_inbyte: data=%x\r\n", aBitByte));
00400 local_irq_restore(flags);
00401 return aBitByte;
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
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
00419 if ((error=i2c_start(n))) return error;
00420
00421 if(!i2c_outbyte(n,theSlave)) {
00422 i2c_stop(n);
00423 return ERR_I2C_BSY;
00424 }
00425
00426 for (i=0;i<size;i++) {
00427 if(!i2c_outbyte(n,theData[i])) {
00428 i2c_stop(n);
00429 return ERR_I2C_NACK;
00430 }
00431 }
00432 if (stop) i2c_stop(n);
00433 return 0;
00434 }
00435
00436
00437
00438
00439
00440
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
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;
00457 }
00458 for (i=0;i<size;i++) {
00459 theData[i]=i2c_inbyte(n, (i<(size-1)));
00460 }
00461 i2c_stop(n);
00462 return 0;
00463 }
00464
00465 extern int _353_io_board_present;
00466
00467
00468
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
00476 if(_IOC_TYPE(cmd) != CMOSCAM_IOCTYPE) {
00477 return -EINVAL;
00478 }
00479
00480
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
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);
00498 case I2C_READREG:
00499
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);
00506 if (error) return -error;
00507 error=i2c_readData(I2C_ARGBUS(arg), I2C_ARGSLAVE(arg) | 0x01, &data[1], 1, 0);
00508 if (error) return -error;
00509 D(printk("returned %d\n", data[1]));
00510 return data[1];
00511
00512 case I2C_16_WRITEREG:
00513
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);
00522 case I2C_16_READREG:
00523
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);
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
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 #define X3X3_I2C_DRIVER_NAME "Elphel (R) model 353 i2c character device driver"
00553
00554
00555
00556 #define I2CBUFSIZE 8196
00557
00558 static unsigned char i2c_enable[X3X3_I2C_CHANNELS*128];
00559
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
00566
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
00634
00635
00636
00637 pd[0]=p;
00638 return 0;
00639 }
00640
00642
00643
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
00668 return 0;
00669 }
00670
00672 static loff_t xi2c_lseek(struct file * file, loff_t offset, int orig) {
00673
00674
00675
00676
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
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
00702 switch (p) {
00703 case X3X3_I2C_RAW:
00704 case X3X3_I2C1_RAW:
00705 (file->f_pos) &= ~(0x7f);
00706 break;
00707 case X3X3_I2C_16_AINC :
00708 case X3X3_I2C1_16_AINC : {
00709 if ((file->f_pos) & 1) (file->f_pos)++;
00710 break;
00711 }
00712 }
00713
00714
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];
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
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
00757
00758 }
00759 userbuf=&i2cbuf[1];
00760
00761
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;
00813 if( (p + count) > thissize) {
00814 count = thissize - p;
00815 }
00816 if( count > (I2CBUFSIZE-1)) {
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);
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);
00831 if (error) return -EINVAL;
00832 error=i2c_readData (bus, slave_adr | 0x01, &i2cbuf[1], count,0);
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);
00839 if (error) return -EINVAL;
00840 error=i2c_readData (bus, slave_adr | 0x01, &i2cbuf[1], count,0);
00841 if (error) return -EINVAL;
00842 break;
00843 case X3X3_I2C_CTRL :
00844 userbuf=&bbitdelays[*off];
00845
00846 break;
00847 case X3X3_I2C_ENABLE:
00848 userbuf=&i2c_enable[*off];
00849 break;
00850 default:return -EINVAL;
00851 }
00852
00853
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);
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];
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
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
00899
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) {
00948 count = thissize - p;
00949 }
00950 if( count > (I2CBUFSIZE-1)) {
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
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);
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);
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);
00982 if (error) return -EINVAL;
00983 break;
00984
00985
00986
00987 default:return -EINVAL;
00988 }
00989
00991 switch ((int)file->private_data) {
00992 case X3X3_I2C_RAW:
00993 case X3X3_I2C1_RAW:
00994 *off &= ~(0x7f);
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
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
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);
01032 sizes[X3X3_I2C_8_AINC]= 128*256;
01033 sizes[X3X3_I2C_16_AINC]= 256*256;
01034 sizes[X3X3_I2C1_8_AINC]= 128*256;
01035 sizes[X3X3_I2C1_16_AINC]= 256*256;
01036 sizes[X3X3_I2C_RAW]= 128*256;
01037 sizes[X3X3_I2C1_RAW]= 128*256;
01038 sizes[X3X3_I2C_ENABLE]= sizeof(i2c_enable);
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
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062 return 0;
01063 }
01064
01065
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);