Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/macppc/dev Add a PMU initialization call at ADB ini...
details: https://anonhg.NetBSD.org/src/rev/c936ff31f51d
branches: trunk
changeset: 573559:c936ff31f51d
user: briggs <briggs%NetBSD.org@localhost>
date: Tue Feb 01 02:46:00 2005 +0000
description:
Add a PMU initialization call at ADB init time. This probes the machine
type for PMU / battery information, then uses that when getting battery
information for APM. Allows older PowerBooks (pre-smart batteries) to
function with apm enabled in the kernel. Thanks to Linux code for battery
information for these old batteries. Something is still odd, though,
because a charging battery can show > 100% when it's near to full charge.
Enable more interrupts from PMU and handle PB3400 card eject buttons
properly, too.
Also use #defines for commands instead of raw hex codes.
diffstat:
sys/arch/macppc/dev/adb.c | 8 +-
sys/arch/macppc/dev/pm_direct.c | 207 +++++++++++++++++++++++++++++++++++++--
sys/arch/macppc/dev/pm_direct.h | 3 +-
3 files changed, 201 insertions(+), 17 deletions(-)
diffs (truncated from 388 to 300 lines):
diff -r 244f355738a8 -r c936ff31f51d sys/arch/macppc/dev/adb.c
--- a/sys/arch/macppc/dev/adb.c Tue Feb 01 02:23:26 2005 +0000
+++ b/sys/arch/macppc/dev/adb.c Tue Feb 01 02:46:00 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: adb.c,v 1.16 2005/02/01 02:05:10 briggs Exp $ */
+/* $NetBSD: adb.c,v 1.17 2005/02/01 02:46:00 briggs Exp $ */
/*-
* Copyright (C) 1994 Bradley A. Grantham
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: adb.c,v 1.16 2005/02/01 02:05:10 briggs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: adb.c,v 1.17 2005/02/01 02:46:00 briggs Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -46,6 +46,7 @@
#include <macppc/dev/adbvar.h>
#include <macppc/dev/akbdvar.h>
+#include <macppc/dev/pm_direct.h>
#include <macppc/dev/viareg.h>
#include <dev/ofw/openfirm.h>
@@ -134,6 +135,9 @@
ADBReInit();
intr_establish(irq, IST_LEVEL, IPL_HIGH, (int (*)(void *))adb_intr, sc);
+ if (adbHardware == ADB_HW_PMU) {
+ pm_init();
+ }
#ifdef ADB_DEBUG
if (adb_debug)
diff -r 244f355738a8 -r c936ff31f51d sys/arch/macppc/dev/pm_direct.c
--- a/sys/arch/macppc/dev/pm_direct.c Tue Feb 01 02:23:26 2005 +0000
+++ b/sys/arch/macppc/dev/pm_direct.c Tue Feb 01 02:46:00 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pm_direct.c,v 1.22 2005/02/01 02:23:26 briggs Exp $ */
+/* $NetBSD: pm_direct.c,v 1.23 2005/02/01 02:46:00 briggs Exp $ */
/*
* Copyright (C) 1997 Takashi Hamada
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pm_direct.c,v 1.22 2005/02/01 02:23:26 briggs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pm_direct.c,v 1.23 2005/02/01 02:46:00 briggs Exp $");
#ifdef DEBUG
#ifndef ADB_DEBUG
@@ -54,8 +54,11 @@
#include <sys/systm.h>
#include <machine/adbsys.h>
+#include <machine/autoconf.h>
#include <machine/cpu.h>
+#include <dev/ofw/openfirm.h>
+
#include <macppc/dev/adbvar.h>
#include <macppc/dev/pm_direct.h>
#include <macppc/dev/viareg.h>
@@ -97,6 +100,11 @@
u_int pm_LCD_contrast = 0x0;
u_int pm_counter = 0; /* clock count */
+static enum batt_type { BATT_COMET, BATT_HOOPER, BATT_SMART } pmu_batt_type;
+static int pmu_nbatt;
+static int strinlist(char *, char *, int);
+static enum pmu_type { PMU_UNKNOWN, PMU_OHARE, PMU_G3, PMU_KEYLARGO } pmu_type;
+
/* these values shows that number of data returned after 'send' cmd is sent */
signed char pm_send_cmd_type[] = {
-1, -1, -1, -1, -1, -1, -1, -1,
@@ -268,6 +276,83 @@
pmHardware = PM_HW_PB5XX; /* XXX */
}
+static int
+strinlist(char *targ, char *list, int listlen)
+{
+ char *str;
+ int sl;
+
+ str = list;
+ while (listlen > 0) {
+ sl = strlen(str);
+ if (strncmp(targ, str, sl) == 0)
+ return 1;
+ str += sl+1;
+ listlen -= sl+1;
+ }
+ return 0;
+}
+
+/*
+ * Check the hardware type of the Power Manager
+ */
+void
+pm_init(void)
+{
+ uint32_t regs[10];
+ PMData pmdata;
+ char compat[128];
+ int clen, node, imask;
+
+ node = OF_peer(0);
+ if (node == -1) {
+ printf("pmu: Failed to get root");
+ return;
+ }
+ clen = OF_getprop(node, "compatible", compat, sizeof(compat));
+ if (clen <= 0) {
+ printf("pmu: failed to read root compatible data %d\n", clen);
+ return;
+ }
+
+ imask = PMU_INT_PCEJECT | PMU_INT_SNDBRT | PMU_INT_ADB | PMU_INT_TICK;
+
+ if (strinlist("AAPL,3500", compat, clen) ||
+ strinlist("AAPL,3400/2400", compat, clen)) {
+ /* How to distinguish BATT_COMET? */
+ pmu_nbatt = 1;
+ pmu_batt_type = BATT_HOOPER;
+ pmu_type = PMU_OHARE;
+ } else if (strinlist("AAPL,PowerBook1998", compat, clen) ||
+ strinlist("PowerBook1,1", compat, clen)) {
+ pmu_nbatt = 2;
+ pmu_batt_type = BATT_SMART;
+ pmu_type = PMU_G3;
+ } else {
+ pmu_nbatt = 1;
+ pmu_batt_type = BATT_SMART;
+ pmu_type = PMU_KEYLARGO;
+ node = getnodebyname(0, "power-mgt");
+ if (node == -1) {
+ printf("pmu: can't find power-mgt\n");
+ return;
+ }
+ clen = OF_getprop(node, "prim-info", regs, sizeof(regs));
+ if (clen < 24) {
+ printf("pmu: failed to read prim-info\n");
+ return;
+ }
+ pmu_nbatt = regs[6] >> 16;
+ }
+
+ pmdata.command = PMU_SET_IMASK;
+ pmdata.num_data = 1;
+ pmdata.s_buf = pmdata.data;
+ pmdata.r_buf = pmdata.data;
+ pmdata.data[0] = imask;
+ pmgrop(&pmdata);
+}
+
/*
* Check the existent ADB devices
@@ -568,7 +653,7 @@
PM_VIA_CLR_INTR(); /* clear VIA1 interrupt */
/* ask PM what happend */
- pmdata.command = 0x78;
+ pmdata.command = PMU_INT_ACK;
pmdata.num_data = 0;
pmdata.data[0] = pmdata.data[1] = 0;
pmdata.s_buf = &pmdata.data[2];
@@ -596,7 +681,7 @@
} else {
#ifdef ADB_DEBUG
if (adb_debug)
- pm_printerr("driver does not supported this event.",
+ pm_printerr("driver does not support this event.",
rval, pmdata.num_data, pmdata.data);
#endif
}
@@ -839,7 +924,7 @@
PM_VIA_CLR_INTR(); /* clear VIA1 interrupt */
/* ask PM what happend */
- pmdata.command = 0x78;
+ pmdata.command = PMU_INT_ACK;
pmdata.num_data = 0;
pmdata.s_buf = &pmdata.data[2];
pmdata.r_buf = &pmdata.data[2];
@@ -874,7 +959,7 @@
pm_printerr("#33", rval, pmdata.num_data, pmdata.data);
*/
/* this is an experimental code */
- pmdata.command = 0x41;
+ pmdata.command = PMU_SET_BRIGHTNESS;
pmdata.num_data = 1;
pmdata.s_buf = pmdata.data;
pmdata.r_buf = pmdata.data;
@@ -886,7 +971,7 @@
pmdata.data[0] = pm_LCD_brightness;
rval = pm_pmgrop_pm2(&pmdata);
break;
- case 0x10: /* ADB data that were requested by TALK command */
+ case 0x10: /* ADB data requested by TALK command */
case 0x14:
pm_adb_get_TALK_result(&pmdata);
break;
@@ -898,7 +983,7 @@
default:
#ifdef ADB_DEBUG
if (adb_debug)
- pm_printerr("driver does not supported this event.",
+ pm_printerr("driver does not support this event.",
pmdata.data[2], pmdata.num_data,
pmdata.data);
#endif
@@ -977,7 +1062,7 @@
adbCompRout = compRout;
adbCompData = data;
- pmdata.command = 0x20;
+ pmdata.command = PMU_ADB_CMD;
pmdata.s_buf = pmdata.data;
pmdata.r_buf = pmdata.data;
@@ -1065,7 +1150,7 @@
/* this command enables the interrupt by operating ADB devices */
if (HwCfgFlags3 & 0x00020000) { /* PB Duo series, PB 5XX series */
- pmdata.command = 0x20;
+ pmdata.command = PMU_ADB_CMD;
pmdata.num_data = 4;
pmdata.s_buf = pmdata.data;
pmdata.r_buf = pmdata.data;
@@ -1074,7 +1159,7 @@
pmdata.data[2] = 0x00;
pmdata.data[3] = 0x0c; /* each bit may express the existent ADB device */
} else { /* PB 1XX series */
- pmdata.command = 0x20;
+ pmdata.command = PMU_ADB_CMD;
pmdata.num_data = 3;
pmdata.s_buf = pmdata.data;
pmdata.r_buf = pmdata.data;
@@ -1125,6 +1210,16 @@
int i;
struct adbCommand packet;
+ if (pmu_type == PMU_OHARE && pmdata->num_data == 4 &&
+ pmdata->data[1] == 0x2c && pmdata->data[3] == 0xff &&
+ ((pmdata->data[2] & ~1) == 0xf4)) {
+ if (pmdata->data[2] == 0xf4) {
+ pm_eject_pcmcia(0);
+ } else {
+ pm_eject_pcmcia(1);
+ }
+ return;
+ }
/* set up data for adb_pass_up */
packet.data[0] = pmdata->num_data-1; /* number of raw data */
packet.data[1] = pmdata->data[3]; /* ADB command */
@@ -1155,7 +1250,7 @@
}
/* poll the other device */
- tmp_pmdata.command = 0x20;
+ tmp_pmdata.command = PMU_ADB_CMD;
tmp_pmdata.num_data = 3;
tmp_pmdata.s_buf = tmp_pmdata.data;
tmp_pmdata.r_buf = tmp_pmdata.data;
@@ -1280,8 +1375,8 @@
* Thanks to Paul Mackerras and Fabio Riccardi's Linux implementation
* for a clear description of the PMU results.
*/
-int
-pm_battery_info(int battery, struct pmu_battery_info *info)
+static int
+pm_battery_info_smart(int battery, struct pmu_battery_info *info)
{
PMData p;
@@ -1330,6 +1425,90 @@
return 1;
}
+static int
+pm_battery_info_legacy(int battery, struct pmu_battery_info *info, int ty)
+{
+ PMData p;
+ long pcharge=0, charge, vb, vmax, lmax;
+ long vmax_charging, vmax_charged, amperage, voltage;
+
+ p.command = PMU_BATTERY_STATE;
+ p.num_data = 0;
+ p.s_buf = p.r_buf = p.data;
+ pmgrop(&p);
+
+ info->flags = p.data[0];
+
+ if (info->flags & PMU_PWR_BATT_PRESENT) {
+ if (ty == BATT_COMET) {
Home |
Main Index |
Thread Index |
Old Index