Home | History | Annotate | Line # | Download | only in pci
      1  1.34  jdolecek /*	$NetBSD: viaenv.c,v 1.34 2018/03/04 13:24:17 jdolecek 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.34  jdolecek __KERNEL_RCSID(0, "$NetBSD: viaenv.c,v 1.34 2018/03/04 13:24:17 jdolecek 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.34  jdolecek 	case PCI_PRODUCT_VIATECH_VT82C686A_PWR:
    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.34  jdolecek 	case PCI_PRODUCT_VIATECH_VT82C686A_PWR:
    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