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 = ¶m[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 = ¶m[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