This source file includes following definitions.
- adt_match
- adt_attach
- adt_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 ADT7460_2_5V 0x20
28 #define ADT7460_VCCP 0x21
29 #define ADT7460_VCC 0x22
30 #define ADT7460_V5 0x23
31 #define ADT7460_V12 0x24
32 #define ADT7460_REM1_TEMP 0x25
33 #define ADT7460_LOCAL_TEMP 0x26
34 #define ADT7460_REM2_TEMP 0x27
35 #define ADT7460_TACH1L 0x28
36 #define ADT7460_TACH1H 0x29
37 #define ADT7460_TACH2L 0x2a
38 #define ADT7460_TACH2H 0x2b
39 #define ADT7460_TACH3L 0x2c
40 #define ADT7460_TACH3H 0x2d
41 #define ADT7460_TACH4L 0x2e
42 #define ADT7460_TACH4H 0x2f
43 #define ADT7460_REVISION 0x3f
44 #define ADT7460_CONFIG 0x40
45 #define ADT7460_CONFIG_Vcc 0x80
46
47
48 #define ADT_2_5V 0
49 #define ADT_VCCP 1
50 #define ADT_VCC 2
51 #define ADT_V5 3
52 #define ADT_V12 4
53 #define ADT_REM1_TEMP 5
54 #define ADT_LOCAL_TEMP 6
55 #define ADT_REM2_TEMP 7
56 #define ADT_TACH1 8
57 #define ADT_TACH2 9
58 #define ADT_TACH3 10
59 #define ADT_TACH4 11
60 #define ADT_NUM_SENSORS 12
61
62 struct adt_chip {
63 const char *name;
64 short ratio[5];
65 int type;
66 short vcc;
67 } adt_chips[] = {
68
69
70
71 { "adt7460", { 2500, 0, 3300, 0, 0 }, 7460, 5000 },
72 { "adt7467", { 2500, 2250, 3300, 5000, 12000 }, 7467, 5000 },
73 { "adt7475", { 0, 2250, 3300, 0, 0 }, 7475, 0 },
74 { "adt7476", { 2500, 2250, 3300, 5000, 12000 }, 7476, 0 },
75 { "adm1027", { 2500, 2250, 3300, 5000, 12000 }, 1027, 5000 },
76 { "lm85", { 2500, 2250, 3300, 5000, 12000 }, 7467, 0 },
77 { "emc6d100", { 2500, 2250, 3300, 5000, 12000 }, 6100, 0 },
78 { "emc6w201", { 2500, 2250, 3300, 5000, 12000 }, 6201, 0 },
79 { "lm96000", { 2500, 2250, 3300, 5000, 12000 }, 96000, 0 },
80 { "sch5017", { 5000, 2250, 3300, 5000, 12000 }, 5017, 0 }
81 };
82
83 struct {
84 char sensor;
85 u_int8_t cmd;
86 u_short index;
87 } worklist[] = {
88 { ADT_2_5V, ADT7460_2_5V, 32768 + 0 },
89 { ADT_VCCP, ADT7460_VCCP, 32768 + 1 },
90 { ADT_VCC, ADT7460_VCC, 32768 + 2 },
91 { ADT_V5, ADT7460_V5, 32768 + 3 },
92 { ADT_V12, ADT7460_V12, 32768 + 4 },
93 { ADT_REM1_TEMP, ADT7460_REM1_TEMP },
94 { ADT_LOCAL_TEMP, ADT7460_LOCAL_TEMP },
95 { ADT_REM2_TEMP, ADT7460_REM2_TEMP },
96 { ADT_TACH1, ADT7460_TACH1L },
97 { ADT_TACH2, ADT7460_TACH2L },
98 { ADT_TACH3, ADT7460_TACH3L },
99 { ADT_TACH4, ADT7460_TACH4L },
100 };
101
102 struct adt_softc {
103 struct device sc_dev;
104 i2c_tag_t sc_tag;
105 i2c_addr_t sc_addr;
106 u_int8_t sc_conf;
107 struct adt_chip *chip;
108
109 struct ksensor sc_sensor[ADT_NUM_SENSORS];
110 struct ksensordev sc_sensordev;
111 };
112
113 int adt_match(struct device *, void *, void *);
114 void adt_attach(struct device *, struct device *, void *);
115
116 void adt_refresh(void *);
117
118 struct cfattach adt_ca = {
119 sizeof(struct adt_softc), adt_match, adt_attach
120 };
121
122 struct cfdriver adt_cd = {
123 NULL, "adt", DV_DULL
124 };
125
126 int
127 adt_match(struct device *parent, void *match, void *aux)
128 {
129 struct i2c_attach_args *ia = aux;
130 int i;
131
132 for (i = 0; i < sizeof(adt_chips) / sizeof(adt_chips[0]); i++)
133 if (strcmp(ia->ia_name, adt_chips[i].name) == 0)
134 return (1);
135 return (0);
136 }
137
138 void
139 adt_attach(struct device *parent, struct device *self, void *aux)
140 {
141 struct adt_softc *sc = (struct adt_softc *)self;
142 struct i2c_attach_args *ia = aux;
143 u_int8_t cmd, rev, data;
144 int i;
145
146 sc->sc_tag = ia->ia_tag;
147 sc->sc_addr = ia->ia_addr;
148
149 iic_acquire_bus(sc->sc_tag, 0);
150
151 for (i = 0; i < sizeof(adt_chips) / sizeof(adt_chips[0]); i++) {
152 if (strcmp(ia->ia_name, adt_chips[i].name) == 0) {
153 sc->chip = &adt_chips[i];
154 break;
155 }
156 }
157
158 cmd = ADT7460_REVISION;
159 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
160 sc->sc_addr, &cmd, sizeof cmd, &rev, sizeof rev, 0)) {
161 iic_release_bus(sc->sc_tag, 0);
162 printf(": cannot read REV register\n");
163 return;
164 }
165
166 cmd = ADT7460_CONFIG;
167 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
168 sc->sc_addr, &cmd, sizeof cmd, &sc->sc_conf, sizeof sc->sc_conf, 0)) {
169 iic_release_bus(sc->sc_tag, 0);
170 printf(": cannot read config register\n");
171 return;
172 }
173
174 if (sc->chip->type == 7460) {
175 data = 1;
176 cmd = ADT7460_CONFIG;
177 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
178 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
179 iic_release_bus(sc->sc_tag, 0);
180 printf(": cannot set control register\n");
181 return;
182 }
183 }
184
185 iic_release_bus(sc->sc_tag, 0);
186
187 printf(": %s rev 0x%02x", ia->ia_name, rev);
188
189
190 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
191 sizeof(sc->sc_sensordev.xname));
192
193 sc->sc_sensor[ADT_2_5V].type = SENSOR_VOLTS_DC;
194 strlcpy(sc->sc_sensor[ADT_2_5V].desc, "+2.5Vin",
195 sizeof(sc->sc_sensor[ADT_2_5V].desc));
196
197 if (sc->chip->type == 5017)
198 strlcpy(sc->sc_sensor[ADT_2_5V].desc, "+5VTR",
199 sizeof(sc->sc_sensor[ADT_2_5V].desc));
200
201 sc->sc_sensor[ADT_VCCP].type = SENSOR_VOLTS_DC;
202 strlcpy(sc->sc_sensor[ADT_VCCP].desc, "Vccp",
203 sizeof(sc->sc_sensor[ADT_VCCP].desc));
204
205 sc->sc_sensor[ADT_VCC].type = SENSOR_VOLTS_DC;
206 strlcpy(sc->sc_sensor[ADT_VCC].desc, "Vcc",
207 sizeof(sc->sc_sensor[ADT_VCC].desc));
208
209 sc->sc_sensor[ADT_V5].type = SENSOR_VOLTS_DC;
210 strlcpy(sc->sc_sensor[ADT_V5].desc, "+5V",
211 sizeof(sc->sc_sensor[ADT_V5].desc));
212
213 sc->sc_sensor[ADT_V12].type = SENSOR_VOLTS_DC;
214 strlcpy(sc->sc_sensor[ADT_V12].desc, "+12V",
215 sizeof(sc->sc_sensor[ADT_V12].desc));
216
217 sc->sc_sensor[ADT_REM1_TEMP].type = SENSOR_TEMP;
218 strlcpy(sc->sc_sensor[ADT_REM1_TEMP].desc, "Remote",
219 sizeof(sc->sc_sensor[ADT_REM1_TEMP].desc));
220
221 sc->sc_sensor[ADT_LOCAL_TEMP].type = SENSOR_TEMP;
222 strlcpy(sc->sc_sensor[ADT_LOCAL_TEMP].desc, "Internal",
223 sizeof(sc->sc_sensor[ADT_LOCAL_TEMP].desc));
224
225 sc->sc_sensor[ADT_REM2_TEMP].type = SENSOR_TEMP;
226 strlcpy(sc->sc_sensor[ADT_REM2_TEMP].desc, "Remote",
227 sizeof(sc->sc_sensor[ADT_REM2_TEMP].desc));
228
229 sc->sc_sensor[ADT_TACH1].type = SENSOR_FANRPM;
230 sc->sc_sensor[ADT_TACH2].type = SENSOR_FANRPM;
231 sc->sc_sensor[ADT_TACH3].type = SENSOR_FANRPM;
232 sc->sc_sensor[ADT_TACH4].type = SENSOR_FANRPM;
233
234 if (sensor_task_register(sc, adt_refresh, 5) == NULL) {
235 printf(", unable to register update task\n");
236 return;
237 }
238
239 for (i = 0; i < ADT_NUM_SENSORS; i++) {
240 if (worklist[i].index >= 32768 &&
241 sc->chip->ratio[worklist[i].index - 32768] == 0)
242 continue;
243 sc->sc_sensor[i].flags &= ~SENSOR_FINVALID;
244 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
245 }
246 sensordev_install(&sc->sc_sensordev);
247
248
249 printf("\n");
250 }
251
252 void
253 adt_refresh(void *arg)
254 {
255 struct adt_softc *sc = arg;
256 u_int8_t cmd, data, data2;
257 u_int16_t fan;
258 int i, ratio;
259
260 iic_acquire_bus(sc->sc_tag, 0);
261
262 for (i = 0; i < sizeof worklist / sizeof(worklist[0]); i++) {
263
264 if (worklist[i].index >= 32768) {
265 ratio = sc->chip->ratio[worklist[i].index - 32768];
266 if (ratio == 0)
267 continue;
268 }
269 cmd = worklist[i].cmd;
270 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
271 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
272 sc->sc_sensor[i].flags |= SENSOR_FINVALID;
273 continue;
274 }
275
276 sc->sc_sensor[i].flags &= ~SENSOR_FINVALID;
277 switch (worklist[i].sensor) {
278 case ADT_VCC:
279 if (sc->chip->vcc && (sc->sc_conf & ADT7460_CONFIG_Vcc))
280 ratio = sc->chip->vcc;
281
282 case ADT_2_5V:
283 case ADT_VCCP:
284 case ADT_V5:
285 case ADT_V12:
286 sc->sc_sensor[i].value = ratio * 1000 * (u_int)data / 192;
287 break;
288 case ADT_LOCAL_TEMP:
289 case ADT_REM1_TEMP:
290 case ADT_REM2_TEMP:
291 if (data == 0x80)
292 sc->sc_sensor[i].flags |= SENSOR_FINVALID;
293 else
294 sc->sc_sensor[i].value =
295 (int8_t)data * 1000000 + 273150000;
296 break;
297 case ADT_TACH1:
298 case ADT_TACH2:
299 case ADT_TACH3:
300 case ADT_TACH4:
301 cmd = worklist[i].cmd + 1;
302 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
303 sc->sc_addr, &cmd, sizeof cmd, &data2, sizeof data2, 0)) {
304 sc->sc_sensor[i].flags |= SENSOR_FINVALID;
305 continue;
306 }
307
308 fan = data + (data2 << 8);
309 if (fan == 0 || fan == 0xffff)
310 sc->sc_sensor[i].flags |= SENSOR_FINVALID;
311 else
312 sc->sc_sensor[i].value = (90000 * 60) / fan;
313 break;
314 default:
315 sc->sc_sensor[i].flags |= SENSOR_FINVALID;
316 break;
317 }
318 }
319
320 iic_release_bus(sc->sc_tag, 0);
321 }