1 /* $NetBSD: ofw_patch.c,v 1.19 2026/10/07 11:18:09 jdc Exp $ */ 2 3 /*- 4 * Copyright (c) 2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Julian Coleman. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: ofw_patch.c,v 1.19 2026/10/07 11:18:09 jdc Exp $"); 33 34 #include <sys/param.h> 35 36 #include <dev/i2c/i2cvar.h> 37 #include <dev/scsipi/scsipiconf.h> 38 39 #include <machine/autoconf.h> 40 #include <machine/openfirm.h> 41 #include <sparc64/sparc64/ofw_patch.h> 42 #include <sparc64/sparc64/static_edid.h> 43 44 /* 45 * GPIO pin configurations 46 * num: the bit representing the pin 47 * act: on/off are reversed 48 * def: default state for LED or ALERT (will be set or checked by the driver) 49 * to: timeout (secs) before which we need to read the state 50 */ 51 static void 52 add_gpio_pin(prop_array_t pins, const char *name, int num, int act, 53 int def, int to) 54 { 55 prop_dictionary_t pin = prop_dictionary_create(); 56 prop_dictionary_set_string(pin, "name", name); 57 prop_dictionary_set_uint32(pin, "pin", num); 58 prop_dictionary_set_bool(pin, "active_high", act); 59 if (def != -1) 60 prop_dictionary_set_int32(pin, "default_state", def); 61 if (to != -1) 62 prop_dictionary_set_int32(pin, "timeout", to); 63 prop_array_add(pins, pin); 64 prop_object_release(pin); 65 } 66 67 static prop_array_t 68 create_i2c_dict(device_t busdev) 69 { 70 prop_dictionary_t props = device_properties(busdev); 71 prop_array_t cfg = NULL; 72 73 cfg = prop_dictionary_get(props, "i2c-child-devices"); 74 if (!cfg) { 75 DPRINTF(ACDB_PROBE, ("\nCreating new i2c-child-devices\n")); 76 cfg = prop_array_create(); 77 prop_dictionary_set(props, "i2c-child-devices", cfg); 78 prop_dictionary_set_bool(props, "i2c-indirect-config", false); 79 } 80 return cfg; 81 } 82 83 static void 84 add_i2c_device(prop_array_t cfg, const char *name, const char *compat, 85 uint32_t addr, uint64_t node) 86 { 87 prop_dictionary_t dev; 88 devhandle_t child_devhandle; 89 90 DPRINTF(ACDB_PROBE, ("\nAdding i2c device: %s (%s) @ 0x%x (%lx)\n", 91 name, compat == NULL ? "NULL" : compat, addr, node & 0xffffffff)); 92 dev = prop_dictionary_create(); 93 prop_dictionary_set_string(dev, "name", name); 94 if (compat != NULL) 95 prop_dictionary_set_data(dev, "compatible", compat, 96 strlen(compat) + 1); 97 prop_dictionary_set_uint32(dev, "addr", addr); 98 if (node != 0) { 99 child_devhandle = 100 devhandle_from_of(devhandle_invalid(), node); 101 } else { 102 child_devhandle = devhandle_invalid(); 103 } 104 prop_dictionary_set_data(dev, "devhandle", 105 &child_devhandle, sizeof(child_devhandle)); 106 107 prop_array_add(cfg, dev); 108 prop_object_release(dev); 109 } 110 111 static void 112 add_gpio_props_v210(device_t dev, void *aux) 113 { 114 struct i2c_attach_args *ia = aux; 115 prop_dictionary_t dict = device_properties(dev); 116 prop_array_t pins; 117 118 switch (ia->ia_addr) { 119 case 0x38: /* front panel LEDs */ 120 pins = prop_array_create(); 121 add_gpio_pin(pins, "LED indicator", 7, 0, -1, -1); 122 add_gpio_pin(pins, "LED fault", 5, 0, 0, -1); 123 add_gpio_pin(pins, "LED power", 4, 0, 1, -1); 124 prop_dictionary_set(dict, "pins", pins); 125 prop_object_release(pins); 126 break; 127 case 0x23: /* drive bay O/1 LEDs */ 128 pins = prop_array_create(); 129 add_gpio_pin(pins, "LED bay0_fault", 10, 0, 0, -1); 130 add_gpio_pin(pins, "LED bay1_fault", 11, 0, 0, -1); 131 add_gpio_pin(pins, "LED bay0_remove", 12, 0, 0, -1); 132 add_gpio_pin(pins, "LED bay1_remove", 13, 0, 0, -1); 133 prop_dictionary_set(dict, "pins", pins); 134 prop_object_release(pins); 135 break; 136 case 0x25: /* drive bay 2/3 LEDs (v240 only)*/ 137 pins = prop_array_create(); 138 add_gpio_pin(pins, "LED bay2_fault", 10, 0, 0, -1); 139 add_gpio_pin(pins, "LED bay3_fault", 11, 0, 0, -1); 140 add_gpio_pin(pins, "LED bay2_remove", 12, 0, 0, -1); 141 add_gpio_pin(pins, "LED bay3_remove", 13, 0, 0, -1); 142 prop_dictionary_set(dict, "pins", pins); 143 prop_object_release(pins); 144 break; 145 } 146 } 147 148 static void 149 add_gpio_props_v245(device_t dev, void *aux) 150 { 151 struct i2c_attach_args *ia = aux; 152 prop_dictionary_t dict = device_properties(dev); 153 prop_array_t pins; 154 155 switch (ia->ia_addr) { 156 case 0x12: /* V215 disk status / LED's */ 157 pins = prop_array_create(); 158 add_gpio_pin(pins, "ALERT HDD 0 present", 159 6, 1, -1, -1); 160 add_gpio_pin(pins, "ALERT HDD 1 present", 161 7, 1, -1, -1); 162 add_gpio_pin(pins, "LED hdd0_fault", 0, 0, 0, -1); 163 add_gpio_pin(pins, "LED hdd0_remove", 4, 0, 0, -1); 164 add_gpio_pin(pins, "LED hdd1_fault", 1, 0, 0, -1); 165 add_gpio_pin(pins, "LED hdd1_remove", 5, 0, 0, -1); 166 prop_dictionary_set(dict, "pins", pins); 167 prop_object_release(pins); 168 break; 169 case 0x22: /* V245 disk status / LED's */ 170 pins = prop_array_create(); 171 add_gpio_pin(pins, "ALERT HDD 0 present", 172 8, 1, -1, -1); 173 add_gpio_pin(pins, "ALERT HDD 1 present", 174 9, 1, -1, -1); 175 add_gpio_pin(pins, "ALERT HDD 2 present", 176 10, 1, -1, -1); 177 add_gpio_pin(pins, "ALERT HDD 3 present", 178 11, 1, -1, -1); 179 add_gpio_pin(pins, "LED hdd0_fault", 0, 0, 0, -1); 180 add_gpio_pin(pins, "LED hdd0_remove", 4, 0, 0, -1); 181 add_gpio_pin(pins, "LED hdd1_fault", 1, 0, 0, -1); 182 add_gpio_pin(pins, "LED hdd1_remove", 5, 0, 0, -1); 183 add_gpio_pin(pins, "LED hdd2_fault", 2, 0, 0, -1); 184 add_gpio_pin(pins, "LED hdd2_remove", 6, 0, 0, -1); 185 add_gpio_pin(pins, "LED hdd3_fault", 3, 0, 0, -1); 186 add_gpio_pin(pins, "LED hdd3_remove", 7, 0, 0, -1); 187 prop_dictionary_set(dict, "pins", pins); 188 prop_object_release(pins); 189 break; 190 case 0x3e: /* PSU 0 */ 191 pins = prop_array_create(); 192 prop_dictionary_set(dict, "pins", pins); 193 add_gpio_pin(pins, "ALERT PSU 0 input power", 194 6, 0, 0, -1); 195 prop_object_release(pins); 196 break; 197 case 0x3f: /* PSU 1 */ 198 pins = prop_array_create(); 199 prop_dictionary_set(dict, "pins", pins); 200 add_gpio_pin(pins, "ALERT PSU 1 input power", 201 6, 0, 0, -1); 202 prop_object_release(pins); 203 break; 204 } 205 } 206 207 static void 208 add_gpio_props_u45(device_t dev, void *aux) 209 { 210 struct i2c_attach_args *ia = aux; 211 prop_dictionary_t dict = device_properties(dev); 212 prop_array_t pins; 213 214 switch (ia->ia_addr) { 215 case 0x18: /* front panel LEDs */ 216 pins = prop_array_create(); 217 add_gpio_pin(pins, "LED power", 0, 1, -1, -1); 218 add_gpio_pin(pins, "LED fault", 1, 0, -1, -1); 219 prop_dictionary_set(dict, "pins", pins); 220 prop_object_release(pins); 221 break; 222 } 223 } 224 225 static void 226 add_gpio_props_e250(device_t dev, void *aux) 227 { 228 struct i2c_attach_args *ia = aux; 229 prop_dictionary_t dict = device_properties(dev); 230 prop_array_t pins; 231 232 switch (ia->ia_addr) { 233 case 0x38: /* interrupt status */ 234 pins = prop_array_create(); 235 add_gpio_pin(pins, "ALERT high_temp", 1, 0, -1, 30); 236 add_gpio_pin(pins, "ALERT disk_event", 2, 0, -1, 30); 237 add_gpio_pin(pins, "ALERT fan_fail", 4, 0, -1, 30); 238 add_gpio_pin(pins, "ALERT key_event", 5, 0, -1, 30); 239 add_gpio_pin(pins, "ALERT psu_event", 6, 0, -1, 30); 240 prop_dictionary_set(dict, "pins", pins); 241 prop_object_release(pins); 242 break; 243 case 0x39: /* PSU status */ 244 pins = prop_array_create(); 245 add_gpio_pin(pins, "INDICATOR psu0_present", 246 0, 0, -1, -1); 247 add_gpio_pin(pins, "INDICATOR psu1_present", 248 1, 0, -1, -1); 249 add_gpio_pin(pins, "ALERT psu0_fault", 4, 0, 1, -1); 250 add_gpio_pin(pins, "ALERT psu1_fault", 5, 0, 1, -1); 251 prop_dictionary_set(dict, "pins", pins); 252 prop_object_release(pins); 253 break; 254 case 0x3d: /* disk status */ 255 pins = prop_array_create(); 256 add_gpio_pin(pins, "ALERT disk0_present", 257 0, 0, -1, -1); 258 add_gpio_pin(pins, "ALERT disk1_present", 259 1, 0, -1, -1); 260 add_gpio_pin(pins, "ALERT disk2_present", 261 2, 0, -1, -1); 262 add_gpio_pin(pins, "ALERT disk3_present", 263 3, 0, -1, -1); 264 add_gpio_pin(pins, "ALERT disk4_present", 265 4, 0, -1, -1); 266 add_gpio_pin(pins, "ALERT disk5_present", 267 5, 0, -1, -1); 268 prop_dictionary_set(dict, "pins", pins); 269 prop_object_release(pins); 270 break; 271 case 0x3e: /* front panel LEDs (E250/E450) */ 272 pins = prop_array_create(); 273 add_gpio_pin(pins, "LED disk_fault", 0, 0, -1, -1); 274 add_gpio_pin(pins, "LED psu_fault", 1, 0, -1, -1); 275 add_gpio_pin(pins, "LED overtemp", 2, 0, -1, -1); 276 add_gpio_pin(pins, "LED fault", 3, 0, -1, -1); 277 add_gpio_pin(pins, "LED activity", 4, 0, -1, -1); 278 /* Pin 5 is power LED, but not controllable */ 279 add_gpio_pin(pins, "INDICATOR key_normal", 6, 0, -1, -1); 280 add_gpio_pin(pins, "INDICATOR key_diag", 7, 0, -1, -1); 281 /* If not "normal" or "diag", key is "lock" */ 282 prop_dictionary_set(dict, "pins", pins); 283 prop_object_release(pins); 284 break; 285 case 0x3f: /* disk fault LEDs */ 286 pins = prop_array_create(); 287 add_gpio_pin(pins, "LED disk0_fault", 0, 0, -1, -1); 288 add_gpio_pin(pins, "LED disk1_fault", 1, 0, -1, -1); 289 add_gpio_pin(pins, "LED disk2_fault", 2, 0, -1, -1); 290 add_gpio_pin(pins, "LED disk3_fault", 3, 0, -1, -1); 291 add_gpio_pin(pins, "LED disk4_fault", 4, 0, -1, -1); 292 add_gpio_pin(pins, "LED disk5_fault", 5, 0, -1, -1); 293 prop_dictionary_set(dict, "pins", pins); 294 prop_object_release(pins); 295 break; 296 } 297 } 298 299 void 300 add_drivebay_props(device_t dev, int ofnode, void *aux) 301 { 302 struct scsipibus_attach_args *sa = aux; 303 int target = sa->sa_periph->periph_target; 304 prop_dictionary_t dict = device_properties(dev); 305 char path[256]= ""; 306 char name[16]; 307 int nbays; 308 309 if ((strcmp(machine_model, "SUNW,Sun-Fire-V210") == 0) || 310 (strcmp(machine_model, "SUNW,Sun-Fire-V240") == 0)) { 311 OF_package_to_path(ofnode, path, sizeof(path)); 312 313 /* see if we're on the onboard controller's 1st channel */ 314 if (strcmp(path, "/pci@1c,600000/scsi@2") != 0) 315 return; 316 317 /* yes, yes we are */ 318 if (strcmp(machine_model, "SUNW,Sun-Fire-V240") == 0) 319 nbays = 4; 320 else 321 nbays = 2; 322 if ( target < nbays) { 323 snprintf(name, sizeof(name), "bay%d", target); 324 prop_dictionary_set_string(dict, "location", name); 325 } 326 } 327 328 if (!strcmp(machine_model, "SUNW,Ultra-250")) { 329 OF_package_to_path(ofnode, path, sizeof(path)); 330 331 /* see if we're on the onboard controller's 1st channel */ 332 if (strcmp(path, "/pci@1f,4000/scsi@3") != 0) 333 return; 334 335 /* disk 0 is target 0 */ 336 if (!target) { 337 strncpy(name, "bay0", sizeof(name)); 338 prop_dictionary_set_string(dict, "location", name); 339 /* disks 1 - 5 are targets 8 - 12 */ 340 } else if ( target < 13) { 341 snprintf(name, sizeof(name), "bay%d", target - 7); 342 prop_dictionary_set_string(dict, "location", name); 343 } 344 } 345 } 346 347 /* 348 * Add SPARCle spdmem devices (0x50 and 0x51) that are not in the OFW tree 349 */ 350 static void 351 add_spdmem_props_sparcle(device_t busdev) 352 { 353 prop_array_t cfg; 354 int i; 355 356 DPRINTF(ACDB_PROBE, ("\nAdding spdmem for SPARCle ")); 357 358 cfg = create_i2c_dict(busdev); 359 for (i = 0x50; i <= 0x51; i++) 360 add_i2c_device(cfg, "dimm-spd", NULL, i, 0); 361 prop_object_release(cfg); 362 } 363 364 /* 365 * Add V210/V240 environmental sensors that are not in the OFW tree. 366 */ 367 static void 368 add_env_sensors_v210(device_t busdev) 369 { 370 prop_array_t cfg; 371 372 DPRINTF(ACDB_PROBE, ("\nAdding sensors for %s ", machine_model)); 373 cfg = create_i2c_dict(busdev); 374 375 /* ADM1026 at 0x2e */ 376 add_i2c_device(cfg, "hardware-monitor", "i2c-adm1026", 0x2e, 0); 377 378 /* LM75 at 0x4e */ 379 add_i2c_device(cfg, "temperature-sensor", "i2c-lm75", 0x4e, 0); 380 } 381 382 /* 383 * Add U45 environmental sensors that are not in the OFW tree. 384 */ 385 static void 386 add_env_sensors_u45(device_t busdev) 387 { 388 prop_array_t cfg; 389 390 DPRINTF(ACDB_PROBE, ("\nAdding sensors for %s ", machine_model)); 391 cfg = create_i2c_dict(busdev); 392 393 /* LM95221 at 0x2b */ 394 add_i2c_device(cfg, "temperature-sensor", "i2c-lm95221", 0x2b, 0); 395 396 /* NXP LM75A at 0x4f */ 397 add_i2c_device(cfg, "temperature-sensor", "i2c-lm75a", 0x4f, 0); 398 } 399 400 /* 401 * Add V245 environmental sensors that are not in the OFW tree. 402 */ 403 static void 404 add_env_sensors_v245(device_t busdev, int model) 405 { 406 prop_array_t cfg; 407 408 DPRINTF(ACDB_PROBE, ("\nAdding sensors for %s ", machine_model)); 409 cfg = create_i2c_dict(busdev); 410 411 /* PCA9556 at 0x12 (V215) */ 412 if (model == 215) 413 add_i2c_device(cfg, "gpio", "i2c-pca9556", 0x12, 0); 414 415 /* PCA9555 at 0x22 (V245) */ 416 if (model == 245) 417 add_i2c_device(cfg, "gpio", "i2c-pca9555", 0x22, 0); 418 419 /* LM95221 at 0x2b */ 420 add_i2c_device(cfg, "temperature-sensor", "i2c-lm95221", 0x2b, 0); 421 422 /* ADT7475 at 0x2e */ 423 add_i2c_device(cfg, "hardware-monitor", "i2c-adt7475", 0x2e, 0); 424 } 425 426 /* Sensors and GPIO's for E450 and E250 */ 427 static void 428 add_i2c_props_e450(device_t busdev, uint64_t node) 429 { 430 prop_array_t cfg; 431 432 DPRINTF(ACDB_PROBE, ("\nAdding sensors for %s ", machine_model)); 433 cfg = create_i2c_dict(busdev); 434 435 /* Power supply 1 temperature. */ 436 add_i2c_device(cfg, "PSU-1", "ecadc", 0x48, node); 437 438 /* Power supply 2 temperature. */ 439 add_i2c_device(cfg, "PSU-2", "ecadc", 0x49, node); 440 441 /* Power supply 3 temperature. */ 442 add_i2c_device(cfg, "PSU-3", "ecadc", 0x4a, node); 443 444 /* Ambient temperature. */ 445 add_i2c_device(cfg, "ambient", "i2c-lm75", 0x4d, node); 446 447 /* CPU temperatures. */ 448 add_i2c_device(cfg, "CPU", "ecadc", 0x4f, node); 449 450 prop_object_release(cfg); 451 } 452 453 static void 454 add_i2c_props_e250(device_t busdev, uint64_t node) 455 { 456 prop_array_t cfg; 457 int i; 458 459 DPRINTF(ACDB_PROBE, ("\nAdding sensors for %s ", machine_model)); 460 cfg = create_i2c_dict(busdev); 461 462 /* PSU temperature / CPU fan */ 463 add_i2c_device(cfg, "PSU", "ecadc", 0x4a, node); 464 465 /* CPU & system board temperature */ 466 add_i2c_device(cfg, "CPU", "ecadc", 0x4f, node); 467 468 /* GPIO's */ 469 for (i = 0x38; i <= 0x39; i++) 470 add_i2c_device(cfg, "gpio", "i2c-pcf8574", i, node); 471 for (i = 0x3d; i <= 0x3f; i++) 472 add_i2c_device(cfg, "gpio", "i2c-pcf8574", i, node); 473 474 /* NVRAM */ 475 add_i2c_device(cfg, "nvram", "i2c-at24c02", 0x52, node); 476 477 prop_object_release(cfg); 478 } 479 480 /* 481 * Fix-up U45 incorrect properties in the OFW tree. 482 */ 483 static void 484 fix_properties_u45(device_t busdev) 485 { 486 prop_dictionary_t props = device_properties(busdev); 487 prop_array_t cfg; 488 prop_object_t dev; 489 uint32_t addr; 490 const char *name; 491 int i, n; 492 493 cfg = prop_dictionary_get(props, "i2c-child-devices"); 494 if (!cfg) 495 return; 496 497 n = prop_array_count(cfg); 498 for (i = 0; i < n; i++) { 499 dev = prop_array_get(cfg, i); 500 if (prop_object_type(dev) == PROP_TYPE_DICTIONARY && 501 prop_dictionary_get_uint32(dev, "addr", &addr) && 502 prop_dictionary_get_string(dev, "name", &name)) { 503 /* Change psu-fru-prom to a standard eeprom */ 504 if (addr == 0x57) 505 prop_dictionary_set_data(dev, "compatible", 506 "i2c-at24c02", strlen("i2c-at24c02") + 1); 507 /* Remove fake lm76 at addresses 2b, 48 and 4f */ 508 if ((addr == 0x2b || addr == 0x48 || addr == 0x4f) && 509 !strcmp(name, "temperature")) { 510 prop_array_remove(cfg, i); 511 i -= 1; 512 n -= 1; 513 } 514 } 515 } 516 } 517 518 /* 519 * Fix-up V245 incorrect properties in the OFW tree. 520 */ 521 static void 522 fix_properties_v245(device_t busdev) 523 { 524 prop_dictionary_t props = device_properties(busdev); 525 prop_array_t cfg; 526 prop_object_t dev; 527 uint32_t addr; 528 const char *name; 529 int i, n; 530 531 cfg = prop_dictionary_get(props, "i2c-child-devices"); 532 if (!cfg) 533 return; 534 535 n = prop_array_count(cfg); 536 for (i = 0; i < n; i++) { 537 dev = prop_array_get(cfg, i); 538 if (prop_object_type(dev) == PROP_TYPE_DICTIONARY && 539 prop_dictionary_get_uint32(dev, "addr", &addr) && 540 prop_dictionary_get_string(dev, "name", &name)) { 541 /* Change psu-fru-prom's to standard eeprom's */ 542 if (addr == 0x36 || addr == 0x37) 543 prop_dictionary_set_data(dev, "compatible", 544 "i2c-at24c02", strlen("i2c-at24c02") + 1); 545 } 546 } 547 } 548 549 /* 550 * Fix-up V445 incorrect properties in the OFW tree. 551 */ 552 static void 553 fix_properties_v445(device_t busdev) 554 { 555 prop_dictionary_t props = device_properties(busdev); 556 prop_array_t cfg; 557 prop_object_t dev; 558 uint32_t addr; 559 const char *name; 560 int i, n; 561 562 cfg = prop_dictionary_get(props, "i2c-child-devices"); 563 if (!cfg) 564 return; 565 566 n = prop_array_count(cfg); 567 for (i = 0; i < n; i++) { 568 dev = prop_array_get(cfg, i); 569 if (prop_object_type(dev) == PROP_TYPE_DICTIONARY && 570 prop_dictionary_get_uint32(dev, "addr", &addr) && 571 prop_dictionary_get_string(dev, "name", &name)) { 572 /* Change power-supply-fru-prom to a standard eeprom */ 573 if (addr == 0x12 || addr == 0x19 || 574 addr == 0x29 || addr == 0x39) 575 prop_dictionary_set_data(dev, "compatible", 576 "i2c-at24c02", strlen("i2c-at24c02") + 1); 577 /* Remove "I2c-lm75" from hardware-monitor */ 578 if (addr == 0x4d) 579 // prop_dictionary_remove(dev, "compatible"); 580 prop_dictionary_set_data(dev, "compatible", 581 "i2c-unknown", strlen("i2c-unknown") + 1); 582 } 583 } 584 } 585 586 /* Hardware specific i2c bus properties */ 587 void 588 set_i2c_bus_props(device_t busdev, uint64_t busnode) 589 { 590 591 if (!strcmp(machine_model, "TAD,SPARCLE")) 592 add_spdmem_props_sparcle(busdev); 593 594 if (device_is_a(busdev, "pcfiic")) { 595 if (!strcmp(machine_model, "SUNW,Sun-Fire-V240") || 596 !strcmp(machine_model, "SUNW,Sun-Fire-V210")) 597 add_env_sensors_v210(busdev); 598 599 if (!strcmp(machine_model, "SUNW,A70") || 600 !strcmp(machine_model, "SUNW,Ultra-25")) { 601 add_env_sensors_u45(busdev); 602 fix_properties_u45(busdev); 603 } 604 605 /* E450 SUNW,envctrl */ 606 if (!strcmp(machine_model, "SUNW,Ultra-4")) 607 add_i2c_props_e450(busdev, busnode); 608 609 /* E250 SUNW,envctrltwo */ 610 if (!strcmp(machine_model, "SUNW,Ultra-250")) 611 add_i2c_props_e250(busdev, busnode); 612 } 613 614 if (device_is_a(busdev, "firei2c")) { 615 if (!strcmp(machine_model, "SUNW,Sun-Fire-V245") || 616 !strcmp(machine_model, "SUNW,Sun-Fire-V215")) { 617 add_env_sensors_v245(busdev, 618 strcmp(machine_model, "SUNW,Sun-Fire-V245") 619 ? 215 : 245); 620 fix_properties_v245(busdev); 621 } 622 623 if (!strcmp(machine_model, "SUNW,Sun-Fire-V445")) 624 fix_properties_v445(busdev); 625 } 626 } 627 628 629 /* Hardware specific i2c device properties */ 630 void 631 set_i2c_dev_props(device_t dev, device_t busdev, void *aux) 632 { 633 634 if ((!strcmp(machine_model, "SUNW,Sun-Fire-V240") || 635 !strcmp(machine_model, "SUNW,Sun-Fire-V210"))) { 636 if (device_is_a(dev, "pcagpio")) 637 add_gpio_props_v210(dev, aux); 638 639 if (device_is_a(dev, "adm1026hm")) { 640 prop_dictionary_t props = device_properties(dev); 641 prop_dictionary_set_uint8(props, "fan_div2", 0x55); 642 /* There are only 3 fans in the 1st group on V240 */ 643 if (!strcmp(machine_model, "SUNW,Sun-Fire-V240")) 644 prop_dictionary_set_uint8(props, 645 "fan_mask", 0x08); 646 } 647 } 648 649 if (!strcmp(machine_model, "SUNW,Sun-Fire-V245") || 650 !strcmp(machine_model, "SUNW,Sun-Fire-V215")) { 651 /* CPU temperatures are offset by 29C */ 652 if (device_is_a(dev, "adt7462sm")){ 653 prop_dictionary_t props = device_properties(dev); 654 prop_dictionary_set_uint32(props, 655 "temp_off", 0x001d1d00); 656 } 657 /* Disk status / LED's */ 658 if (device_is_a(dev, "pcagpio") || 659 device_is_a(dev, "pcf8574io")) 660 add_gpio_props_v245(dev, aux); 661 662 /* Tach pulse is set incorrectly */ 663 if (device_is_a(dev, "dbcool")) { 664 prop_dictionary_t props = device_properties(dev); 665 prop_dictionary_set_uint16(props, 666 "fan_div", 0x0022); 667 } 668 } 669 670 if (!strcmp(machine_model, "SUNW,Sun-Blade-2500-S") || 671 !strcmp(machine_model, "SUNW,Sun-Blade-1500-S")) { 672 /* Tach pulse is set incorrectly on both chips */ 673 if (device_is_a(dev, "dbcool")) { 674 prop_dictionary_t props = device_properties(dev); 675 prop_dictionary_set_uint16(props, 676 "fan_div", 0x0044); 677 } 678 } 679 680 /* U45 has 5 measured fans */ 681 if (!strcmp(machine_model, "SUNW,A70")) { 682 if (device_is_a(dev, "adt7462sm")){ 683 prop_dictionary_t props = device_properties(dev); 684 prop_dictionary_set_uint8(props, "fan_conf", 0x1f); 685 } 686 } 687 688 /* U45 pcagpio @ firei2c controls the front panel LED */ 689 if (!strcmp(machine_model, "SUNW,A70") || 690 !strcmp(machine_model, "SUNW,Ultra-25")) 691 if (device_is_a(dev, "pcagpio") && 692 device_is_a(busdev, "firei2c")) 693 add_gpio_props_u45(dev, aux); 694 695 /* E250 GPIO's */ 696 if (!strcmp(machine_model, "SUNW,Ultra-250")) 697 if (device_is_a(dev, "pcf8574io")) 698 add_gpio_props_e250(dev, aux); 699 700 if (!strcmp(machine_model, "SUNW,Sun-Fire-V445")) { 701 /* CPU temperatures are offset by 29C */ 702 if (device_is_a(dev, "admtemp")) { 703 prop_dictionary_t props = device_properties(dev); 704 prop_dictionary_set_uint16(props, 705 "temp_off", 0x1d00); 706 } 707 } 708 709 /* Sun use offsets from 2000 but range 1970 to 2069 */ 710 if (device_is_a(dev, "dsrtc")) { 711 prop_dictionary_t props = device_properties(dev); 712 prop_dictionary_set_uint(props, "start-year", 2000); 713 } 714 } 715 716 /* Static EDID definitions */ 717 void 718 set_static_edid(prop_dictionary_t dict) 719 { 720 if (!strcmp(machine_model, "NATE,Meso-999")) { 721 prop_data_t edid; 722 723 DPRINTF(ACDB_PROBE, ("\nAdding EDID for Meso-999 ")); 724 edid = prop_data_create_copy(edid_meso999, 725 sizeof(edid_meso999)); 726 prop_dictionary_set(dict, "EDID:1", edid); 727 prop_object_release(edid); 728 } 729 } 730