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