This source file includes following definitions.
- lmenv_match
- lmenv_attach
- lmenv_refresh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/device.h>
22 #include <sys/sensors.h>
23
24 #include <dev/i2c/i2cvar.h>
25
26
27 #define LM87_2_5V 0x20
28 #define LM87_VCCP1 0x21
29 #define LM87_VCC 0x22
30 #define LM87_5V 0x23
31 #define LM87_12V 0x24
32 #define LM87_VCCP2 0x25
33 #define LM87_EXT_TEMP 0x26
34 #define LM87_INT_TEMP 0x27
35 #define LM87_FAN1 0x28
36 #define LM87_FAN2 0x29
37 #define LM87_REVISION 0x3f
38 #define LM87_CONFIG1 0x40
39 #define LM87_CONFIG1_START 0x01
40 #define LM87_CONFIG1_INTCLR 0x08
41 #define LM87_CHANNEL 0x16
42 #define LM87_CHANNEL_AIN1 0x01
43 #define LM87_CHANNEL_AIN2 0x02
44 #define LM87_FANDIV 0x47
45
46
47 #define LMENV_2_5V 0
48 #define LMENV_VCCP1 1
49 #define LMENV_VCC 2
50 #define LMENV_5V 3
51 #define LMENV_12V 4
52 #define LMENV_VCCP2 5
53 #define LMENV_EXT_TEMP 6
54 #define LMENV_INT_TEMP 7
55 #define LMENV_FAN1 8
56 #define LMENV_FAN2 9
57 #define LMENV_NUM_SENSORS 10
58
59 struct lmenv_softc {
60 struct device sc_dev;
61 i2c_tag_t sc_tag;
62 i2c_addr_t sc_addr;
63
64 struct ksensor sc_sensor[LMENV_NUM_SENSORS];
65 struct ksensordev sc_sensordev;
66 int sc_fan1_div, sc_fan2_div;
67 int sc_family;
68 };
69
70 int lmenv_match(struct device *, void *, void *);
71 void lmenv_attach(struct device *, struct device *, void *);
72
73 void lmenv_refresh(void *);
74
75 struct cfattach lmenv_ca = {
76 sizeof(struct lmenv_softc), lmenv_match, lmenv_attach
77 };
78
79 struct cfdriver lmenv_cd = {
80 NULL, "lmenv", DV_DULL
81 };
82
83 int
84 lmenv_match(struct device *parent, void *match, void *aux)
85 {
86 struct i2c_attach_args *ia = aux;
87
88 if (strcmp(ia->ia_name, "lm87") == 0 ||
89 strcmp(ia->ia_name, "lm87cimt") == 0 ||
90 strcmp(ia->ia_name, "adm9240") == 0 ||
91 strcmp(ia->ia_name, "lm81") == 0 ||
92 strcmp(ia->ia_name, "ds1780") == 0)
93 return (1);
94 return (0);
95 }
96
97 void
98 lmenv_attach(struct device *parent, struct device *self, void *aux)
99 {
100 struct lmenv_softc *sc = (struct lmenv_softc *)self;
101 struct i2c_attach_args *ia = aux;
102 u_int8_t cmd, data, data2, channel;
103 int i;
104
105 sc->sc_tag = ia->ia_tag;
106 sc->sc_addr = ia->ia_addr;
107
108 sc->sc_family = 87;
109 if (strcmp(ia->ia_name, "lm81") == 0 ||
110 strcmp(ia->ia_name, "adm9240") == 0 ||
111 strcmp(ia->ia_name, "ds1780") == 0)
112 sc->sc_family = 81;
113
114 iic_acquire_bus(sc->sc_tag, 0);
115
116 cmd = LM87_REVISION;
117 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
118 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
119 iic_release_bus(sc->sc_tag, 0);
120 printf(": cannot read ID register\n");
121 return;
122 }
123 printf(": %s rev %x", ia->ia_name, data);
124
125 cmd = LM87_FANDIV;
126 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
127 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
128 iic_release_bus(sc->sc_tag, 0);
129 printf(", cannot read Fan Divisor register\n");
130 return;
131 }
132 sc->sc_fan1_div = 1 << ((data >> 4) & 0x03);
133 sc->sc_fan2_div = 1 << ((data >> 6) & 0x03);
134
135 if (sc->sc_family == 87) {
136 cmd = LM87_CHANNEL;
137 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
138 sc->sc_addr, &cmd, sizeof cmd, &channel,
139 sizeof channel, 0)) {
140 iic_release_bus(sc->sc_tag, 0);
141 printf(", cannot read Channel register\n");
142 return;
143 }
144 }
145
146 cmd = LM87_CONFIG1;
147 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
148 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
149 iic_release_bus(sc->sc_tag, 0);
150 printf(", cannot read Configuration Register 1\n");
151 return;
152 }
153
154
155
156
157
158 data2 = (data | LM87_CONFIG1_START);
159 data2 = data2 & ~LM87_CONFIG1_INTCLR;
160
161 if (data != data2) {
162 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
163 sc->sc_addr, &cmd, sizeof cmd, &data2, sizeof data2, 0)) {
164 iic_release_bus(sc->sc_tag, 0);
165 printf(", cannot write Configuration Register 1\n");
166 return;
167 }
168 printf(", starting scan");
169 }
170 iic_release_bus(sc->sc_tag, 0);
171
172
173 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
174 sizeof(sc->sc_sensordev.xname));
175
176 sc->sc_sensor[LMENV_2_5V].type = SENSOR_VOLTS_DC;
177 strlcpy(sc->sc_sensor[LMENV_2_5V].desc, "+2.5Vin",
178 sizeof(sc->sc_sensor[LMENV_2_5V].desc));
179
180 sc->sc_sensor[LMENV_VCCP1].type = SENSOR_VOLTS_DC;
181 strlcpy(sc->sc_sensor[LMENV_VCCP1].desc, "Vccp",
182 sizeof(sc->sc_sensor[LMENV_VCCP1].desc));
183
184 sc->sc_sensor[LMENV_VCC].type = SENSOR_VOLTS_DC;
185 strlcpy(sc->sc_sensor[LMENV_VCC].desc, "+Vcc",
186 sizeof(sc->sc_sensor[LMENV_VCC].desc));
187
188 sc->sc_sensor[LMENV_5V].type = SENSOR_VOLTS_DC;
189 strlcpy(sc->sc_sensor[LMENV_5V].desc, "+5Vin/Vcc",
190 sizeof(sc->sc_sensor[LMENV_5V].desc));
191
192 sc->sc_sensor[LMENV_12V].type = SENSOR_VOLTS_DC;
193 strlcpy(sc->sc_sensor[LMENV_12V].desc, "+12Vin",
194 sizeof(sc->sc_sensor[LMENV_12V].desc));
195
196 sc->sc_sensor[LMENV_VCCP2].type = SENSOR_VOLTS_DC;
197 strlcpy(sc->sc_sensor[LMENV_VCCP2].desc, "Vccp",
198 sizeof(sc->sc_sensor[LMENV_VCCP2].desc));
199
200 sc->sc_sensor[LMENV_EXT_TEMP].type = SENSOR_TEMP;
201 strlcpy(sc->sc_sensor[LMENV_EXT_TEMP].desc, "External",
202 sizeof(sc->sc_sensor[LMENV_EXT_TEMP].desc));
203 if (sc->sc_family == 81)
204 sc->sc_sensor[LMENV_EXT_TEMP].flags |= SENSOR_FINVALID;
205
206 sc->sc_sensor[LMENV_INT_TEMP].type = SENSOR_TEMP;
207 strlcpy(sc->sc_sensor[LMENV_INT_TEMP].desc, "Internal",
208 sizeof(sc->sc_sensor[LMENV_INT_TEMP].desc));
209
210 if (channel & LM87_CHANNEL_AIN1) {
211 sc->sc_sensor[LMENV_FAN1].type = SENSOR_VOLTS_DC;
212 strlcpy(sc->sc_sensor[LMENV_FAN1].desc, "AIN1",
213 sizeof(sc->sc_sensor[LMENV_FAN1].desc));
214 } else {
215 sc->sc_sensor[LMENV_FAN1].type = SENSOR_FANRPM;
216 }
217
218 if (channel & LM87_CHANNEL_AIN2) {
219 sc->sc_sensor[LMENV_FAN2].type = SENSOR_VOLTS_DC;
220 strlcpy(sc->sc_sensor[LMENV_FAN2].desc, "AIN2",
221 sizeof(sc->sc_sensor[LMENV_FAN2].desc));
222 } else {
223 sc->sc_sensor[LMENV_FAN2].type = SENSOR_FANRPM;
224 }
225
226 if (sensor_task_register(sc, lmenv_refresh, 5) == NULL) {
227 printf(", unable to register update task\n");
228 return;
229 }
230
231 for (i = 0; i < LMENV_NUM_SENSORS; i++)
232 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
233 sensordev_install(&sc->sc_sensordev);
234
235 printf("\n");
236 }
237
238 void
239 lmenv_refresh(void *arg)
240 {
241 struct lmenv_softc *sc = arg;
242 u_int8_t cmd, data;
243 u_int tmp;
244 int sensor;
245
246 iic_acquire_bus(sc->sc_tag, 0);
247
248 for (sensor = 0; sensor < LMENV_NUM_SENSORS; sensor++) {
249 cmd = LM87_2_5V + sensor;
250 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
251 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
252 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID;
253 continue;
254 }
255
256 sc->sc_sensor[sensor].flags &= ~SENSOR_FINVALID;
257 switch (sensor) {
258 case LMENV_2_5V:
259 sc->sc_sensor[sensor].value = 2500000 * data / 192;
260 break;
261 case LMENV_5V:
262 sc->sc_sensor[sensor].value = 5000000 * data / 192;
263 break;
264 case LMENV_12V:
265 sc->sc_sensor[sensor].value = 12000000 * data / 192;
266 break;
267 case LMENV_VCCP1:
268 case LMENV_VCCP2:
269 sc->sc_sensor[sensor].value = 2700000 * data / 192;
270 break;
271 case LMENV_VCC:
272 sc->sc_sensor[sensor].value = 3300000 * data / 192;
273 break;
274 case LMENV_EXT_TEMP:
275 if (sc->sc_family == 81) {
276 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID;
277 break;
278 }
279
280 case LMENV_INT_TEMP:
281 if (data == 0x80)
282 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID;
283 else
284 sc->sc_sensor[sensor].value =
285 (int8_t)data * 1000000 + 273150000;
286 break;
287 case LMENV_FAN1:
288 if (sc->sc_sensor[sensor].type == SENSOR_VOLTS_DC) {
289 sc->sc_sensor[sensor].value =
290 1870000 * data / 192;
291 break;
292 }
293 tmp = data * sc->sc_fan1_div;
294 if (tmp == 0)
295 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID;
296 else
297 sc->sc_sensor[sensor].value = 1350000 / tmp;
298 break;
299 case LMENV_FAN2:
300 if (sc->sc_sensor[sensor].type == SENSOR_VOLTS_DC) {
301 sc->sc_sensor[sensor].value =
302 1870000 * data / 192;
303 break;
304 }
305 tmp = data * sc->sc_fan2_div;
306 if (tmp == 0)
307 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID;
308 else
309 sc->sc_sensor[sensor].value = 1350000 / tmp;
310 break;
311 default:
312 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID;
313 break;
314 }
315 }
316
317 iic_release_bus(sc->sc_tag, 0);
318 }