1*471aeecfSnaddy /* $OpenBSD: asb100.c,v 1.12 2022/04/06 18:59:28 naddy Exp $ */
2e19478bdSdjm
3e19478bdSdjm /*
43da0678cSdjm * Copyright (c) 2005 Damien Miller <djm@openbsd.org>
5e19478bdSdjm *
6e19478bdSdjm * Permission to use, copy, modify, and distribute this software for any
7e19478bdSdjm * purpose with or without fee is hereby granted, provided that the above
8e19478bdSdjm * copyright notice and this permission notice appear in all copies.
9e19478bdSdjm *
10e19478bdSdjm * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11e19478bdSdjm * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12e19478bdSdjm * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13e19478bdSdjm * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14e19478bdSdjm * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15e19478bdSdjm * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16e19478bdSdjm * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17e19478bdSdjm */
18e19478bdSdjm
19e19478bdSdjm #include <sys/param.h>
20e19478bdSdjm #include <sys/systm.h>
21e19478bdSdjm #include <sys/device.h>
22e19478bdSdjm #include <sys/sensors.h>
23e19478bdSdjm
24e19478bdSdjm #include <dev/i2c/i2cvar.h>
25e19478bdSdjm
26e19478bdSdjm /* Apparently the ASB100 always lives here */
27e19478bdSdjm #define ASB100_ADDR 0x2d
28e19478bdSdjm
29e19478bdSdjm /* ASB100 registers */
30e19478bdSdjm #define ASB100_TEMP3 0x17
31e19478bdSdjm #define ASB100_TEMP3_MAX 0x18
32e19478bdSdjm #define ASB100_TEMP3_HYST 0x19
33e19478bdSdjm #define ASB100_VIN0 0x20
34e19478bdSdjm #define ASB100_VIN1 0x21
35e19478bdSdjm #define ASB100_VIN2 0x22
36e19478bdSdjm #define ASB100_VIN3 0x23
37e19478bdSdjm #define ASB100_VIN4 0x24
38e19478bdSdjm #define ASB100_VIN5 0x25
39e19478bdSdjm #define ASB100_VIN6 0x26
40e19478bdSdjm #define ASB100_TEMP0 0x27
41e19478bdSdjm #define ASB100_FAN0 0x28
42e19478bdSdjm #define ASB100_FAN1 0x29
43e19478bdSdjm #define ASB100_FAN2 0x30
44e19478bdSdjm #define ASB100_VIN0_MIN 0x2b
45e19478bdSdjm #define ASB100_VIN0_MAX 0x2c
46e19478bdSdjm #define ASB100_VIN1_MIN 0x2d
47e19478bdSdjm #define ASB100_VIN1_MAX 0x2e
48e19478bdSdjm #define ASB100_VIN2_MIN 0x2f
49e19478bdSdjm #define ASB100_VIN2_MAX 0x30
50e19478bdSdjm #define ASB100_VIN3_MIN 0x31
51e19478bdSdjm #define ASB100_VIN3_MAX 0x32
52e19478bdSdjm #define ASB100_VIN4_MIN 0x33
53e19478bdSdjm #define ASB100_VIN4_MAX 0x34
54e19478bdSdjm #define ASB100_VIN5_MIN 0x35
55e19478bdSdjm #define ASB100_VIN5_MAX 0x36
56e19478bdSdjm #define ASB100_VIN6_MIN 0x37
57e19478bdSdjm #define ASB100_VIN6_MAX 0x38
58e19478bdSdjm #define ASB100_TEMP0_MAX 0x39
59e19478bdSdjm #define ASB100_TEMP0_HYST 0x3a
60e19478bdSdjm #define ASB100_FAN0_MIN 0x3b
61e19478bdSdjm #define ASB100_FAN1_MIN 0x3c
62e19478bdSdjm #define ASB100_FAN2_MIN 0x3d
63e19478bdSdjm #define ASB100_CONFIG 0x40
64e19478bdSdjm #define ASB100_ALARM1 0x41
65e19478bdSdjm #define ASB100_ALARM2 0x42
66e19478bdSdjm #define ASB100_SMIM1 0x43
67e19478bdSdjm #define ASB100_SMIM2 0x44
68e19478bdSdjm #define ASB100_VID_FANDIV01 0x47 /* 0-3 vid, 4-5 fan0, 6-7 fan1 */
69e19478bdSdjm #define ASB100_I2C_ADDR 0x48
70e19478bdSdjm #define ASB100_CHIPID 0x49
71e19478bdSdjm #define ASB100_I2C_SUBADDR 0x4a
72e19478bdSdjm #define ASB100_PIN_FANDIV2 0x4b /* 6-7 fan2 */
73e19478bdSdjm #define ASB100_IRQ 0x4c
74e19478bdSdjm #define ASB100_BANK 0x4e
75e19478bdSdjm #define ASB100_CHIPMAN 0x4f
76e19478bdSdjm #define ASB100_VID_CHIPID 0x58 /* 0 vid highbit, 1-7 chipid */
77e19478bdSdjm #define ASB100_PWM 0x59 /* 0-3 duty cycle, 7 enable */
78e19478bdSdjm
79e19478bdSdjm /* TEMP1/2 sensors live on other chips, pointed to by the I2C_SUBADDR reg */
80e19478bdSdjm #define ASB100_SUB1_TEMP1 0x50 /* LM75 format */
81e19478bdSdjm #define ASB100_SUB1_TEMP1_HYST 0x53
82e19478bdSdjm #define ASB100_SUB1_TEMP1_MAX 0x55
83e19478bdSdjm #define ASB100_SUB2_TEMP2 0x50 /* LM75 format */
84e19478bdSdjm #define ASB100_SUB2_TEMP2_HYST 0x53
85e19478bdSdjm #define ASB100_SUB2_TEMP2_MAX 0x55
86e19478bdSdjm
87e19478bdSdjm /* Sensors */
88e19478bdSdjm #define ASB100_SENSOR_VIN0 0
89e19478bdSdjm #define ASB100_SENSOR_VIN1 1
90e19478bdSdjm #define ASB100_SENSOR_VIN2 2
91e19478bdSdjm #define ASB100_SENSOR_VIN3 3
92e19478bdSdjm #define ASB100_SENSOR_VIN4 4
93e19478bdSdjm #define ASB100_SENSOR_VIN5 5
94e19478bdSdjm #define ASB100_SENSOR_VIN6 6
95e19478bdSdjm #define ASB100_SENSOR_FAN0 7
96e19478bdSdjm #define ASB100_SENSOR_FAN1 8
97e19478bdSdjm #define ASB100_SENSOR_FAN2 9
98e19478bdSdjm #define ASB100_SENSOR_TEMP0 10
99e19478bdSdjm #define ASB100_SENSOR_TEMP1 11
100e19478bdSdjm #define ASB100_SENSOR_TEMP2 12
101e19478bdSdjm #define ASB100_SENSOR_TEMP3 13
102e19478bdSdjm #define ASB100_NUM_SENSORS 14
103e19478bdSdjm
104e19478bdSdjm struct asbtm_softc {
105e19478bdSdjm struct device sc_dev;
106e19478bdSdjm i2c_tag_t sc_tag;
107e19478bdSdjm i2c_addr_t sc_addr;
108e19478bdSdjm
109275cbf62Sderaadt struct ksensor sc_sensor[ASB100_NUM_SENSORS];
110275cbf62Sderaadt struct ksensordev sc_sensordev;
111e19478bdSdjm int sc_fanmul[3];
112e19478bdSdjm int sc_satellite[2];
113e19478bdSdjm };
114e19478bdSdjm
115e19478bdSdjm int asbtm_banksel(struct asbtm_softc *, u_int8_t, u_int8_t *);
116e19478bdSdjm int asbtm_match(struct device *, void *, void *);
117e19478bdSdjm void asbtm_attach(struct device *, struct device *, void *);
118e19478bdSdjm void asbtm_refresh(void *);
119e19478bdSdjm
120*471aeecfSnaddy const struct cfattach asbtm_ca = {
121e19478bdSdjm sizeof(struct asbtm_softc), asbtm_match, asbtm_attach
122e19478bdSdjm };
123e19478bdSdjm
124e19478bdSdjm struct cfdriver asbtm_cd = {
125e19478bdSdjm NULL, "asbtm", DV_DULL
126e19478bdSdjm };
127e19478bdSdjm
128e19478bdSdjm int
asbtm_match(struct device * parent,void * match,void * aux)129e19478bdSdjm asbtm_match(struct device *parent, void *match, void *aux)
130e19478bdSdjm {
131e19478bdSdjm struct i2c_attach_args *ia = aux;
132e19478bdSdjm
133e19478bdSdjm if (strcmp(ia->ia_name, "asb100") == 0)
134e19478bdSdjm return (1);
135e19478bdSdjm
136e19478bdSdjm return (0);
137e19478bdSdjm }
138e19478bdSdjm
139e19478bdSdjm int
asbtm_banksel(struct asbtm_softc * sc,u_int8_t new_bank,u_int8_t * orig_bank)140e19478bdSdjm asbtm_banksel(struct asbtm_softc *sc, u_int8_t new_bank, u_int8_t *orig_bank)
141e19478bdSdjm {
142e19478bdSdjm u_int8_t cmd, data;
143e19478bdSdjm
144e19478bdSdjm new_bank &= 0xf;
145e19478bdSdjm
146e19478bdSdjm cmd = ASB100_BANK;
147e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
148e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0))
149e19478bdSdjm return (-1);
150e19478bdSdjm
151e19478bdSdjm if (orig_bank != NULL)
152e19478bdSdjm *orig_bank = data & 0x0f;
153e19478bdSdjm
154e19478bdSdjm if ((data & 0xf) != new_bank) {
155e19478bdSdjm cmd = ASB100_BANK;
156e19478bdSdjm data = new_bank | (data & 0xf0);
157e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr,
158e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0))
159e19478bdSdjm return (-1);
160e19478bdSdjm }
161e19478bdSdjm
162e19478bdSdjm return (0);
163e19478bdSdjm }
164e19478bdSdjm
165e19478bdSdjm void
asbtm_attach(struct device * parent,struct device * self,void * aux)166e19478bdSdjm asbtm_attach(struct device *parent, struct device *self, void *aux)
167e19478bdSdjm {
168e19478bdSdjm struct asbtm_softc *sc = (struct asbtm_softc *)self;
169e19478bdSdjm struct i2c_attach_args *ia = aux;
170e19478bdSdjm u_int8_t orig_bank, cmd, data;
171e19478bdSdjm int i;
172e19478bdSdjm
173e19478bdSdjm sc->sc_tag = ia->ia_tag;
174e19478bdSdjm sc->sc_addr = ia->ia_addr;
175e19478bdSdjm
176e19478bdSdjm iic_acquire_bus(sc->sc_tag, 0);
177e19478bdSdjm
178e19478bdSdjm if (asbtm_banksel(sc, 0, &orig_bank) == -1) {
179e19478bdSdjm printf(": cannot get/set register bank\n");
180e19478bdSdjm iic_release_bus(sc->sc_tag, 0);
181e19478bdSdjm return;
182e19478bdSdjm }
183e19478bdSdjm
184e19478bdSdjm cmd = ASB100_VID_FANDIV01;
185e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
186e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0)) {
187e19478bdSdjm printf(": cannot get fan01 register\n");
188e19478bdSdjm iic_release_bus(sc->sc_tag, 0);
189e19478bdSdjm return;
190e19478bdSdjm }
191e19478bdSdjm sc->sc_fanmul[0] = (1 << (data >> 4) & 0x3);
192e19478bdSdjm sc->sc_fanmul[1] = (1 << (data >> 6) & 0x3);
193e19478bdSdjm
194e19478bdSdjm cmd = ASB100_PIN_FANDIV2;
195e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
196e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0)) {
197e19478bdSdjm printf(": cannot get fan2 register\n");
198e19478bdSdjm iic_release_bus(sc->sc_tag, 0);
199e19478bdSdjm return;
200e19478bdSdjm }
201e19478bdSdjm sc->sc_fanmul[0] = (1 << (data >> 6) & 0x3);
202e19478bdSdjm
203e19478bdSdjm cmd = ASB100_I2C_SUBADDR;
204e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
205e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0)) {
206e19478bdSdjm printf(": cannot get satellite chip address register\n");
207e19478bdSdjm iic_release_bus(sc->sc_tag, 0);
208e19478bdSdjm return;
209e19478bdSdjm }
210e19478bdSdjm /* Maybe a relative address of zero means "not present" here... */
211e19478bdSdjm sc->sc_satellite[0] = 0x48 + (data & 0xf);
212e19478bdSdjm sc->sc_satellite[1] = 0x48 + ((data >> 4) & 0xf);
213e19478bdSdjm
214e19478bdSdjm iic_ignore_addr(sc->sc_satellite[0]);
215e19478bdSdjm iic_ignore_addr(sc->sc_satellite[1]);
216e19478bdSdjm if (sc->sc_satellite[0] == sc->sc_satellite[1])
217e19478bdSdjm sc->sc_satellite[1] = -1;
218e19478bdSdjm
219e19478bdSdjm if (asbtm_banksel(sc, orig_bank, NULL) == -1) {
220e19478bdSdjm printf(": cannot restore saved bank %d\n", orig_bank);
221e19478bdSdjm iic_release_bus(sc->sc_tag, 0);
222e19478bdSdjm return;
223e19478bdSdjm }
224e19478bdSdjm
225e19478bdSdjm iic_release_bus(sc->sc_tag, 0);
226e19478bdSdjm
227e19478bdSdjm /* Initialize sensor data. */
22827515a6bSderaadt strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
22927515a6bSderaadt sizeof(sc->sc_sensordev.xname));
230e19478bdSdjm
231e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN0].type = SENSOR_VOLTS_DC;
232e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN1].type = SENSOR_VOLTS_DC;
233e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN2].type = SENSOR_VOLTS_DC;
234e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN3].type = SENSOR_VOLTS_DC;
235e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN4].type = SENSOR_VOLTS_DC;
236e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN5].type = SENSOR_VOLTS_DC;
237e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN6].type = SENSOR_VOLTS_DC;
238e19478bdSdjm
239e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_FAN0].type = SENSOR_FANRPM;
240e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_FAN1].type = SENSOR_FANRPM;
241b6ddb18bSdjm sc->sc_sensor[ASB100_SENSOR_FAN2].type = SENSOR_FANRPM;
242e19478bdSdjm
243e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_TEMP0].type = SENSOR_TEMP;
24427515a6bSderaadt strlcpy(sc->sc_sensor[ASB100_SENSOR_TEMP0].desc, "External",
245e19478bdSdjm sizeof(sc->sc_sensor[ASB100_SENSOR_TEMP0].desc));
246e19478bdSdjm
247e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_TEMP1].type = SENSOR_TEMP;
24827515a6bSderaadt strlcpy(sc->sc_sensor[ASB100_SENSOR_TEMP1].desc, "Internal",
249e19478bdSdjm sizeof(sc->sc_sensor[ASB100_SENSOR_TEMP1].desc));
250e19478bdSdjm
251e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_TEMP2].type = SENSOR_TEMP;
25227515a6bSderaadt strlcpy(sc->sc_sensor[ASB100_SENSOR_TEMP2].desc, "Internal",
253e19478bdSdjm sizeof(sc->sc_sensor[ASB100_SENSOR_TEMP2].desc));
254e19478bdSdjm if (sc->sc_satellite[1] == -1)
255e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_TEMP2].flags |= SENSOR_FINVALID;
256e19478bdSdjm
257e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_TEMP3].type = SENSOR_TEMP;
25827515a6bSderaadt strlcpy(sc->sc_sensor[ASB100_SENSOR_TEMP3].desc, "External",
259e19478bdSdjm sizeof(sc->sc_sensor[ASB100_SENSOR_TEMP3].desc));
260e19478bdSdjm
261abd9fc28Sdlg if (sensor_task_register(sc, asbtm_refresh, 5) == NULL) {
262e19478bdSdjm printf(", unable to register update task\n");
263e19478bdSdjm return;
264e19478bdSdjm }
265e19478bdSdjm
266e19478bdSdjm for (i = 0; i < ASB100_NUM_SENSORS; i++)
26727515a6bSderaadt sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
26827515a6bSderaadt sensordev_install(&sc->sc_sensordev);
269e19478bdSdjm
270e19478bdSdjm printf("\n");
271e19478bdSdjm }
272e19478bdSdjm
273e19478bdSdjm static void
fanval(struct ksensor * sens,int mul,u_int8_t data)274275cbf62Sderaadt fanval(struct ksensor *sens, int mul, u_int8_t data)
275e19478bdSdjm {
276e19478bdSdjm int tmp = data * mul;
277e19478bdSdjm
278e19478bdSdjm if (tmp == 0)
279e19478bdSdjm sens->flags |= SENSOR_FINVALID;
280e19478bdSdjm else {
281e19478bdSdjm sens->value = 1350000 / tmp;
282e19478bdSdjm sens->flags &= ~SENSOR_FINVALID;
283e19478bdSdjm }
284e19478bdSdjm }
285e19478bdSdjm
286e19478bdSdjm void
asbtm_refresh(void * arg)287e19478bdSdjm asbtm_refresh(void *arg)
288e19478bdSdjm {
289e19478bdSdjm struct asbtm_softc *sc = arg;
290e19478bdSdjm u_int8_t orig_bank, cmd, data;
291e19478bdSdjm int8_t sdata;
292e19478bdSdjm u_int16_t sdata2;
293e19478bdSdjm
294e19478bdSdjm iic_acquire_bus(sc->sc_tag, 0);
295e19478bdSdjm
296e19478bdSdjm if (asbtm_banksel(sc, 0, &orig_bank) == -1) {
2973da0678cSdjm printf("%s: cannot get/set register bank\n",
2983da0678cSdjm sc->sc_dev.dv_xname);
299e19478bdSdjm iic_release_bus(sc->sc_tag, 0);
300e19478bdSdjm return;
301e19478bdSdjm }
302e19478bdSdjm
303e19478bdSdjm cmd = ASB100_VIN0;
304e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
305e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
306e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN0].value = (data * 1000000) / 16;
307e19478bdSdjm
308e19478bdSdjm cmd = ASB100_VIN1;
309e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
310e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
311e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN1].value = (data * 1000000) / 16;
312e19478bdSdjm
313e19478bdSdjm cmd = ASB100_VIN2;
314e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
315e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
316e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN2].value = (data * 1000000) / 16;
317e19478bdSdjm
318e19478bdSdjm cmd = ASB100_VIN3;
319e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
320e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
321e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN3].value = (data * 1000000) / 16;
322e19478bdSdjm
323e19478bdSdjm cmd = ASB100_VIN4;
324e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
325e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
326e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN4].value = (data * 1000000) / 16;
327e19478bdSdjm
328e19478bdSdjm cmd = ASB100_VIN5;
329e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
330e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
331e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN5].value = (data * 1000000) / 16;
332e19478bdSdjm
333e19478bdSdjm cmd = ASB100_VIN6;
334e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
335e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
336e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_VIN6].value = (data * 1000000) / 16;
337e19478bdSdjm
338e19478bdSdjm cmd = ASB100_FAN0;
339e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
340e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
341e19478bdSdjm fanval(&sc->sc_sensor[ASB100_SENSOR_FAN0],
342e19478bdSdjm sc->sc_fanmul[0], data);
343e19478bdSdjm
344e19478bdSdjm cmd = ASB100_FAN1;
345e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
346e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
347e19478bdSdjm fanval(&sc->sc_sensor[ASB100_SENSOR_FAN1],
348e19478bdSdjm sc->sc_fanmul[1], data);
349e19478bdSdjm
350e19478bdSdjm cmd = ASB100_FAN2;
351e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
352e19478bdSdjm &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
353e19478bdSdjm fanval(&sc->sc_sensor[ASB100_SENSOR_FAN2],
354e19478bdSdjm sc->sc_fanmul[2], data);
355e19478bdSdjm
356e19478bdSdjm cmd = ASB100_TEMP0;
357e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
358e19478bdSdjm &cmd, sizeof cmd, &sdata, sizeof sdata, 0) == 0)
359e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_TEMP0].value = 273150000 +
360e19478bdSdjm 1000000 * sdata;
361e19478bdSdjm
362e19478bdSdjm cmd = ASB100_TEMP3;
363e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
364e19478bdSdjm &cmd, sizeof cmd, &data, sizeof sdata, 0) == 0)
365e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_TEMP3].value = 273150000 +
366e19478bdSdjm 1000000 * sdata;
367e19478bdSdjm
368e19478bdSdjm /* Read satellite chips for TEMP1/TEMP2 */
369e19478bdSdjm cmd = ASB100_SUB1_TEMP1;
370e19478bdSdjm if (sc->sc_satellite[0] != -1) {
371e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
372e19478bdSdjm sc->sc_satellite[0], &cmd, sizeof cmd, &sdata2,
373e19478bdSdjm sizeof sdata2, 0) == 0 && sdata2 != 0xffff) {
374e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_TEMP1].value = 273150000 +
37591eacc75Sderaadt 500000 * (betoh16(sdata2) / 128);
3765b811e82Sdjm sc->sc_sensor[ASB100_SENSOR_TEMP2].flags &=
3775b811e82Sdjm ~SENSOR_FINVALID;
378e19478bdSdjm } else {
379e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_TEMP2].flags |=
380e19478bdSdjm SENSOR_FINVALID;
381e19478bdSdjm }
382e19478bdSdjm }
383e19478bdSdjm
384e19478bdSdjm cmd = ASB100_SUB2_TEMP2;
385e19478bdSdjm if (sc->sc_satellite[1] != -1) {
386e19478bdSdjm if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
387e19478bdSdjm sc->sc_satellite[1], &cmd, sizeof cmd, &sdata2,
388e19478bdSdjm sizeof sdata2, 0) == 0 && sdata2 != 0xffff) {
389e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_TEMP2].value = 273150000 +
39091eacc75Sderaadt 500000 * (betoh16(sdata2) / 128);
3915b811e82Sdjm sc->sc_sensor[ASB100_SENSOR_TEMP2].flags &=
3925b811e82Sdjm ~SENSOR_FINVALID;
393e19478bdSdjm } else {
394e19478bdSdjm sc->sc_sensor[ASB100_SENSOR_TEMP2].flags |=
395e19478bdSdjm SENSOR_FINVALID;
396e19478bdSdjm }
397e19478bdSdjm }
398e19478bdSdjm
399e19478bdSdjm asbtm_banksel(sc, orig_bank, NULL);
400e19478bdSdjm
401e19478bdSdjm iic_release_bus(sc->sc_tag, 0);
402e19478bdSdjm }
403