summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorUwe Stuehler <uwe@cvs.openbsd.org>2005-01-26 06:34:55 +0000
committerUwe Stuehler <uwe@cvs.openbsd.org>2005-01-26 06:34:55 +0000
commit8d5992f42a303bf7855b57d7aa3a24fba59ffeee (patch)
treecf9833405207add16097ea76404d2dc202411a68 /sys
parentbdcf45340fd9d4ef44a2ace40aae2f9d2a636631 (diff)
New device for the dedicated SSP unit, automatic battery charging, and
reporting the remaining battery life to apmd(8). ok drahn@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/arm/xscale/pxa2x0_apm.c57
-rw-r--r--sys/arch/arm/xscale/pxa2x0_apm.h16
-rw-r--r--sys/arch/arm/xscale/pxa2x0reg.h29
-rw-r--r--sys/arch/zaurus/conf/GENERIC5
-rw-r--r--sys/arch/zaurus/conf/RAMDISK5
-rw-r--r--sys/arch/zaurus/conf/files.zaurus9
-rw-r--r--sys/arch/zaurus/dev/zaurus_apm.c357
-rw-r--r--sys/arch/zaurus/dev/zaurus_scoop.c36
-rw-r--r--sys/arch/zaurus/dev/zaurus_scoopreg.h12
-rw-r--r--sys/arch/zaurus/dev/zaurus_scoopvar.h5
-rw-r--r--sys/arch/zaurus/dev/zaurus_ssp.c145
-rw-r--r--sys/arch/zaurus/dev/zaurus_sspvar.h19
12 files changed, 621 insertions, 74 deletions
diff --git a/sys/arch/arm/xscale/pxa2x0_apm.c b/sys/arch/arm/xscale/pxa2x0_apm.c
index 4af0b9ee836..242cdf2ca0e 100644
--- a/sys/arch/arm/xscale/pxa2x0_apm.c
+++ b/sys/arch/arm/xscale/pxa2x0_apm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0_apm.c,v 1.2 2005/01/20 23:34:36 uwe Exp $ */
+/* $OpenBSD: pxa2x0_apm.c,v 1.3 2005/01/26 06:34:53 uwe Exp $ */
/*-
* Copyright (c) 2001 Alexander Guy. All rights reserved.
@@ -77,8 +77,8 @@ int apm_userstandbys;
int apm_suspends;
int apm_battlow;
-void apm_battery_info(struct pxa2x0_apm_softc *,
- struct pxaapm_battery_info *);
+void apm_power_info(struct pxa2x0_apm_softc *,
+ struct apm_power_info *);
void apm_standby(struct pxa2x0_apm_softc *);
void apm_suspend(struct pxa2x0_apm_softc *);
void apm_resume(struct pxa2x0_apm_softc *);
@@ -115,13 +115,17 @@ struct filterops apmread_filtops =
#define SCFLAG_OPEN (SCFLAG_OREAD|SCFLAG_OWRITE)
void
-apm_battery_info(struct pxa2x0_apm_softc *sc,
- struct pxaapm_battery_info *battp)
+apm_power_info(struct pxa2x0_apm_softc *sc,
+ struct apm_power_info *power)
{
- bzero(battp, sizeof(struct pxaapm_battery_info));
- if (sc->sc_battery_info != NULL)
- sc->sc_battery_info(battp);
+ power->ac_state = APM_AC_UNKNOWN;
+ power->battery_state = APM_BATT_UNKNOWN;;
+ power->battery_life = 0 /* APM_BATT_LIFE_UNKNOWN */;
+ power->minutes_left = 0;
+
+ if (sc->sc_power_info != NULL)
+ sc->sc_power_info(sc, power);
}
void
@@ -272,7 +276,6 @@ int
apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
struct pxa2x0_apm_softc *sc;
- struct pxaapm_battery_info batt;
struct apm_power_info *power;
int error = 0;
@@ -325,41 +328,7 @@ apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
break;
case APM_IOC_GETPOWER:
power = (struct apm_power_info *)data;
-
- apm_battery_info(sc, &batt);
-
- power->ac_state = ((batt.flags & PXAAPM_AC_PRESENT) ?
- APM_AC_ON : APM_AC_OFF);
- power->battery_life =
- ((batt.cur_charge * 100) / batt.max_charge);
-
- /*
- * If the battery is charging, return the minutes left until
- * charging is complete. apmd knows this.
- */
-
- if (!(batt.flags & PXAAPM_BATT_PRESENT)) {
- power->battery_state = APM_BATT_UNKNOWN;
- power->minutes_left = 0;
- power->battery_life = 0;
- } else if ((power->ac_state == APM_AC_ON) &&
- (batt.draw > 0)) {
- power->minutes_left =
- (((batt.max_charge - batt.cur_charge) * 3600) /
- batt.draw) / 60;
- power->battery_state = APM_BATT_CHARGING;
- } else {
- power->minutes_left =
- ((batt.cur_charge * 3600) / (-batt.draw)) / 60;
-
- /* XXX - Arbitrary */
- if (power->battery_life > 60)
- power->battery_state = APM_BATT_HIGH;
- else if (power->battery_life < 10)
- power->battery_state = APM_BATT_CRITICAL;
- else
- power->battery_state = APM_BATT_LOW;
- }
+ apm_power_info(sc, power);
break;
default:
diff --git a/sys/arch/arm/xscale/pxa2x0_apm.h b/sys/arch/arm/xscale/pxa2x0_apm.h
index 719f0e0ddfa..9891822b118 100644
--- a/sys/arch/arm/xscale/pxa2x0_apm.h
+++ b/sys/arch/arm/xscale/pxa2x0_apm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0_apm.h,v 1.2 2005/01/20 23:34:36 uwe Exp $ */
+/* $OpenBSD: pxa2x0_apm.h,v 1.3 2005/01/26 06:34:53 uwe Exp $ */
/*
* Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
@@ -22,16 +22,7 @@
#include <sys/event.h>
#include <machine/bus.h>
-
-#define PXAAPM_AC_PRESENT (1<<0)
-#define PXAAPM_BATT_PRESENT (1<<1)
-
-struct pxaapm_battery_info {
- int flags;
- u_int cur_charge;
- u_int max_charge;
- int draw;
-};
+#include <machine/apmvar.h>
struct pxa2x0_apm_softc {
struct device sc_dev;
@@ -41,8 +32,9 @@ struct pxa2x0_apm_softc {
int sc_flags;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_pm_ioh;
- void (*sc_battery_info)(struct pxaapm_battery_info *);
void (*sc_periodic_check)(struct pxa2x0_apm_softc *);
+ void (*sc_power_info)(struct pxa2x0_apm_softc *,
+ struct apm_power_info *);
};
extern void pxa2x0_apm_attach_sub(struct pxa2x0_apm_softc *);
diff --git a/sys/arch/arm/xscale/pxa2x0reg.h b/sys/arch/arm/xscale/pxa2x0reg.h
index c77eff0ecde..7db654ec524 100644
--- a/sys/arch/arm/xscale/pxa2x0reg.h
+++ b/sys/arch/arm/xscale/pxa2x0reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0reg.h,v 1.8 2005/01/12 17:14:37 uwe Exp $ */
+/* $OpenBSD: pxa2x0reg.h,v 1.9 2005/01/26 06:34:53 uwe Exp $ */
/* $NetBSD: pxa2x0reg.h,v 1.4 2003/06/11 20:43:01 scw Exp $ */
/*
@@ -108,7 +108,10 @@
#define PXA2X0_GPIO_SIZE 0x70
#define PXA2X0_POWMAN_BASE 0x40f00000 /* Power management */
#define PXA2X0_POWMAN_SIZE 0x100
-#define PXA2X0_SSP_BASE 0x41000000
+#define PXA2X0_SSP_BASE 0x41000000 /* SSP serial port */
+#define PXA2X0_SSP1_BASE 0x41700000 /* PXA270 */
+#define PXA2X0_SSP2_BASE 0x41900000 /* PXA270 */
+#define PXA2X0_SSP_SIZE 0x40
#define PXA2X0_MMC_BASE 0x41100000 /* MultiMediaCard */
#define PXA2X0_MMC_SIZE 0x48
#define PXA2X0_CLKMAN_BASE 0x41300000 /* Clock Manager */
@@ -218,14 +221,20 @@ struct pxa2x0_dma_desc {
#define I2C_ISAR 0x16a0 /* Slave address */
/* Power Manager */
-#define POWMAN_RCSR 0x30 /* Reset Controller Status Register */
-#define RCSR_GPR (1<<3)
-#define RCSR_SMR (1<<2)
-#define RCSR_WDR (1<<1)
+#define POWMAN_PSSR 0x04 /* Sleep Status register */
+#define PSSR_RDH (1<<5)
+#define POWMAN_PCFR 0x1c /* General Configuration register */
+#define PCFR_GRP_EN (1<<4) /* PXA270 */
+#define PCFR_GP_ROD (1<<8) /* PXA270 */
+#define POWMAN_RCSR 0x30 /* Reset Controller Status register */
#define RCSR_HWR (1<<0)
+#define RCSR_WDR (1<<1)
+#define RCSR_SMR (1<<2)
+#define RCSR_GPR (1<<3)
/* Clock Manager */
#define CLKMAN_CCCR 0x00 /* Core Clock Configuration */
+#define CCCR_CPDIS (1<<31) /* PXA270 */
#define CCCR_TURBO_X1 (2<<7)
#define CCCR_TURBO_X15 (3<<7) /* x 1.5 */
#define CCCR_TURBO_X2 (4<<7)
@@ -715,4 +724,12 @@ struct pxa2x0_dma_desc {
#define OST_OIER 0x001c /* Interrupt Enable */
#define OIER_E3 (1<<3)
+/* Synchronous Serial Protocol (SSP) serial ports */
+#define SSP_SSCR0 0x00
+#define SSP_SSCR1 0x04
+#define SSP_SSSR 0x08
+#define SSSR_TNF (1<<2)
+#define SSSR_RNE (1<<3)
+#define SSP_SSDR 0x10
+
#endif /* _ARM_XSCALE_PXA2X0REG_H_ */
diff --git a/sys/arch/zaurus/conf/GENERIC b/sys/arch/zaurus/conf/GENERIC
index 092ded82753..08ac78e8395 100644
--- a/sys/arch/zaurus/conf/GENERIC
+++ b/sys/arch/zaurus/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.23 2005/01/25 21:16:57 drahn Exp $
+# $OpenBSD: GENERIC,v 1.24 2005/01/26 06:34:53 uwe Exp $
#
# GENERIC machine description file
#
@@ -182,6 +182,9 @@ ukphy* at mii? # "unknown" PHYs
lcd0 at pxaip?
wsdisplay* at lcd? console ?
+# Dedicated SSP unit for ADC, touch screen, and backlight
+zssp0 at pxaip?
+
# APM emulation
apm0 at pxaip?
diff --git a/sys/arch/zaurus/conf/RAMDISK b/sys/arch/zaurus/conf/RAMDISK
index 00335981668..9ddf56b7633 100644
--- a/sys/arch/zaurus/conf/RAMDISK
+++ b/sys/arch/zaurus/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.17 2005/01/20 23:34:36 uwe Exp $
+# $OpenBSD: RAMDISK,v 1.18 2005/01/26 06:34:53 uwe Exp $
#
# GENERIC machine description file
#
@@ -162,6 +162,9 @@ ukphy* at mii? # "unknown" PHYs
lcd0 at pxaip?
wsdisplay* at lcd? console ?
+# Dedicated SSP unit for ADC, touch screen, and backlight
+zssp0 at pxaip?
+
# APM emulation
apm0 at pxaip?
diff --git a/sys/arch/zaurus/conf/files.zaurus b/sys/arch/zaurus/conf/files.zaurus
index defaaf6e15b..ea706f82b13 100644
--- a/sys/arch/zaurus/conf/files.zaurus
+++ b/sys/arch/zaurus/conf/files.zaurus
@@ -1,4 +1,4 @@
-# $OpenBSD: files.zaurus,v 1.13 2005/01/20 23:34:36 uwe Exp $
+# $OpenBSD: files.zaurus,v 1.14 2005/01/26 06:34:53 uwe Exp $
#
# First try for arm-specific configuration info
#
@@ -38,9 +38,14 @@ device scoop
attach scoop at pxaip with scoop_pxaip
file arch/zaurus/dev/zaurus_scoop.c scoop
+# Dedicated SSP unit for ADC, touch screen, and backlight
+device zssp
+attach zssp at pxaip
+file arch/zaurus/dev/zaurus_ssp.c zssp
+
# Power manager and APM emulation
attach apm at pxaip with apm_pxaip
-file arch/zaurus/zaurus/zaurus_apm.c apm_pxaip
+file arch/zaurus/dev/zaurus_apm.c apm_pxaip
#
# Machine-independent ATA drivers
diff --git a/sys/arch/zaurus/dev/zaurus_apm.c b/sys/arch/zaurus/dev/zaurus_apm.c
new file mode 100644
index 00000000000..2fc758ea385
--- /dev/null
+++ b/sys/arch/zaurus/dev/zaurus_apm.c
@@ -0,0 +1,357 @@
+/* $OpenBSD: zaurus_apm.c,v 1.1 2005/01/26 06:34:54 uwe Exp $ */
+
+/*
+ * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0_apm.h>
+#include <arm/xscale/pxa2x0_gpio.h>
+
+#include <zaurus/dev/zaurus_scoopvar.h>
+#include <zaurus/dev/zaurus_sspvar.h>
+
+int apm_match(struct device *, void *, void *);
+void apm_attach(struct device *, struct device *, void *);
+
+struct cfattach apm_pxaip_ca = {
+ sizeof (struct pxa2x0_apm_softc), apm_match, apm_attach
+};
+
+/* MAX1111 command word */
+#define MAXCTRL_PD0 (1<<0)
+#define MAXCTRL_PD1 (1<<1)
+#define MAXCTRL_SGL (1<<2)
+#define MAXCTRL_UNI (1<<3)
+#define MAXCTRL_SEL_SHIFT 4
+#define MAXCTRL_STR (1<<7)
+
+/* MAX1111 ADC channels */
+#define BATT_THM 2
+#define BATT_AD 4
+#define JK_VAD 6
+
+/* Battery-related GPIO pins */
+#define GPIO_AC_IN_C3000 115 /* active low */
+#define GPIO_CHRG_FULL_C3000 101
+#define GPIO_BATT_COVER_C3000 90 /* active low */
+
+/* Internal software power states */
+#define PS_UNKNOWN 0
+#define PS_BATT_ABSENT 1
+#define PS_NOT_CHARGING 2
+#define PS_CHARGING 3
+#define PS_BATT_FULL 4
+
+#ifdef APMDEBUG
+const char *zaurus_power_state_names[5] = {
+ "unknown", "absent", "not charging", "charging", "full"
+};
+#endif
+
+int zaurus_power_state = PS_UNKNOWN;
+
+struct battery_voltage_threshold {
+ int voltage;
+ int life;
+ int state;
+};
+
+struct battery_voltage_threshold zaurus_battery_c3000[] = {
+ {194, 100, APM_BATT_HIGH},
+ {188, 75, APM_BATT_HIGH},
+ {184, 50, APM_BATT_HIGH},
+ {180, 25, APM_BATT_LOW},
+ {176, 5, APM_BATT_LOW},
+ {0, 0, APM_BATT_CRITICAL},
+};
+
+struct battery_voltage_threshold *zaurus_main_battery =
+ zaurus_battery_c3000;
+
+int max1111_adc_value(int);
+int max1111_adc_value_avg(int, int);
+#if 0
+int zaurus_jkvad_voltage(void);
+int zaurus_battery_temp(void);
+#endif
+int zaurus_battery_voltage(void);
+int zaurus_battery_life(void);
+int zaurus_battery_state(void);
+int zaurus_ac_present(void);
+int zaurus_charge_complete(void);
+void zaurus_charge_control(int);
+void zaurus_power_check(struct pxa2x0_apm_softc *);
+void zaurus_power_info(struct pxa2x0_apm_softc *,
+ struct apm_power_info *);
+
+int
+apm_match(struct device *parent, void *match, void *aux)
+{
+ return 1;
+}
+
+void
+apm_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct pxa2x0_apm_softc *sc = (struct pxa2x0_apm_softc *)self;
+
+ pxa2x0_gpio_set_function(GPIO_AC_IN_C3000, GPIO_IN);
+ pxa2x0_gpio_set_function(GPIO_CHRG_FULL_C3000, GPIO_IN);
+ pxa2x0_gpio_set_function(GPIO_BATT_COVER_C3000, GPIO_IN);
+
+#if 0
+ (void)pxa2x0_gpio_intr_establish(GPIO_AC_IN_C3000, IST_EDGE_BOTH,
+ IPL_BIO, apm_intr, sc, "apm_ac");
+#endif
+
+ sc->sc_periodic_check = zaurus_power_check;
+ sc->sc_power_info = zaurus_power_info;
+
+ /* Initialize the battery status before APM is enabled. */
+ zaurus_power_check(sc);
+
+ pxa2x0_apm_attach_sub(sc);
+}
+
+int
+max1111_adc_value(int chan)
+{
+
+ return zssp_read_max1111(MAXCTRL_PD0 | MAXCTRL_PD1 |
+ MAXCTRL_SGL | MAXCTRL_UNI | (chan << MAXCTRL_SEL_SHIFT) |
+ MAXCTRL_STR);
+}
+
+/* XXX simplify */
+int
+max1111_adc_value_avg(int chan, int pause)
+{
+ int val[5];
+ int i, j, k, x;
+ int sum = 0;
+
+ for (i = 0; i < 5; i++) {
+ val[i] = max1111_adc_value(chan);
+ if (i != 4)
+ delay(pause * 1000);
+ }
+
+ x = val[0];
+ j = 0;
+ for (i = 1; i < 5; i++) {
+ if (x < val[i]) {
+ x = val[i];
+ j = i;
+ }
+ }
+
+ x = val[4];
+ k = 4;
+ for (i = 3; i >= 0; i--) {
+ if (x > val[i]) {
+ x = val[i];
+ k = i;
+ }
+ }
+
+ for (i = 0; i < 5; i++) {
+ if (i == j || i == k)
+ continue;
+ sum += val[i];
+ }
+
+ return (sum / 3);
+}
+
+#if 0
+/*
+ * Return the voltage available for charging. This will be zero,
+ * unless A/C power is connected.
+ */
+int
+zaurus_jkvad_voltage(void)
+{
+
+ return max1111_adc_value_avg(JK_VAD, 10);
+}
+
+int
+zaurus_battery_temp(void)
+{
+ int temp;
+
+ scoop_battery_temp_adc(1);
+ delay(10000);
+ temp = max1111_adc_value_avg(BATT_THM, 1);
+ scoop_battery_temp_adc(0);
+
+ return temp;
+}
+#endif
+
+int
+zaurus_battery_voltage(void)
+{
+
+ return max1111_adc_value_avg(BATT_AD, 10);
+}
+
+int
+zaurus_battery_life(void)
+{
+ int i;
+ int voltage;
+
+ voltage = zaurus_battery_voltage();
+
+ for (i = 0; zaurus_main_battery[i].voltage > 0; i++) {
+ if (voltage >= zaurus_main_battery[i].voltage)
+ break;
+ }
+
+ return zaurus_main_battery[i].life;
+}
+
+int
+zaurus_battery_state(void)
+{
+ int i;
+ int voltage;
+
+ voltage = zaurus_battery_voltage();
+
+ for (i = 0; zaurus_main_battery[i].voltage > 0; i++) {
+ if (voltage >= zaurus_main_battery[i].voltage)
+ break;
+ }
+
+ return zaurus_main_battery[i].state;
+}
+
+int
+zaurus_ac_present(void)
+{
+
+ return !pxa2x0_gpio_get_bit(GPIO_AC_IN_C3000);
+}
+
+/*
+ * Return non-zero if the charge complete signal is set. This signal
+ * is valid only after charging is restarted.
+ */
+int
+zaurus_charge_complete(void)
+{
+
+ return pxa2x0_gpio_get_bit(GPIO_CHRG_FULL_C3000);
+}
+
+void
+zaurus_charge_control(int state)
+{
+
+ switch (state) {
+ case PS_CHARGING:
+ scoop_charge_battery(1, 0);
+ scoop_led_set(SCOOP_LED_ORANGE, 1);
+ break;
+ case PS_NOT_CHARGING:
+ case PS_BATT_FULL:
+ scoop_charge_battery(0, 0);
+ scoop_led_set(SCOOP_LED_ORANGE, 0);
+ /* Always force a 15 ms delay before charging again. */
+ delay(15000);
+ break;
+ default:
+ printf("zaurus_charge_control: bad state %d\n", state);
+ break;
+ }
+
+ zaurus_power_state = state;
+}
+
+/*
+ * Check A/C power and control battery charging. This gets called once
+ * from apm_attach(), and once per second from the APM kernel thread.
+ */
+void
+zaurus_power_check(struct pxa2x0_apm_softc *sc)
+{
+ int state = zaurus_power_state;
+
+ switch (state) {
+ case PS_UNKNOWN:
+ case PS_BATT_ABSENT:
+ state = PS_NOT_CHARGING;
+ zaurus_charge_control(state);
+ /* FALLTHROUGH */
+
+ case PS_NOT_CHARGING:
+ if (zaurus_ac_present())
+ state = PS_CHARGING;
+ break;
+
+ case PS_CHARGING:
+ if (!zaurus_ac_present())
+ state = PS_NOT_CHARGING;
+ else if (zaurus_charge_complete())
+ state = PS_BATT_FULL;
+ break;
+
+ case PS_BATT_FULL:
+ if (!zaurus_ac_present())
+ state = PS_NOT_CHARGING;
+ break;
+
+ default:
+ printf("zaurus_power_check: bad state %d\n", state);
+ break;
+ }
+
+ if (state != zaurus_power_state) {
+#ifdef APMDEBUG
+ printf("zaurus_power_check: battery state %s -> %s volt %d\n",
+ zaurus_power_state_names[zaurus_power_state],
+ zaurus_power_state_names[state],
+ zaurus_battery_voltage());
+#endif
+ zaurus_charge_control(state);
+ }
+}
+
+/*
+ * Report A/C and battery state in response to a request from apmd.
+ */
+void
+zaurus_power_info(struct pxa2x0_apm_softc *sc,
+ struct apm_power_info *power)
+{
+
+ if (zaurus_power_state == PS_CHARGING) {
+ power->ac_state = APM_AC_ON;
+ power->battery_state = APM_BATT_CHARGING;
+ power->battery_life = 100;
+ } else {
+ power->ac_state = zaurus_ac_present() ? APM_AC_ON :
+ APM_AC_OFF;
+ power->battery_state = zaurus_battery_state();
+ power->battery_life = zaurus_battery_life();
+ }
+}
diff --git a/sys/arch/zaurus/dev/zaurus_scoop.c b/sys/arch/zaurus/dev/zaurus_scoop.c
index 9f851de62dc..184043cafd4 100644
--- a/sys/arch/zaurus/dev/zaurus_scoop.c
+++ b/sys/arch/zaurus/dev/zaurus_scoop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: zaurus_scoop.c,v 1.3 2005/01/20 23:34:37 uwe Exp $ */
+/* $OpenBSD: zaurus_scoop.c,v 1.4 2005/01/26 06:34:54 uwe Exp $ */
/*
* Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
@@ -130,12 +130,42 @@ scoop_led_set(int led, int on)
switch(led) {
case SCOOP_LED_GREEN:
scoop_gpio_pin_write(scoop_cd.cd_devs[0],
- C3000_SCOOP0_LED_GREEN, on);
+ SCOOP0_LED_GREEN_C3000, on);
break;
case SCOOP_LED_ORANGE:
scoop_gpio_pin_write(scoop_cd.cd_devs[0],
- C3000_SCOOP0_LED_ORANGE, on);
+ SCOOP0_LED_ORANGE_C3000, on);
break;
}
}
}
+
+void
+scoop_battery_temp_adc(int enable)
+{
+
+ if (scoop_cd.cd_ndevs > 0 && scoop_cd.cd_devs[0] != NULL)
+ scoop_gpio_pin_write(scoop_cd.cd_devs[0],
+ SCOOP0_ADC_TEMP_ON_C3000, enable);
+}
+
+void
+scoop_charge_battery(int enable, int voltage_high)
+{
+
+ if (scoop_cd.cd_ndevs > 0 && scoop_cd.cd_devs[0] != NULL) {
+ scoop_gpio_pin_write(scoop_cd.cd_devs[0],
+ SCOOP0_JK_B_C3000, voltage_high);
+ scoop_gpio_pin_write(scoop_cd.cd_devs[0],
+ SCOOP0_CHARGE_OFF_C3000, !enable);
+ }
+}
+
+void
+scoop_discharge_battery(int enable)
+{
+
+ if (scoop_cd.cd_ndevs > 0 && scoop_cd.cd_devs[0] != NULL)
+ scoop_gpio_pin_write(scoop_cd.cd_devs[0],
+ SCOOP0_JK_A_C3000, enable);
+}
diff --git a/sys/arch/zaurus/dev/zaurus_scoopreg.h b/sys/arch/zaurus/dev/zaurus_scoopreg.h
index 67abaf93e67..9b7f0c56c5e 100644
--- a/sys/arch/zaurus/dev/zaurus_scoopreg.h
+++ b/sys/arch/zaurus/dev/zaurus_scoopreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: zaurus_scoopreg.h,v 1.3 2005/01/20 23:34:36 uwe Exp $ */
+/* $OpenBSD: zaurus_scoopreg.h,v 1.4 2005/01/26 06:34:54 uwe Exp $ */
/*
* Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
@@ -34,6 +34,10 @@
#define SCOOP_GPRR 0x28
/* GPIO bit assignments for the Zaurus C3000. */
-#define C3000_SCOOP0_LED_GREEN 1
-#define C3000_SCOOP0_LED_ORANGE 7
-#define C3000_SCOOP1_BACKLIGHT_ON 8
+#define SCOOP0_LED_GREEN_C3000 1
+#define SCOOP0_JK_B_C3000 2
+#define SCOOP0_CHARGE_OFF_C3000 3
+#define SCOOP0_LED_ORANGE_C3000 7
+#define SCOOP0_JK_A_C3000 8
+#define SCOOP0_ADC_TEMP_ON_C3000 9
+#define SCOOP1_BACKLIGHT_ON_C3000 8
diff --git a/sys/arch/zaurus/dev/zaurus_scoopvar.h b/sys/arch/zaurus/dev/zaurus_scoopvar.h
index 497680e49f4..f48b0d5d58b 100644
--- a/sys/arch/zaurus/dev/zaurus_scoopvar.h
+++ b/sys/arch/zaurus/dev/zaurus_scoopvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: zaurus_scoopvar.h,v 1.3 2005/01/20 23:34:37 uwe Exp $ */
+/* $OpenBSD: zaurus_scoopvar.h,v 1.4 2005/01/26 06:34:54 uwe Exp $ */
/*
* Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
@@ -21,3 +21,6 @@
void scoop_backlight_set(int);
void scoop_led_set(int, int);
+void scoop_battery_temp_adc(int);
+void scoop_charge_battery(int, int);
+void scoop_discharge_battery(int);
diff --git a/sys/arch/zaurus/dev/zaurus_ssp.c b/sys/arch/zaurus/dev/zaurus_ssp.c
new file mode 100644
index 00000000000..4c29aab21de
--- /dev/null
+++ b/sys/arch/zaurus/dev/zaurus_ssp.c
@@ -0,0 +1,145 @@
+/* $OpenBSD: zaurus_ssp.c,v 1.1 2005/01/26 06:34:54 uwe Exp $ */
+
+/*
+ * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0var.h>
+#include <arm/xscale/pxa2x0_gpio.h>
+
+#include <zaurus/dev/zaurus_sspvar.h>
+
+#define GPIO_TG_CS_C3000 53
+#define GPIO_MAX1111_CS_C3000 20
+#define GPIO_ADS7846_CS_C3000 14 /* SSP SFRM */
+
+#define SSCR0_LZ9JG18 0x01ab
+#define SSCR0_MAX1111 0x0387
+
+struct zssp_softc {
+ struct device sc_dev;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+};
+
+int zssp_match(struct device *, void *, void *);
+void zssp_attach(struct device *, struct device *, void *);
+
+struct cfattach zssp_ca = {
+ sizeof (struct zssp_softc), zssp_match, zssp_attach
+};
+
+struct cfdriver zssp_cd = {
+ NULL, "zssp", DV_DULL
+};
+
+int
+zssp_match(struct device *parent, void *match, void *aux)
+{
+ return 1;
+}
+
+void
+zssp_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct zssp_softc *sc = (struct zssp_softc *)self;
+
+ sc->sc_iot = &pxa2x0_bs_tag;
+ if (bus_space_map(sc->sc_iot, PXA2X0_SSP1_BASE, PXA2X0_SSP_SIZE,
+ 0, &sc->sc_ioh))
+ panic("can't map %s", sc->sc_dev.dv_xname);
+
+ pxa2x0_clkman_config(CKEN_SSP, 1);
+
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, SSCR0_LZ9JG18);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR1, 0);
+
+ pxa2x0_gpio_set_function(GPIO_TG_CS_C3000, GPIO_OUT|GPIO_SET);
+ pxa2x0_gpio_set_function(GPIO_MAX1111_CS_C3000, GPIO_OUT|GPIO_SET);
+ pxa2x0_gpio_set_function(GPIO_ADS7846_CS_C3000, GPIO_OUT|GPIO_SET);
+
+ printf("\n");
+}
+
+int
+zssp_read_max1111(u_int32_t cmd)
+{
+ struct zssp_softc *sc;
+ int voltage[2];
+ int i;
+
+ if (zssp_cd.cd_ndevs < 1 || zssp_cd.cd_devs[0] == NULL) {
+ printf("zssp_read_max1111: not configured\n");
+ return 0;
+ }
+ sc = (struct zssp_softc *)zssp_cd.cd_devs[0];
+
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, SSCR0_MAX1111);
+
+ pxa2x0_gpio_set_bit(GPIO_TG_CS_C3000);
+ pxa2x0_gpio_set_bit(GPIO_ADS7846_CS_C3000);
+ pxa2x0_gpio_clear_bit(GPIO_MAX1111_CS_C3000);
+
+ delay(1);
+
+ /* Send the command word and read a dummy word back. */
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, cmd);
+ while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+ & SSSR_TNF) != SSSR_TNF)
+ /* poll */;
+ /* XXX is this delay necessary? */
+ delay(1);
+ while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+ & SSSR_RNE) != SSSR_RNE)
+ /* poll */;
+ i = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR);
+
+ for (i = 0; i < 2; i++) {
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSDR, 0);
+ while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+ & SSSR_TNF) != SSSR_TNF)
+ /* poll */;
+ /* XXX again, is this delay necessary? */
+ delay(1);
+ while ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSP_SSSR)
+ & SSSR_RNE) != SSSR_RNE)
+ /* poll */;
+ voltage[i] = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ SSP_SSDR);
+ }
+
+ pxa2x0_gpio_set_bit(GPIO_TG_CS_C3000);
+ pxa2x0_gpio_set_bit(GPIO_ADS7846_CS_C3000);
+ pxa2x0_gpio_set_bit(GPIO_MAX1111_CS_C3000);
+
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSP_SSCR0, 0);
+
+ /* XXX no idea what this means, but it's what Linux would do. */
+ if ((voltage[0] & 0xc0) != 0 || (voltage[1] & 0x3f) != 0)
+ voltage[0] = -1;
+ else
+ voltage[0] = ((voltage[0] << 2) & 0xfc) |
+ ((voltage[1] >> 6) & 0x03);
+
+ return voltage[0];
+}
diff --git a/sys/arch/zaurus/dev/zaurus_sspvar.h b/sys/arch/zaurus/dev/zaurus_sspvar.h
new file mode 100644
index 00000000000..18b7f1399c2
--- /dev/null
+++ b/sys/arch/zaurus/dev/zaurus_sspvar.h
@@ -0,0 +1,19 @@
+/* $OpenBSD: zaurus_sspvar.h,v 1.1 2005/01/26 06:34:54 uwe Exp $ */
+
+/*
+ * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+int zssp_read_max1111(u_int32_t);