Annotation of sys/dev/i2c/maxim6690.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: maxim6690.c,v 1.15 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: /* Maxim MAX6642/90 registers */
27: #define MAX6690_INT_TEMP 0x00
28: #define MAX6690_EXT_TEMP 0x01
29: #define MAX6690_INT_TEMP2 0x11
30: #define MAX6690_EXT_TEMP2 0x10
31: #define MAX6690_STATUS 0x02
32: #define MAX6690_DEVID 0xfe
33: #define MAX6690_REVISION 0xff /* absent on MAX6642 */
34:
35: #define MAX6642_TEMP_INVALID 0xff /* sensor disconnected */
36: #define MAX6690_TEMP_INVALID 0x80 /* sensor disconnected */
37: #define MAX6690_TEMP_INVALID2 0x7f /* open-circuit without pull-up */
38: #define LM90_TEMP_INVALID 0x7f /* sensor disconnected */
39:
40: #define MAX6642_TEMP2_MASK 0xc0 /* significant bits */
41: #define MAX6690_TEMP2_MASK 0xe0 /* significant bits */
42: #define LM90_TEMP2_MASK 0xe0 /* significant bits */
43:
44: /* Sensors */
45: #define MAXTMP_INT 0
46: #define MAXTMP_EXT 1
47: #define MAXTMP_NUM_SENSORS 2
48:
49: struct maxtmp_softc {
50: struct device sc_dev;
51: i2c_tag_t sc_tag;
52: i2c_addr_t sc_addr;
53:
54: u_int8_t sc_temp_invalid[2];
55: u_int8_t sc_temp2_mask;
56:
57: struct ksensor sc_sensor[MAXTMP_NUM_SENSORS];
58: struct ksensordev sc_sensordev;
59: };
60:
61: int maxtmp_match(struct device *, void *, void *);
62: void maxtmp_attach(struct device *, struct device *, void *);
63: int maxtmp_check(struct i2c_attach_args *, u_int8_t *, u_int8_t *);
64: void maxtmp_refresh(void *);
65:
66: struct cfattach maxtmp_ca = {
67: sizeof(struct maxtmp_softc), maxtmp_match, maxtmp_attach
68: };
69:
70: struct cfdriver maxtmp_cd = {
71: NULL, "maxtmp", DV_DULL
72: };
73:
74: int
75: maxtmp_match(struct device *parent, void *match, void *aux)
76: {
77: struct i2c_attach_args *ia = aux;
78:
79: if (strcmp(ia->ia_name, "max6642") == 0 ||
80: strcmp(ia->ia_name, "max6690") == 0 ||
81: strcmp(ia->ia_name, "max6657") == 0 ||
82: strcmp(ia->ia_name, "max6658") == 0 ||
83: strcmp(ia->ia_name, "max6659") == 0 ||
84: strcmp(ia->ia_name, "lm63") == 0 ||
85: strcmp(ia->ia_name, "lm86") == 0 ||
86: strcmp(ia->ia_name, "lm89") == 0 ||
87: strcmp(ia->ia_name, "lm89-1") == 0 ||
88: strcmp(ia->ia_name, "lm90") == 0 ||
89: strcmp(ia->ia_name, "lm99") == 0 ||
90: strcmp(ia->ia_name, "lm99-1") == 0)
91: return (1);
92: return (0);
93: }
94:
95: void
96: maxtmp_attach(struct device *parent, struct device *self, void *aux)
97: {
98: struct maxtmp_softc *sc = (struct maxtmp_softc *)self;
99: struct i2c_attach_args *ia = aux;
100: int i;
101:
102: sc->sc_tag = ia->ia_tag;
103: sc->sc_addr = ia->ia_addr;
104:
105: if (strcmp(ia->ia_name, "max6642") == 0) {
106: sc->sc_temp_invalid[0] = MAX6642_TEMP_INVALID;
107: sc->sc_temp_invalid[1] = MAX6642_TEMP_INVALID;
108: sc->sc_temp2_mask = MAX6642_TEMP2_MASK;
109: } else if (strcmp(ia->ia_name, "max6690") == 0 ||
110: strcmp(ia->ia_name, "max6657") == 0 ||
111: strcmp(ia->ia_name, "max6658") == 0 ||
112: strcmp(ia->ia_name, "max6659") == 0) {
113: sc->sc_temp_invalid[0] = MAX6690_TEMP_INVALID;
114: sc->sc_temp_invalid[1] = MAX6690_TEMP_INVALID2;
115: sc->sc_temp2_mask = MAX6690_TEMP2_MASK;
116: } else {
117: sc->sc_temp_invalid[0] = LM90_TEMP_INVALID;
118: sc->sc_temp_invalid[1] = LM90_TEMP_INVALID;
119: sc->sc_temp2_mask = LM90_TEMP2_MASK;
120: }
121: printf(": %s", ia->ia_name);
122:
123: /* Initialize sensor data. */
124: strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
125: sizeof(sc->sc_sensordev.xname));
126:
127: sc->sc_sensor[MAXTMP_INT].type = SENSOR_TEMP;
128: strlcpy(sc->sc_sensor[MAXTMP_INT].desc, "Internal",
129: sizeof(sc->sc_sensor[MAXTMP_INT].desc));
130:
131: sc->sc_sensor[MAXTMP_EXT].type = SENSOR_TEMP;
132: strlcpy(sc->sc_sensor[MAXTMP_EXT].desc, "External",
133: sizeof(sc->sc_sensor[MAXTMP_EXT].desc));
134:
135: if (sensor_task_register(sc, maxtmp_refresh, 5) == NULL) {
136: printf(", unable to register update task\n");
137: return;
138: }
139:
140: for (i = 0; i < MAXTMP_NUM_SENSORS; i++)
141: sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
142: sensordev_install(&sc->sc_sensordev);
143:
144: printf("\n");
145: }
146:
147: void maxtmp_readport(struct maxtmp_softc *, u_int8_t, u_int8_t, int);
148:
149: void
150: maxtmp_readport(struct maxtmp_softc *sc, u_int8_t cmd1, u_int8_t cmd2,
151: int index)
152: {
153: u_int8_t data, data2;
154:
155: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
156: sc->sc_addr, &cmd1, sizeof cmd1, &data, sizeof data, 0))
157: goto invalid;
158: if (data == sc->sc_temp_invalid[0] || data == sc->sc_temp_invalid[1])
159: goto invalid;
160: if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
161: sc->sc_addr, &cmd2, sizeof cmd2, &data2, sizeof data2, 0))
162: goto invalid;
163:
164: /* Set any meaningless bits to zero. */
165: data2 &= sc->sc_temp2_mask;
166:
167: sc->sc_sensor[index].value = 273150000 +
168: 1000000 * data + (data2 >> 5) * 1000000 / 8;
169: return;
170:
171: invalid:
172: sc->sc_sensor[index].flags |= SENSOR_FINVALID;
173: }
174:
175: void
176: maxtmp_refresh(void *arg)
177: {
178: struct maxtmp_softc *sc = arg;
179:
180: iic_acquire_bus(sc->sc_tag, 0);
181:
182: maxtmp_readport(sc, MAX6690_INT_TEMP, MAX6690_INT_TEMP2, MAXTMP_INT);
183: maxtmp_readport(sc, MAX6690_EXT_TEMP, MAX6690_EXT_TEMP2, MAXTMP_EXT);
184:
185: iic_release_bus(sc->sc_tag, 0);
186: }
CVSweb