Re: Problem with backlit keyboard on aluminium powerbook
Am Donnerstag, 23. September 2004 10:17 schrieb Pierre Habouzit:
> there is, I pointed it to the pbbutonsd author. the fact is that it
> searches for an /dev/i2c-??? device, starting from 0, to 255 until it
> finds one that responds '4' when you open it.
>
> unfortunateley, it actually take i2c-0 ... whereas on my pb, it's i2c-4
> that is the right one... you can patch in the pbbutons src the file
> src/module_pmac.c in the function called (IIRC) find_lmu_bus there is a
> loop that starts with 0 and searches the right i2-c make it start from
> 4 and all will work (at least it does here)
Please try this patch for pbbuttonsd 0.6.5. It should solve the LMU problem
for users of /dev/i2c-4 as well as for users of /dev/i2c-0. Pbbuttonsd now
checks /dev/i2c-4 first. I need to know if it works also on older Powerbooks
which uses /dev/i2c-0. Feedback is very welcome.
As a side effect this patch fix the cover open/close bug which blocked the
Brightness control keys ;-).
Best Regards
Matthias
diff -Naur pbbuttonsd-0.6.5/src/input_manager.c pbbuttonsd-0.6.5-fixed/src/input_manager.c
--- pbbuttonsd-0.6.5/src/input_manager.c Fri Jul 16 18:52:02 2004
+++ pbbuttonsd-0.6.5-fixed/src/input_manager.c Fri Sep 24 17:25:51 2004
@@ -204,7 +204,7 @@
sprintf(filename, "/dev/input/event%d", n);
if ((fd = open(filename, O_RDONLY)) >= 0) {
ioctl(fd, EVIOCGBIT(0, EV_MAX), bit);
- if (test_bit(EV_KEY, bit) && test_bit(EV_REP, bit)) {
+ if (test_bit(EV_KEY, bit) && test_bit(EV_REP, bit)) {
ioctl(fd, EVIOCGID, id);
if (id[ID_PRODUCT] != base->evdevs[m].product ||
id[ID_VENDOR] != base->evdevs[m].vendor) {
diff -Naur pbbuttonsd-0.6.5/src/module_pmac.c pbbuttonsd-0.6.5-fixed/src/module_pmac.c
--- pbbuttonsd-0.6.5/src/module_pmac.c Wed Sep 8 22:01:41 2004
+++ pbbuttonsd-0.6.5-fixed/src/module_pmac.c Fri Sep 24 16:40:41 2004
@@ -50,6 +50,7 @@
int version; /* PMU version */
char *identity; /* Identity string of this laptop */
struct modflags_pmac flags;
+ int flagschanged; /* PMU flags that have changed recently */
int oharevolbutton; /* level of volume button on OHARE PBs scaled to 0..100 */
int oharebrightbutton; /* level of brightness button on OHARE PBs scaled to 0..15 */
@@ -144,8 +145,10 @@
base->identity = identitystring;
ioctl(base->fd_pmu, PMU_IOC_CAN_SLEEP, &val);
base->flags.sleepsupported = val == 1 ? 1 : 0; /* check if sleep is supported on this system */
- val = pmac_update_flags ();
- pmac_update_batteryinfo (val);
+
+ pmac_update_flags ();
+ pmac_update_batteryinfo ();
+ base->flagschanged = 0;
/* Every frame buffer driver could register a backlight controller,
* but only the right one is accepted. Verification is done by checking
@@ -228,7 +231,6 @@
pmac_secure (struct tagitem *taglist)
{
struct moddata_pmac *base = &modbase_pmac;
- int cf;
if (base->flags.set_tpmode == 1) {
base->flags.set_tpmode = 0;
@@ -243,12 +245,12 @@
process_queue_single (CONFIGQUEUE, TAG_PREPAREFORSLEEP, 0);
#ifdef WITH_PMUD
activate_sleepmode ();
- cf = pmac_update_flags ();
+ base->flagschanged = pmac_update_flags ();
#else
do {
activate_sleepmode ();
- cf = pmac_update_flags ();
- } while (cf != -1 && base->flags.coveropen == 0);
+ base->flagschanged = pmac_update_flags ();
+ } while (base->flags.coveropen == 0);
#endif
base->timeleft = 7200; /* reset time value so that the */
/* filter approximate the real value from top. Otherwise */
@@ -257,7 +259,7 @@
/* thresholds quick enough. This problem occours only */
/* after wakeup on battery after the battery had been */
/* recharged during sleep. */
- pmac_update_batteryinfo (cf);
+ pmac_update_batteryinfo ();
process_queue_single (CONFIGQUEUE, TAG_WAKEUPFROMSLEEP, 0);
base->batlog_cycle = batlog_setup();
}
@@ -441,15 +443,16 @@
{
struct moddata_pmac *base = &modbase_pmac;
struct tagitem args[6];
- int val, cf;
+ int val;
taglist_init (args);
val = base->timeleft;
- cf = pmac_update_flags (); /* ac power and cover status */
- pmac_update_batteryinfo (cf);
+ if (base->flagschanged == 0) /* check if anybody else has already read the flags */
+ base->flagschanged = pmac_update_flags (); /* if not, get ac power and cover status */
+ pmac_update_batteryinfo ();
- if (cf & PMU_ENV_AC_POWER) {
+ if (base->flagschanged & PMU_ENV_AC_POWER) {
taglist_add (args, TAG_POWERCHANGED, base->flags.ac_power);
if (!base->flags.ac_power) /* running on Battery */
base->batlog_cycle++; /* then increase cycle */
@@ -460,7 +463,7 @@
}
#ifndef WITH_PMUD
- if ((cf != -1) && (cf & PMU_ENV_LID_CLOSED))
+ if (base->flagschanged & PMU_ENV_LID_CLOSED)
taglist_add (args, TAG_COVERSTATUS, base->flags.coveropen);
#endif
if (base->version == OHARE_PMU) { /* PowerBook 3400, etc */
@@ -484,6 +487,7 @@
if (args[0].tag != TAG_END)
process_queue (CONFIGQUEUE, args); /* distribute changes to other modules */
+ base->flagschanged = 0;
}
@@ -544,7 +548,7 @@
* ac_power, bat_present and charging.
*/
void
-pmac_update_batteryinfo (int cf)
+pmac_update_batteryinfo ()
{
struct moddata_pmac *base = &modbase_pmac;
FILE *fd;
@@ -552,26 +556,6 @@
int val, n, syscurrent, time_rem = 0;
int charge, chargemax, current, voltage, timeleft[MAX_BATTERIES];
- /* use /proc/pmu/info as fallback, if PMU_GET_COVER did't work
- * As I know this has not happend yet and it is doubtable that
- * /proc/pmu/info will work correctly in this case. So this
- * routine may be removed in future versions.
- */
- if (cf == -1) {
- print_error(_("WARNING: Couldn't get AC plug status from hardware, use /proc/pmu/info as fallback.\n"));
- print_error(_(" Please send a message to the author if this ever happens.\n"));
- if ((fd = fopen ("/proc/pmu/info","r"))) {
- while (fgets (buffer, sizeof (buffer), fd))
- if ((token = strtok (buffer,":\n"))) {
- if (!strncmp ("AC Power", token, 8))
- base->flags.ac_power = atoi (strtok(0,":\n"));
- else
- strtok (0,":\n");
- }
- fclose(fd);
- }
- }
-
syscurrent = 0;
for (n=0; n < MAX_BATTERIES; n++) {
charge = chargemax = current = voltage = timeleft[n] = 0;
@@ -637,6 +621,38 @@
}
}
+/* use /proc/pmu/info as fallback, if PMU_GET_COVER did't work
+ * As I know this has not happend yet and it is doubtable that
+ * /proc/pmu/info will work correctly in this case. So this
+ * routine may be removed in future versions.
+ */
+int
+pmac_get_procac ()
+{
+ FILE *fd;
+ char buffer[100], *token;
+ int ac = 0; /* return battery if anything fails */
+
+ print_error(_("WARNING: Couldn't get AC plug status from hardware, use /proc/pmu/info as fallback.\n"));
+ print_error(_(" Please send a message to the author if this ever happens.\n"));
+ if ((fd = fopen ("/proc/pmu/info","r"))) {
+ while (fgets (buffer, sizeof (buffer), fd))
+ if ((token = strtok (buffer,":\n"))) {
+ if (!strncmp ("AC Power", token, 8))
+ ac = atoi (strtok(0,":\n"));
+ else
+ strtok (0,":\n");
+ }
+ fclose(fd);
+ }
+ return ac;
+}
+
+/* This funtion gets some important flags from the PMU driver. If the
+ * driver doesn't support the ioctl or reports an error, power source
+ * will be read from /proc/pmu/info as fallback, so that power source
+ * should always be set correctly.
+ */
int
pmac_update_flags()
{
@@ -654,7 +670,8 @@
envnew = base->flags.ac_power ? PMU_ENV_AC_POWER : 0;
envnew |= base->flags.coveropen ? PMU_ENV_LID_CLOSED : 0;
} else
- return -1;
+ base->flags.ac_power = pmac_get_procac();
+
return (envold ^ envnew);
}
@@ -968,7 +985,11 @@
/* This function tries to find the I2C device that controls the keyboard
* illumination and the ambient light sensor used in alluminum PowerBooks
- * It returns the device number on success, otherwise a negative error code
+ * It returns the device number on success, otherwise a negative error code.
+ * The loop starts with device 4 because that's the correct device on
+ * 17" alluminum PowerBooks. Device 0 could be errornous detected because
+ * the function uses only circumstantial evidence to detect the correct
+ * device.
*/
int
lmu_find_bus ()
@@ -979,8 +1000,8 @@
char i2cdevice[20], buf[4];
int n, fd, rc = -E_NOCHAR;
- for(n=0; n < 256; n++) {
- snprintf(i2cdevice, 19, "/dev/i2c-%d", n );
+ for(n=4; n < 260; n++) {
+ snprintf(i2cdevice, 19, "/dev/i2c-%d", (n & 255) );
if ((fd = open (i2cdevice, O_RDWR)) >= 0 ) {
if (ioctl (fd, I2C_SLAVE, LMU_ADDR) >= 0 ) {
if (read (fd, buf, 4) == 4 ) {
@@ -988,8 +1009,8 @@
rc = n;
break;
}
- } else
- close (fd);
+ }
+ close (fd);
} else if (errno == ENODEV) {
rc = -E_NOCHAR;
break;
diff -Naur pbbuttonsd-0.6.5/src/module_pmac.h pbbuttonsd-0.6.5-fixed/src/module_pmac.h
--- pbbuttonsd-0.6.5/src/module_pmac.h Fri Aug 27 08:49:31 2004
+++ pbbuttonsd-0.6.5-fixed/src/module_pmac.h Thu Sep 23 16:18:26 2004
@@ -86,7 +86,8 @@
void pmac_pmu_handler (int fd);
void pmac_timer (struct tagitem *taglist);
-void pmac_update_batteryinfo (int cf);
+void pmac_update_batteryinfo ();
+int pmac_get_procac ();
int pmac_update_flags ();
void activate_sleepmode ();
int pmac_get_lcdbacklight();
Reply to: