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