Annotation of sys/dev/i2c/adm1031.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: adm1031.c,v 1.8 2007/06/24 05:34:35 dlg Exp $ */
2:
3: /*
4: * Copyright (c) 2005 Theo de Raadt
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: #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: /* adm 1031 registers */
27: #define ADM1031_INT_TEMP 0x0a
28: #define ADM1031_EXT_TEMP 0x0b
29: #define ADM1031_EXT2_TEMP 0x0c
30: #define ADM1031_FAN 0x08
31: #define ADM1031_FANC 0x20
32: #define ADM1031_FAN2 0x09
33: #define ADM1031_FAN2C 0x21
34: #define ADM1024_FANC_VAL(x) (x >> 6)
35:
36: /* Sensors */
37: #define ADMTT_INT 0
38: #define ADMTT_EXT 1
39: #define ADMTT_EXT2 2
40: #define ADMTT_FAN 3
41: #define ADMTT_FAN2 4
42: #define ADMTT_NUM_SENSORS 5
43:
44: struct admtt_softc {
45: struct device sc_dev;
46: i2c_tag_t sc_tag;
47: i2c_addr_t sc_addr;
48: int sc_fanmul;
49:
50: struct ksensor sc_sensor[ADMTT_NUM_SENSORS];
51: struct ksensordev sc_sensordev;
52: };
53:
54: int admtt_match(struct device *, void *, void *);
55: void admtt_attach(struct device *, struct device *, void *);
56: void admtt_refresh(void *);
57:
58: struct cfattach admtt_ca = {
59: sizeof(struct admtt_softc), admtt_match, admtt_attach
60: };
61:
62: struct cfdriver admtt_cd = {
63: NULL, "admtt", DV_DULL
64: };
65:
66: int
67: admtt_match(struct device *parent, void *match, void *aux)
68: {
69: struct i2c_attach_args *ia = aux;
70:
71: if (strcmp(ia->ia_name, "adm1031") == 0)
72: return (1);
73: return (0);
74: }
75:
76: void
77: admtt_attach(struct device *parent, struct device *self, void *aux)
78: {
79: struct admtt_softc *sc = (struct admtt_softc *)self;
80: struct i2c_attach_args *ia = aux;
81: u_int8_t cmd, data;
82: int i;
83:
84: sc->sc_tag = ia->ia_tag;
85: sc->sc_addr = ia->ia_addr;
86:
87: cmd = ADM1031_FANC;
88: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
89: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
90: printf(", unable to read fan setting\n");
91: return;
92: }
93: sc->sc_fanmul = 11250/8 * (1 << ADM1024_FANC_VAL(data)) * 60;
94:
95: /* Initialize sensor data. */
96: strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
97: sizeof(sc->sc_sensordev.xname));
98:
99: sc->sc_sensor[ADMTT_INT].type = SENSOR_TEMP;
100: strlcpy(sc->sc_sensor[ADMTT_INT].desc, "Internal",
101: sizeof(sc->sc_sensor[ADMTT_INT].desc));
102:
103: sc->sc_sensor[ADMTT_EXT].type = SENSOR_TEMP;
104: strlcpy(sc->sc_sensor[ADMTT_EXT].desc, "External",
105: sizeof(sc->sc_sensor[ADMTT_EXT].desc));
106:
107: sc->sc_sensor[ADMTT_EXT2].type = SENSOR_TEMP;
108: strlcpy(sc->sc_sensor[ADMTT_EXT2].desc, "External",
109: sizeof(sc->sc_sensor[ADMTT_EXT2].desc));
110:
111: sc->sc_sensor[ADMTT_FAN].type = SENSOR_FANRPM;
112:
113: sc->sc_sensor[ADMTT_FAN2].type = SENSOR_FANRPM;
114:
115: if (sensor_task_register(sc, admtt_refresh, 5) == NULL) {
116: printf(", unable to register update task\n");
117: return;
118: }
119:
120: for (i = 0; i < ADMTT_NUM_SENSORS; i++)
121: sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
122: sensordev_install(&sc->sc_sensordev);
123:
124: printf("\n");
125: }
126:
127: void
128: admtt_refresh(void *arg)
129: {
130: struct admtt_softc *sc = arg;
131: u_int8_t cmd, data;
132:
133: iic_acquire_bus(sc->sc_tag, 0);
134:
135: cmd = ADM1031_INT_TEMP;
136: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
137: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
138: sc->sc_sensor[ADMTT_INT].value = 273150000 + 1000000 * data;
139:
140: cmd = ADM1031_EXT_TEMP;
141: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
142: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
143: sc->sc_sensor[ADMTT_EXT].value = 273150000 + 1000000 * data;
144:
145: cmd = ADM1031_EXT2_TEMP;
146: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
147: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
148: sc->sc_sensor[ADMTT_EXT2].value = 273150000 + 1000000 * data;
149:
150: cmd = ADM1031_FAN;
151: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
152: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
153: if (data == 0)
154: sc->sc_sensor[ADMTT_FAN].flags |= SENSOR_FINVALID;
155: else {
156: sc->sc_sensor[ADMTT_FAN].value =
157: sc->sc_fanmul / (2 * (int)data);
158: sc->sc_sensor[ADMTT_FAN].flags &= ~SENSOR_FINVALID;
159: }
160: }
161:
162: cmd = ADM1031_FAN2;
163: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
164: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
165: if (data == 0)
166: sc->sc_sensor[ADMTT_FAN2].flags |= SENSOR_FINVALID;
167: else {
168: sc->sc_sensor[ADMTT_FAN2].value =
169: sc->sc_fanmul / (2 * (int)data);
170: sc->sc_sensor[ADMTT_FAN2].flags &= ~SENSOR_FINVALID;
171: }
172: }
173:
174: iic_release_bus(sc->sc_tag, 0);
175: }
CVSweb