acpi_thermal.c revision 70271
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *	$FreeBSD: head/sys/dev/acpica/acpi_thermal.c 70271 2000-12-22 14:41:55Z takawata $
28 */
29
30#include "opt_acpi.h"
31#include <sys/param.h>
32#include <sys/kernel.h>
33#include <sys/bus.h>
34
35#include "acpi.h"
36
37#include <dev/acpica/acpivar.h>
38
39/*
40 * Hooks for the ACPI CA debugging infrastructure
41 */
42#define _COMPONENT	THERMAL_CONTROL
43MODULE_NAME("THERMAL")
44
45#define TZ_KELVTOC(x)	(((x) - 2732) / 10), (((x) - 2732) % 10)
46
47struct acpi_tz_softc {
48    device_t	tz_dev;
49    ACPI_HANDLE	tz_handle;
50};
51
52static int	acpi_tz_probe(device_t dev);
53static int	acpi_tz_attach(device_t dev);
54static void     acpi_tz_check_tripping_point(void *context);
55static device_method_t acpi_tz_methods[] = {
56    /* Device interface */
57    DEVMETHOD(device_probe,	acpi_tz_probe),
58    DEVMETHOD(device_attach,	acpi_tz_attach),
59
60    {0, 0}
61};
62
63static driver_t acpi_tz_driver = {
64    "acpi_tz",
65    acpi_tz_methods,
66    sizeof(struct acpi_tz_softc),
67};
68
69devclass_t acpi_tz_devclass;
70DRIVER_MODULE(acpi_tz, acpi, acpi_tz_driver, acpi_tz_devclass, 0, 0);
71
72static int
73acpi_tz_probe(device_t dev)
74{
75
76    FUNCTION_TRACE(__FUNCTION__);
77
78    if ((acpi_get_type(dev) == ACPI_TYPE_THERMAL) &&
79	!acpi_disabled("thermal")) {
80	device_set_desc(dev, "thermal zone");
81	return_VALUE(0);
82    }
83    return_VALUE(ENXIO);
84}
85static void acpi_tz_check_tripping_point(void *context)
86{
87	device_t dev = context;
88	struct acpi_tz_softc *sc;
89	UINT32 param[4];
90	ACPI_BUFFER b;
91	sc = device_get_softc(dev);
92	b.Pointer = &param[0];
93	b.Length = sizeof(param);
94	if((AcpiEvaluateObject(sc->tz_handle,"_TMP",NULL,&b)) != AE_OK){
95		device_printf(dev,"CANNOT FOUND _TMP\n");
96		return;
97	}
98
99	device_printf(dev,"%d.%d K\n",param[1]/10,param[1]%10);
100	return;
101}
102#define ACPI_TZ_STATUS_CHANGE 0x80
103#define ACPI_TZ_TRIPPOINT_CHANGE 0x81
104static void acpi_tz_notify_handler( ACPI_HANDLE h,UINT32 notify, void *context)
105{
106	device_t dev = context;
107
108	switch(notify){
109	case ACPI_TZ_STATUS_CHANGE:
110	case ACPI_TZ_TRIPPOINT_CHANGE:
111		/*Check trip point*/
112		AcpiOsQueueForExecution(OSD_PRIORITY_LO,
113		    acpi_tz_check_tripping_point,context);
114		break;
115  }
116}
117static int
118acpi_tz_attach(device_t dev)
119{
120    struct acpi_tz_softc	*sc;
121    UINT32			param[4];
122    ACPI_BUFFER			buf;
123    ACPI_STATUS			status;
124
125    FUNCTION_TRACE(__FUNCTION__);
126
127    sc = device_get_softc(dev);
128    sc->tz_dev = dev;
129    sc->tz_handle = acpi_get_handle(dev);
130
131    buf.Pointer = &param[0];
132    buf.Length = sizeof(param);
133    if ((status = AcpiEvaluateObject(sc->tz_handle, "_TMP", NULL, &buf)) != AE_OK) {
134	device_printf(sc->tz_dev, "can't fetch temperature - %s\n", acpi_strerror(status));
135	return_VALUE(ENXIO);
136    }
137    if (param[0] != ACPI_TYPE_NUMBER) {
138	device_printf(sc->tz_dev, "%s._TMP does not evaluate to ACPI_TYPE_NUMBER\n",
139		      acpi_name(sc->tz_handle));
140	return_VALUE(ENXIO);
141    }
142    device_printf(sc->tz_dev, "current temperature %d.%dC\n", TZ_KELVTOC(param[1]));
143
144    AcpiInstallNotifyHandler(sc->tz_handle,ACPI_DEVICE_NOTIFY,
145			     acpi_tz_notify_handler,dev);
146    return_VALUE(0);
147}
148
149
150
151
152
153
154
155