1 /* $OpenBSD: lm87.c,v 1.19 2007/06/24 05:34:35 dlg Exp $ */ 2 3 /* 4 * Copyright (c) 2005 Mark Kettenis 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 /* LM87 registers */ 27 #define LM87_2_5V 0x20 28 #define LM87_VCCP1 0x21 29 #define LM87_VCC 0x22 30 #define LM87_5V 0x23 31 #define LM87_12V 0x24 32 #define LM87_VCCP2 0x25 33 #define LM87_EXT_TEMP 0x26 34 #define LM87_INT_TEMP 0x27 35 #define LM87_FAN1 0x28 36 #define LM87_FAN2 0x29 37 #define LM87_REVISION 0x3f 38 #define LM87_CONFIG1 0x40 39 #define LM87_CONFIG1_START 0x01 40 #define LM87_CONFIG1_INTCLR 0x08 41 #define LM87_CHANNEL 0x16 42 #define LM87_CHANNEL_AIN1 0x01 43 #define LM87_CHANNEL_AIN2 0x02 44 #define LM87_FANDIV 0x47 45 46 /* Sensors */ 47 #define LMENV_2_5V 0 48 #define LMENV_VCCP1 1 49 #define LMENV_VCC 2 50 #define LMENV_5V 3 51 #define LMENV_12V 4 52 #define LMENV_VCCP2 5 53 #define LMENV_EXT_TEMP 6 54 #define LMENV_INT_TEMP 7 55 #define LMENV_FAN1 8 56 #define LMENV_FAN2 9 57 #define LMENV_NUM_SENSORS 10 58 59 struct lmenv_softc { 60 struct device sc_dev; 61 i2c_tag_t sc_tag; 62 i2c_addr_t sc_addr; 63 64 struct ksensor sc_sensor[LMENV_NUM_SENSORS]; 65 struct ksensordev sc_sensordev; 66 int sc_fan1_div, sc_fan2_div; 67 int sc_family; 68 }; 69 70 int lmenv_match(struct device *, void *, void *); 71 void lmenv_attach(struct device *, struct device *, void *); 72 73 void lmenv_refresh(void *); 74 75 struct cfattach lmenv_ca = { 76 sizeof(struct lmenv_softc), lmenv_match, lmenv_attach 77 }; 78 79 struct cfdriver lmenv_cd = { 80 NULL, "lmenv", DV_DULL 81 }; 82 83 int 84 lmenv_match(struct device *parent, void *match, void *aux) 85 { 86 struct i2c_attach_args *ia = aux; 87 88 if (strcmp(ia->ia_name, "lm87") == 0 || 89 strcmp(ia->ia_name, "lm87cimt") == 0 || 90 strcmp(ia->ia_name, "adm9240") == 0 || 91 strcmp(ia->ia_name, "lm81") == 0 || 92 strcmp(ia->ia_name, "ds1780") == 0) 93 return (1); 94 return (0); 95 } 96 97 void 98 lmenv_attach(struct device *parent, struct device *self, void *aux) 99 { 100 struct lmenv_softc *sc = (struct lmenv_softc *)self; 101 struct i2c_attach_args *ia = aux; 102 u_int8_t cmd, data, data2, channel; 103 int i; 104 105 sc->sc_tag = ia->ia_tag; 106 sc->sc_addr = ia->ia_addr; 107 108 sc->sc_family = 87; 109 if (strcmp(ia->ia_name, "lm81") == 0 || 110 strcmp(ia->ia_name, "adm9240") == 0 || 111 strcmp(ia->ia_name, "ds1780") == 0) 112 sc->sc_family = 81; 113 114 iic_acquire_bus(sc->sc_tag, 0); 115 116 cmd = LM87_REVISION; 117 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 118 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) { 119 iic_release_bus(sc->sc_tag, 0); 120 printf(": cannot read ID register\n"); 121 return; 122 } 123 printf(": %s rev %x", ia->ia_name, data); 124 125 cmd = LM87_FANDIV; 126 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 127 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) { 128 iic_release_bus(sc->sc_tag, 0); 129 printf(", cannot read Fan Divisor register\n"); 130 return; 131 } 132 sc->sc_fan1_div = 1 << ((data >> 4) & 0x03); 133 sc->sc_fan2_div = 1 << ((data >> 6) & 0x03); 134 135 if (sc->sc_family == 87) { 136 cmd = LM87_CHANNEL; 137 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 138 sc->sc_addr, &cmd, sizeof cmd, &channel, 139 sizeof channel, 0)) { 140 iic_release_bus(sc->sc_tag, 0); 141 printf(", cannot read Channel register\n"); 142 return; 143 } 144 } 145 146 cmd = LM87_CONFIG1; 147 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 148 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) { 149 iic_release_bus(sc->sc_tag, 0); 150 printf(", cannot read Configuration Register 1\n"); 151 return; 152 } 153 154 /* 155 * if chip is not running, try to start it. 156 * if it is stalled doing an interrupt, unstall it 157 */ 158 data2 = (data | LM87_CONFIG1_START); 159 data2 = data2 & ~LM87_CONFIG1_INTCLR; 160 161 if (data != data2) { 162 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, 163 sc->sc_addr, &cmd, sizeof cmd, &data2, sizeof data2, 0)) { 164 iic_release_bus(sc->sc_tag, 0); 165 printf(", cannot write Configuration Register 1\n"); 166 return; 167 } 168 printf(", starting scan"); 169 } 170 iic_release_bus(sc->sc_tag, 0); 171 172 /* Initialize sensor data. */ 173 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, 174 sizeof(sc->sc_sensordev.xname)); 175 176 sc->sc_sensor[LMENV_2_5V].type = SENSOR_VOLTS_DC; 177 strlcpy(sc->sc_sensor[LMENV_2_5V].desc, "+2.5Vin", 178 sizeof(sc->sc_sensor[LMENV_2_5V].desc)); 179 180 sc->sc_sensor[LMENV_VCCP1].type = SENSOR_VOLTS_DC; 181 strlcpy(sc->sc_sensor[LMENV_VCCP1].desc, "Vccp", 182 sizeof(sc->sc_sensor[LMENV_VCCP1].desc)); 183 184 sc->sc_sensor[LMENV_VCC].type = SENSOR_VOLTS_DC; 185 strlcpy(sc->sc_sensor[LMENV_VCC].desc, "+Vcc", 186 sizeof(sc->sc_sensor[LMENV_VCC].desc)); 187 188 sc->sc_sensor[LMENV_5V].type = SENSOR_VOLTS_DC; 189 strlcpy(sc->sc_sensor[LMENV_5V].desc, "+5Vin/Vcc", 190 sizeof(sc->sc_sensor[LMENV_5V].desc)); 191 192 sc->sc_sensor[LMENV_12V].type = SENSOR_VOLTS_DC; 193 strlcpy(sc->sc_sensor[LMENV_12V].desc, "+12Vin", 194 sizeof(sc->sc_sensor[LMENV_12V].desc)); 195 196 sc->sc_sensor[LMENV_VCCP2].type = SENSOR_VOLTS_DC; 197 strlcpy(sc->sc_sensor[LMENV_VCCP2].desc, "Vccp", 198 sizeof(sc->sc_sensor[LMENV_VCCP2].desc)); 199 200 sc->sc_sensor[LMENV_EXT_TEMP].type = SENSOR_TEMP; 201 strlcpy(sc->sc_sensor[LMENV_EXT_TEMP].desc, "External", 202 sizeof(sc->sc_sensor[LMENV_EXT_TEMP].desc)); 203 if (sc->sc_family == 81) 204 sc->sc_sensor[LMENV_EXT_TEMP].flags |= SENSOR_FINVALID; 205 206 sc->sc_sensor[LMENV_INT_TEMP].type = SENSOR_TEMP; 207 strlcpy(sc->sc_sensor[LMENV_INT_TEMP].desc, "Internal", 208 sizeof(sc->sc_sensor[LMENV_INT_TEMP].desc)); 209 210 if (channel & LM87_CHANNEL_AIN1) { 211 sc->sc_sensor[LMENV_FAN1].type = SENSOR_VOLTS_DC; 212 strlcpy(sc->sc_sensor[LMENV_FAN1].desc, "AIN1", 213 sizeof(sc->sc_sensor[LMENV_FAN1].desc)); 214 } else { 215 sc->sc_sensor[LMENV_FAN1].type = SENSOR_FANRPM; 216 } 217 218 if (channel & LM87_CHANNEL_AIN2) { 219 sc->sc_sensor[LMENV_FAN2].type = SENSOR_VOLTS_DC; 220 strlcpy(sc->sc_sensor[LMENV_FAN2].desc, "AIN2", 221 sizeof(sc->sc_sensor[LMENV_FAN2].desc)); 222 } else { 223 sc->sc_sensor[LMENV_FAN2].type = SENSOR_FANRPM; 224 } 225 226 if (sensor_task_register(sc, lmenv_refresh, 5) == NULL) { 227 printf(", unable to register update task\n"); 228 return; 229 } 230 231 for (i = 0; i < LMENV_NUM_SENSORS; i++) 232 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]); 233 sensordev_install(&sc->sc_sensordev); 234 235 printf("\n"); 236 } 237 238 void 239 lmenv_refresh(void *arg) 240 { 241 struct lmenv_softc *sc = arg; 242 u_int8_t cmd, data; 243 u_int tmp; 244 int sensor; 245 246 iic_acquire_bus(sc->sc_tag, 0); 247 248 for (sensor = 0; sensor < LMENV_NUM_SENSORS; sensor++) { 249 cmd = LM87_2_5V + sensor; 250 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 251 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) { 252 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID; 253 continue; 254 } 255 256 sc->sc_sensor[sensor].flags &= ~SENSOR_FINVALID; 257 switch (sensor) { 258 case LMENV_2_5V: 259 sc->sc_sensor[sensor].value = 2500000 * data / 192; 260 break; 261 case LMENV_5V: 262 sc->sc_sensor[sensor].value = 5000000 * data / 192; 263 break; 264 case LMENV_12V: 265 sc->sc_sensor[sensor].value = 12000000 * data / 192; 266 break; 267 case LMENV_VCCP1: 268 case LMENV_VCCP2: 269 sc->sc_sensor[sensor].value = 2700000 * data / 192; 270 break; 271 case LMENV_VCC: 272 sc->sc_sensor[sensor].value = 3300000 * data / 192; 273 break; 274 case LMENV_EXT_TEMP: 275 if (sc->sc_family == 81) { 276 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID; 277 break; /* missing on LM81 */ 278 } 279 /* FALLTHROUGH */ 280 case LMENV_INT_TEMP: 281 if (data == 0x80) 282 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID; 283 else 284 sc->sc_sensor[sensor].value = 285 (int8_t)data * 1000000 + 273150000; 286 break; 287 case LMENV_FAN1: 288 if (sc->sc_sensor[sensor].type == SENSOR_VOLTS_DC) { 289 sc->sc_sensor[sensor].value = 290 1870000 * data / 192; 291 break; 292 } 293 tmp = data * sc->sc_fan1_div; 294 if (tmp == 0) 295 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID; 296 else 297 sc->sc_sensor[sensor].value = 1350000 / tmp; 298 break; 299 case LMENV_FAN2: 300 if (sc->sc_sensor[sensor].type == SENSOR_VOLTS_DC) { 301 sc->sc_sensor[sensor].value = 302 1870000 * data / 192; 303 break; 304 } 305 tmp = data * sc->sc_fan2_div; 306 if (tmp == 0) 307 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID; 308 else 309 sc->sc_sensor[sensor].value = 1350000 / tmp; 310 break; 311 default: 312 sc->sc_sensor[sensor].flags |= SENSOR_FINVALID; 313 break; 314 } 315 } 316 317 iic_release_bus(sc->sc_tag, 0); 318 } 319