acpi_acad.c revision 70271
1/*-
2 * Copyright (c) 2000 Takanori Watanabe
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/dev/acpica/acpi_acad.c 70271 2000-12-22 14:41:55Z takawata $
27 */
28
29#include "opt_acpi.h"
30#include <sys/param.h>
31#include <sys/kernel.h>
32#include <sys/bus.h>
33
34#include <machine/bus.h>
35#include <machine/resource.h>
36#include <sys/rman.h>
37#include <sys/ioccom.h>
38#include <sys/malloc.h>
39#include <sys/conf.h>
40
41#include  "acpi.h"
42#include <dev/acpica/acpivar.h>
43#include <dev/acpica/acpiio.h>
44
45
46#define ACPI_DEVICE_CHECK_PNP		0x00
47#define ACPI_DEVICE_CHECK_EXISTENCE	0x01
48#define ACPI_POWERSOURCE_STAT_CHANGE	0x80
49
50static void acpi_acad_get_status(void * );
51static void acpi_acad_notify_handler(ACPI_HANDLE , UINT32 ,void *);
52static int acpi_acad_probe(device_t);
53static int acpi_acad_attach(device_t);
54
55struct  acpi_acad_softc {
56	int status;
57};
58
59static void
60acpi_acad_get_status(void *context)
61{
62	device_t dev = context;
63	struct acpi_acad_softc *sc = device_get_softc(dev);
64	ACPI_HANDLE h = acpi_get_handle(dev);
65
66	if (acpi_EvaluateNumber(h, "_PSR", &sc->status) != AE_OK)
67		return;
68	device_printf(dev,"%s\n",(sc->status) ? "On Line" : "Off Line");
69}
70
71static void
72acpi_acad_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
73{
74	device_t dev = context;
75
76	device_printf(dev, "Notify %d\n", notify);
77	switch (notify) {
78	case ACPI_DEVICE_CHECK_PNP:
79	case ACPI_DEVICE_CHECK_EXISTENCE:
80	case ACPI_POWERSOURCE_STAT_CHANGE:
81		/*Temporally. It is better to notify policy manager*/
82		AcpiOsQueueForExecution(OSD_PRIORITY_LO,
83		    acpi_acad_get_status,context);
84		break;
85	default:
86		break;
87	}
88}
89
90static int
91acpi_acad_probe(device_t dev)
92{
93
94    if ((acpi_get_type(dev) == ACPI_TYPE_DEVICE) &&
95	acpi_MatchHid(dev, "ACPI0003")) {
96
97      /*
98       * Set device description
99       */
100	device_set_desc(dev, "AC adapter");
101	return(0);
102    }
103    return(ENXIO);
104}
105
106static int
107acpi_acad_attach(device_t dev)
108{
109
110	ACPI_HANDLE handle = acpi_get_handle(dev);
111	AcpiInstallNotifyHandler(handle,
112				 ACPI_DEVICE_NOTIFY,
113				 acpi_acad_notify_handler, dev);
114	/*Installing system notify is not so good*/
115	AcpiInstallNotifyHandler(handle,
116				 ACPI_SYSTEM_NOTIFY,
117				 acpi_acad_notify_handler, dev);
118
119	acpi_acad_get_status((void *)dev);
120	return(0);
121}
122
123static device_method_t acpi_acad_methods[] = {
124    /* Device interface */
125    DEVMETHOD(device_probe,	acpi_acad_probe),
126    DEVMETHOD(device_attach,	acpi_acad_attach),
127
128    {0, 0}
129};
130
131static driver_t acpi_acad_driver = {
132    "acpi_acad",
133    acpi_acad_methods,
134    sizeof(struct acpi_acad_softc),
135};
136
137static devclass_t acpi_acad_devclass;
138DRIVER_MODULE(acpi_acad,acpi,acpi_acad_driver,acpi_acad_devclass,0,0);
139