1 /* $NetBSD: adm1021.c,v 1.12 2016/01/04 19:24:15 christos Exp $ */ 2 /* $OpenBSD: adm1021.c,v 1.27 2007/06/24 05:34:35 dlg Exp $ */ 3 4 /* 5 * Copyright (c) 2005 Theo de Raadt 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * Driver for ADM1021 and compatible temperature sensors, including ADM1021, 22 * ADM1021A, ADM1023, ADM1032, GL523SM, G781, LM84, MAX1617, MAX1617A, 23 * NE1617A, and Xeon embedded temperature sensors. 24 * 25 * Some sensors differ from the ADM1021/MAX1617/NE1617A: 26 * ADM1021A ADM1023 ADM1032 G781 LM84 MAX1617A 27 * company/revision reg X X X X X 28 * no negative temps X X X X 29 * 11-bit remote temp X X X 30 * no low limits X 31 * therm (high) limits X X 32 * 33 * Registers 0x00 to 0x0f have separate read/write addresses, but 34 * registers 0x10 and above have the same read/write address. 35 * The 11-bit (extended) temperature consists of a separate register with 36 * 3 valid bits that are always added to the external temperature (even if 37 * the temperature is negative). 38 */ 39 40 #include <sys/cdefs.h> 41 __KERNEL_RCSID(0, "$NetBSD: adm1021.c,v 1.12 2016/01/04 19:24:15 christos Exp $"); 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/device.h> 46 #include <dev/sysmon/sysmonvar.h> 47 48 #include <dev/i2c/i2cvar.h> 49 50 /* Registers */ 51 #define ADM1021_INT_TEMP 0x00 /* Internal temperature value */ 52 #define ADM1021_EXT_TEMP 0x01 /* External temperature value */ 53 #define ADM1021_STATUS 0x02 /* Status */ 54 #define ADM1021_CONFIG_READ 0x03 /* Read configuration */ 55 #define ADM1021_CONV_RATE_READ 0x04 /* Read conversion rate */ 56 #define ADM1021_INT_HIGH_READ 0x05 /* Read internal high limit */ 57 #define ADM1021_INT_LOW_READ 0x06 /* Read internal low limit */ 58 #define ADM1021_EXT_HIGH_READ 0x07 /* Read external high limit */ 59 #define ADM1021_EXT_LOW_READ 0x08 /* Read external low limit */ 60 #define ADM1021_CONFIG_WRITE 0x09 /* Write configuration */ 61 #define ADM1021_CONV_RATE_WRITE 0x0a /* Write conversion rate */ 62 #define ADM1021_INT_HIGH_WRITE 0x0b /* Write internal high limit */ 63 #define ADM1021_INT_LOW_WRITE 0x0c /* Write internal low limit */ 64 #define ADM1021_EXT_HIGH_WRITE 0x0d /* Write external high limit */ 65 #define ADM1021_EXT_LOW_WRITE 0x0e /* Write external low limit */ 66 #define ADM1021_ONE_SHOT 0x0f /* One shot command */ 67 #define ADM1023_EXT_TEMP2 0x10 /* R/W external temp low byte */ 68 #define ADM1023_EXT_TEMP_OFF 0x11 /* R/W external temp offset */ 69 #define ADM1023_EXT_TEMP_OFF2 0x12 /* R/W external temp off low byte */ 70 #define ADM1023_EXT_HIGH2 0x13 /* R/W external high lim low byte */ 71 #define ADM1023_EXT_LOW2 0x14 /* R/W external low lim low byte */ 72 #define ADM1032_EXT_THERM 0x19 /* R/W external Therm (high) limit */ 73 #define ADM1032_INT_THERM 0x20 /* R/W internal Therm (high) limit */ 74 #define ADM1032_THERM_HYST 0x21 /* R/W Therm hysteris */ 75 #define ADM1032_ALERT_QUEUE 0x22 /* R/W consecutive alert queue */ 76 #define ADM1021_COMPANY 0xfe /* Company ID */ 77 #define ADM1021_DIE_REVISION 0xff /* Die revision code */ 78 79 /* Register values */ 80 #define ADM1021_CONFIG_RUN 0x40 81 82 #define ADM1021_STATUS_INVAL 0x7f 83 #define ADM1021_STATUS_NOEXT 0x40 /* External diode is open-circuit */ 84 85 #define ADM1023_EXT2_SHIFT 5 86 #define ADM1023_EXT2_MASK 0x07 87 88 #define ADM1021_COMPANY_ADM 0x41 /* 'A' */ 89 #define ADM1021_COMPANY_GMT 0x47 /* 'G' */ 90 #define ADM1021_COMPANY_MAXIM 0x4d /* 'M' */ 91 92 #define ADM1021_REV_1021 0x00 93 #define ADM1021_REV_1021A 0x30 94 #define ADM1021_REV_MASK 0xf0 95 96 /* Sensors */ 97 #define ADMTEMP_INT 0 98 #define ADMTEMP_EXT 1 99 #define ADMTEMP_NUM_SENSORS 2 100 101 #define ADMTEMP_MAX_NEG -65 102 #define ADMTEMP_MAX_POS 127 103 #define ADMTEMP_LOW_DEFAULT 0xc9 /* (-55) */ 104 105 /* Limit registers might read 0xff, so we ignore them if they do */ 106 #define ADMTEMP_LIM_INVAL -1 /* 0xff */ 107 108 #define ADMTEMP_NAMELEN 9 /* Maximum name length + 1 */ 109 110 struct admtemp_softc { 111 i2c_tag_t sc_tag; 112 i2c_addr_t sc_addr; 113 114 int sc_flags; 115 int sc_noexternal, sc_noneg, sc_nolow; 116 int sc_ext11, sc_therm; 117 struct sysmon_envsys *sc_sme; 118 envsys_data_t sc_sensor[ADMTEMP_NUM_SENSORS]; 119 int sc_setdef[ADMTEMP_NUM_SENSORS]; 120 uint8_t sc_highlim[ADMTEMP_NUM_SENSORS]; 121 uint8_t sc_lowlim[ADMTEMP_NUM_SENSORS]; 122 uint8_t sc_highlim2, sc_lowlim2; 123 uint8_t sc_thermlim[ADMTEMP_NUM_SENSORS]; 124 }; 125 126 int admtemp_match(device_t, cfdata_t, void *); 127 void admtemp_attach(device_t, device_t, void *); 128 void admtemp_refresh(struct sysmon_envsys *, envsys_data_t *); 129 void admtemp_getlim_1021(struct sysmon_envsys *, envsys_data_t *, 130 sysmon_envsys_lim_t *, uint32_t *); 131 void admtemp_getlim_1023(struct sysmon_envsys *, envsys_data_t *, 132 sysmon_envsys_lim_t *, uint32_t *); 133 void admtemp_getlim_1032(struct sysmon_envsys *, envsys_data_t *, 134 sysmon_envsys_lim_t *, uint32_t *); 135 void admtemp_setlim_1021(struct sysmon_envsys *, envsys_data_t *, 136 sysmon_envsys_lim_t *, uint32_t *); 137 void admtemp_setlim_1023(struct sysmon_envsys *, envsys_data_t *, 138 sysmon_envsys_lim_t *, uint32_t *); 139 void admtemp_setlim_1032(struct sysmon_envsys *, envsys_data_t *, 140 sysmon_envsys_lim_t *, uint32_t *); 141 142 CFATTACH_DECL_NEW(admtemp, sizeof(struct admtemp_softc), 143 admtemp_match, admtemp_attach, NULL, NULL); 144 145 /* XXX: add flags for compats to admtemp_setflags() */ 146 static const char * admtemp_compats[] = { 147 "i2c-max1617", 148 NULL 149 }; 150 151 int 152 admtemp_match(device_t parent, cfdata_t match, void *aux) 153 { 154 struct i2c_attach_args *ia = aux; 155 156 if (ia->ia_name == NULL) { 157 /* 158 * Indirect config - not much we can do! 159 * Check typical addresses. 160 */ 161 if (((ia->ia_addr >= 0x18) && (ia->ia_addr <= 0x1a)) || 162 ((ia->ia_addr >= 0x29) && (ia->ia_addr <= 0x2b)) || 163 ((ia->ia_addr >= 0x4c) && (ia->ia_addr <= 0x4e))) 164 return (1); 165 } else { 166 /* 167 * Direct config - match via the list of compatible 168 * hardware or simply match the device name. 169 */ 170 if (ia->ia_ncompat > 0) { 171 if (iic_compat_match(ia, admtemp_compats)) 172 return 1; 173 } else { 174 if (strcmp(ia->ia_name, "admtemp") == 0) 175 return 1; 176 } 177 } 178 179 return 0; 180 } 181 182 static int 183 admtemp_exec(struct admtemp_softc *sc, i2c_op_t op, uint8_t *cmd, 184 uint8_t *data) 185 { 186 return iic_exec(sc->sc_tag, op, sc->sc_addr, cmd, sizeof(*cmd), data, 187 sizeof(*data), 0); 188 } 189 190 /* 191 * Set flags based on chip type for direct config, or by testing for 192 * indirect config. 193 * 194 * LM84, MAX1617, and NE1617A don't have company/revision registers. 195 * If we can't read the company register, we'll check the 196 * internal low limit to see if we have an LM84. 197 * 198 * To check if an ADM chip has 11-bit sensors, we'll write 0.125 199 * to the external temperature limit low byte register and read it 200 * back (because we can't tell from the id/rev). 201 * 202 * To check if an ADM chip has a Therm output, we check that we 203 * read 0x55 (default value) from the external therm limit. 204 * 205 * If an ADM chip doesn't have 11-bit sensors, check the revision to 206 * determine if it handles negative temperatures. 207 */ 208 static void 209 admtemp_setflags(struct admtemp_softc *sc, struct i2c_attach_args *ia, 210 uint8_t* comp, uint8_t *rev, char* name) 211 { 212 uint8_t cmd, data, tmp; 213 int i; 214 215 *comp = 0; 216 *rev = 0; 217 218 cmd = ADM1021_COMPANY; 219 admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, comp); 220 221 cmd = ADM1021_DIE_REVISION; 222 admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, rev); 223 224 sc->sc_noneg = 1; 225 sc->sc_nolow = 0; 226 sc->sc_ext11 = 0; 227 sc->sc_therm = 0; 228 229 /* Direct config */ 230 for (i = 0; i < ia->ia_ncompat; i++) { 231 if (strcmp("i2c-max1617", ia->ia_compat[i]) == 0) { 232 sc->sc_noneg = 0; 233 strlcpy(name, "MAX1617A", ADMTEMP_NAMELEN); 234 return; 235 } 236 } 237 238 /* Indirect config */ 239 if (*comp == 0) { 240 sc->sc_noneg = 0; 241 cmd = ADM1021_INT_LOW_READ; 242 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, comp) == 0 && 243 *comp != ADMTEMP_LOW_DEFAULT) { 244 sc->sc_nolow = 1; 245 strlcpy(name, "LM84", ADMTEMP_NAMELEN); 246 } else 247 strlcpy(name, "MAX1617", ADMTEMP_NAMELEN); 248 } 249 250 if (*comp == ADM1021_COMPANY_MAXIM) { 251 sc->sc_noneg = 0; 252 strlcpy(name, "MAX1617A", ADMTEMP_NAMELEN); 253 } 254 255 if (*comp == ADM1021_COMPANY_GMT) { 256 sc->sc_ext11 = 1; 257 sc->sc_therm = 1; 258 strlcpy(name, "G781", ADMTEMP_NAMELEN); 259 } 260 261 if (*comp == ADM1021_COMPANY_ADM) { 262 cmd = ADM1023_EXT_HIGH2; 263 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &data) == 0) { 264 tmp = 1 << ADM1023_EXT2_SHIFT; 265 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &tmp); 266 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, 267 &tmp) == 0 && tmp == 1 << ADM1023_EXT2_SHIFT) { 268 sc->sc_ext11 = 1; 269 strlcpy(name, "ADM1023", ADMTEMP_NAMELEN); 270 } 271 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &data); 272 } 273 cmd = ADM1032_EXT_THERM; 274 if (sc->sc_ext11 && 275 admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &data) == 0 276 && data == 0x55) { 277 sc->sc_therm = 1; 278 strlcpy(name, "ADM1032", ADMTEMP_NAMELEN); 279 } 280 if (!sc->sc_ext11 && 281 (*rev & ADM1021_REV_MASK) == ADM1021_REV_1021A) { 282 sc->sc_noneg = 0; 283 strlcpy(name, "ADM1021A", ADMTEMP_NAMELEN); 284 } else 285 strlcpy(name, "ADM1021", ADMTEMP_NAMELEN); 286 } 287 } 288 289 void 290 admtemp_attach(device_t parent, device_t self, void *aux) 291 { 292 struct admtemp_softc *sc = device_private(self); 293 struct i2c_attach_args *ia = aux; 294 uint8_t cmd, data, stat, comp, rev; 295 char name[ADMTEMP_NAMELEN]; 296 297 sc->sc_tag = ia->ia_tag; 298 sc->sc_addr = ia->ia_addr; 299 300 iic_acquire_bus(sc->sc_tag, 0); 301 cmd = ADM1021_CONFIG_READ; 302 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &data) != 0) { 303 iic_release_bus(sc->sc_tag, 0); 304 aprint_error_dev(self, "cannot get control register\n"); 305 return; 306 } 307 if (data & ADM1021_CONFIG_RUN) { 308 cmd = ADM1021_STATUS; 309 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &stat)) { 310 iic_release_bus(sc->sc_tag, 0); 311 aprint_error_dev(self, 312 "cannot read status register\n"); 313 return; 314 } 315 if ((stat & ADM1021_STATUS_INVAL) == ADM1021_STATUS_INVAL) { 316 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, 317 &stat)) { 318 iic_release_bus(sc->sc_tag, 0); 319 aprint_error_dev(self, 320 "cannot read status register\n"); 321 return; 322 } 323 } 324 325 /* means external is dead */ 326 if ((stat & ADM1021_STATUS_INVAL) != ADM1021_STATUS_INVAL && 327 (stat & ADM1021_STATUS_NOEXT)) 328 sc->sc_noexternal = 1; 329 330 data &= ~ADM1021_CONFIG_RUN; 331 cmd = ADM1021_CONFIG_WRITE; 332 if (admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &data)) { 333 iic_release_bus(sc->sc_tag, 0); 334 aprint_error_dev(self, 335 "cannot set control register\n"); 336 return; 337 } 338 } 339 340 admtemp_setflags(sc, ia, &comp, &rev, name); 341 342 iic_release_bus(sc->sc_tag, 0); 343 344 aprint_normal(": %s temperature sensor", name); 345 if (comp) 346 aprint_normal(": id. 0x%02x, rev. 0x%02x\n", comp, rev); 347 else 348 aprint_normal("\n"); 349 aprint_naive(": Temperature sensor\n"); 350 351 /* Initialize sensor data. */ 352 sc->sc_sensor[ADMTEMP_INT].state = ENVSYS_SINVALID; 353 sc->sc_sensor[ADMTEMP_INT].units = ENVSYS_STEMP; 354 sc->sc_sensor[ADMTEMP_EXT].state = ENVSYS_SINVALID; 355 sc->sc_sensor[ADMTEMP_EXT].units = ENVSYS_STEMP; 356 sc->sc_sensor[ADMTEMP_INT].flags = ENVSYS_FMONLIMITS; 357 sc->sc_sensor[ADMTEMP_EXT].flags = ENVSYS_FMONLIMITS; 358 strlcpy(sc->sc_sensor[ADMTEMP_INT].desc, "internal", 359 sizeof(sc->sc_sensor[ADMTEMP_INT].desc)); 360 strlcpy(sc->sc_sensor[ADMTEMP_EXT].desc, "external", 361 sizeof(sc->sc_sensor[ADMTEMP_EXT].desc)); 362 sc->sc_sme = sysmon_envsys_create(); 363 if (sysmon_envsys_sensor_attach( 364 sc->sc_sme, &sc->sc_sensor[ADMTEMP_INT])) { 365 sysmon_envsys_destroy(sc->sc_sme); 366 aprint_error_dev(self, 367 "unable to attach internal at sysmon\n"); 368 return; 369 } 370 if (sc->sc_noexternal == 0 && 371 sysmon_envsys_sensor_attach( 372 sc->sc_sme, &sc->sc_sensor[ADMTEMP_EXT])) { 373 sysmon_envsys_destroy(sc->sc_sme); 374 aprint_error_dev(self, 375 "unable to attach external at sysmon\n"); 376 return; 377 } 378 sc->sc_sme->sme_name = device_xname(self); 379 sc->sc_sme->sme_cookie = sc; 380 sc->sc_sme->sme_refresh = admtemp_refresh; 381 if (sc->sc_therm) { 382 sc->sc_sme->sme_get_limits = admtemp_getlim_1032; 383 sc->sc_sme->sme_set_limits = admtemp_setlim_1032; 384 } else if (sc->sc_ext11) { 385 sc->sc_sme->sme_get_limits = admtemp_getlim_1023; 386 sc->sc_sme->sme_set_limits = admtemp_setlim_1023; 387 } else { 388 sc->sc_sme->sme_get_limits = admtemp_getlim_1021; 389 sc->sc_sme->sme_set_limits = admtemp_setlim_1021; 390 } 391 if (sysmon_envsys_register(sc->sc_sme)) { 392 aprint_error_dev(self, 393 "unable to register with sysmon\n"); 394 sysmon_envsys_destroy(sc->sc_sme); 395 return; 396 } 397 } 398 399 400 void 401 admtemp_refresh(struct sysmon_envsys *sme, envsys_data_t *edata) 402 { 403 struct admtemp_softc *sc = sme->sme_cookie; 404 uint8_t cmd, xdata; 405 int8_t sdata; 406 407 iic_acquire_bus(sc->sc_tag, 0); 408 409 if (edata->sensor == ADMTEMP_INT) 410 cmd = ADM1021_INT_TEMP; 411 else 412 cmd = ADM1021_EXT_TEMP; 413 414 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &sdata) == 0) { 415 if (sdata == ADM1021_STATUS_INVAL) { 416 edata->state = ENVSYS_SINVALID; 417 } else { 418 edata->value_cur = 273150000 + 1000000 * sdata; 419 edata->state = ENVSYS_SVALID; 420 } 421 } 422 if (edata->sensor == ADMTEMP_EXT && sc->sc_ext11) { 423 cmd = ADM1023_EXT_TEMP2; 424 admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &xdata); 425 edata->value_cur += 426 (xdata >> ADM1023_EXT2_SHIFT & ADM1023_EXT2_MASK) * 125000; 427 } 428 429 iic_release_bus(sc->sc_tag, 0); 430 } 431 432 void 433 admtemp_getlim_1021(struct sysmon_envsys *sme, envsys_data_t *edata, 434 sysmon_envsys_lim_t *limits, uint32_t *props) 435 { 436 struct admtemp_softc *sc = sme->sme_cookie; 437 uint8_t cmd; 438 int8_t hdata = 0x7f, ldata = 0xc9; 439 440 *props &= ~(PROP_CRITMAX | PROP_CRITMIN); 441 442 iic_acquire_bus(sc->sc_tag, 0); 443 444 if (edata->sensor == ADMTEMP_INT) 445 cmd = ADM1021_INT_HIGH_READ; 446 else 447 cmd = ADM1021_EXT_HIGH_READ; 448 449 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &hdata) == 0 && 450 hdata != ADMTEMP_LIM_INVAL) { 451 limits->sel_critmax = 273150000 + 1000000 * hdata; 452 *props |= PROP_CRITMAX; 453 } 454 455 if (sc->sc_nolow == 1) { 456 goto release; 457 } 458 459 if (edata->sensor == ADMTEMP_INT) 460 cmd = ADM1021_INT_LOW_READ; 461 else 462 cmd = ADM1021_EXT_LOW_READ; 463 464 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &ldata) == 0 && 465 ldata != ADMTEMP_LIM_INVAL) { 466 limits->sel_critmin = 273150000 + 1000000 * ldata; 467 *props |= PROP_CRITMIN; 468 } 469 470 release: 471 iic_release_bus(sc->sc_tag, 0); 472 473 /* Save the values if this is the first time through. */ 474 if (sc->sc_setdef[edata->sensor] == 0) { 475 sc->sc_setdef[edata->sensor] = 1; 476 sc->sc_highlim[edata->sensor] = hdata; 477 sc->sc_lowlim[edata->sensor] = ldata; 478 } 479 } 480 481 void 482 admtemp_getlim_1023(struct sysmon_envsys *sme, envsys_data_t *edata, 483 sysmon_envsys_lim_t *limits, uint32_t *props) 484 { 485 struct admtemp_softc *sc = sme->sme_cookie; 486 uint8_t cmd, xhdata = 0, xldata = 0; 487 int8_t hdata = 0x7f, ldata = 0xc9; 488 489 *props &= ~(PROP_CRITMAX | PROP_CRITMIN); 490 491 iic_acquire_bus(sc->sc_tag, 0); 492 493 if (edata->sensor == ADMTEMP_INT) 494 cmd = ADM1021_INT_HIGH_READ; 495 else 496 cmd = ADM1021_EXT_HIGH_READ; 497 498 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &hdata) == 0 && 499 hdata != ADMTEMP_LIM_INVAL) { 500 limits->sel_critmax = 273150000 + 1000000 * hdata; 501 *props |= PROP_CRITMAX; 502 } 503 504 if (edata->sensor == ADMTEMP_EXT) { 505 cmd = ADM1023_EXT_HIGH2; 506 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &xhdata) == 0) 507 limits->sel_critmax += 508 (xhdata >> ADM1023_EXT2_SHIFT & ADM1023_EXT2_MASK) 509 * 125000; 510 } 511 512 if (edata->sensor == ADMTEMP_INT) 513 cmd = ADM1021_INT_LOW_READ; 514 else 515 cmd = ADM1021_EXT_LOW_READ; 516 517 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &ldata) == 0 && 518 ldata != ADMTEMP_LIM_INVAL) { 519 limits->sel_critmin = 273150000 + 1000000 * ldata; 520 *props |= PROP_CRITMIN; 521 } 522 523 if (edata->sensor == ADMTEMP_EXT) { 524 cmd = ADM1023_EXT_LOW2; 525 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &xldata) == 0) 526 limits->sel_critmin += 527 (xldata >> ADM1023_EXT2_SHIFT & ADM1023_EXT2_MASK) 528 * 125000; 529 } 530 531 iic_release_bus(sc->sc_tag, 0); 532 533 /* Save the values if this is the first time through. */ 534 if (sc->sc_setdef[edata->sensor] == 0) { 535 sc->sc_setdef[edata->sensor] = 1; 536 sc->sc_highlim[edata->sensor] = hdata; 537 sc->sc_lowlim[edata->sensor] = ldata; 538 if (edata->sensor == ADMTEMP_EXT) { 539 sc->sc_highlim2 = xhdata; 540 sc->sc_lowlim2 = xldata; 541 } 542 } 543 } 544 545 void 546 admtemp_getlim_1032(struct sysmon_envsys *sme, envsys_data_t *edata, 547 sysmon_envsys_lim_t *limits, uint32_t *props) 548 { 549 struct admtemp_softc *sc = sme->sme_cookie; 550 uint8_t cmd, xhdata = 0, xldata = 0; 551 int8_t tdata = 0x55, hdata = 0x55, ldata = 0; 552 553 *props &= ~(PROP_WARNMAX | PROP_CRITMAX | PROP_WARNMIN); 554 555 iic_acquire_bus(sc->sc_tag, 0); 556 557 if (edata->sensor == ADMTEMP_INT) 558 cmd = ADM1032_INT_THERM; 559 else 560 cmd = ADM1032_EXT_THERM; 561 562 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &tdata) == 0 && 563 tdata != ADMTEMP_LIM_INVAL) { 564 limits->sel_critmax = 273150000 + 1000000 * tdata; 565 *props |= PROP_CRITMAX; 566 } 567 568 if (edata->sensor == ADMTEMP_INT) 569 cmd = ADM1021_INT_HIGH_READ; 570 else 571 cmd = ADM1021_EXT_HIGH_READ; 572 573 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &hdata) == 0 && 574 hdata != ADMTEMP_LIM_INVAL) { 575 limits->sel_warnmax = 273150000 + 1000000 * hdata; 576 *props |= PROP_WARNMAX; 577 } 578 579 if (edata->sensor == ADMTEMP_EXT) { 580 cmd = ADM1023_EXT_HIGH2; 581 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &xhdata) == 0) 582 limits->sel_warnmax += 583 (xhdata >> ADM1023_EXT2_SHIFT & ADM1023_EXT2_MASK) 584 * 125000; 585 } 586 587 if (edata->sensor == ADMTEMP_INT) 588 cmd = ADM1021_INT_LOW_READ; 589 else 590 cmd = ADM1021_EXT_LOW_READ; 591 592 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &ldata) == 0 && 593 ldata != ADMTEMP_LIM_INVAL) { 594 limits->sel_warnmin = 273150000 + 1000000 * ldata; 595 *props |= PROP_WARNMIN; 596 } 597 598 if (edata->sensor == ADMTEMP_EXT) { 599 cmd = ADM1023_EXT_LOW2; 600 if (admtemp_exec(sc, I2C_OP_READ_WITH_STOP, &cmd, &xldata) == 0) 601 limits->sel_warnmin += 602 (xldata >> ADM1023_EXT2_SHIFT & ADM1023_EXT2_MASK) 603 * 125000; 604 } 605 606 iic_release_bus(sc->sc_tag, 0); 607 608 /* Save the values if this is the first time through. */ 609 if (sc->sc_setdef[edata->sensor] == 0) { 610 sc->sc_setdef[edata->sensor] = 1; 611 sc->sc_thermlim[edata->sensor] = tdata; 612 sc->sc_highlim[edata->sensor] = hdata; 613 sc->sc_lowlim[edata->sensor] = ldata; 614 if (edata->sensor == ADMTEMP_EXT) { 615 sc->sc_highlim2 = xhdata; 616 sc->sc_lowlim2 = xldata; 617 } 618 } 619 } 620 621 void 622 admtemp_setlim_1021(struct sysmon_envsys *sme, envsys_data_t *edata, 623 sysmon_envsys_lim_t *limits, uint32_t *props) 624 { 625 struct admtemp_softc *sc = sme->sme_cookie; 626 uint8_t cmd; 627 int tmp; 628 int8_t sdata; 629 630 iic_acquire_bus(sc->sc_tag, 0); 631 632 if (*props & PROP_CRITMAX) { 633 if (edata->sensor == ADMTEMP_INT) 634 cmd = ADM1021_INT_HIGH_WRITE; 635 else 636 cmd = ADM1021_EXT_HIGH_WRITE; 637 638 if (limits == NULL) /* Restore defaults */ 639 sdata = sc->sc_highlim[edata->sensor]; 640 else { 641 tmp = (limits->sel_critmax - 273150000) / 1000000; 642 if (tmp > ADMTEMP_MAX_POS) 643 sdata = ADMTEMP_MAX_POS; 644 else if (tmp < 0 && sc->sc_noneg) 645 sdata = 0; 646 else if (tmp < ADMTEMP_MAX_NEG) 647 sdata = ADMTEMP_MAX_NEG; 648 else 649 sdata = tmp & 0xff; 650 } 651 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &sdata); 652 } 653 654 if (*props & PROP_CRITMIN && sc->sc_nolow == 0) { 655 if (edata->sensor == ADMTEMP_INT) 656 cmd = ADM1021_INT_LOW_WRITE; 657 else 658 cmd = ADM1021_EXT_LOW_WRITE; 659 if (limits == NULL) 660 sdata = sc->sc_lowlim[edata->sensor]; 661 else { 662 tmp = (limits->sel_critmin - 273150000) / 1000000; 663 if (tmp > ADMTEMP_MAX_POS) 664 sdata = ADMTEMP_MAX_POS; 665 else if (tmp < 0 && sc->sc_noneg) 666 sdata = 0; 667 else if (tmp < ADMTEMP_MAX_NEG) 668 sdata = ADMTEMP_MAX_NEG; 669 else 670 sdata = tmp & 0xff; 671 } 672 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &sdata); 673 } 674 675 iic_release_bus(sc->sc_tag, 0); 676 } 677 678 static void 679 admtemp_encode_temp(const uint32_t val, int8_t *sdata, uint8_t *xdata, 680 const int ext11) 681 { 682 int32_t tmp; 683 684 if (ext11) { 685 /* Split temperature into high and low bytes */ 686 tmp = (val - 273150000) / 125000; 687 *xdata = (tmp & ADM1023_EXT2_MASK) << ADM1023_EXT2_SHIFT; 688 tmp -= (int32_t) (*xdata >> ADM1023_EXT2_SHIFT); 689 tmp /= 8; /* 1000000 / 125000 */ 690 } else { 691 *xdata = 0; 692 tmp = (val - 273150000) / 1000000; 693 } 694 if (tmp > ADMTEMP_MAX_POS) 695 *sdata = ADMTEMP_MAX_POS; 696 else if (tmp < 0) 697 *sdata = 0; 698 else 699 *sdata = tmp & 0xff; 700 } 701 702 void 703 admtemp_setlim_1023(struct sysmon_envsys *sme, envsys_data_t *edata, 704 sysmon_envsys_lim_t *limits, uint32_t *props) 705 { 706 struct admtemp_softc *sc = sme->sme_cookie; 707 int ext11; 708 uint8_t cmd, xdata; 709 int8_t sdata; 710 711 if (edata->sensor == ADMTEMP_INT) 712 ext11 = 0; 713 else 714 ext11 = 1; 715 716 iic_acquire_bus(sc->sc_tag, 0); 717 718 if (*props & PROP_CRITMAX) { 719 if (edata->sensor == ADMTEMP_INT) 720 cmd = ADM1021_INT_HIGH_WRITE; 721 else 722 cmd = ADM1021_EXT_HIGH_WRITE; 723 724 if (limits == NULL) { /* Restore defaults */ 725 sdata = sc->sc_highlim[edata->sensor]; 726 xdata = sc->sc_highlim2; 727 } else 728 admtemp_encode_temp(limits->sel_critmax, &sdata, 729 &xdata, ext11); 730 731 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &sdata); 732 if (ext11) { 733 cmd = ADM1023_EXT_HIGH2; 734 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &xdata); 735 } 736 } 737 738 if (*props & PROP_CRITMIN) { 739 if (edata->sensor == ADMTEMP_INT) 740 cmd = ADM1021_INT_LOW_WRITE; 741 else 742 cmd = ADM1021_EXT_LOW_WRITE; 743 if (limits == NULL) { 744 sdata = sc->sc_lowlim[edata->sensor]; 745 xdata = sc->sc_lowlim2; 746 } else 747 admtemp_encode_temp(limits->sel_critmax, &sdata, 748 &xdata, ext11); 749 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &sdata); 750 if (ext11) { 751 cmd = ADM1023_EXT_LOW2; 752 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &xdata); 753 } 754 } 755 756 iic_release_bus(sc->sc_tag, 0); 757 } 758 759 void 760 admtemp_setlim_1032(struct sysmon_envsys *sme, envsys_data_t *edata, 761 sysmon_envsys_lim_t *limits, uint32_t *props) 762 { 763 struct admtemp_softc *sc = sme->sme_cookie; 764 int ext11; 765 uint8_t cmd, xdata; 766 int8_t sdata; 767 768 if (edata->sensor == ADMTEMP_INT) 769 ext11 = 0; 770 else 771 ext11 = 1; 772 773 iic_acquire_bus(sc->sc_tag, 0); 774 775 if (*props & PROP_CRITMAX) { 776 if (edata->sensor == ADMTEMP_INT) 777 cmd = ADM1032_INT_THERM; 778 else 779 cmd = ADM1032_EXT_THERM; 780 if (limits == NULL) /* Restore default */ 781 sdata = sc->sc_thermlim[edata->sensor]; 782 else 783 admtemp_encode_temp(limits->sel_critmax, &sdata, 784 &xdata, 0); 785 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &sdata); 786 } 787 788 if (*props & PROP_WARNMAX) { 789 if (edata->sensor == ADMTEMP_INT) 790 cmd = ADM1021_INT_HIGH_WRITE; 791 else 792 cmd = ADM1021_EXT_HIGH_WRITE; 793 794 if (limits == NULL) { /* Restore defaults */ 795 sdata = sc->sc_highlim[edata->sensor]; 796 xdata = sc->sc_highlim2; 797 } else 798 admtemp_encode_temp(limits->sel_warnmax, &sdata, 799 &xdata, ext11); 800 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &sdata); 801 802 if (ext11) { 803 cmd = ADM1023_EXT_HIGH2; 804 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &xdata); 805 } 806 } 807 808 if (*props & PROP_WARNMIN) { 809 if (edata->sensor == ADMTEMP_INT) 810 cmd = ADM1021_INT_LOW_WRITE; 811 else 812 cmd = ADM1021_EXT_LOW_WRITE; 813 if (limits == NULL) { 814 sdata = sc->sc_lowlim[edata->sensor]; 815 xdata = sc->sc_lowlim2; 816 } else 817 admtemp_encode_temp(limits->sel_warnmin, &sdata, 818 &xdata, ext11); 819 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &sdata); 820 821 if (ext11) { 822 cmd = ADM1023_EXT_LOW2; 823 admtemp_exec(sc, I2C_OP_WRITE_WITH_STOP, &cmd, &xdata); 824 } 825 } 826 827 iic_release_bus(sc->sc_tag, 0); 828 } 829