summaryrefslogtreecommitdiffstats
path: root/sys/dev/asmc
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2008-04-07 11:22:12 +0000
committerrpaulo <rpaulo@FreeBSD.org>2008-04-07 11:22:12 +0000
commite654fd2681678b7fd039050924c46b8c53d6a92a (patch)
tree765eee43b5b5b9cede4c13b858b53faf4737b776 /sys/dev/asmc
parent0db35b0777e2a52e735f00892a0b8aa606f76519 (diff)
downloadFreeBSD-src-e654fd2681678b7fd039050924c46b8c53d6a92a.zip
FreeBSD-src-e654fd2681678b7fd039050924c46b8c53d6a92a.tar.gz
The SMC is represented on the acpi tables, so we can completely remove
dependency on isa. We are now an acpi child. Also: * Add compile time debugging activation * Increase the delay for the SMS init flag.
Diffstat (limited to 'sys/dev/asmc')
-rw-r--r--sys/dev/asmc/asmc.c114
-rw-r--r--sys/dev/asmc/asmcvar.h26
2 files changed, 84 insertions, 56 deletions
diff --git a/sys/dev/asmc/asmc.c b/sys/dev/asmc/asmc.c
index 5a9114d..d0ce889 100644
--- a/sys/dev/asmc/asmc.c
+++ b/sys/dev/asmc/asmc.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2007 Rui Paulo <rpaulo@FreeBSD.org>
+ * Copyright (c) 2007, 2008 Rui Paulo <rpaulo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -48,17 +48,15 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/taskqueue.h>
-#include <isa/isavar.h>
-#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
-
+#include <contrib/dev/acpica/acpi.h>
+#include <dev/acpica/acpivar.h>
#include <dev/asmc/asmcvar.h>
/*
* Device interface.
*/
-static void asmc_identify(driver_t *driver, device_t parent);
static int asmc_probe(device_t dev);
static int asmc_attach(device_t dev);
static int asmc_detach(device_t dev);
@@ -201,7 +199,6 @@ struct asmc_model asmc_models[] = {
* Driver methods.
*/
static device_method_t asmc_methods[] = {
- DEVMETHOD(device_identify, asmc_identify),
DEVMETHOD(device_probe, asmc_probe),
DEVMETHOD(device_attach, asmc_attach),
DEVMETHOD(device_detach, asmc_detach),
@@ -215,17 +212,21 @@ static driver_t asmc_driver = {
sizeof(struct asmc_softc)
};
-static devclass_t asmc_devclass;
+/*
+ * Debugging
+ */
+#define _COMPONENT ACPI_OEM
+ACPI_MODULE_NAME("ASMC")
+#ifdef DEBUG
+#define ASMC_DPRINTF(str) device_printf(dev, str)
+#endif
-DRIVER_MODULE(asmc, isa, asmc_driver, asmc_devclass, NULL, NULL);
+static char *asmc_ids[] = { "APP0001", NULL };
-static void
-asmc_identify(driver_t *driver, device_t parent)
-{
- if (device_find_child(parent, "asmc", -1) == NULL &&
- asmc_match(parent))
- BUS_ADD_CHILD(parent, 0, "asmc", -1);
-}
+static devclass_t asmc_devclass;
+
+DRIVER_MODULE(asmc, acpi, asmc_driver, asmc_devclass, NULL, NULL);
+MODULE_DEPEND(asmc, acpi, 1, 1, 1);
static struct asmc_model *
asmc_match(device_t dev)
@@ -250,13 +251,16 @@ asmc_probe(device_t dev)
{
struct asmc_model *model;
- if (resource_disabled("asmc", 0))
+ if (acpi_disabled("asmc"))
return (ENXIO);
+ if (ACPI_ID_PROBE(device_get_parent(dev), dev, asmc_ids) == NULL)
+ return (ENXIO);
+
model = asmc_match(dev);
- if (!model)
+ if (!model) {
+ device_printf(dev, "model not recognized\n");
return (ENXIO);
- if (isa_get_irq(dev) == -1)
- bus_set_resource(dev, SYS_RES_IRQ, 0, ASMC_IRQ, 1);
+ }
device_set_desc(dev, model->smc_desc);
return (BUS_PROBE_DEFAULT);
@@ -273,6 +277,13 @@ asmc_attach(device_t dev)
struct sysctl_oid *sysctlnode;
struct asmc_model *model;
+ sc->sc_ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
+ &sc->sc_rid_port, RF_ACTIVE);
+ if (sc->sc_ioport == NULL) {
+ device_printf(dev, "unable to allocate IO port\n");
+ return (ENOMEM);
+ }
+
sysctlctx = device_get_sysctl_ctx(dev);
sysctlnode = device_get_sysctl_tree(dev);
@@ -420,16 +431,16 @@ asmc_attach(device_t dev)
/*
* Allocate an IRQ for the SMS.
*/
- sc->sc_rid = 0;
- sc->sc_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_rid,
- ASMC_IRQ, ASMC_IRQ, 1, RF_ACTIVE);
- if (sc->sc_res == NULL) {
+ sc->sc_rid_irq = 0;
+ sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &sc->sc_rid_irq, RF_ACTIVE);
+ if (sc->sc_irq == NULL) {
device_printf(dev, "unable to allocate IRQ resource\n");
ret = ENXIO;
goto err2;
}
- ret = bus_setup_intr(dev, sc->sc_res,
+ ret = bus_setup_intr(dev, sc->sc_irq,
INTR_TYPE_MISC | INTR_MPSAFE,
#ifdef INTR_FILTER
asmc_sms_intrfast, asmc_sms_handler,
@@ -445,8 +456,10 @@ asmc_attach(device_t dev)
nosms:
return (0);
err1:
- bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid, sc->sc_res);
+ bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid_irq, sc->sc_irq);
err2:
+ bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_rid_port,
+ sc->sc_ioport);
mtx_destroy(&sc->sc_mtx);
if (sc->sc_sms_tq)
taskqueue_free(sc->sc_sms_tq);
@@ -464,9 +477,13 @@ asmc_detach(device_t dev)
taskqueue_free(sc->sc_sms_tq);
}
if (sc->sc_cookie)
- bus_teardown_intr(dev, sc->sc_res, sc->sc_cookie);
- if (sc->sc_res)
- bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid, sc->sc_res);
+ bus_teardown_intr(dev, sc->sc_irq, sc->sc_cookie);
+ if (sc->sc_irq)
+ bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid_irq,
+ sc->sc_irq);
+ if (sc->sc_ioport)
+ bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_rid_port,
+ sc->sc_ioport);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -486,6 +503,7 @@ asmc_init(device_t dev)
* We are ready to recieve interrupts from the SMS.
*/
buf[0] = 0x01;
+ ASMC_DPRINTF(("intok key\n"));
asmc_key_write(dev, ASMC_KEY_INTOK, buf, 1);
DELAY(50);
@@ -493,20 +511,24 @@ asmc_init(device_t dev)
* Initiate the polling intervals.
*/
buf[0] = 20; /* msecs */
+ ASMC_DPRINTF(("low int key\n"));
asmc_key_write(dev, ASMC_KEY_SMS_LOW_INT, buf, 1);
DELAY(200);
buf[0] = 20; /* msecs */
+ ASMC_DPRINTF(("high int key\n"));
asmc_key_write(dev, ASMC_KEY_SMS_HIGH_INT, buf, 1);
DELAY(200);
buf[0] = 0x00;
buf[1] = 0x60;
+ ASMC_DPRINTF(("sms low key\n"));
asmc_key_write(dev, ASMC_KEY_SMS_LOW, buf, 2);
DELAY(200);
buf[0] = 0x01;
buf[1] = 0xc0;
+ ASMC_DPRINTF(("sms high key\n"));
asmc_key_write(dev, ASMC_KEY_SMS_HIGH, buf, 2);
DELAY(200);
@@ -515,8 +537,9 @@ asmc_init(device_t dev)
* required.
*/
buf[0] = 0x01;
+ ASMC_DPRINTF(("sms flag key\n"));
asmc_key_write(dev, ASMC_KEY_SMS_FLAG, buf, 1);
- DELAY(50);
+ DELAY(200);
/*
* Wait up to 5 seconds for SMS initialization.
@@ -525,11 +548,14 @@ asmc_init(device_t dev)
if (asmc_key_read(dev, ASMC_KEY_SMS, buf, 2) == 0 &&
(buf[0] != 0x00 || buf[1] != 0x00)) {
error = 0;
+ device_printf(dev, "WARNING: Sudden Motion Sensor "
+ "not initialized!\n");
goto nosms;
}
buf[0] = ASMC_SMS_INIT1;
buf[1] = ASMC_SMS_INIT2;
+ ASMC_DPRINTF(("sms key\n"));
asmc_key_write(dev, ASMC_KEY_SMS, buf, 2);
DELAY(50);
}
@@ -562,18 +588,19 @@ nosms:
static int
asmc_wait(device_t dev, uint8_t val)
{
+ struct asmc_softc *sc = device_get_softc(dev);
u_int i;
val = val & ASMC_STATUS_MASK;
for (i = 0; i < 1000; i++) {
- if ((inb(ASMC_CMDPORT) & ASMC_STATUS_MASK) == val)
+ if ((ASMC_CMDPORT_READ(sc) & ASMC_STATUS_MASK) == val)
return (0);
DELAY(10);
}
device_printf(dev, "%s failed: 0x%x, 0x%x\n", __func__, val,
- inb(ASMC_CMDPORT));
+ ASMC_CMDPORT_READ(sc));
return (1);
}
@@ -586,22 +613,22 @@ asmc_key_read(device_t dev, const char *key, uint8_t *buf, uint8_t len)
mtx_lock_spin(&sc->sc_mtx);
- outb(ASMC_CMDPORT, ASMC_CMDREAD);
+ ASMC_CMDPORT_WRITE(sc, ASMC_CMDREAD);
if (asmc_wait(dev, 0x0c))
goto out;
for (i = 0; i < 4; i++) {
- outb(ASMC_DATAPORT, key[i]);
+ ASMC_DATAPORT_WRITE(sc, key[i]);
if (asmc_wait(dev, 0x04))
goto out;
}
- outb(ASMC_DATAPORT, len);
+ ASMC_DATAPORT_WRITE(sc, len);
for (i = 0; i < len; i++) {
if (asmc_wait(dev, 0x05))
goto out;
- buf[i] = inb(ASMC_DATAPORT);
+ buf[i] = ASMC_DATAPORT_READ(sc);
}
error = 0;
@@ -619,22 +646,25 @@ asmc_key_write(device_t dev, const char *key, uint8_t *buf, uint8_t len)
mtx_lock_spin(&sc->sc_mtx);
- outb(ASMC_CMDPORT, ASMC_CMDWRITE);
+ ASMC_DPRINTF(("cmd port: cmd write\n"));
+ ASMC_CMDPORT_WRITE(sc, ASMC_CMDWRITE);
if (asmc_wait(dev, 0x0c))
goto out;
+ ASMC_DPRINTF(("data port: key\n"));
for (i = 0; i < 4; i++) {
- outb(ASMC_DATAPORT, key[i]);
+ ASMC_DATAPORT_WRITE(sc, key[i]);
if (asmc_wait(dev, 0x04))
goto out;
}
+ ASMC_DPRINTF(("data port: length\n"));
+ ASMC_DATAPORT_WRITE(sc, len);
- outb(ASMC_DATAPORT, len);
-
+ ASMC_DPRINTF(("data port: buffer\n"));
for (i = 0; i < len; i++) {
if (asmc_wait(dev, 0x04))
goto out;
- outb(ASMC_DATAPORT, buf[i]);
+ ASMC_DATAPORT_WRITE(sc, buf[i]);
}
error = 0;
@@ -820,7 +850,7 @@ asmc_sms_intrfast(void *arg)
struct asmc_softc *sc = device_get_softc(dev);
mtx_lock_spin(&sc->sc_mtx);
- type = inb(ASMC_INTPORT);
+ type = ASMC_INTPORT_READ(sc);
mtx_unlock_spin(&sc->sc_mtx);
sc->sc_sms_intrtype = type;
@@ -886,7 +916,7 @@ asmc_sms_task(void *arg, int pending)
}
snprintf(notify, sizeof(notify), " notify=0x%x", type);
- devctl_notify("ISA", "asmc", "SMS", notify);
+ devctl_notify("ACPI", "asmc", "SMS", notify);
}
static int
diff --git a/sys/dev/asmc/asmcvar.h b/sys/dev/asmc/asmcvar.h
index 8e1c202..baee9c9 100644
--- a/sys/dev/asmc/asmcvar.h
+++ b/sys/dev/asmc/asmcvar.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2007 Rui Paulo <rpaulo@FreeBSD.org>
+ * Copyright (c) 2007, 2008 Rui Paulo <rpaulo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,8 +41,10 @@ struct asmc_softc {
struct sysctl_oid *sc_sms_tree;
struct sysctl_oid *sc_light_tree;
struct asmc_model *sc_model;
- int sc_rid;
- struct resource *sc_res;
+ int sc_rid_port;
+ int sc_rid_irq;
+ struct resource *sc_ioport;
+ struct resource *sc_irq;
void *sc_cookie;
int sc_sms_intrtype;
struct taskqueue *sc_sms_tq;
@@ -50,30 +52,26 @@ struct asmc_softc {
};
/*
- * The Sudden Motion Sensor is able to generate an interrupt when
- * there are certain critical conditions (free fall, high acceleration and
- * shocks).
- * The following IRQ is used.
- */
-#define ASMC_IRQ 6
-
-/*
* Data port.
*/
-#define ASMC_DATAPORT 0x300
+#define ASMC_DATAPORT_READ(sc) bus_read_1(sc->sc_ioport, 0x00)
+#define ASMC_DATAPORT_WRITE(sc, val) \
+ bus_write_1(sc->sc_ioport, 0, val)
#define ASMC_STATUS_MASK 0x0f
/*
* Command port.
*/
-#define ASMC_CMDPORT 0x304
+#define ASMC_CMDPORT_READ(sc) bus_read_1(sc->sc_ioport, 0x04)
+#define ASMC_CMDPORT_WRITE(sc, val) \
+ bus_write_1(sc->sc_ioport, 4, val)
#define ASMC_CMDREAD 0x10
#define ASMC_CMDWRITE 0x11
/*
* Interrupt port.
*/
-#define ASMC_INTPORT 0x31f
+#define ASMC_INTPORT_READ(sc) bus_read_1(sc->sc_ioport, 0x1f)
/* Number of keys */
OpenPOWER on IntegriCloud