1 /* $OpenBSD: adm1026.c,v 1.12 2022/04/06 18:59:28 naddy 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 1026 registers */ 27 #define ADM1026_TEMP 0x1f 28 #define ADM1026_STATUS 0x20 29 #define ADM1026_Vbat 0x26 30 #define ADM1026_Ain8 0x27 31 #define ADM1026_EXT1 0x28 32 #define ADM1026_EXT2 0x29 33 #define ADM1026_V3_3stby 0x2a 34 #define ADM1026_V3_3main 0x2b 35 #define ADM1026_V5 0x2c 36 #define ADM1026_Vccp 0x2d 37 #define ADM1026_V12 0x2e 38 #define ADM1026_Vminus12 0x2f 39 #define ADM1026_FAN0 0x38 40 #define ADM1026_FAN1 0x39 41 #define ADM1026_FAN2 0x3a 42 #define ADM1026_FAN3 0x3b 43 #define ADM1026_FAN4 0x3c 44 #define ADM1026_FAN5 0x3d 45 #define ADM1026_FAN6 0x3e 46 #define ADM1026_FAN7 0x3f 47 #define ADM1026_EXT1_OFF 0x6e 48 #define ADM1026_EXT2_OFF 0x6f 49 #define ADM1026_FAN0123DIV 0x02 50 #define ADM1026_FAN4567DIV 0x03 51 #define ADM1026_CONTROL 0x00 52 #define ADM1026_CONTROL_START 0x01 53 #define ADM1026_CONTROL_INTCLR 0x04 54 55 /* Sensors */ 56 #define ADMCTS_TEMP 0 57 #define ADMCTS_EXT1 1 58 #define ADMCTS_EXT2 2 59 #define ADMCTS_Vbat 3 60 #define ADMCTS_V3_3stby 4 61 #define ADMCTS_V3_3main 5 62 #define ADMCTS_V5 6 63 #define ADMCTS_Vccp 7 64 #define ADMCTS_V12 8 65 #define ADMCTS_Vminus12 9 66 #define ADMCTS_FAN0 10 67 #define ADMCTS_FAN1 11 68 #define ADMCTS_FAN2 12 69 #define ADMCTS_FAN3 13 70 #define ADMCTS_FAN4 14 71 #define ADMCTS_FAN5 15 72 #define ADMCTS_FAN6 16 73 #define ADMCTS_FAN7 17 74 #define ADMCTS_NUM_SENSORS 18 75 76 struct admcts_softc { 77 struct device sc_dev; 78 i2c_tag_t sc_tag; 79 i2c_addr_t sc_addr; 80 81 struct ksensor sc_sensor[ADMCTS_NUM_SENSORS]; 82 struct ksensordev sc_sensordev; 83 int sc_fanmul[8]; 84 }; 85 86 int admcts_match(struct device *, void *, void *); 87 void admcts_attach(struct device *, struct device *, void *); 88 void admcts_refresh(void *); 89 90 const struct cfattach admcts_ca = { 91 sizeof(struct admcts_softc), admcts_match, admcts_attach 92 }; 93 94 struct cfdriver admcts_cd = { 95 NULL, "admcts", DV_DULL 96 }; 97 98 int 99 admcts_match(struct device *parent, void *match, void *aux) 100 { 101 struct i2c_attach_args *ia = aux; 102 103 if (strcmp(ia->ia_name, "adm1026") == 0) 104 return (1); 105 return (0); 106 } 107 108 void 109 admcts_attach(struct device *parent, struct device *self, void *aux) 110 { 111 struct admcts_softc *sc = (struct admcts_softc *)self; 112 struct i2c_attach_args *ia = aux; 113 u_int8_t cmd, data, data2; 114 int i; 115 116 sc->sc_tag = ia->ia_tag; 117 sc->sc_addr = ia->ia_addr; 118 119 iic_acquire_bus(sc->sc_tag, 0); 120 cmd = ADM1026_CONTROL; 121 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 122 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) { 123 iic_release_bus(sc->sc_tag, 0); 124 printf(": cannot get control register\n"); 125 return; 126 } 127 data2 = data | ADM1026_CONTROL_START; 128 data2 = data2 & ~ADM1026_CONTROL_INTCLR; 129 if (data != data2) { 130 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, 131 sc->sc_addr, &cmd, sizeof cmd, &data2, sizeof data2, 0)) { 132 iic_release_bus(sc->sc_tag, 0); 133 printf(": cannot set control register\n"); 134 return; 135 } 136 } 137 138 cmd = ADM1026_FAN0123DIV; 139 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 140 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) { 141 iic_release_bus(sc->sc_tag, 0); 142 printf(": cannot get fan0123div register\n"); 143 return; 144 } 145 sc->sc_fanmul[0] = (1 << ((data >> 0) & 0x3)); 146 sc->sc_fanmul[1] = (1 << ((data >> 2) & 0x3)); 147 sc->sc_fanmul[2] = (1 << ((data >> 4) & 0x3)); 148 sc->sc_fanmul[3] = (1 << ((data >> 6) & 0x3)); 149 150 cmd = ADM1026_FAN4567DIV; 151 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 152 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) { 153 iic_release_bus(sc->sc_tag, 0); 154 printf(": cannot get fan0123div register\n"); 155 return; 156 } 157 sc->sc_fanmul[4] = (1 << ((data >> 0) & 0x3)); 158 sc->sc_fanmul[5] = (1 << ((data >> 2) & 0x3)); 159 sc->sc_fanmul[6] = (1 << ((data >> 4) & 0x3)); 160 sc->sc_fanmul[7] = (1 << ((data >> 6) & 0x3)); 161 162 iic_release_bus(sc->sc_tag, 0); 163 164 /* Initialize sensor data. */ 165 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, 166 sizeof(sc->sc_sensordev.xname)); 167 168 sc->sc_sensor[ADMCTS_TEMP].type = SENSOR_TEMP; 169 strlcpy(sc->sc_sensor[ADMCTS_TEMP].desc, "Internal", 170 sizeof(sc->sc_sensor[ADMCTS_TEMP].desc)); 171 172 sc->sc_sensor[ADMCTS_Vbat].type = SENSOR_VOLTS_DC; 173 strlcpy(sc->sc_sensor[ADMCTS_Vbat].desc, "Vbat", 174 sizeof(sc->sc_sensor[ADMCTS_Vbat].desc)); 175 176 sc->sc_sensor[ADMCTS_EXT1].type = SENSOR_TEMP; 177 strlcpy(sc->sc_sensor[ADMCTS_EXT1].desc, "External", 178 sizeof(sc->sc_sensor[ADMCTS_EXT1].desc)); 179 180 sc->sc_sensor[ADMCTS_EXT2].type = SENSOR_TEMP; 181 strlcpy(sc->sc_sensor[ADMCTS_EXT2].desc, "External", 182 sizeof(sc->sc_sensor[ADMCTS_EXT2].desc)); 183 184 sc->sc_sensor[ADMCTS_V3_3stby].type = SENSOR_VOLTS_DC; 185 strlcpy(sc->sc_sensor[ADMCTS_V3_3stby].desc, "3.3 V standby", 186 sizeof(sc->sc_sensor[ADMCTS_V3_3stby].desc)); 187 188 sc->sc_sensor[ADMCTS_V3_3main].type = SENSOR_VOLTS_DC; 189 strlcpy(sc->sc_sensor[ADMCTS_V3_3main].desc, "3.3 V main", 190 sizeof(sc->sc_sensor[ADMCTS_V3_3main].desc)); 191 192 sc->sc_sensor[ADMCTS_V5].type = SENSOR_VOLTS_DC; 193 strlcpy(sc->sc_sensor[ADMCTS_V5].desc, "5 V", 194 sizeof(sc->sc_sensor[ADMCTS_V5].desc)); 195 196 sc->sc_sensor[ADMCTS_Vccp].type = SENSOR_VOLTS_DC; 197 strlcpy(sc->sc_sensor[ADMCTS_Vccp].desc, "Vccp", 198 sizeof(sc->sc_sensor[ADMCTS_Vccp].desc)); 199 200 sc->sc_sensor[ADMCTS_V12].type = SENSOR_VOLTS_DC; 201 strlcpy(sc->sc_sensor[ADMCTS_V12].desc, "12 V", 202 sizeof(sc->sc_sensor[ADMCTS_V12].desc)); 203 204 sc->sc_sensor[ADMCTS_Vminus12].type = SENSOR_VOLTS_DC; 205 strlcpy(sc->sc_sensor[ADMCTS_Vminus12].desc, "-12 V", 206 sizeof(sc->sc_sensor[ADMCTS_Vminus12].desc)); 207 208 sc->sc_sensor[ADMCTS_FAN1].type = SENSOR_FANRPM; 209 sc->sc_sensor[ADMCTS_FAN2].type = SENSOR_FANRPM; 210 sc->sc_sensor[ADMCTS_FAN3].type = SENSOR_FANRPM; 211 sc->sc_sensor[ADMCTS_FAN4].type = SENSOR_FANRPM; 212 sc->sc_sensor[ADMCTS_FAN5].type = SENSOR_FANRPM; 213 sc->sc_sensor[ADMCTS_FAN6].type = SENSOR_FANRPM; 214 sc->sc_sensor[ADMCTS_FAN7].type = SENSOR_FANRPM; 215 216 if (sensor_task_register(sc, admcts_refresh, 5) == NULL) { 217 printf(", unable to register update task\n"); 218 return; 219 } 220 221 for (i = 0; i < ADMCTS_NUM_SENSORS; i++) 222 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]); 223 sensordev_install(&sc->sc_sensordev); 224 225 printf("\n"); 226 } 227 228 static void 229 fanval(struct ksensor *sens, int mul, u_int8_t data) 230 { 231 int tmp = data * mul; 232 233 if (tmp == 0) 234 sens->flags |= SENSOR_FINVALID; 235 else 236 sens->value = 1630000 / tmp; 237 } 238 239 void 240 admcts_refresh(void *arg) 241 { 242 struct admcts_softc *sc = arg; 243 u_int8_t cmd, data; 244 int8_t sdata; 245 246 iic_acquire_bus(sc->sc_tag, 0); 247 248 cmd = ADM1026_TEMP; 249 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 250 sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata, 0) == 0) 251 sc->sc_sensor[ADMCTS_TEMP].value = 273150000 + 1000000 * sdata; 252 253 cmd = ADM1026_EXT1; 254 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 255 sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata, 0) == 0) 256 sc->sc_sensor[ADMCTS_EXT1].value = 273150000 + 1000000 * sdata; 257 258 cmd = ADM1026_EXT2; 259 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 260 sc->sc_addr, &cmd, sizeof cmd, &sdata, sizeof sdata, 0) == 0) 261 sc->sc_sensor[ADMCTS_EXT2].value = 273150000 + 1000000 * sdata; 262 263 cmd = ADM1026_Vbat; 264 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 265 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 266 sc->sc_sensor[ADMCTS_Vbat].value = 3000000 * data / 192; 267 268 cmd = ADM1026_V3_3stby; 269 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 270 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 271 sc->sc_sensor[ADMCTS_V3_3stby].value = 3300000 * data / 192; 272 273 cmd = ADM1026_V3_3main; 274 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 275 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 276 sc->sc_sensor[ADMCTS_V3_3main].value = 3300000 * data / 192; 277 278 cmd = ADM1026_V5; 279 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 280 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 281 sc->sc_sensor[ADMCTS_V5].value = 5500000 * data / 192; 282 283 cmd = ADM1026_Vccp; 284 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 285 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 286 sc->sc_sensor[ADMCTS_Vccp].value = 2250000 * data / 192; 287 288 cmd = ADM1026_V12; 289 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 290 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 291 sc->sc_sensor[ADMCTS_V12].value = 12000000 * data / 192; 292 293 cmd = ADM1026_Vminus12; 294 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 295 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 296 sc->sc_sensor[ADMCTS_Vminus12].value = -2125000 * data / 192; 297 298 cmd = ADM1026_FAN0; 299 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 300 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 301 fanval(&sc->sc_sensor[ADMCTS_FAN0], sc->sc_fanmul[0], data); 302 303 cmd = ADM1026_FAN1; 304 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 305 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 306 fanval(&sc->sc_sensor[ADMCTS_FAN1], sc->sc_fanmul[1], data); 307 308 cmd = ADM1026_FAN2; 309 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 310 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 311 fanval(&sc->sc_sensor[ADMCTS_FAN2], sc->sc_fanmul[2], data); 312 313 cmd = ADM1026_FAN3; 314 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 315 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 316 fanval(&sc->sc_sensor[ADMCTS_FAN3], sc->sc_fanmul[3], data); 317 318 cmd = ADM1026_FAN4; 319 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 320 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 321 fanval(&sc->sc_sensor[ADMCTS_FAN4], sc->sc_fanmul[4], data); 322 323 cmd = ADM1026_FAN5; 324 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 325 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 326 fanval(&sc->sc_sensor[ADMCTS_FAN5], sc->sc_fanmul[5], data); 327 328 cmd = ADM1026_FAN6; 329 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 330 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 331 fanval(&sc->sc_sensor[ADMCTS_FAN6], sc->sc_fanmul[6], data); 332 333 cmd = ADM1026_FAN7; 334 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, 335 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0) == 0) 336 fanval(&sc->sc_sensor[ADMCTS_FAN7], sc->sc_fanmul[7], data); 337 338 iic_release_bus(sc->sc_tag, 0); 339 } 340