diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2005-08-28 03:52:38 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2005-08-28 03:52:38 +0000 |
commit | f702359a5217f2aa146500644779605174f8483e (patch) | |
tree | ef2e6c7b86389da5ac53f33c2d592e143b90b28e /sys/dev/isa/aps.c | |
parent | 462bbbc23a7344fc1324f9c66f54fae1270dcb61 (diff) |
wake aps up on resume from suspend/standby; ok deraadt@
tested by jsg@ naddy@ and some helpful souls on tech@
Diffstat (limited to 'sys/dev/isa/aps.c')
-rw-r--r-- | sys/dev/isa/aps.c | 103 |
1 files changed, 73 insertions, 30 deletions
diff --git a/sys/dev/isa/aps.c b/sys/dev/isa/aps.c index 33f911f9e10..688609ff826 100644 --- a/sys/dev/isa/aps.c +++ b/sys/dev/isa/aps.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aps.c,v 1.4 2005/08/06 01:30:33 jsg Exp $ */ +/* $OpenBSD: aps.c,v 1.5 2005/08/28 03:52:37 djm Exp $ */ /* * Copyright (c) 2005 Jonathan Gray <jsg@openbsd.org> * @@ -43,10 +43,12 @@ int aps_match(struct device *, void *, void *); void aps_attach(struct device *, struct device *, void *); +int aps_init(bus_space_tag_t, bus_space_handle_t); u_int8_t aps_mem_read_1(bus_space_tag_t, bus_space_handle_t, int, u_int8_t); int aps_read_data(struct aps_softc *); void aps_refresh_sensor_data(struct aps_softc *sc); void aps_refresh(void *); +void aps_power(int, void *); struct cfattach aps_ca = { sizeof(struct aps_softc), @@ -141,35 +143,7 @@ aps_attach(struct device *parent, struct device *self, void *aux) printf("\n"); - bus_space_write_1(iot, ioh, APS_INIT, 0x17); - bus_space_write_1(iot, ioh, APS_STATE, 0x81); - bus_space_write_1(iot, ioh, APS_CMD, 0x01); - if (!aps_mem_read_1(iot, ioh, APS_CMD, 0x00)) - goto out; - if (!aps_mem_read_1(iot, ioh, APS_STATE, 0x00)) - goto out; - if (!aps_mem_read_1(iot, ioh, APS_XACCEL, 0x60)) - goto out; - if (!aps_mem_read_1(iot, ioh, APS_XACCEL + 1, 0x00)) - goto out; - bus_space_write_1(iot, ioh, APS_INIT, 0x14); - bus_space_write_1(iot, ioh, APS_STATE, 0x01); - bus_space_write_1(iot, ioh, APS_CMD, 0x01); - if (!aps_mem_read_1(iot, ioh, APS_CMD, 0x00)) - goto out; - bus_space_write_1(iot, ioh, APS_INIT, 0x10); - bus_space_write_1(iot, ioh, APS_STATE, 0xc8); - bus_space_write_1(iot, ioh, APS_XACCEL, 0x00); - bus_space_write_1(iot, ioh, APS_XACCEL + 1, 0x02); - bus_space_write_1(iot, ioh, APS_CMD, 0x01); - if (!aps_mem_read_1(iot, ioh, APS_CMD, 0x00)) - goto out; - /* refresh data */ - bus_space_write_1(iot, ioh, APS_INIT, 0x11); - bus_space_write_1(iot, ioh, APS_CMD, 0x01); - if (!aps_mem_read_1(iot, ioh, APS_ACCEL_STATE, 0x50)) - goto out; - if (!aps_mem_read_1(iot, ioh, APS_STATE, 0x00)) + if (!aps_init(iot, ioh)) goto out; sc->numsensors = APS_NUM_SENSORS; @@ -229,6 +203,8 @@ aps_attach(struct device *parent, struct device *self, void *aux) SENSOR_ADD(&sc->sensors[i]); } + powerhook_establish(aps_power, (void *)sc); + /* Refresh sensor data every 0.5 seconds */ timeout_set(&aps_timeout, aps_refresh, sc); timeout_add(&aps_timeout, (5 * hz) / 10); @@ -238,6 +214,43 @@ out: return; } +int +aps_init(bus_space_tag_t iot, bus_space_handle_t ioh) +{ + bus_space_write_1(iot, ioh, APS_INIT, 0x17); + bus_space_write_1(iot, ioh, APS_STATE, 0x81); + bus_space_write_1(iot, ioh, APS_CMD, 0x01); + if (!aps_mem_read_1(iot, ioh, APS_CMD, 0x00)) + return (0); + if (!aps_mem_read_1(iot, ioh, APS_STATE, 0x00)) + return (0); + if (!aps_mem_read_1(iot, ioh, APS_XACCEL, 0x60)) + return (0); + if (!aps_mem_read_1(iot, ioh, APS_XACCEL + 1, 0x00)) + return (0); + bus_space_write_1(iot, ioh, APS_INIT, 0x14); + bus_space_write_1(iot, ioh, APS_STATE, 0x01); + bus_space_write_1(iot, ioh, APS_CMD, 0x01); + if (!aps_mem_read_1(iot, ioh, APS_CMD, 0x00)) + return (0); + bus_space_write_1(iot, ioh, APS_INIT, 0x10); + bus_space_write_1(iot, ioh, APS_STATE, 0xc8); + bus_space_write_1(iot, ioh, APS_XACCEL, 0x00); + bus_space_write_1(iot, ioh, APS_XACCEL + 1, 0x02); + bus_space_write_1(iot, ioh, APS_CMD, 0x01); + if (!aps_mem_read_1(iot, ioh, APS_CMD, 0x00)) + return (0); + /* refresh data */ + bus_space_write_1(iot, ioh, APS_INIT, 0x11); + bus_space_write_1(iot, ioh, APS_CMD, 0x01); + if (!aps_mem_read_1(iot, ioh, APS_ACCEL_STATE, 0x50)) + return (0); + if (!aps_mem_read_1(iot, ioh, APS_STATE, 0x00)) + return (0); + + return (1); +} + u_int8_t aps_mem_read_1(bus_space_tag_t iot, bus_space_handle_t ioh, int reg, u_int8_t val) @@ -333,3 +346,33 @@ aps_refresh(void *arg) aps_refresh_sensor_data(sc); timeout_add(&aps_timeout, (5 * hz) / 10); } + +void +aps_power(int why, void *arg) +{ + struct aps_softc *sc = (struct aps_softc *)arg; + bus_space_tag_t iot = sc->aps_iot; + bus_space_handle_t ioh = sc->aps_ioh; + + if (why != PWR_RESUME) { + if (timeout_pending(&aps_timeout)) + timeout_del(&aps_timeout); + } else { + /* + * Redo the init sequence on resume, because APS is + * as forgetful as it is deaf. + */ + bus_space_write_1(iot, ioh, APS_INIT, 0x13); + bus_space_write_1(iot, ioh, APS_CMD, 0x01); + bus_space_read_1(iot, ioh, APS_CMD); + bus_space_write_1(iot, ioh, APS_INIT, 0x13); + bus_space_write_1(iot, ioh, APS_CMD, 0x01); + + if (aps_mem_read_1(iot, ioh, APS_CMD, 0x00) && + aps_init(iot, ioh)) + timeout_add(&aps_timeout, (5 * hz) / 10); + else + printf("aps: failed to wake up\n"); + } +} + |