viaenv.c revision 1.33 1 1.33 ozaki /* $NetBSD: viaenv.c,v 1.33 2014/08/11 06:02:38 ozaki-r Exp $ */
2 1.1 joda
3 1.1 joda /*
4 1.1 joda * Copyright (c) 2000 Johan Danielsson
5 1.1 joda * All rights reserved.
6 1.1 joda *
7 1.2 thorpej * Redistribution and use in source and binary forms, with or without
8 1.2 thorpej * modification, are permitted provided that the following conditions
9 1.2 thorpej * are met:
10 1.1 joda *
11 1.2 thorpej * 1. Redistributions of source code must retain the above copyright
12 1.2 thorpej * notice, this list of conditions and the following disclaimer.
13 1.1 joda *
14 1.2 thorpej * 2. Redistributions in binary form must reproduce the above copyright
15 1.2 thorpej * notice, this list of conditions and the following disclaimer in the
16 1.2 thorpej * documentation and/or other materials provided with the distribution.
17 1.1 joda *
18 1.1 joda * 3. Neither the name of author nor the names of any contributors may
19 1.1 joda * be used to endorse or promote products derived from this
20 1.1 joda * software without specific prior written permission.
21 1.1 joda *
22 1.1 joda * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
23 1.1 joda * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 1.1 joda * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 1.1 joda * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 1.1 joda * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 1.1 joda * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 1.1 joda * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 1.1 joda * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 1.1 joda * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 1.1 joda * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 1.1 joda * POSSIBILITY OF SUCH DAMAGE.
33 1.1 joda */
34 1.1 joda
35 1.18 xtraeme /*
36 1.18 xtraeme * Driver for the hardware monitoring and power management timer
37 1.18 xtraeme * in the VIA VT82C686A and VT8231 South Bridges.
38 1.18 xtraeme */
39 1.5 lukem
40 1.5 lukem #include <sys/cdefs.h>
41 1.33 ozaki __KERNEL_RCSID(0, "$NetBSD: viaenv.c,v 1.33 2014/08/11 06:02:38 ozaki-r Exp $");
42 1.1 joda
43 1.1 joda #include <sys/param.h>
44 1.1 joda #include <sys/systm.h>
45 1.1 joda #include <sys/kernel.h>
46 1.1 joda #include <sys/device.h>
47 1.1 joda
48 1.24 ad #include <sys/bus.h>
49 1.18 xtraeme #include <dev/ic/acpipmtimer.h>
50 1.18 xtraeme
51 1.1 joda #include <dev/pci/pcivar.h>
52 1.1 joda #include <dev/pci/pcireg.h>
53 1.18 xtraeme #include <dev/pci/pcidevs.h>
54 1.1 joda
55 1.3 thorpej #include <dev/sysmon/sysmonvar.h>
56 1.3 thorpej
57 1.1 joda #ifdef VIAENV_DEBUG
58 1.1 joda unsigned int viaenv_debug = 0;
59 1.18 xtraeme #define DPRINTF(X) do { if (viaenv_debug) printf X ; } while(0)
60 1.1 joda #else
61 1.1 joda #define DPRINTF(X)
62 1.1 joda #endif
63 1.1 joda
64 1.2 thorpej #define VIANUMSENSORS 10 /* three temp, two fan, five voltage */
65 1.1 joda
66 1.1 joda struct viaenv_softc {
67 1.2 thorpej bus_space_tag_t sc_iot;
68 1.2 thorpej bus_space_handle_t sc_ioh;
69 1.18 xtraeme bus_space_handle_t sc_pm_ioh;
70 1.1 joda
71 1.2 thorpej int sc_fan_div[2]; /* fan RPM divisor */
72 1.1 joda
73 1.25 xtraeme struct sysmon_envsys *sc_sme;
74 1.25 xtraeme envsys_data_t sc_sensor[VIANUMSENSORS];
75 1.1 joda
76 1.6 thorpej struct timeval sc_lastread;
77 1.1 joda };
78 1.3 thorpej
79 1.18 xtraeme /* autoconf(9) glue */
80 1.27 xtraeme static int viaenv_match(device_t, cfdata_t, void *);
81 1.27 xtraeme static void viaenv_attach(device_t, device_t, void *);
82 1.18 xtraeme
83 1.27 xtraeme CFATTACH_DECL_NEW(viaenv, sizeof(struct viaenv_softc),
84 1.18 xtraeme viaenv_match, viaenv_attach, NULL, NULL);
85 1.18 xtraeme
86 1.18 xtraeme /* envsys(4) glue */
87 1.25 xtraeme static void viaenv_refresh(struct sysmon_envsys *, envsys_data_t *);
88 1.18 xtraeme
89 1.18 xtraeme static int val_to_uK(unsigned int);
90 1.18 xtraeme static int val_to_rpm(unsigned int, int);
91 1.18 xtraeme static long val_to_uV(unsigned int, int);
92 1.1 joda
93 1.1 joda static int
94 1.27 xtraeme viaenv_match(device_t parent, cfdata_t match, void *aux)
95 1.1 joda {
96 1.27 xtraeme struct pci_attach_args *pa = aux;
97 1.2 thorpej
98 1.18 xtraeme if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_VIATECH)
99 1.18 xtraeme return 0;
100 1.18 xtraeme
101 1.18 xtraeme switch (PCI_PRODUCT(pa->pa_id)) {
102 1.18 xtraeme case PCI_PRODUCT_VIATECH_VT82C686A_SMB:
103 1.18 xtraeme case PCI_PRODUCT_VIATECH_VT8231_PWR:
104 1.2 thorpej return 1;
105 1.18 xtraeme default:
106 1.18 xtraeme return 0;
107 1.18 xtraeme }
108 1.1 joda }
109 1.1 joda
110 1.2 thorpej /*
111 1.2 thorpej * XXX there doesn't seem to exist much hard documentation on how to
112 1.2 thorpej * convert the raw values to usable units, this code is more or less
113 1.2 thorpej * stolen from the Linux driver, but changed to suit our conditions
114 1.2 thorpej */
115 1.2 thorpej
116 1.2 thorpej /*
117 1.2 thorpej * lookup-table to translate raw values to uK, this is the same table
118 1.2 thorpej * used by the Linux driver (modulo units); there is a fifth degree
119 1.2 thorpej * polynomial that supposedly been used to generate this table, but I
120 1.2 thorpej * haven't been able to figure out how -- it doesn't give the same values
121 1.2 thorpej */
122 1.2 thorpej
123 1.3 thorpej static const long val_to_temp[] = {
124 1.2 thorpej 20225, 20435, 20645, 20855, 21045, 21245, 21425, 21615, 21785, 21955,
125 1.2 thorpej 22125, 22285, 22445, 22605, 22755, 22895, 23035, 23175, 23315, 23445,
126 1.2 thorpej 23565, 23695, 23815, 23925, 24045, 24155, 24265, 24365, 24465, 24565,
127 1.2 thorpej 24665, 24765, 24855, 24945, 25025, 25115, 25195, 25275, 25355, 25435,
128 1.2 thorpej 25515, 25585, 25655, 25725, 25795, 25865, 25925, 25995, 26055, 26115,
129 1.2 thorpej 26175, 26235, 26295, 26355, 26405, 26465, 26515, 26575, 26625, 26675,
130 1.2 thorpej 26725, 26775, 26825, 26875, 26925, 26975, 27025, 27065, 27115, 27165,
131 1.2 thorpej 27205, 27255, 27295, 27345, 27385, 27435, 27475, 27515, 27565, 27605,
132 1.2 thorpej 27645, 27685, 27735, 27775, 27815, 27855, 27905, 27945, 27985, 28025,
133 1.2 thorpej 28065, 28105, 28155, 28195, 28235, 28275, 28315, 28355, 28405, 28445,
134 1.2 thorpej 28485, 28525, 28565, 28615, 28655, 28695, 28735, 28775, 28825, 28865,
135 1.2 thorpej 28905, 28945, 28995, 29035, 29075, 29125, 29165, 29205, 29245, 29295,
136 1.2 thorpej 29335, 29375, 29425, 29465, 29505, 29555, 29595, 29635, 29685, 29725,
137 1.2 thorpej 29765, 29815, 29855, 29905, 29945, 29985, 30035, 30075, 30125, 30165,
138 1.2 thorpej 30215, 30255, 30305, 30345, 30385, 30435, 30475, 30525, 30565, 30615,
139 1.2 thorpej 30655, 30705, 30755, 30795, 30845, 30885, 30935, 30975, 31025, 31075,
140 1.2 thorpej 31115, 31165, 31215, 31265, 31305, 31355, 31405, 31455, 31505, 31545,
141 1.2 thorpej 31595, 31645, 31695, 31745, 31805, 31855, 31905, 31955, 32005, 32065,
142 1.2 thorpej 32115, 32175, 32225, 32285, 32335, 32395, 32455, 32515, 32575, 32635,
143 1.2 thorpej 32695, 32755, 32825, 32885, 32955, 33025, 33095, 33155, 33235, 33305,
144 1.2 thorpej 33375, 33455, 33525, 33605, 33685, 33765, 33855, 33935, 34025, 34115,
145 1.2 thorpej 34205, 34295, 34395, 34495, 34595, 34695, 34805, 34905, 35015, 35135,
146 1.2 thorpej 35245, 35365, 35495, 35615, 35745, 35875, 36015, 36145, 36295, 36435,
147 1.2 thorpej 36585, 36745, 36895, 37065, 37225, 37395, 37575, 37755, 37935, 38125,
148 1.2 thorpej 38325, 38525, 38725, 38935, 39155, 39375, 39605, 39835, 40075, 40325,
149 1.2 thorpej 40575, 40835, 41095, 41375, 41655, 41935,
150 1.1 joda };
151 1.1 joda
152 1.1 joda /* use above table to convert values to temperatures in micro-Kelvins */
153 1.1 joda static int
154 1.1 joda val_to_uK(unsigned int val)
155 1.1 joda {
156 1.2 thorpej int i = val / 4;
157 1.2 thorpej int j = val % 4;
158 1.2 thorpej
159 1.2 thorpej assert(i >= 0 && i <= 255);
160 1.2 thorpej
161 1.2 thorpej if (j == 0 || i == 255)
162 1.2 thorpej return val_to_temp[i] * 10000;
163 1.2 thorpej
164 1.2 thorpej /* is linear interpolation ok? */
165 1.2 thorpej return (val_to_temp[i] * (4 - j) +
166 1.2 thorpej val_to_temp[i + 1] * j) * 2500 /* really: / 4 * 10000 */ ;
167 1.1 joda }
168 1.1 joda
169 1.1 joda static int
170 1.1 joda val_to_rpm(unsigned int val, int div)
171 1.1 joda {
172 1.2 thorpej
173 1.2 thorpej if (val == 0)
174 1.2 thorpej return 0;
175 1.2 thorpej
176 1.2 thorpej return 1350000 / val / div;
177 1.1 joda }
178 1.1 joda
179 1.1 joda static long
180 1.1 joda val_to_uV(unsigned int val, int index)
181 1.1 joda {
182 1.3 thorpej static const long mult[] =
183 1.3 thorpej {1250000, 1250000, 1670000, 2600000, 6300000};
184 1.2 thorpej
185 1.2 thorpej assert(index >= 0 && index <= 4);
186 1.2 thorpej
187 1.2 thorpej return (25LL * val + 133) * mult[index] / 2628;
188 1.1 joda }
189 1.1 joda
190 1.1 joda #define VIAENV_TSENS3 0x1f
191 1.1 joda #define VIAENV_TSENS1 0x20
192 1.1 joda #define VIAENV_TSENS2 0x21
193 1.1 joda #define VIAENV_VSENS1 0x22
194 1.1 joda #define VIAENV_VSENS2 0x23
195 1.1 joda #define VIAENV_VCORE 0x24
196 1.1 joda #define VIAENV_VSENS3 0x25
197 1.1 joda #define VIAENV_VSENS4 0x26
198 1.1 joda #define VIAENV_FAN1 0x29
199 1.1 joda #define VIAENV_FAN2 0x2a
200 1.1 joda #define VIAENV_FANCONF 0x47 /* fan configuration */
201 1.1 joda #define VIAENV_TLOW 0x49 /* temperature low order value */
202 1.1 joda #define VIAENV_TIRQ 0x4b /* temperature interrupt configuration */
203 1.1 joda
204 1.18 xtraeme #define VIAENV_GENCFG 0x40 /* general configuration */
205 1.18 xtraeme #define VIAENV_GENCFG_TMR32 (1 << 11) /* 32-bit PM timer */
206 1.18 xtraeme #define VIAENV_GENCFG_PMEN (1 << 15) /* enable PM I/O space */
207 1.18 xtraeme #define VIAENV_PMBASE 0x48 /* power management I/O space base */
208 1.18 xtraeme #define VIAENV_PMSIZE 128 /* HWM and power management I/O space size */
209 1.18 xtraeme #define VIAENV_PM_TMR 0x08 /* PM timer */
210 1.18 xtraeme #define VIAENV_HWMON_CONF 0x70 /* HWMon I/O base */
211 1.18 xtraeme #define VIAENV_HWMON_CTL 0x74 /* HWMon control register */
212 1.1 joda
213 1.1 joda static void
214 1.21 xtraeme viaenv_refresh_sensor_data(struct viaenv_softc *sc, envsys_data_t *edata)
215 1.1 joda {
216 1.6 thorpej static const struct timeval onepointfive = { 1, 500000 };
217 1.21 xtraeme static int old_sensor = -1;
218 1.14 kardel struct timeval t, utv;
219 1.18 xtraeme uint8_t v, v2;
220 1.14 kardel int i;
221 1.6 thorpej
222 1.6 thorpej /* Read new values at most once every 1.5 seconds. */
223 1.6 thorpej timeradd(&sc->sc_lastread, &onepointfive, &t);
224 1.14 kardel getmicrouptime(&utv);
225 1.14 kardel i = timercmp(&utv, &t, >);
226 1.6 thorpej if (i)
227 1.14 kardel sc->sc_lastread = utv;
228 1.6 thorpej
229 1.21 xtraeme if (i == 0 && old_sensor == edata->sensor)
230 1.6 thorpej return;
231 1.6 thorpej
232 1.21 xtraeme old_sensor = edata->sensor;
233 1.21 xtraeme
234 1.6 thorpej /* temperature */
235 1.21 xtraeme if (edata->sensor == 0) {
236 1.21 xtraeme v = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TIRQ);
237 1.21 xtraeme v2 = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TSENS1);
238 1.21 xtraeme DPRINTF(("TSENS1 = %d\n", (v2 << 2) | (v >> 6)));
239 1.22 xtraeme edata->value_cur = val_to_uK((v2 << 2) | (v >> 6));
240 1.22 xtraeme edata->state = ENVSYS_SVALID;
241 1.21 xtraeme } else if (edata->sensor == 1) {
242 1.21 xtraeme v = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TLOW);
243 1.21 xtraeme v2 = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TSENS2);
244 1.21 xtraeme DPRINTF(("TSENS2 = %d\n", (v2 << 2) | ((v >> 4) & 0x3)));
245 1.22 xtraeme edata->value_cur = val_to_uK((v2 << 2) | ((v >> 4) & 0x3));
246 1.22 xtraeme edata->state = ENVSYS_SVALID;
247 1.21 xtraeme } else if (edata->sensor == 2) {
248 1.21 xtraeme v = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TLOW);
249 1.21 xtraeme v2 = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_TSENS3);
250 1.21 xtraeme DPRINTF(("TSENS3 = %d\n", (v2 << 2) | (v >> 6)));
251 1.22 xtraeme edata->value_cur = val_to_uK((v2 << 2) | (v >> 6));
252 1.22 xtraeme edata->state = ENVSYS_SVALID;
253 1.21 xtraeme } else if (edata->sensor > 2 && edata->sensor < 5) {
254 1.21 xtraeme /* fans */
255 1.21 xtraeme v = bus_space_read_1(sc->sc_iot, sc->sc_ioh, VIAENV_FANCONF);
256 1.2 thorpej
257 1.21 xtraeme sc->sc_fan_div[0] = 1 << ((v >> 4) & 0x3);
258 1.21 xtraeme sc->sc_fan_div[1] = 1 << ((v >> 6) & 0x3);
259 1.1 joda
260 1.6 thorpej v = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
261 1.21 xtraeme VIAENV_FAN1 + edata->sensor - 3);
262 1.21 xtraeme DPRINTF(("FAN%d = %d / %d\n", edata->sensor - 3, v,
263 1.21 xtraeme sc->sc_fan_div[edata->sensor - 3]));
264 1.22 xtraeme edata->value_cur = val_to_rpm(v,
265 1.21 xtraeme sc->sc_fan_div[edata->sensor - 3]);
266 1.22 xtraeme edata->state = ENVSYS_SVALID;
267 1.21 xtraeme } else {
268 1.6 thorpej v = bus_space_read_1(sc->sc_iot, sc->sc_ioh,
269 1.21 xtraeme VIAENV_VSENS1 + edata->sensor - 5);
270 1.21 xtraeme DPRINTF(("V%d = %d\n", edata->sensor - 5, v));
271 1.22 xtraeme edata->value_cur = val_to_uV(v, edata->sensor - 5);
272 1.22 xtraeme edata->state = ENVSYS_SVALID;
273 1.2 thorpej }
274 1.1 joda }
275 1.1 joda
276 1.1 joda static void
277 1.27 xtraeme viaenv_attach(device_t parent, device_t self, void *aux)
278 1.1 joda {
279 1.27 xtraeme struct viaenv_softc *sc = device_private(self);
280 1.27 xtraeme struct pci_attach_args *pa = aux;
281 1.2 thorpej pcireg_t iobase, control;
282 1.2 thorpej int i;
283 1.2 thorpej
284 1.18 xtraeme aprint_naive("\n");
285 1.18 xtraeme aprint_normal(": VIA Technologies ");
286 1.18 xtraeme switch (PCI_PRODUCT(pa->pa_id)) {
287 1.18 xtraeme case PCI_PRODUCT_VIATECH_VT82C686A_SMB:
288 1.18 xtraeme aprint_normal("VT82C686A Hardware Monitor\n");
289 1.18 xtraeme break;
290 1.18 xtraeme case PCI_PRODUCT_VIATECH_VT8231_PWR:
291 1.18 xtraeme aprint_normal("VT8231 Hardware Monitor\n");
292 1.18 xtraeme break;
293 1.18 xtraeme default:
294 1.18 xtraeme aprint_normal("Unknown Hardware Monitor\n");
295 1.18 xtraeme break;
296 1.2 thorpej }
297 1.18 xtraeme
298 1.30 phx sc->sc_iot = pa->pa_iot;
299 1.30 phx
300 1.18 xtraeme iobase = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_HWMON_CONF);
301 1.29 ad DPRINTF(("%s: iobase 0x%x\n", device_xname(self), iobase));
302 1.18 xtraeme control = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_HWMON_CTL);
303 1.18 xtraeme
304 1.18 xtraeme /* Check if the Hardware Monitor enable bit is set */
305 1.18 xtraeme if ((control & 1) == 0) {
306 1.27 xtraeme aprint_normal_dev(self, "Hardware Monitor disabled\n");
307 1.18 xtraeme goto nohwm;
308 1.2 thorpej }
309 1.2 thorpej
310 1.18 xtraeme /* Map Hardware Monitor I/O space */
311 1.18 xtraeme if (bus_space_map(sc->sc_iot, iobase & 0xff80,
312 1.18 xtraeme VIAENV_PMSIZE, 0, &sc->sc_ioh)) {
313 1.27 xtraeme aprint_error_dev(self, "failed to map I/O space\n");
314 1.18 xtraeme goto nohwm;
315 1.18 xtraeme }
316 1.2 thorpej
317 1.21 xtraeme for (i = 0; i < 3; i++)
318 1.25 xtraeme sc->sc_sensor[i].units = ENVSYS_STEMP;
319 1.2 thorpej
320 1.18 xtraeme #define COPYDESCR(x, y) \
321 1.18 xtraeme do { \
322 1.18 xtraeme strlcpy((x), (y), sizeof(x)); \
323 1.18 xtraeme } while (0)
324 1.18 xtraeme
325 1.25 xtraeme COPYDESCR(sc->sc_sensor[0].desc, "TSENS1");
326 1.25 xtraeme COPYDESCR(sc->sc_sensor[1].desc, "TSENS2");
327 1.25 xtraeme COPYDESCR(sc->sc_sensor[2].desc, "TSENS3");
328 1.18 xtraeme
329 1.21 xtraeme for (i = 3; i < 5; i++)
330 1.25 xtraeme sc->sc_sensor[i].units = ENVSYS_SFANRPM;
331 1.18 xtraeme
332 1.25 xtraeme COPYDESCR(sc->sc_sensor[3].desc, "FAN1");
333 1.25 xtraeme COPYDESCR(sc->sc_sensor[4].desc, "FAN2");
334 1.18 xtraeme
335 1.21 xtraeme for (i = 5; i < 10; i++)
336 1.25 xtraeme sc->sc_sensor[i].units = ENVSYS_SVOLTS_DC;
337 1.18 xtraeme
338 1.25 xtraeme COPYDESCR(sc->sc_sensor[5].desc, "VSENS1"); /* CPU core (2V) */
339 1.25 xtraeme COPYDESCR(sc->sc_sensor[6].desc, "VSENS2"); /* NB core? (2.5V) */
340 1.25 xtraeme COPYDESCR(sc->sc_sensor[7].desc, "Vcore"); /* Vcore (3.3V) */
341 1.25 xtraeme COPYDESCR(sc->sc_sensor[8].desc, "VSENS3"); /* VSENS3 (5V) */
342 1.25 xtraeme COPYDESCR(sc->sc_sensor[9].desc, "VSENS4"); /* VSENS4 (12V) */
343 1.1 joda
344 1.18 xtraeme #undef COPYDESCR
345 1.18 xtraeme
346 1.33 ozaki for (i = 0; i < 10; i++) {
347 1.31 pgoyette sc->sc_sensor[i].state = ENVSYS_SINVALID;
348 1.32 tls sc->sc_sensor[i].flags |= ENVSYS_FHAS_ENTROPY;
349 1.33 ozaki }
350 1.31 pgoyette
351 1.26 njoly sc->sc_sme = sysmon_envsys_create();
352 1.26 njoly
353 1.26 njoly /* Initialize sensors */
354 1.26 njoly for (i = 0; i < VIANUMSENSORS; i++) {
355 1.26 njoly if (sysmon_envsys_sensor_attach(sc->sc_sme,
356 1.26 njoly &sc->sc_sensor[i])) {
357 1.26 njoly sysmon_envsys_destroy(sc->sc_sme);
358 1.26 njoly return;
359 1.26 njoly }
360 1.26 njoly }
361 1.26 njoly
362 1.3 thorpej /*
363 1.3 thorpej * Hook into the System Monitor.
364 1.3 thorpej */
365 1.27 xtraeme sc->sc_sme->sme_name = device_xname(self);
366 1.25 xtraeme sc->sc_sme->sme_cookie = sc;
367 1.25 xtraeme sc->sc_sme->sme_refresh = viaenv_refresh;
368 1.3 thorpej
369 1.25 xtraeme if (sysmon_envsys_register(sc->sc_sme)) {
370 1.27 xtraeme aprint_error_dev(self, "unable to register with sysmon\n");
371 1.25 xtraeme sysmon_envsys_destroy(sc->sc_sme);
372 1.25 xtraeme return;
373 1.25 xtraeme }
374 1.18 xtraeme
375 1.18 xtraeme nohwm:
376 1.18 xtraeme /* Check if power management I/O space is enabled */
377 1.18 xtraeme control = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_GENCFG);
378 1.18 xtraeme if ((control & VIAENV_GENCFG_PMEN) == 0) {
379 1.27 xtraeme aprint_normal_dev(self,
380 1.27 xtraeme "Power Managament controller disabled\n");
381 1.18 xtraeme goto nopm;
382 1.18 xtraeme }
383 1.18 xtraeme
384 1.18 xtraeme /* Map power management I/O space */
385 1.18 xtraeme iobase = pci_conf_read(pa->pa_pc, pa->pa_tag, VIAENV_PMBASE);
386 1.18 xtraeme if (bus_space_map(sc->sc_iot, PCI_MAPREG_IO_ADDR(iobase),
387 1.18 xtraeme VIAENV_PMSIZE, 0, &sc->sc_pm_ioh)) {
388 1.27 xtraeme aprint_error_dev(self, "failed to map PM I/O space\n");
389 1.18 xtraeme goto nopm;
390 1.18 xtraeme }
391 1.18 xtraeme
392 1.18 xtraeme /* Attach our PM timer with the generic acpipmtimer function */
393 1.27 xtraeme acpipmtimer_attach(self, sc->sc_iot, sc->sc_pm_ioh,
394 1.18 xtraeme VIAENV_PM_TMR,
395 1.18 xtraeme ((control & VIAENV_GENCFG_TMR32) ? ACPIPMT_32BIT : 0));
396 1.18 xtraeme
397 1.18 xtraeme nopm:
398 1.18 xtraeme return;
399 1.1 joda }
400 1.1 joda
401 1.25 xtraeme static void
402 1.25 xtraeme viaenv_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
403 1.1 joda {
404 1.3 thorpej struct viaenv_softc *sc = sme->sme_cookie;
405 1.1 joda
406 1.21 xtraeme viaenv_refresh_sensor_data(sc, edata);
407 1.1 joda }
408