Hi

On Sa, Jan 17, 2004 at 12:56:41 +1100, Benjamin Herrenschmidt wrote:
> On Sat, 2004-01-17 at 00:22, Alexander Clausen wrote:
> > On Fr, Jan 16, 2004 at 05:39:48 +1100, Benjamin Herrenschmidt wrote:
> > > 
> > > It seem to be fairly easy to drive over i2c, somebody is already hacking
> > > something afaik. 
> > >
> > 
> > Yes, that somebody is me ;)
> > I've got the i2c read/write parts ready, it's only lacking automatic
> > detection of the i2c bus number (and eventually address?), I don't have
> > an idea how to do that exactly...
> 
> sysfs ?
> 
> Ben.
> 

Attached is a patch to lmu.c to do automatic detection on Linux 2.6 via
sysfs. Please report if it works.

Alex
--- lmu.c.old   2004-01-18 16:38:35.000000000 +0100
+++ lmu.c               2004-01-21 17:17:14.358397224 +0100
@@ -37,45 +37,87 @@
 
 /* #define DEBUG */
 
-#define ADDR 0x42
-
 int
-open_bus ( ) {
-       char filename[20], buf[4];
-       int num = 0, file;
+probe_adapter (int *lmu_addr, int *device_num) {
+       int file;
+       int bytes;
+       char adapter[1024];
+       char filename[100];
+       __u32 raw_reg;
+       int lmu_bus;
+       int i;
+       int bus_num;
+       
+       file = open ( "/proc/device-tree/uni-n/i2c/lmu-controller/reg", 
O_RDONLY );
+       if ( file == -1 ) {
+               perror ("open failed");
+               printf ("no lmu device found\n");
+               return -1;
+       }
+
+       bytes = read ( file, &raw_reg, 4 );
+       if ( bytes == -1 ) {
+               perror ("read failed");
+               printf ("no lmu device found\n");
+               close ( file );
+               return -1;
+       }
 
-       /* try eacch bus */
-       while ( num <= 16 ) {
-               snprintf( filename, 19, "/dev/i2c-%d", num );
+       close ( file );
+       
+       lmu_bus = ( raw_reg & 0x000000001 );
+       *lmu_addr = ( raw_reg & 0xFE ) >> 1;
+
+       for (i = 0; i <= 16; i++) {
+               sprintf( filename, "/sys/class/i2c-adapter/i2c-%d/device/name", 
i );
                
-               if ( (file = open (filename, O_RDWR) ) < 0 ) {
-                       if ( errno == ENODEV ) {
-                               close ( file );
-                               return -1; /* last bus */
-                       } else if ( errno == EACCES ) {
-                               return -2; /* not root? */
-                       } else {
-                               num++; /* couldn't open file, try next bus */
-                               close ( file );
-                               continue;
-                       }
+               file = open( filename, O_RDONLY );
+               if ( file < 0 ) {
+                       if (errno == ENOENT)
+                               break;
                }
 
-               if ( ioctl ( file, I2C_SLAVE, ADDR) < 0 ) {
-                       num++; /* ioctl failed, try next bus */
+               bytes = read ( file, &adapter, 1023 );
+               adapter[bytes] = '\0';
+               
+               if(bytes <= 0) {
+                       perror("read() failed");
                        close ( file );
                        continue;
                }
-       
                
-               if ( read ( file, buf, 4 ) == 4 ) {
-                       printf( "bus found: %s\n", filename );
-                       break; /* bus found */
-               } {
-                       close ( file );
+               if ( sscanf ( adapter, "uni-n %d", &bus_num ) == 1 ) {
+                       if ( bus_num == lmu_bus ) {
+                               printf ( "lmu device found: /dev/i2c-%d\n", i );
+                               *device_num = i;
+                               close ( file );
+                               return 1;
+                       }
                }
                
-               num++;
+               close ( file );
+       }
+       
+       return 0;
+}
+
+int
+open_bus ( ) {
+       char filename[20];
+       int num, addr, file, ret, err;
+
+       ret = probe_adapter (&addr, &num);
+       
+       snprintf( filename, 19, "/dev/i2c-%d", num );
+       
+       if ( (file = open (filename, O_RDWR) ) < 0 ) {
+               return errno;
+       }
+
+       if ( ioctl ( file, I2C_SLAVE, addr) < 0 ) {
+               err = errno;
+               close ( file );
+               return err;
        }
 
        return ( file != -1 ) ? file : -1;
--- lmu.h.old   2004-01-18 16:32:36.000000000 +0100
+++ lmu.h               2004-01-19 15:12:34.000000000 +0100
@@ -24,4 +24,6 @@
 extern int get_env_light_level ( int dev, int *left, int *right );
 
 
+extern int probe_adapter ( int *addr, int *adapter );
+
 #endif /* __LMU_H__ */

Reply via email to