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