Gaudenz Steinlin <[EMAIL PROTECTED]> wrote: Hi,
> On my powerbook 5,8 pommed does not work at all. It correctly detects > the powerbook model, but doing an ioctl on /dev/i2c-7 (probably in > pmac/kbd_backlight.c) fails. The keyboard and lcd backlight keys do not > work, but pommed keeps running. Below is the output of pommed -d on > startup. Could you please try out the attached patch, on top of the current SVN ? It'll enumerate the i2c adapters to find the one we should use. Also, please check that you have i2c-dev loaded. In case it doesn't work, please send me the content of /sys/class/i2c-dev/*/name. Thanks, JB. -- Julien BLACHE - Debian & GNU/Linux Developer - <[EMAIL PROTECTED]> Public key available on <http://www.jblache.org> - KeyID: F5D6 5169 GPG Fingerprint : 935A 79F1 C8B3 3521 FD62 7CC7 CD61 4FD7 F5D6 5169
Index: pmac/kbd_backlight.c =================================================================== --- pmac/kbd_backlight.c (revision 318) +++ pmac/kbd_backlight.c (working copy) @@ -45,15 +45,18 @@ #include "../dbus.h" -#define I2C_DEV "/dev/i2c-7" -#define I2C_SLAVE 0x0703 +/* I2C ioctl */ +#define I2C_SLAVE 0x0703 +#define SYSFS_I2C_BASE "/sys/class/i2c-dev" +#define I2C_ADAPTER_NAME "uni-n 0" + struct _kbd_bck_info kbd_bck_info; -static int lmuaddr; /* i2c bus address */ -static char *i2cdev; /* i2c bus device */ +static unsigned int lmuaddr; /* i2c bus address */ +static char i2cdev[16]; /* i2c bus device */ int @@ -107,10 +110,10 @@ if (lmuaddr == 0) return; - fd = open (i2cdev, O_RDWR); + fd = open(i2cdev, O_RDWR); if (fd < 0) { - logmsg(LOG_ERR, "Could not open %s: %s\n", I2C_DEV, strerror(errno)); + logmsg(LOG_ERR, "Could not open %s: %s\n", i2cdev, strerror(errno)); return; } @@ -222,6 +225,9 @@ #include "../kbd_auto.c" +static int +kbd_probe_lmu(void); + void kbd_backlight_init(void) { @@ -238,15 +244,11 @@ kbd_bck_info.auto_on = 0; - lmuaddr = kbd_get_lmuaddr(); - i2cdev = "/dev/i2c-7"; + ret = kbd_probe_lmu(); - ret = kbd_probe_lmu(lmuaddr, i2cdev); - if ((!has_kbd_backlight()) || (ret < 0)) { lmuaddr = 0; - i2cdev = NULL; kbd_bck_info.r_sens = 0; kbd_bck_info.l_sens = 0; @@ -284,12 +286,75 @@ kbd_cfg.step = KBD_BACKLIGHT_MAX / 2; } + +static int +kbd_get_i2cdev(void) +{ + char buf[PATH_MAX]; + int i2c_bus; + int ret; + + FILE *fp; + + /* All the 256 minors (major 89) are reserved for i2c adapters */ + for (i2c_bus = 0; i2c_bus < 256; i2c_bus++) + { + ret = snprintf(buf, PATH_MAX - 1, "%s/i2c-%d/name", SYSFS_I2C_BASE, i2c_bus); + if ((ret < 0) || (ret >= (PATH_MAX - 1))) + { + logmsg(LOG_WARNING, "Error: i2c device probe: device path too long"); + + i2c_bus = 256; + break; + } + + fp = fopen(buf, "r"); + if ((fp == NULL) && (errno != ENOENT)) + { + logmsg(LOG_ERR, "Error: i2c device probe: cannot open %s: %s", buf, strerror(errno)); + continue; + } + + ret = fread(buf, 1, PATH_MAX - 1, fp); + fclose(fp); + + if (ret < 1) + continue; + + buf[ret - 1] = '\0'; + + logdebug("Found i2c adapter [%s]\n", buf); + + if (ret < strlen(I2C_ADAPTER_NAME)) + continue; + + if (strncmp(buf, I2C_ADAPTER_NAME, strlen(I2C_ADAPTER_NAME)) == 0) + { + logmsg(LOG_INFO, "Found %s i2c adapter at i2c-%d", I2C_ADAPTER_NAME, i2c_bus); + break; + } + } + + if (i2c_bus > 255) + return -1; + + ret = snprintf(i2cdev, sizeof(i2cdev) - 1, "/dev/i2c-%d", i2c_bus); + if ((ret < 0) || (ret >= (sizeof(i2cdev) - 1))) + { + logmsg(LOG_WARNING, "Error: i2c device path too long"); + + return -1; + } + + return 0; +} + int kbd_get_lmuaddr(void) { struct device_node *node; - int plen, lmuaddr = -1; - long *reg = NULL; + int plen; + unsigned long *reg = NULL; of_init(); @@ -298,72 +363,51 @@ return -1; reg = of_find_property(node, "reg", &plen); - lmuaddr = (int) (*reg >> 1); + lmuaddr = (unsigned int) (*reg >> 1); free(reg); of_free_node(node); - return lmuaddr; + logdebug("Found LMU controller at address 0x%x\n", lmuaddr); + + return 0; } -#if 0 /* Old code */ -int -kbd_get_lmuaddr2(void) +static int +kbd_probe_lmu(void) { int fd; int ret; - long reg; + char buffer[4]; - fd = open(LMU_REG, O_RDONLY); - if (fd < 0) + ret = kbd_get_lmuaddr(); + if (ret < 0) { - logmsg(LOG_ERR, "Could not open lmu %s: %s\n", LMU_REG, strerror(errno)); + lmuaddr = 0; - fd = open(LMU_REG_55, O_RDONLY); - if (fd < 0) - { - logmsg(LOG_ERR, "Could not open lmu %s: %s\n", LMU_REG_55, strerror(errno)); - - return -1; - } + return -1; } - ret = read(fd, ®, sizeof(long)); - close(fd); + ret = kbd_get_i2cdev(); + if (ret < 0) + { + lmuaddr = 0; - if (ret == sizeof(long)) - return (int)(reg >> 1); + return -1; + } - return 0; -} -#endif /* 0 */ - - -char * -kbd_get_i2cdev(int addr) -{ - return I2C_DEV; -} - -int -kbd_probe_lmu(int addr, char *dev) -{ - int fd; - int ret; - char buffer[4]; - - fd = open(dev, O_RDWR); + fd = open(i2cdev, O_RDWR); if (fd < 0) { - logmsg(LOG_WARNING, "Could not open device %s: %s\n", dev, strerror(errno)); + logmsg(LOG_WARNING, "Could not open device %s: %s\n", i2cdev, strerror(errno)); return -1; } - ret = ioctl(fd, I2C_SLAVE, addr); + ret = ioctl(fd, I2C_SLAVE, lmuaddr); if (ret < 0) { - logmsg(LOG_ERR, "ioctl failed on %s: %s\n", dev, strerror(errno)); + logmsg(LOG_ERR, "ioctl failed on %s: %s\n", i2cdev, strerror(errno)); close(fd); return -1; @@ -372,14 +416,14 @@ ret = read(fd, buffer, 4); if (ret != 4) { - logmsg(LOG_WARNING, "Probing failed on %s: %s\n", dev, strerror(errno)); + logmsg(LOG_WARNING, "Probing failed on %s: %s\n", i2cdev, strerror(errno)); close(fd); return -1; } close(fd); - logdebug("Probing successful on %s\n", dev); + logdebug("Probing successful on %s\n", i2cdev); return 0; } Index: kbd_backlight.h =================================================================== --- kbd_backlight.h (revision 318) +++ kbd_backlight.h (working copy) @@ -5,19 +5,9 @@ #ifndef __KBD_BACKLIGHT_H__ #define __KBD_BACKLIGHT_H__ -#ifdef __powerpc__ -int -kbd_get_lmuaddr(void); - -char* -kbd_get_i2cdev(int addr); - -int -kbd_probe_lmu(int addr, char* i2cdev); - -#else +#ifndef __powerpc__ #define KBD_BACKLIGHT "/sys/class/leds/smc:kbd_backlight/brightness" -#endif /* __powerpc__ */ +#endif /* !__powerpc__ */ #define KBD_BACKLIGHT_OFF 0