xref: /openbsd-src/sys/arch/sparc64/dev/environ.c (revision eb7eaf8de3ff431d305450f61b441e5460c82246)
1*eb7eaf8dSmpi /*	$OpenBSD: environ.c,v 1.2 2021/10/24 17:05:03 mpi Exp $	*/
2df5a06c9Skettenis 
3df5a06c9Skettenis /*
4df5a06c9Skettenis  * Copyright (c) 2008 Mark Kettenis
5df5a06c9Skettenis  *
6df5a06c9Skettenis  * Permission to use, copy, modify, and distribute this software for any
7df5a06c9Skettenis  * purpose with or without fee is hereby granted, provided that the above
8df5a06c9Skettenis  * copyright notice and this permission notice appear in all copies.
9df5a06c9Skettenis  *
10df5a06c9Skettenis  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11df5a06c9Skettenis  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12df5a06c9Skettenis  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13df5a06c9Skettenis  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14df5a06c9Skettenis  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15df5a06c9Skettenis  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16df5a06c9Skettenis  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17df5a06c9Skettenis  */
18df5a06c9Skettenis 
19df5a06c9Skettenis /*
20df5a06c9Skettenis  * Driver for environment device on Enterprise 3000/4000/5000/6000
21df5a06c9Skettenis  * and Enterprise 3500/4500/5500/6500.
22df5a06c9Skettenis  */
23df5a06c9Skettenis 
24df5a06c9Skettenis #include <sys/param.h>
25df5a06c9Skettenis #include <sys/device.h>
26df5a06c9Skettenis #include <sys/kernel.h>
27df5a06c9Skettenis #include <sys/sensors.h>
28df5a06c9Skettenis #include <sys/systm.h>
29df5a06c9Skettenis 
30df5a06c9Skettenis #include <machine/bus.h>
31df5a06c9Skettenis #include <machine/autoconf.h>
32df5a06c9Skettenis 
33df5a06c9Skettenis #include <sparc64/dev/fhcvar.h>
34df5a06c9Skettenis 
35df5a06c9Skettenis struct environ_softc {
36df5a06c9Skettenis 	struct device		sc_dv;
37df5a06c9Skettenis 	bus_space_tag_t		sc_iot;
38df5a06c9Skettenis 	bus_space_handle_t	sc_ioh;
39df5a06c9Skettenis 
40df5a06c9Skettenis 	struct ksensor		sc_sensor;
41df5a06c9Skettenis 	struct ksensordev	sc_sensordev;
42df5a06c9Skettenis };
43df5a06c9Skettenis 
44df5a06c9Skettenis int	environ_match(struct device *, void *, void *);
45df5a06c9Skettenis void	environ_attach(struct device *, struct device *, void *);
46df5a06c9Skettenis void	environ_refresh(void *);
47df5a06c9Skettenis 
48*eb7eaf8dSmpi const struct cfattach environ_ca = {
49df5a06c9Skettenis 	sizeof(struct environ_softc), environ_match, environ_attach
50df5a06c9Skettenis };
51df5a06c9Skettenis 
52df5a06c9Skettenis struct cfdriver environ_cd = {
53df5a06c9Skettenis 	NULL, "environ", DV_DULL
54df5a06c9Skettenis };
55df5a06c9Skettenis 
56df5a06c9Skettenis int
environ_match(struct device * parent,void * cf,void * aux)57df5a06c9Skettenis environ_match(struct device *parent, void *cf, void *aux)
58df5a06c9Skettenis {
59df5a06c9Skettenis 	struct fhc_attach_args *fa = aux;
60df5a06c9Skettenis 
61df5a06c9Skettenis 	if (strcmp("environment", fa->fa_name) == 0)
62df5a06c9Skettenis 		return (1);
63df5a06c9Skettenis 	return (0);
64df5a06c9Skettenis }
65df5a06c9Skettenis 
66df5a06c9Skettenis void
environ_attach(struct device * parent,struct device * self,void * aux)67df5a06c9Skettenis environ_attach(struct device *parent, struct device *self, void *aux)
68df5a06c9Skettenis {
69df5a06c9Skettenis 	struct environ_softc *sc = (void *)self;
70df5a06c9Skettenis 	struct fhc_attach_args *fa = aux;
71df5a06c9Skettenis 
72df5a06c9Skettenis 	sc->sc_iot = fa->fa_bustag;
73df5a06c9Skettenis 	if (fhc_bus_map(sc->sc_iot, fa->fa_reg[0].fbr_slot,
74df5a06c9Skettenis 	    fa->fa_reg[0].fbr_offset, fa->fa_reg[0].fbr_size, 0,
75df5a06c9Skettenis 	    &sc->sc_ioh)) {
76df5a06c9Skettenis 		printf(": can't map registers\n");
77df5a06c9Skettenis 		return;
78df5a06c9Skettenis 	}
79df5a06c9Skettenis 
80df5a06c9Skettenis 	/* First reading allegedly gives garbage. */
81df5a06c9Skettenis 	bus_space_read_1(sc->sc_iot, sc->sc_ioh, 0);
82df5a06c9Skettenis 	delay(30);
83df5a06c9Skettenis 
84df5a06c9Skettenis 	/* Initialize sensor data. */
85df5a06c9Skettenis 	strlcpy(sc->sc_sensordev.xname, sc->sc_dv.dv_xname,
86df5a06c9Skettenis 	    sizeof(sc->sc_sensordev.xname));
87df5a06c9Skettenis 	sc->sc_sensor.type = SENSOR_TEMP;
88df5a06c9Skettenis 
89df5a06c9Skettenis 	sensor_attach(&sc->sc_sensordev, &sc->sc_sensor);
90df5a06c9Skettenis 
91df5a06c9Skettenis 	if (sensor_task_register(sc, environ_refresh, 5) == NULL) {
92df5a06c9Skettenis 		printf(": unable to register update task\n");
93df5a06c9Skettenis 		return;
94df5a06c9Skettenis 	}
95df5a06c9Skettenis 
96df5a06c9Skettenis 	sensordev_install(&sc->sc_sensordev);
97df5a06c9Skettenis 
98df5a06c9Skettenis 	printf("\n");
99df5a06c9Skettenis }
100df5a06c9Skettenis 
101df5a06c9Skettenis /*
102df5a06c9Skettenis  * Calibration table for 2nd generation CPU boards.
103df5a06c9Skettenis  */
104df5a06c9Skettenis int8_t environ_cpu2_temp[] = {
105df5a06c9Skettenis 	-17, -16, -15, -14, -13, -12, -11, -10,
106df5a06c9Skettenis 	 -9,  -8,  -7,  -6,  -5,  -4,  -3,  -2,
107df5a06c9Skettenis 	 -1,   0,   1,   2,   3,   4,   5,   6,
108df5a06c9Skettenis 	  7,   8,   9,  10,  11,  12,  13,  13,
109df5a06c9Skettenis 	 14,  15,  16,  16,  17,  18,  18,  19,
110df5a06c9Skettenis 	 20,  20,  21,  22,  22,  23,  24,  24,
111df5a06c9Skettenis 	 25,  25,  26,  26,  27,  27,  28,  28,
112df5a06c9Skettenis 	 29,  30,  30,  31,  31,  32,  32,  33,
113df5a06c9Skettenis 	 33,  34,  34,  35,  35,  36,  36,  37,
114df5a06c9Skettenis 	 37,  37,  38,  38,  39,  39,  40,  40,
115df5a06c9Skettenis 	 41,  41,  42,  42,  43,  43,  43,  44,
116df5a06c9Skettenis 	 44,  45,  45,  46,  46,  46,  47,  47,
117df5a06c9Skettenis 	 48,  48,  49,  49,  50,  50,  50,  51,
118df5a06c9Skettenis 	 51,  52,  52,  53,  53,  53,  54,  54,
119df5a06c9Skettenis 	 55,  55,  56,  56,  56,  57,  57,  58,
120df5a06c9Skettenis 	 58,  59,  59,  59,  60,  60,  61,  61,
121df5a06c9Skettenis 	 62,  62,  63,  63,  63,  64,  64,  65,
122df5a06c9Skettenis 	 65,  66,  66,  67,  67,  68,  68,  68,
123df5a06c9Skettenis 	 69,  69,  70,  70,  71,  71,  72,  72,
124df5a06c9Skettenis 	 73,  73,  74,  74,  75,  75,  76,  76,
125df5a06c9Skettenis 	 77,  77,  78,  78,  79,  79,  80,  80,
126df5a06c9Skettenis 	 81,  81,  82,  83,  83,  84,  84,  85,
127df5a06c9Skettenis 	 85,  86,  87,  87,  88,  88,  89,  90,
128df5a06c9Skettenis 	 90,  91,  92,  92,  93,  94,  94,  95,
129df5a06c9Skettenis 	 96,  96,  97,  98,  99,  99, 100, 101,
130df5a06c9Skettenis 	102, 103, 103, 104, 105, 106, 107, 108,
131df5a06c9Skettenis 	109, 110
132df5a06c9Skettenis };
133df5a06c9Skettenis 
134df5a06c9Skettenis void
environ_refresh(void * arg)135df5a06c9Skettenis environ_refresh(void *arg)
136df5a06c9Skettenis {
137df5a06c9Skettenis 	struct environ_softc *sc = arg;
138df5a06c9Skettenis 	u_int8_t val;
139df5a06c9Skettenis 	int8_t temp;
140df5a06c9Skettenis 
141df5a06c9Skettenis 	val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 0);
142df5a06c9Skettenis 
143df5a06c9Skettenis 	if (val == 0xff) {
144df5a06c9Skettenis 		sc->sc_sensor.flags |= SENSOR_FINVALID;
145df5a06c9Skettenis 		return;
146df5a06c9Skettenis 	}
147df5a06c9Skettenis 
148df5a06c9Skettenis 	if (val < sizeof(environ_cpu2_temp))
149df5a06c9Skettenis 		temp = environ_cpu2_temp[val];
150df5a06c9Skettenis 	else
151df5a06c9Skettenis 		temp = 110;
152df5a06c9Skettenis 
153df5a06c9Skettenis 	sc->sc_sensor.value = val * 1000000 + 273150000;
154df5a06c9Skettenis 	sc->sc_sensor.flags &= ~SENSOR_FINVALID;
155df5a06c9Skettenis }
156