Annotation of sys/dev/i2c/adm1025.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: adm1025.c,v 1.25 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 1025 registers */
27: #define ADM1025_V2_5 0x20
28: #define ADM1025_Vccp 0x21
29: #define ADM1025_V3_3 0x22
30: #define ADM1025_V5 0x23
31: #define ADM1025_V12 0x24
32: #define ADM1025_Vcc 0x25
33: #define ADM1025_EXT_TEMP 0x26
34: #define ADM1025_INT_TEMP 0x27
35: #define ADM1025_STATUS2 0x42
36: #define ADM1025_STATUS2_EXT 0x40
37: #define ADM1025_COMPANY 0x3e /* contains 0x41 */
38: #define ADM1025_STEPPING 0x3f /* contains 0x2? */
39: #define ADM1025_CONFIG 0x40
40: #define ADM1025_CONFIG_START 0x01
41: #define SMSC47M192_V1_5 0x50
42: #define SMSC47M192_V1_8 0x51
43: #define SMSC47M192_TEMP2 0x52
44:
45: /* Sensors */
46: #define ADMTM_INT 0
47: #define ADMTM_EXT 1
48: #define ADMTM_V2_5 2
49: #define ADMTM_Vccp 3
50: #define ADMTM_V3_3 4
51: #define ADMTM_V5 5
52: #define ADMTM_V12 6
53: #define ADMTM_Vcc 7
54: #define ADMTM_NUM_SENSORS 8
55: #define SMSC_V1_5 8
56: #define SMSC_V1_8 9
57: #define SMSC_TEMP2 10
58: #define SMSC_NUM_SENSORS 3
59: struct admtm_softc {
60: struct device sc_dev;
61: i2c_tag_t sc_tag;
62: i2c_addr_t sc_addr;
63:
64: struct ksensor sc_sensor[ADMTM_NUM_SENSORS + SMSC_NUM_SENSORS];
65: struct ksensordev sc_sensordev;
66: int sc_nsensors;
67: int sc_model;
68: };
69:
70: int admtm_match(struct device *, void *, void *);
71: void admtm_attach(struct device *, struct device *, void *);
72: void admtm_refresh(void *);
73:
74: struct cfattach admtm_ca = {
75: sizeof(struct admtm_softc), admtm_match, admtm_attach
76: };
77:
78: struct cfdriver admtm_cd = {
79: NULL, "admtm", DV_DULL
80: };
81:
82: int
83: admtm_match(struct device *parent, void *match, void *aux)
84: {
85: struct i2c_attach_args *ia = aux;
86:
87: if (strcmp(ia->ia_name, "adm1025") == 0 ||
88: strcmp(ia->ia_name, "47m192") == 0 ||
89: strcmp(ia->ia_name, "ne1619") == 0)
90: return (1);
91: return (0);
92: }
93:
94: void
95: admtm_attach(struct device *parent, struct device *self, void *aux)
96: {
97: struct admtm_softc *sc = (struct admtm_softc *)self;
98: struct i2c_attach_args *ia = aux;
99: u_int8_t cmd, data, data2;
100: int i;
101:
102: sc->sc_tag = ia->ia_tag;
103: sc->sc_addr = ia->ia_addr;
104:
105: printf(": %s", ia->ia_name);
106:
107: sc->sc_nsensors = ADMTM_NUM_SENSORS;
108: sc->sc_model = 1025;
109: if (strcmp(ia->ia_name, "47m192") == 0) {
110: sc->sc_nsensors += SMSC_NUM_SENSORS;
111: sc->sc_model = 192;
112: }
113:
114: iic_acquire_bus(sc->sc_tag, 0);
115: cmd = ADM1025_CONFIG;
116: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
117: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
118: iic_release_bus(sc->sc_tag, 0);
119: printf(", cannot get control register\n");
120: return;
121: }
122:
123: data2 = data | ADM1025_CONFIG_START;
124: if (data != data2) {
125: if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
126: sc->sc_addr, &cmd, sizeof cmd, &data2, sizeof data2, 0)) {
127: iic_release_bus(sc->sc_tag, 0);
128: printf(", cannot set control register\n");
129: return;
130: }
131: }
132: iic_release_bus(sc->sc_tag, 0);
133:
134: /* Initialize sensor data. */
135: strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
136: sizeof(sc->sc_sensordev.xname));
137:
138: sc->sc_sensor[ADMTM_INT].type = SENSOR_TEMP;
139: strlcpy(sc->sc_sensor[ADMTM_INT].desc, "Internal",
140: sizeof(sc->sc_sensor[ADMTM_INT].desc));
141:
142: sc->sc_sensor[ADMTM_EXT].type = SENSOR_TEMP;
143: strlcpy(sc->sc_sensor[ADMTM_EXT].desc, "External",
144: sizeof(sc->sc_sensor[ADMTM_EXT].desc));
145:
146: sc->sc_sensor[ADMTM_V2_5].type = SENSOR_VOLTS_DC;
147: strlcpy(sc->sc_sensor[ADMTM_V2_5].desc, "2.5 V",
148: sizeof(sc->sc_sensor[ADMTM_V2_5].desc));
149:
150: sc->sc_sensor[ADMTM_Vccp].type = SENSOR_VOLTS_DC;
151: strlcpy(sc->sc_sensor[ADMTM_Vccp].desc, "Vccp",
152: sizeof(sc->sc_sensor[ADMTM_Vccp].desc));
153:
154: sc->sc_sensor[ADMTM_V3_3].type = SENSOR_VOLTS_DC;
155: strlcpy(sc->sc_sensor[ADMTM_V3_3].desc, "3.3 V",
156: sizeof(sc->sc_sensor[ADMTM_V3_3].desc));
157:
158: sc->sc_sensor[ADMTM_V5].type = SENSOR_VOLTS_DC;
159: strlcpy(sc->sc_sensor[ADMTM_V5].desc, "5 V",
160: sizeof(sc->sc_sensor[ADMTM_V5].desc));
161:
162: sc->sc_sensor[ADMTM_V12].type = SENSOR_VOLTS_DC;
163: strlcpy(sc->sc_sensor[ADMTM_V12].desc, "12 V",
164: sizeof(sc->sc_sensor[ADMTM_V12].desc));
165:
166: sc->sc_sensor[ADMTM_Vcc].type = SENSOR_VOLTS_DC;
167: strlcpy(sc->sc_sensor[ADMTM_Vcc].desc, "Vcc",
168: sizeof(sc->sc_sensor[ADMTM_Vcc].desc));
169:
170: sc->sc_sensor[SMSC_V1_5].type = SENSOR_VOLTS_DC;
171: strlcpy(sc->sc_sensor[SMSC_V1_5].desc, "1.5 V",
172: sizeof(sc->sc_sensor[SMSC_V1_5].desc));
173:
174: sc->sc_sensor[SMSC_V1_8].type = SENSOR_VOLTS_DC;
175: strlcpy(sc->sc_sensor[SMSC_V1_8].desc, "1.8 V",
176: sizeof(sc->sc_sensor[SMSC_V1_8].desc));
177:
178: sc->sc_sensor[SMSC_TEMP2].type = SENSOR_TEMP;
179: strlcpy(sc->sc_sensor[SMSC_TEMP2].desc, "External",
180: sizeof(sc->sc_sensor[SMSC_TEMP2].desc));
181:
182: if (sensor_task_register(sc, admtm_refresh, 5) == NULL) {
183: printf(", unable to register update task\n");
184: return;
185: }
186:
187: for (i = 0; i < sc->sc_nsensors; i++)
188: sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
189: sensordev_install(&sc->sc_sensordev);
190:
191: printf("\n");
192: }
193:
194: void
195: admtm_refresh(void *arg)
196: {
197: struct admtm_softc *sc = arg;
198: u_int8_t cmd, data;
199: int8_t sdata;
200:
201: iic_acquire_bus(sc->sc_tag, 0);
202:
203: cmd = ADM1025_INT_TEMP;
204: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
205: sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata, 0) == 0)
206: sc->sc_sensor[ADMTM_INT].value = 273150000 + 1000000 * sdata;
207:
208: cmd = ADM1025_EXT_TEMP;
209: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
210: sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata, 0) == 0)
211: sc->sc_sensor[ADMTM_EXT].value = 273150000 + 1000000 * sdata;
212:
213: cmd = ADM1025_STATUS2;
214: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
215: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) {
216: if (data & ADM1025_STATUS2_EXT)
217: sc->sc_sensor[ADMTM_EXT].flags |= SENSOR_FINVALID;
218: else
219: sc->sc_sensor[ADMTM_EXT].flags &= ~SENSOR_FINVALID;
220: }
221:
222: cmd = ADM1025_V2_5;
223: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
224: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
225: sc->sc_sensor[ADMTM_V2_5].value = 2500000 * data / 192;
226:
227: cmd = ADM1025_Vccp;
228: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
229: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
230: sc->sc_sensor[ADMTM_Vcc].value = 2249000 * data / 192;
231:
232: cmd = ADM1025_V3_3;
233: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
234: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
235: sc->sc_sensor[ADMTM_V3_3].value = 3300000 * data / 192;
236:
237: cmd = ADM1025_V5;
238: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
239: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
240: sc->sc_sensor[ADMTM_V5].value = 5000000 * data / 192;
241:
242: cmd = ADM1025_V12;
243: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
244: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
245: sc->sc_sensor[ADMTM_V12].value = 12000000 * data / 192;
246:
247: cmd = ADM1025_Vcc;
248: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
249: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
250: sc->sc_sensor[ADMTM_Vcc].value = 3300000 * data / 192;
251:
252: if (sc->sc_model == 192) {
253: cmd = SMSC47M192_V1_5;
254: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
255: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
256: sc->sc_sensor[SMSC_V1_5].value = 1500000 * data / 192;
257:
258: cmd = SMSC47M192_V1_8;
259: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
260: sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0)
261: sc->sc_sensor[SMSC_V1_8].value = 1800000 * data / 192;
262:
263: cmd = SMSC47M192_TEMP2;
264: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
265: sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata,
266: 0) == 0)
267: sc->sc_sensor[SMSC_TEMP2].value = 273150000 + 1000000 * sdata;
268:
269: }
270:
271: iic_release_bus(sc->sc_tag, 0);
272: }
CVSweb