acpibat.c revision 1.6
1/* $OpenBSD: acpibat.c,v 1.6 2005/12/28 03:25:15 marco Exp $ */
2/*
3 * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/param.h>
19#include <sys/systm.h>
20#include <sys/device.h>
21#include <sys/malloc.h>
22
23#include <machine/bus.h>
24
25#include <dev/acpi/acpireg.h>
26#include <dev/acpi/acpivar.h>
27#include <dev/acpi/acpidev.h>
28#include <dev/acpi/amltypes.h>
29#include <dev/acpi/dsdt.h>
30
31int acpibat_match(struct device *, void *, void *);
32void acpibat_attach(struct device *, struct device *, void *);
33
34struct acpibat_softc {
35	struct device		sc_dev;
36
37	bus_space_tag_t		sc_iot;
38	bus_space_handle_t	sc_ioh;
39
40	struct acpi_softc	*sc_acpi;
41	struct aml_node		*sc_devnode;
42
43	struct acpibat_bif	sc_bif;
44	struct acpibat_bst	sc_bst;
45};
46
47struct cfattach acpibat_ca = {
48	sizeof(struct acpibat_softc), acpibat_match, acpibat_attach
49};
50
51struct cfdriver acpibat_cd = {
52	NULL, "acpibat", DV_DULL
53};
54
55int acpibat_getbif(struct acpibat_softc *);
56int acpibat_getbst(struct acpibat_softc *);
57
58int
59acpibat_match(struct device *parent, void *match, void *aux)
60{
61	struct acpi_attach_args *aa = aux;
62	struct cfdata *cf = match;
63
64	/* sanity */
65	if (aa->aaa_name == NULL ||
66	    strcmp(aa->aaa_name, cf->cf_driver->cd_name) != 0 ||
67	    aa->aaa_table != NULL)
68		return (0);
69
70	return (1);
71}
72
73void
74acpibat_attach(struct device *parent, struct device *self, void *aux)
75{
76	struct acpibat_softc *sc = (struct acpibat_softc *) self;
77	struct acpi_attach_args *aa = aux;
78
79	printf("\n");
80
81	sc->sc_acpi = (struct acpi_softc *)parent;
82	sc->sc_devnode = aa->aaa_node->child;
83	/* acpibat_getbif(sc); */
84
85	printf("\n");
86}
87
88int
89acpibat_getbif(struct acpibat_softc *sc)
90{
91	struct aml_value res, env;
92
93	memset(&res, 0, sizeof(res));
94	memset(&env, 0, sizeof(env));
95
96	if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_BIF", &res, &env)) {
97		dprintf(50, "%s: no _BIF\n",
98		    DEVNAME(sc));
99		return (1);
100	}
101
102	if (res.length != 13) {
103		printf("%s: invalid _BIF, battery information not saved\n",
104		    DEVNAME(sc));
105		return (1);
106	}
107
108	sc->sc_bif.bif_power_unit = aml_intval(&res.v_package[0]);
109	sc->sc_bif.bif_capacity = aml_intval(&res.v_package[1]);
110	sc->sc_bif.bif_last_capacity = aml_intval(&res.v_package[2]);
111	sc->sc_bif.bif_technology = aml_intval(&res.v_package[3]);
112	sc->sc_bif.bif_voltage = aml_intval(&res.v_package[4]);
113	sc->sc_bif.bif_warning = aml_intval(&res.v_package[5]);
114	sc->sc_bif.bif_low = aml_intval(&res.v_package[6]);
115	sc->sc_bif.bif_cap_granu1 = aml_intval(&res.v_package[7]);
116	sc->sc_bif.bif_cap_granu2 = aml_intval(&res.v_package[8]);
117	sc->sc_bif.bif_model = aml_strval(&res.v_package[9]);
118	sc->sc_bif.bif_serial = aml_strval(&res.v_package[10]);
119	sc->sc_bif.bif_type = aml_strval(&res.v_package[11]);
120	sc->sc_bif.bif_oem = aml_strval(&res.v_package[12]);
121
122	dprintf(20, "power_unit: %u capacity: %u last_cap: %u tech: %u "
123	    "volt: %u warn: %u low: %u gran1: %u gran2: %d model: %s "
124	    "serial: %s type: %s oem: %s\n",
125	    sc->sc_bif.bif_power_unit,
126	    sc->sc_bif.bif_capacity,
127	    sc->sc_bif.bif_last_capacity,
128	    sc->sc_bif.bif_technology,
129	    sc->sc_bif.bif_voltage,
130	    sc->sc_bif.bif_warning,
131	    sc->sc_bif.bif_low,
132	    sc->sc_bif.bif_cap_granu1,
133	    sc->sc_bif.bif_cap_granu2,
134	    sc->sc_bif.bif_model,
135	    sc->sc_bif.bif_serial,
136	    sc->sc_bif.bif_type,
137	    sc->sc_bif.bif_oem);
138
139	return (0);
140}
141
142int
143acpibat_getbst(struct acpibat_softc *sc)
144{
145	struct aml_value res, env;
146
147	memset(&res, 0, sizeof(res));
148	memset(&env, 0, sizeof(env));
149
150	if (aml_eval_name(sc->sc_acpi, sc->sc_devnode, "_BST", &res, &env)) {
151		dprintf(50, "%s: no _BST\n",
152		    DEVNAME(sc));
153		return (1);
154	}
155
156	if (res.length != 4) {
157		printf("%s: invalid _BST, battery status not saved\n",
158		    DEVNAME(sc));
159		return (1);
160	}
161
162	sc->sc_bst.bst_state = aml_intval(&res.v_package[0]);
163	sc->sc_bst.bst_rate = aml_intval(&res.v_package[1]);
164	sc->sc_bst.bst_capacity = aml_intval(&res.v_package[2]);
165	sc->sc_bst.bst_voltage = aml_intval(&res.v_package[3]);
166
167	dprintf(20, "state: %u rate: %u cap: %u volt: %u ",
168	    sc->sc_bst.bst_state,
169	    sc->sc_bst.bst_rate,
170	    sc->sc_bst.bst_capacity,
171	    sc->sc_bst.bst_voltage);
172
173	return (0);
174}
175