1*9593dc34Smglocker /* $OpenBSD: i2c_scan.c,v 1.147 2024/09/04 07:54:52 mglocker Exp $ */ 21165b4a3Sgrange 31165b4a3Sgrange /* 44de9e267Sderaadt * Copyright (c) 2005 Theo de Raadt <deraadt@openbsd.org> 51165b4a3Sgrange * 61165b4a3Sgrange * Permission to use, copy, modify, and distribute this software for any 71165b4a3Sgrange * purpose with or without fee is hereby granted, provided that the above 81165b4a3Sgrange * copyright notice and this permission notice appear in all copies. 91165b4a3Sgrange * 101165b4a3Sgrange * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 111165b4a3Sgrange * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 121165b4a3Sgrange * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 131165b4a3Sgrange * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 141165b4a3Sgrange * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 151165b4a3Sgrange * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 161165b4a3Sgrange * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 171165b4a3Sgrange */ 181165b4a3Sgrange 191165b4a3Sgrange /* 20a031840aSderaadt * I2C bus scanning. We apologize in advance for the massive overuse of 0x. 211165b4a3Sgrange */ 221165b4a3Sgrange 232349585bSderaadt #include "ipmi.h" 242349585bSderaadt 251165b4a3Sgrange #include <sys/param.h> 261165b4a3Sgrange #include <sys/systm.h> 27941c1a56Sderaadt #include <sys/device.h> 281165b4a3Sgrange 291165b4a3Sgrange #define _I2C_PRIVATE 301165b4a3Sgrange #include <dev/i2c/i2cvar.h> 311165b4a3Sgrange 32ad90345aSderaadt #undef I2C_DEBUG 33f5940ae5Sjsg #define I2C_VERBOSE 3400cbb269Sderaadt 3522ef5474Sderaadt #define MAX_IGNORE 8 3622ef5474Sderaadt u_int8_t ignore_addrs[MAX_IGNORE]; 3722ef5474Sderaadt 3822ef5474Sderaadt struct iicprobelist { 3922ef5474Sderaadt u_int8_t start, end; 4022ef5474Sderaadt }; 4147098ca3Sderaadt 42cb54b910Skettenis /* 43cb54b910Skettenis * Addresses at which to probe for sensors. Skip address 0x4f, since 44cb54b910Skettenis * probing it seems to crash at least one Sony VAIO laptop. Only a 45cb54b910Skettenis * few chips can actually sit at that address, and vendors seem to 46cb54b910Skettenis * place those at other addresses, so this isn't a big loss. 47cb54b910Skettenis */ 4822ef5474Sderaadt struct iicprobelist probe_addrs_sensor[] = { 49a7a203e0Sderaadt { 0x18, 0x1f }, 50941c1a56Sderaadt { 0x20, 0x2f }, 5122ef5474Sderaadt { 0x48, 0x4e }, 5222ef5474Sderaadt { 0, 0 } 531165b4a3Sgrange }; 541165b4a3Sgrange 5522ef5474Sderaadt /* 5622ef5474Sderaadt * Addresses at which to probe for eeprom devices. 5722ef5474Sderaadt */ 5822ef5474Sderaadt struct iicprobelist probe_addrs_eeprom[] = { 5922ef5474Sderaadt { 0x50, 0x57 }, 6022ef5474Sderaadt { 0, 0 } 6122ef5474Sderaadt }; 6222ef5474Sderaadt 631c658e45Scnst char *iic_probe_sensor(struct device *, u_int8_t); 641c658e45Scnst char *iic_probe_eeprom(struct device *, u_int8_t); 6522ef5474Sderaadt 662349585bSderaadt #define PFLAG_SENSOR 1 6722ef5474Sderaadt static struct { 6822ef5474Sderaadt struct iicprobelist *pl; 691c658e45Scnst char *(*probe)(struct device *, u_int8_t); 702349585bSderaadt int flags; 7122ef5474Sderaadt } probes[] = { 722349585bSderaadt { probe_addrs_sensor, iic_probe_sensor, PFLAG_SENSOR }, 732349585bSderaadt { probe_addrs_eeprom, iic_probe_eeprom, 0 }, 7422ef5474Sderaadt { NULL, NULL } 7522ef5474Sderaadt }; 76b8fabd7dSderaadt 77e616dcecSderaadt /* 78e616dcecSderaadt * Some Maxim 1617 clones MAY NOT even read cmd 0xfc! When it is 79e616dcecSderaadt * read, they will power-on-reset. Their default condition 80e616dcecSderaadt * (control register bit 0x80) therefore will be that they assert 81e616dcecSderaadt * /ALERT for the 5 potential errors that may occur. One of those 82e616dcecSderaadt * errors is that the external temperature diode is missing. This 83e616dcecSderaadt * is unfortunately a common choice of system designers, except 84e616dcecSderaadt * suddenly now we get a /ALERT, which may on some chipsets cause 85e616dcecSderaadt * us to receive an entirely unexpected SMI .. and then an NMI. 86e616dcecSderaadt * 87e616dcecSderaadt * As we probe each device, if we hit something which looks suspiciously 88e616dcecSderaadt * like it may potentially be a 1617 or clone, we immediately set this 89e616dcecSderaadt * variable to avoid reading that register offset. 90e616dcecSderaadt */ 91e616dcecSderaadt int skip_fc; 92e616dcecSderaadt 933a561bd4Sderaadt static i2c_tag_t probe_ic; 943a561bd4Sderaadt static u_int8_t probe_addr; 953a561bd4Sderaadt static u_int8_t probe_val[256]; 963a561bd4Sderaadt 9724b22cd5Sderaadt void iicprobeinit(struct i2cbus_attach_args *, u_int8_t); 9824b22cd5Sderaadt u_int8_t iicprobenc(u_int8_t); 9924b22cd5Sderaadt u_int8_t iicprobe(u_int8_t); 10024b22cd5Sderaadt u_int16_t iicprobew(u_int8_t); 101010c3e6aSderaadt char *lm75probe(void); 1025f31ae5bSkettenis char *adm1032cloneprobe(u_int8_t); 103ad90345aSderaadt void iic_dump(struct device *, u_int8_t, char *); 1043a561bd4Sderaadt 10524b22cd5Sderaadt void 10624b22cd5Sderaadt iicprobeinit(struct i2cbus_attach_args *iba, u_int8_t addr) 1073a561bd4Sderaadt { 1083a561bd4Sderaadt probe_ic = iba->iba_tag; 1093a561bd4Sderaadt probe_addr = addr; 1103a561bd4Sderaadt memset(probe_val, 0xff, sizeof probe_val); 1113a561bd4Sderaadt } 1123a561bd4Sderaadt 11324b22cd5Sderaadt u_int8_t 11424b22cd5Sderaadt iicprobenc(u_int8_t cmd) 1153a561bd4Sderaadt { 1163a561bd4Sderaadt u_int8_t data; 1173a561bd4Sderaadt 118e616dcecSderaadt /* 119e616dcecSderaadt * If we think we are talking to an evil Maxim 1617 or clone, 120e616dcecSderaadt * avoid accessing this register because it is death. 121e616dcecSderaadt */ 122e616dcecSderaadt if (skip_fc && cmd == 0xfc) 123e616dcecSderaadt return (0xff); 124a5d919cdSgrange iic_acquire_bus(probe_ic, 0); 125643d52faSgrange if (iic_exec(probe_ic, I2C_OP_READ_WITH_STOP, 12691eacc75Sderaadt probe_addr, &cmd, sizeof cmd, &data, sizeof data, 0) != 0) 1273a561bd4Sderaadt data = 0xff; 128a5d919cdSgrange iic_release_bus(probe_ic, 0); 1293a561bd4Sderaadt return (data); 1303a561bd4Sderaadt } 1313a561bd4Sderaadt 13224b22cd5Sderaadt u_int16_t 13324b22cd5Sderaadt iicprobew(u_int8_t cmd) 134fe4ffc8aSderaadt { 13591eacc75Sderaadt u_int16_t data; 136fe4ffc8aSderaadt 137e616dcecSderaadt /* 138e616dcecSderaadt * If we think we are talking to an evil Maxim 1617 or clone, 139e616dcecSderaadt * avoid accessing this register because it is death. 140e616dcecSderaadt */ 141e616dcecSderaadt if (skip_fc && cmd == 0xfc) 142e616dcecSderaadt return (0xffff); 143a5d919cdSgrange iic_acquire_bus(probe_ic, 0); 144643d52faSgrange if (iic_exec(probe_ic, I2C_OP_READ_WITH_STOP, 14591eacc75Sderaadt probe_addr, &cmd, sizeof cmd, &data, sizeof data, 0) != 0) 14691eacc75Sderaadt data = 0xffff; 147a5d919cdSgrange iic_release_bus(probe_ic, 0); 14891eacc75Sderaadt return betoh16(data); 149fe4ffc8aSderaadt } 150fe4ffc8aSderaadt 15124b22cd5Sderaadt u_int8_t 15224b22cd5Sderaadt iicprobe(u_int8_t cmd) 1533a561bd4Sderaadt { 1543a561bd4Sderaadt if (probe_val[cmd] != 0xff) 1553a561bd4Sderaadt return probe_val[cmd]; 15624b22cd5Sderaadt probe_val[cmd] = iicprobenc(cmd); 1573a561bd4Sderaadt return (probe_val[cmd]); 1583a561bd4Sderaadt } 1594e1e7e6eSderaadt 160010c3e6aSderaadt #define LM75TEMP 0x00 161010c3e6aSderaadt #define LM75CONF 0x01 162010c3e6aSderaadt #define LM75Thyst 0x02 163010c3e6aSderaadt #define LM75Tos 0x03 164010c3e6aSderaadt #define LM77Tlow 0x04 165010c3e6aSderaadt #define LM77Thigh 0x05 166010c3e6aSderaadt #define LM75TMASK 0xff80 /* 9 bits in temperature registers */ 167010c3e6aSderaadt #define LM77TMASK 0xfff8 /* 13 bits in temperature registers */ 168010c3e6aSderaadt 169fe4ffc8aSderaadt /* 1709ef2fefcSderaadt * The LM75/LM75A/LM77 family are very hard to detect. Thus, we check 1719ef2fefcSderaadt * for all other possible chips first. These chips do not have an 1729ef2fefcSderaadt * ID register. They do have a few quirks though: 1739ef2fefcSderaadt * - on the LM75 and LM77, registers 0x06 and 0x07 return whatever 1749ef2fefcSderaadt * value was read before 1759ef2fefcSderaadt * - the LM75 lacks registers 0x04 and 0x05, so those act as above 1769ef2fefcSderaadt * - the LM75A returns 0xffff for registers 0x04, 0x05, 0x06 and 0x07 1779ef2fefcSderaadt * - the chip registers loop every 8 registers 178010c3e6aSderaadt * The downside is that we must read almost every register to guess 1799ef2fefcSderaadt * if this is an LM75, LM75A or LM77. 180fe4ffc8aSderaadt */ 181010c3e6aSderaadt char * 182fe4ffc8aSderaadt lm75probe(void) 183fe4ffc8aSderaadt { 184010c3e6aSderaadt u_int16_t temp, thyst, tos, tlow, thigh, mask = LM75TMASK; 185010c3e6aSderaadt u_int8_t conf; 1869ef2fefcSderaadt int i, echocount, ffffcount, score; 1879ef2fefcSderaadt int echoreg67, echoreg45, ffffreg67, ffffreg45; 188fe4ffc8aSderaadt 18982814087Skettenis temp = iicprobew(LM75TEMP); 1909ef2fefcSderaadt 1919ef2fefcSderaadt /* 1929ef2fefcSderaadt * Sometimes the other probes can upset the chip, if we get 0xffff 1939ef2fefcSderaadt * the first time, try it once more. 1949ef2fefcSderaadt */ 1959ef2fefcSderaadt if (temp == 0xffff) 1969ef2fefcSderaadt temp = iicprobew(LM75TEMP); 1979ef2fefcSderaadt 198010c3e6aSderaadt conf = iicprobenc(LM75CONF); 19982814087Skettenis thyst = iicprobew(LM75Thyst); 20082814087Skettenis tos = iicprobew(LM75Tos); 201fe4ffc8aSderaadt 202010c3e6aSderaadt /* totally bogus data */ 203010c3e6aSderaadt if (conf == 0xff && temp == 0xffff && thyst == 0xffff) 204010c3e6aSderaadt return (NULL); 205fe4ffc8aSderaadt 20682814087Skettenis temp &= mask; 20782814087Skettenis thyst &= mask; 20882814087Skettenis tos &= mask; 20982814087Skettenis 210010c3e6aSderaadt /* All values the same? Very unlikely */ 211010c3e6aSderaadt if (temp == thyst && thyst == tos) 212010c3e6aSderaadt return (NULL); 213fe4ffc8aSderaadt 214010c3e6aSderaadt #if notsure 215010c3e6aSderaadt /* more register aliasing effects that indicate not a lm75 */ 216010c3e6aSderaadt if ((temp >> 8) == conf) 217010c3e6aSderaadt return (NULL); 218a859ac9bSderaadt #endif 219fe4ffc8aSderaadt 220010c3e6aSderaadt /* 221010c3e6aSderaadt * LM77/LM75 registers 6, 7 222010c3e6aSderaadt * echo whatever was read just before them from reg 0, 1, or 2 2239ef2fefcSderaadt * 2249ef2fefcSderaadt * LM75A doesn't appear to do this, but does appear to reliably 2259ef2fefcSderaadt * return 0xffff 226010c3e6aSderaadt */ 2279ef2fefcSderaadt for (i = 6, echocount = 2, ffffcount = 0; i <= 7; i++) { 228010c3e6aSderaadt if ((iicprobew(LM75TEMP) & mask) != (iicprobew(i) & mask) || 229010c3e6aSderaadt (iicprobew(LM75Thyst) & mask) != (iicprobew(i) & mask) || 230010c3e6aSderaadt (iicprobew(LM75Tos) & mask) != (iicprobew(i) & mask)) 2319ef2fefcSderaadt echocount--; 2329ef2fefcSderaadt if (iicprobew(i) == 0xffff) 2339ef2fefcSderaadt ffffcount++; 234010c3e6aSderaadt } 235010c3e6aSderaadt 2369ef2fefcSderaadt /* Make sure either both registers echo, or neither does */ 2379ef2fefcSderaadt if (echocount == 1 || ffffcount == 1) 2389ef2fefcSderaadt return (NULL); 2399ef2fefcSderaadt 2409ef2fefcSderaadt echoreg67 = (echocount == 0) ? 0 : 1; 2419ef2fefcSderaadt ffffreg67 = (ffffcount == 0) ? 0 : 1; 2429ef2fefcSderaadt 243010c3e6aSderaadt /* 244010c3e6aSderaadt * LM75 has no registers 4 or 5, and they will act as echos too 2459ef2fefcSderaadt * 2469ef2fefcSderaadt * LM75A doesn't appear to do this either, but does appear to 2479ef2fefcSderaadt * reliably return 0xffff 248010c3e6aSderaadt */ 2499ef2fefcSderaadt for (i = 4, echocount = 2, ffffcount = 0; i <= 5; i++) { 2509ef2fefcSderaadt if ((iicprobew(LM75TEMP) & mask) != (iicprobew(i) & mask) || 2519ef2fefcSderaadt (iicprobew(LM75Thyst) & mask) != (iicprobew(i) & mask) || 2529ef2fefcSderaadt (iicprobew(LM75Tos) & mask) != (iicprobew(i) & mask)) 2539ef2fefcSderaadt echocount--; 2549ef2fefcSderaadt if (iicprobew(i) == 0xffff) 2559ef2fefcSderaadt ffffcount++; 2569ef2fefcSderaadt } 2579ef2fefcSderaadt 2589ef2fefcSderaadt /* Make sure either both registers echo, or neither does */ 2599ef2fefcSderaadt if (echocount == 1 || ffffcount == 1) 2609ef2fefcSderaadt return (NULL); 2619ef2fefcSderaadt 2629ef2fefcSderaadt echoreg45 = (echocount == 0) ? 0 : 1; 2639ef2fefcSderaadt ffffreg45 = (ffffcount == 0) ? 0 : 1; 2649ef2fefcSderaadt 2659ef2fefcSderaadt /* 2669ef2fefcSderaadt * If we find that 4 and 5 are not echos, and don't return 0xffff 2679ef2fefcSderaadt * then based on whether the echo test of registers 6 and 7 2689ef2fefcSderaadt * succeeded or not, we may have an LM77 2699ef2fefcSderaadt */ 2709ef2fefcSderaadt if (echoreg45 == 0 && ffffreg45 == 0 && echoreg67 == 1) { 271010c3e6aSderaadt mask = LM77TMASK; 272010c3e6aSderaadt 273010c3e6aSderaadt /* mask size changed, must re-read for the next checks */ 274010c3e6aSderaadt thyst = iicprobew(LM75Thyst) & mask; 275010c3e6aSderaadt tos = iicprobew(LM75Tos) & mask; 276010c3e6aSderaadt tlow = iicprobew(LM77Tlow) & mask; 277010c3e6aSderaadt thigh = iicprobew(LM77Thigh) & mask; 278010c3e6aSderaadt } 279010c3e6aSderaadt 2800f1683a6Smiod /* a real LM75/LM75A/LM77 repeats its registers.... */ 281ecefcc24Smiod for (i = 0x08; i <= 0xf8; i += 8) { 282010c3e6aSderaadt if (conf != iicprobenc(LM75CONF + i) || 283010c3e6aSderaadt thyst != (iicprobew(LM75Thyst + i) & mask) || 284010c3e6aSderaadt tos != (iicprobew(LM75Tos + i) & mask)) 285010c3e6aSderaadt return (NULL); 2869ef2fefcSderaadt 2879ef2fefcSderaadt /* 2889ef2fefcSderaadt * Check that the repeated registers 0x06 and 0x07 still 2899ef2fefcSderaadt * either echo or return 0xffff 2909ef2fefcSderaadt */ 2919ef2fefcSderaadt if (echoreg67 == 1) { 292010c3e6aSderaadt tos = iicprobew(LM75Tos) & mask; 293010c3e6aSderaadt if (tos != (iicprobew(0x06 + i) & mask) || 294010c3e6aSderaadt tos != (iicprobew(0x07 + i) & mask)) 295010c3e6aSderaadt return (NULL); 2969ef2fefcSderaadt } else if (ffffreg67 == 1) 2979ef2fefcSderaadt if (iicprobew(0x06 + i) != 0xffff || 2989ef2fefcSderaadt iicprobew(0x07 + i) != 0xffff) 2999ef2fefcSderaadt return (NULL); 3009ef2fefcSderaadt 3019ef2fefcSderaadt /* 3029ef2fefcSderaadt * Check that the repeated registers 0x04 and 0x05 still 3039ef2fefcSderaadt * either echo or return 0xffff. If they do neither, and 3049ef2fefcSderaadt * registers 0x06 and 0x07 echo, then we will be probing 3059ef2fefcSderaadt * for an LM77, so make sure those still repeat 3069ef2fefcSderaadt */ 3079ef2fefcSderaadt if (echoreg45 == 1) { 308010c3e6aSderaadt tos = iicprobew(LM75Tos) & mask; 309010c3e6aSderaadt if (tos != (iicprobew(LM77Tlow + i) & mask) || 310010c3e6aSderaadt tos != (iicprobew(LM77Thigh + i) & mask)) 311010c3e6aSderaadt return (NULL); 3129ef2fefcSderaadt } else if (ffffreg45 == 1) { 3139ef2fefcSderaadt if (iicprobew(LM77Tlow + i) != 0xffff || 3149ef2fefcSderaadt iicprobew(LM77Thigh + i) != 0xffff) 3159ef2fefcSderaadt return (NULL); 3169ef2fefcSderaadt } else if (echoreg67 == 1) 317010c3e6aSderaadt if (tlow != (iicprobew(LM77Tlow + i) & mask) || 318010c3e6aSderaadt thigh != (iicprobew(LM77Thigh + i) & mask)) 319010c3e6aSderaadt return (NULL); 320010c3e6aSderaadt } 321fe4ffc8aSderaadt 3229ef2fefcSderaadt /* 3239ef2fefcSderaadt * Given that we now know how the first eight registers behave and 3249ef2fefcSderaadt * that this behaviour is consistently repeated, we can now use 3259ef2fefcSderaadt * the following table: 3269ef2fefcSderaadt * 3279ef2fefcSderaadt * echoreg67 | echoreg45 | ffffreg67 | ffffreg45 | chip 3289ef2fefcSderaadt * ----------+-----------+-----------+-----------+------ 3299ef2fefcSderaadt * 1 | 1 | 0 | 0 | LM75 3309ef2fefcSderaadt * 1 | 0 | 0 | 0 | LM77 3319ef2fefcSderaadt * 0 | 0 | 1 | 1 | LM75A 3329ef2fefcSderaadt */ 3339ef2fefcSderaadt 3349ef2fefcSderaadt /* Convert the various flags into a single score */ 3359ef2fefcSderaadt score = (echoreg67 << 3) + (echoreg45 << 2) + (ffffreg67 << 1) + 3369ef2fefcSderaadt ffffreg45; 3379ef2fefcSderaadt 3389ef2fefcSderaadt switch (score) { 3399ef2fefcSderaadt case 12: 340010c3e6aSderaadt return ("lm75"); 3419ef2fefcSderaadt case 8: 342010c3e6aSderaadt return ("lm77"); 3439ef2fefcSderaadt case 3: 3449ef2fefcSderaadt return ("lm75a"); 3459ef2fefcSderaadt default: 3463fe49b44Sderaadt #if defined(I2C_DEBUG) 3479ef2fefcSderaadt printf("lm75probe: unknown chip, scored %d\n", score); 3483fe49b44Sderaadt #endif /* defined(I2C_DEBUG) */ 3499ef2fefcSderaadt return (NULL); 3509ef2fefcSderaadt } 351fe4ffc8aSderaadt } 352fe4ffc8aSderaadt 35324b22cd5Sderaadt char * 3545f31ae5bSkettenis adm1032cloneprobe(u_int8_t addr) 355e109779fSderaadt { 356e109779fSderaadt if (addr == 0x18 || addr == 0x1a || addr == 0x29 || 357e109779fSderaadt addr == 0x2b || addr == 0x4c || addr == 0x4e) { 3589cc05711Sderaadt u_int8_t reg, val; 3590c1eb8deSderaadt int zero = 0, copy = 0; 360e109779fSderaadt 36124b22cd5Sderaadt val = iicprobe(0x00); 3627af89a61Sderaadt for (reg = 0x00; reg < 0x09; reg++) { 36324b22cd5Sderaadt if (iicprobe(reg) == 0xff) 3649cc05711Sderaadt return (NULL); 36524b22cd5Sderaadt if (iicprobe(reg) == 0x00) 3667af89a61Sderaadt zero++; 36724b22cd5Sderaadt if (val == iicprobe(reg)) 3680c1eb8deSderaadt copy++; 3697af89a61Sderaadt } 3700c1eb8deSderaadt if (zero > 6 || copy > 6) 3717af89a61Sderaadt return (NULL); 37224b22cd5Sderaadt val = iicprobe(0x09); 373e616dcecSderaadt for (reg = 0x0a; reg < 0xfc; reg++) { 37424b22cd5Sderaadt if (iicprobe(reg) != val) 3759cc05711Sderaadt return (NULL); 3767af89a61Sderaadt } 377c7afa571Skettenis /* 0xfe may be Maxim, or some other vendor */ 37824b22cd5Sderaadt if (iicprobe(0xfe) == 0x4d) 379c7afa571Skettenis return ("max1617"); 380a1f396d4Sderaadt /* 381a1f396d4Sderaadt * "xeontemp" is the name we choose for clone chips 382a1f396d4Sderaadt * which have all sorts of buggy bus interactions, such 383a1f396d4Sderaadt * as those we just probed. Why? 384a1f396d4Sderaadt * Intel is partly to blame for this situation. 385a1f396d4Sderaadt */ 3869cc05711Sderaadt return ("xeontemp"); 387e109779fSderaadt } 3889cc05711Sderaadt return (NULL); 389e109779fSderaadt } 390e109779fSderaadt 391b8fabd7dSderaadt void 392b8fabd7dSderaadt iic_ignore_addr(u_int8_t addr) 393b8fabd7dSderaadt { 394b8fabd7dSderaadt int i; 395e109779fSderaadt 396b8fabd7dSderaadt for (i = 0; i < sizeof(ignore_addrs); i++) 397b8fabd7dSderaadt if (ignore_addrs[i] == 0) { 398b8fabd7dSderaadt ignore_addrs[i] = addr; 399b8fabd7dSderaadt return; 400b8fabd7dSderaadt } 401b8fabd7dSderaadt } 402e109779fSderaadt 403d70d6113Scnst #ifdef I2C_VERBOSE 404ad90345aSderaadt void 405ad90345aSderaadt iic_dump(struct device *dv, u_int8_t addr, char *name) 406ad90345aSderaadt { 407481fe91dSderaadt static u_int8_t iicvalcnt[256]; 408481fe91dSderaadt u_int8_t val, val2, max; 409ad90345aSderaadt int i, cnt = 0; 410ad90345aSderaadt 411481fe91dSderaadt /* 412481fe91dSderaadt * Don't bother printing the most often repeated register 413481fe91dSderaadt * value, since it is often weird devices that respond 414481fe91dSderaadt * incorrectly, busted controller driver, or in the worst 415481fe91dSderaadt * case, it in mosts cases, the value 0xff. 416481fe91dSderaadt */ 417481fe91dSderaadt bzero(iicvalcnt, sizeof iicvalcnt); 418481fe91dSderaadt val = iicprobe(0); 419481fe91dSderaadt iicvalcnt[val]++; 420ad90345aSderaadt for (i = 1; i <= 0xff; i++) { 421481fe91dSderaadt val2 = iicprobe(i); 422481fe91dSderaadt iicvalcnt[val2]++; 423481fe91dSderaadt if (val == val2) 424ad90345aSderaadt cnt++; 425ad90345aSderaadt } 426481fe91dSderaadt 427481fe91dSderaadt for (val = max = i = 0; i <= 0xff; i++) 428481fe91dSderaadt if (max < iicvalcnt[i]) { 429481fe91dSderaadt max = iicvalcnt[i]; 430481fe91dSderaadt val = i; 431481fe91dSderaadt } 432481fe91dSderaadt 433447d4274Sderaadt if (cnt == 255) 434447d4274Sderaadt return; 435447d4274Sderaadt 436ad90345aSderaadt printf("%s: addr 0x%x", dv->dv_xname, addr); 437ad90345aSderaadt for (i = 0; i <= 0xff; i++) { 438481fe91dSderaadt if (iicprobe(i) != val) 439ad90345aSderaadt printf(" %02x=%02x", i, iicprobe(i)); 440ad90345aSderaadt } 44152d7500cScnst printf(" words"); 442b86f8d57Sderaadt for (i = 0; i < 8; i++) 443447d4274Sderaadt printf(" %02x=%04x", i, iicprobew(i)); 444ad90345aSderaadt if (name) 445ad90345aSderaadt printf(": %s", name); 446ad90345aSderaadt printf("\n"); 447ad90345aSderaadt } 448d70d6113Scnst #endif /* I2C_VERBOSE */ 449ad90345aSderaadt 45022ef5474Sderaadt char * 4511c658e45Scnst iic_probe_sensor(struct device *self, u_int8_t addr) 45247098ca3Sderaadt { 45347098ca3Sderaadt char *name = NULL; 45447098ca3Sderaadt 455e616dcecSderaadt skip_fc = 0; 45648a89adfSderaadt 45747098ca3Sderaadt /* 458b3667398Skettenis * Many I2C/SMBus devices use register 0x3e as a vendor ID 459b3667398Skettenis * register. 460b3667398Skettenis */ 461b3667398Skettenis switch (iicprobe(0x3e)) { 462a15c982aSkettenis case 0x01: /* National Semiconductor */ 463a15c982aSkettenis /* 464a15c982aSkettenis * Some newer National products use a vendor code at 465a15c982aSkettenis * 0x3e of 0x01, and then 0x3f contains a product code 466a15c982aSkettenis * But some older products are missing a product code, 467a15c982aSkettenis * and contain who knows what in that register. We assume 468a15c982aSkettenis * that some employee was smart enough to keep the numbers 469a15c982aSkettenis * unique. 470a15c982aSkettenis */ 471a15c982aSkettenis if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 472969e6ec1Sderaadt (iicprobe(0x3f) == 0x73 || iicprobe(0x3f) == 0x72) && 473969e6ec1Sderaadt iicprobe(0x00) == 0x00) 474969e6ec1Sderaadt name = "lm93"; /* product 0x72 is the prototype */ 475a15c982aSkettenis else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 476a15c982aSkettenis iicprobe(0x3f) == 0x68) 477a15c982aSkettenis name = "lm96000"; /* adt7460 compat? */ 478a15c982aSkettenis else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 479a15c982aSkettenis (iicprobe(0x3f) == 0x60 || iicprobe(0x3f) == 0x62)) 480a15c982aSkettenis name = "lm85"; /* lm85C/B == adt7460 compat */ 481a15c982aSkettenis else if ((addr & 0x7c) == 0x2c && /* addr 0b01011xx */ 482a15c982aSkettenis iicprobe(0x48) == addr && 483a15c982aSkettenis (iicprobe(0x3f) == 0x03 || iicprobe(0x3f) == 0x04) && 484a15c982aSkettenis (iicprobe(0x40) & 0x80) == 0x00) 485a15c982aSkettenis name = "lm81"; 486a15c982aSkettenis break; 487a15c982aSkettenis case 0x02: /* National Semiconductor? */ 488a15c982aSkettenis if ((iicprobe(0x3f) & 0xfc) == 0x04) 489a15c982aSkettenis name = "lm87"; /* complete check */ 490a15c982aSkettenis break; 491a15c982aSkettenis case 0x23: /* Analog Devices? */ 492a15c982aSkettenis if (iicprobe(0x48) == addr && 493a15c982aSkettenis (iicprobe(0x40) & 0x80) == 0x00 && 494a15c982aSkettenis (addr & 0x7c) == 0x2c) 495a15c982aSkettenis name = "adm9240"; /* lm87 clone */ 496a15c982aSkettenis break; 497b3667398Skettenis case 0x41: /* Analog Devices */ 498b3667398Skettenis /* 499e6bfbe09Sderaadt * Newer chips have a valid 0x3d product number, while 500e6bfbe09Sderaadt * older ones sometimes encoded the product into the 501b3667398Skettenis * upper half of the "step register" at 0x3f. 50247098ca3Sderaadt */ 503b3667398Skettenis if ((addr == 0x2c || addr == 0x2e || addr == 0x2f) && 50424b22cd5Sderaadt iicprobe(0x3d) == 0x70) 50547098ca3Sderaadt name = "adt7470"; 506b3667398Skettenis else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 507b3667398Skettenis iicprobe(0x3d) == 0x76) 50834110729Sderaadt name = "adt7476"; /* or adt7476a */ 509e2beff3dSkettenis else if (addr == 0x2e && iicprobe(0x3d) == 0x75) 510d57c2af9Sderaadt name = "adt7475"; 51124b22cd5Sderaadt else if (iicprobe(0x3d) == 0x27 && 51224b22cd5Sderaadt (iicprobe(0x3f) == 0x60 || iicprobe(0x3f) == 0x6a)) 513680deb82Sderaadt name = "adm1027"; /* or adt7463 */ 51424b22cd5Sderaadt else if (iicprobe(0x3d) == 0x27 && 51524b22cd5Sderaadt (iicprobe(0x3f) == 0x62 || iicprobe(0x3f) == 0x6a)) 5161719fadaSderaadt name = "adt7460"; /* complete check */ 51734110729Sderaadt else if ((addr == 0x2c || addr == 0x2e) && 51834110729Sderaadt iicprobe(0x3d) == 0x62 && iicprobe(0x3f) == 0x04) 51934110729Sderaadt name = "adt7462"; 520680deb82Sderaadt else if (addr == 0x4c && 521680deb82Sderaadt iicprobe(0x3d) == 0x66 && iicprobe(0x3f) == 0x02) 522680deb82Sderaadt name = "adt7466"; 523b3667398Skettenis else if (addr == 0x2e && 524b3667398Skettenis iicprobe(0x3d) == 0x68 && (iicprobe(0x3f) & 0xf0) == 0x70) 52534110729Sderaadt name = "adt7467"; /* or adt7468 */ 526a3ed46d5Sderaadt else if (iicprobe(0x3d) == 0x33 && iicprobe(0x3f) == 0x02) 52747098ca3Sderaadt name = "adm1033"; 528d46ba363Sderaadt else if (iicprobe(0x3d) == 0x34 && iicprobe(0x3f) == 0x02) 529d46ba363Sderaadt name = "adm1034"; 5304ecc4011Skettenis else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 53124b22cd5Sderaadt iicprobe(0x3d) == 0x30 && 5324ecc4011Skettenis (iicprobe(0x01) & 0x80) == 0x00 && 53324b22cd5Sderaadt (iicprobe(0x0d) & 0x70) == 0x00 && 53424b22cd5Sderaadt (iicprobe(0x0e) & 0x70) == 0x00) 5354ecc4011Skettenis /* 5364ecc4011Skettenis * Revision 3 seems to be an adm1031 with 5374ecc4011Skettenis * remote diode 2 shorted. Therefore we 5384ecc4011Skettenis * cannot assume the reserved/unused bits of 5394ecc4011Skettenis * register 0x03 and 0x06 are set to zero. 5404ecc4011Skettenis */ 5411719fadaSderaadt name = "adm1030"; /* complete check */ 5424ecc4011Skettenis else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 54324b22cd5Sderaadt iicprobe(0x3d) == 0x31 && 5444ecc4011Skettenis (iicprobe(0x01) & 0x80) == 0x00 && 54524b22cd5Sderaadt (iicprobe(0x0d) & 0x70) == 0x00 && 54624b22cd5Sderaadt (iicprobe(0x0e) & 0x70) == 0x00 && 54724b22cd5Sderaadt (iicprobe(0x0f) & 0x70) == 0x00) 5481719fadaSderaadt name = "adm1031"; /* complete check */ 5499cc05711Sderaadt else if ((addr & 0x7c) == 0x2c && /* addr 0b01011xx */ 55024b22cd5Sderaadt (iicprobe(0x3f) & 0xf0) == 0x20 && 55124b22cd5Sderaadt (iicprobe(0x40) & 0x80) == 0x00 && 55224b22cd5Sderaadt (iicprobe(0x41) & 0xc0) == 0x00 && 55324b22cd5Sderaadt (iicprobe(0x42) & 0xbc) == 0x00) 5541719fadaSderaadt name = "adm1025"; /* complete check */ 5559cc05711Sderaadt else if ((addr & 0x7c) == 0x2c && /* addr 0b01011xx */ 55624b22cd5Sderaadt (iicprobe(0x3f) & 0xf0) == 0x10 && 55724b22cd5Sderaadt (iicprobe(0x40) & 0x80) == 0x00) 5581719fadaSderaadt name = "adm1024"; /* complete check */ 55924b22cd5Sderaadt else if ((iicprobe(0xff) & 0xf0) == 0x30) 56047098ca3Sderaadt name = "adm1023"; 561b3667398Skettenis else if (addr == 0x2e && 562b3667398Skettenis (iicprobe(0x3f) & 0xf0) == 0xd0 && 56324b22cd5Sderaadt (iicprobe(0x40) & 0x80) == 0x00) 56480c89fdcSderaadt name = "adm1028"; /* adm1022 clone? */ 565b3667398Skettenis else if ((addr == 0x2c || addr == 0x2e || addr == 0x2f) && 566b3667398Skettenis (iicprobe(0x3f) & 0xf0) == 0xc0 && 56724b22cd5Sderaadt (iicprobe(0x40) & 0x80) == 0x00) 56847098ca3Sderaadt name = "adm1022"; 5691719fadaSderaadt break; 570a15c982aSkettenis case 0x49: /* Texas Instruments */ 571a15c982aSkettenis if ((addr == 0x2c || addr == 0x2e || addr == 0x2f) && 572a15c982aSkettenis (iicprobe(0x3f) & 0xf0) == 0xc0 && 573a15c982aSkettenis (iicprobe(0x40) & 0x80) == 0x00) 574a15c982aSkettenis name = "thmc50"; /* adm1022 clone */ 575c3d2b8f7Sderaadt break; 576b3667398Skettenis case 0x55: /* SMSC */ 577b3667398Skettenis if ((addr & 0x7c) == 0x2c && /* addr 0b01011xx */ 578b3667398Skettenis iicprobe(0x3f) == 0x20 && 579b3667398Skettenis (iicprobe(0x47) & 0x70) == 0x00 && 580b3667398Skettenis (iicprobe(0x49) & 0xfe) == 0x80) 58148a89adfSderaadt name = "47m192"; /* adm1025 compat */ 5821719fadaSderaadt break; 58380c89fdcSderaadt case 0x5c: /* SMSC */ 584b3667398Skettenis if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 585ce21cebcSderaadt (iicprobe(0x3f) == 0x69)) 586ce21cebcSderaadt name = "sch5027"; 587ce21cebcSderaadt else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 588b3667398Skettenis (iicprobe(0x3f) & 0xf0) == 0x60) 589e5888777Skettenis name = "emc6d100"; /* emc6d101, emc6d102, emc6d103 */ 590d3d6d5a2Skettenis else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 591d3d6d5a2Skettenis (iicprobe(0x3f) & 0xf0) == 0x80) 592d3d6d5a2Skettenis name = "sch5017"; 593d3d6d5a2Skettenis else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 594d3d6d5a2Skettenis (iicprobe(0x3f) & 0xf0) == 0xb0) 595d3d6d5a2Skettenis name = "emc6w201"; 5961719fadaSderaadt break; 5974c61b7c4Skettenis case 0x61: /* Andigilog */ 5984c61b7c4Skettenis if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 59975412184Scnst iicprobe(0x3f) == 0x69 && 60079d4b091Scnst iicprobe(0x22) >= 0xaf && /* Vdd */ 60175412184Scnst (iicprobe(0x09) & 0xbf) == 0x00 && iicprobe(0x0f) == 0x00 && 60275412184Scnst (iicprobe(0x40) & 0xf0) == 0x00) 60375412184Scnst name = "asc7611"; 60475412184Scnst else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 60579d4b091Scnst iicprobe(0x3f) == 0x6c && 60679d4b091Scnst iicprobe(0x22) >= 0xae) /* Vdd */ 6074c61b7c4Skettenis name = "asc7621"; 6084c61b7c4Skettenis break; 609a15c982aSkettenis case 0xa1: /* Philips */ 610a15c982aSkettenis if ((iicprobe(0x3f) & 0xf0) == 0x20 && 611a15c982aSkettenis (iicprobe(0x40) & 0x80) == 0x00 && 612a15c982aSkettenis (iicprobe(0x41) & 0xc0) == 0x00 && 613a15c982aSkettenis (iicprobe(0x42) & 0xbc) == 0x00) 614a15c982aSkettenis name = "ne1619"; /* adm1025 compat */ 61580c89fdcSderaadt break; 616b3667398Skettenis case 0xda: /* Dallas Semiconductor */ 61724b22cd5Sderaadt if (iicprobe(0x3f) == 0x01 && iicprobe(0x48) == addr && 61824b22cd5Sderaadt (iicprobe(0x40) & 0x80) == 0x00) 619933ace77Sderaadt name = "ds1780"; /* lm87 clones */ 6201719fadaSderaadt break; 6211719fadaSderaadt } 622b7b8e57cSkettenis 62324b22cd5Sderaadt switch (iicprobe(0x4e)) { 624b3667398Skettenis case 0x41: /* Analog Devices */ 6259cc05711Sderaadt if ((addr == 0x48 || addr == 0x4a || addr == 0x4b) && 62624b22cd5Sderaadt (iicprobe(0x4d) == 0x03 || iicprobe(0x4d) == 0x08 || 62724b22cd5Sderaadt iicprobe(0x4d) == 0x07)) 6289cc05711Sderaadt name = "adt7516"; /* adt7517, adt7519 */ 6299cc05711Sderaadt break; 6309cc05711Sderaadt } 6311719fadaSderaadt 632b7b8e57cSkettenis switch (iicprobe(0xfe)) { 633b7b8e57cSkettenis case 0x01: /* National Semiconductor */ 634b7b8e57cSkettenis if (addr == 0x4c && 6356991a698Skettenis iicprobe(0xff) == 0x41 && (iicprobe(0x03) & 0x18) == 0 && 6366991a698Skettenis iicprobe(0x04) <= 0x0f && (iicprobe(0xbf) & 0xf8) == 0) 6376991a698Skettenis name = "lm63"; 6386991a698Skettenis else if (addr == 0x4c && 639b7b8e57cSkettenis iicprobe(0xff) == 0x11 && (iicprobe(0x03) & 0x2a) == 0 && 640b7b8e57cSkettenis iicprobe(0x04) <= 0x09 && (iicprobe(0xbf) & 0xf8) == 0) 6413b5e26bdSderaadt name = "lm86"; 6426991a698Skettenis else if (addr == 0x4c && 643b7b8e57cSkettenis iicprobe(0xff) == 0x31 && (iicprobe(0x03) & 0x2a) == 0 && 644b7b8e57cSkettenis iicprobe(0x04) <= 0x09 && (iicprobe(0xbf) & 0xf8) == 0) 645b7b8e57cSkettenis name = "lm89"; /* or lm99 */ 646b7b8e57cSkettenis else if (addr == 0x4d && 647b7b8e57cSkettenis iicprobe(0xff) == 0x34 && (iicprobe(0x03) & 0x2a) == 0 && 648b7b8e57cSkettenis iicprobe(0x04) <= 0x09 && (iicprobe(0xbf) & 0xf8) == 0) 649b7b8e57cSkettenis name = "lm89-1"; /* or lm99-1 */ 650b7b8e57cSkettenis else if (addr == 0x4c && 651b7b8e57cSkettenis iicprobe(0xff) == 0x21 && (iicprobe(0x03) & 0x2a) == 0 && 652b7b8e57cSkettenis iicprobe(0x04) <= 0x09 && (iicprobe(0xbf) & 0xf8) == 0) 653b7b8e57cSkettenis name = "lm90"; 654b7b8e57cSkettenis break; 6557a7081baSkettenis case 0x23: /* Genesys Logic? */ 6567a7081baSkettenis if ((addr == 0x4c) && 6577a7081baSkettenis (iicprobe(0x03) & 0x3f) == 0x00 && iicprobe(0x04) <= 0x08) 6587a7081baSkettenis /* 6597a7081baSkettenis * Genesys Logic doesn't make the datasheet 660*9593dc34Smglocker * for the GL523SM publicly available, so 6617a7081baSkettenis * the checks above are nothing more than a 6627a7081baSkettenis * (conservative) educated guess. 6637a7081baSkettenis */ 6647a7081baSkettenis name = "gl523sm"; 6657a7081baSkettenis break; 666a15c982aSkettenis case 0x41: /* Analog Devices */ 667b7b8e57cSkettenis if ((addr == 0x4c || addr == 0x4d) && 668b7b8e57cSkettenis iicprobe(0xff) == 0x51 && 669b7b8e57cSkettenis (iicprobe(0x03) & 0x1f) == 0x04 && 670b7b8e57cSkettenis iicprobe(0x04) <= 0x0a) { 671b7b8e57cSkettenis /* If not in adm1032 compatibility mode. */ 672b7b8e57cSkettenis name = "adt7461"; 673b7b8e57cSkettenis } else if ((addr == 0x18 || addr == 0x19 || addr == 0x1a || 674b7b8e57cSkettenis addr == 0x29 || addr == 0x2a || addr == 0x2b || 675b7b8e57cSkettenis addr == 0x4c || addr == 0x4d || addr == 0x4e) && 676b7b8e57cSkettenis (iicprobe(0xff) & 0xf0) == 0x00 && 677b7b8e57cSkettenis (iicprobe(0x03) & 0x3f) == 0x00 && 678b7b8e57cSkettenis iicprobe(0x04) <= 0x07) { 679b7b8e57cSkettenis name = "adm1021"; 680e616dcecSderaadt skip_fc = 1; 681b3667398Skettenis } else if ((addr == 0x18 || addr == 0x19 || addr == 0x1a || 6828b568ffdSderaadt addr == 0x29 || addr == 0x2a || addr == 0x2b || 683b3667398Skettenis addr == 0x4c || addr == 0x4d || addr == 0x4e) && 684b7b8e57cSkettenis (iicprobe(0xff) & 0xf0) == 0x30 && 685b7b8e57cSkettenis (iicprobe(0x03) & 0x3f) == 0x00 && 686b7b8e57cSkettenis iicprobe(0x04) <= 0x07) { 687b7b8e57cSkettenis name = "adm1023"; /* or adm1021a */ 688e616dcecSderaadt skip_fc = 1; 689b7b8e57cSkettenis } else if ((addr == 0x4c || addr == 0x4d || addr == 0x4e) && 690b7b8e57cSkettenis (iicprobe(0x03) & 0x3f) == 0x00 && 691b7b8e57cSkettenis iicprobe(0x04) <= 0x0a) { 692b7b8e57cSkettenis name = "adm1032"; /* or adm1020 */ 693b7b8e57cSkettenis skip_fc = 1; 694b7b8e57cSkettenis } 69564146f5fSkettenis break; 6967a7081baSkettenis case 0x47: /* Global Mixed-mode Technology */ 6977a7081baSkettenis if (addr == 0x4c && iicprobe(0xff) == 0x01 && 6987a7081baSkettenis (iicprobe(0x03) & 0x3f) == 0x00 && iicprobe(0x04) <= 0x08) 6997a7081baSkettenis name = "g781"; 7007a7081baSkettenis if (addr == 0x4d && iicprobe(0xff) == 0x03 && 7017a7081baSkettenis (iicprobe(0x03) & 0x3f) == 0x00 && iicprobe(0x04) <= 0x08) 7027a7081baSkettenis name = "g781-1"; 7037a7081baSkettenis break; 704a15c982aSkettenis case 0x4d: /* Maxim */ 705a15c982aSkettenis if ((addr == 0x18 || addr == 0x19 || addr == 0x1a || 706a15c982aSkettenis addr == 0x29 || addr == 0x2a || addr == 0x2b || 707a15c982aSkettenis addr == 0x4c || addr == 0x4d || addr == 0x4e) && 708a15c982aSkettenis iicprobe(0xff) == 0x08 && (iicprobe(0x02) & 0x03) == 0 && 709a15c982aSkettenis (iicprobe(0x03) & 0x07) == 0 && iicprobe(0x04) <= 0x08) 710a15c982aSkettenis name = "max6690"; 711a15c982aSkettenis else if ((addr == 0x4c || addr == 0x4d || addr == 0x4e) && 712a15c982aSkettenis iicprobe(0xff) == 0x59 && (iicprobe(0x03) & 0x1f) == 0 && 713a15c982aSkettenis iicprobe(0x04) <= 0x07) 714a15c982aSkettenis name = "max6646"; /* max6647/8/9, max6692 */ 715a15c982aSkettenis else if ((addr == 0x4c || addr == 0x4d || addr == 0x4e) && 716a15c982aSkettenis (iicprobe(0x02) & 0x2b) == 0 && 717a15c982aSkettenis (iicprobe(0x03) & 0x0f) == 0 && iicprobe(0x04) <= 0x09) { 718a15c982aSkettenis name = "max6657"; /* max6658, max6659 */ 719a15c982aSkettenis skip_fc = 1; 720a15c982aSkettenis } else if ((addr >= 0x48 && addr <= 0x4f) && 721a15c982aSkettenis (iicprobe(0x02) & 0x2b) == 0 && 722a15c982aSkettenis (iicprobe(0x03) & 0x0f) == 0) 723a15c982aSkettenis name = "max6642"; 724a15c982aSkettenis break; 7254f5e1e1cSderaadt case 0x55: /* Texas Instruments */ 7264f5e1e1cSderaadt if (addr == 0x4c && iicprobe(0xff) == 0x11 && 7274f5e1e1cSderaadt (iicprobe(0x03) & 0x1b) == 0x00 && 7284f5e1e1cSderaadt (iicprobe(0x04) & 0xf0) == 0x00 && 7294f5e1e1cSderaadt (iicprobe(0x10) & 0x0f) == 0x00 && 7304f5e1e1cSderaadt (iicprobe(0x13) & 0x0f) == 0x00 && 7314f5e1e1cSderaadt (iicprobe(0x14) & 0x0f) == 0x00 && 7324f5e1e1cSderaadt (iicprobe(0x15) & 0x0f) == 0x00 && 7334f5e1e1cSderaadt (iicprobe(0x16) & 0x0f) == 0x00 && 7344f5e1e1cSderaadt (iicprobe(0x17) & 0x0f) == 0x00) 7354f5e1e1cSderaadt name = "tmp401"; 7364f5e1e1cSderaadt break; 737ab19912bSderaadt case 0xa1: 738ab19912bSderaadt if ((addr >= 0x48 && addr <= 0x4f) && 739ab19912bSderaadt iicprobe(0xff) == 0x00 && 740ab19912bSderaadt (iicprobe(0x03) & 0xf8) == 0x00 && 741ab19912bSderaadt iicprobe(0x04) <= 0x09) { 742ab19912bSderaadt name = "sa56004x"; /* NXP sa56004x */ 743ab19912bSderaadt skip_fc = 1; 744ab19912bSderaadt } 745ab19912bSderaadt break; 746b7b8e57cSkettenis } 747b7b8e57cSkettenis 748b7b8e57cSkettenis if (addr == iicprobe(0x48) && 74970eaf079Skettenis ((iicprobe(0x4f) == 0x5c && (iicprobe(0x4e) & 0x80)) || 75070eaf079Skettenis (iicprobe(0x4f) == 0xa3 && !(iicprobe(0x4e) & 0x80)))) { 751b486fbb1Sderaadt /* 752a1f396d4Sderaadt * We could toggle 0x4e bit 0x80, then re-read 0x4f to 753a1f396d4Sderaadt * see if the value changes to 0xa3 (indicating Winbond). 754a1f396d4Sderaadt * But we are trying to avoid writes. 755d60647f1Skettenis */ 75670eaf079Skettenis if ((iicprobe(0x4e) & 0x07) == 0) { 757d60647f1Skettenis switch (iicprobe(0x58)) { 758d60647f1Skettenis case 0x10: 759e3516dc3Skettenis case 0x11: /* rev 2? */ 760d60647f1Skettenis name = "w83781d"; 761d60647f1Skettenis break; 762d60647f1Skettenis case 0x21: 763d60647f1Skettenis name = "w83627hf"; 764d60647f1Skettenis break; 765d60647f1Skettenis case 0x30: 766d60647f1Skettenis name = "w83782d"; 767d60647f1Skettenis break; 768d60647f1Skettenis case 0x31: 769d60647f1Skettenis name = "as99127f"; /* rev 2 */ 770d60647f1Skettenis break; 771d60647f1Skettenis case 0x40: 772d60647f1Skettenis name = "w83783s"; 773d60647f1Skettenis break; 774d60647f1Skettenis case 0x71: 775d60647f1Skettenis name = "w83791d"; 776d60647f1Skettenis break; 7779cd4d9d7Skettenis case 0x72: 7789cd4d9d7Skettenis name = "w83791sd"; 7799cd4d9d7Skettenis break; 780d60647f1Skettenis case 0x7a: 781d60647f1Skettenis name = "w83792d"; 782d60647f1Skettenis break; 783abd5869cScnst case 0xc1: 784abd5869cScnst name = "w83627dhg"; 785abd5869cScnst break; 786d60647f1Skettenis } 78770eaf079Skettenis } else { 78870eaf079Skettenis /* 78970eaf079Skettenis * The BIOS left the chip in a non-zero 79070eaf079Skettenis * register bank. Assume it's a W83781D and 79170eaf079Skettenis * let lm(4) sort out the real model. 79270eaf079Skettenis */ 79370eaf079Skettenis name = "w83781d"; 79470eaf079Skettenis } 795cfcc5026Skettenis } else if (addr == (iicprobe(0xfc) & 0x7f) && 796cfcc5026Skettenis iicprobe(0xfe) == 0x79 && iicprobe(0xfb) == 0x51 && 797cfcc5026Skettenis ((iicprobe(0xfd) == 0x5c && (iicprobe(0x00) & 0x80)) || 798cfcc5026Skettenis (iicprobe(0xfd) == 0xa3 && !(iicprobe(0x00) & 0x80)))) { 799cfcc5026Skettenis /* 800cfcc5026Skettenis * We could toggle 0x00 bit 0x80, then re-read 0xfd to 801cfcc5026Skettenis * see if the value changes to 0xa3 (indicating Nuvoton). 802cfcc5026Skettenis * But we are trying to avoid writes. 803cfcc5026Skettenis */ 804cfcc5026Skettenis name = "w83795g"; 8059cd4d9d7Skettenis } else if (addr == iicprobe(0x4a) && iicprobe(0x4e) == 0x50 && 8069cd4d9d7Skettenis iicprobe(0x4c) == 0xa3 && iicprobe(0x4d) == 0x5c) { 8079cd4d9d7Skettenis name = "w83l784r"; 8089cd4d9d7Skettenis } else if (addr == 0x2d && iicprobe(0x4e) == 0x60 && 8099cd4d9d7Skettenis iicprobe(0x4c) == 0xa3 && iicprobe(0x4d) == 0x5c) { 8109cd4d9d7Skettenis name = "w83l785r"; 8112bc4c753Skettenis } else if (addr == 0x2e && iicprobe(0x4e) == 0x70 && 8129cd4d9d7Skettenis iicprobe(0x4c) == 0xa3 && iicprobe(0x4d) == 0x5c) { 813e737756fSkettenis name = "w83l785ts-l"; 814d58ac4cdScnst } else if (addr >= 0x2c && addr <= 0x2f && 8157c26d915Scnst ((iicprobe(0x00) & 0x07) != 0x0 || 8167c26d915Scnst ((iicprobe(0x00) & 0x07) == 0x0 && addr * 2 == iicprobe(0x0b) && 8177c26d915Scnst (iicprobe(0x0c) & 0x40) && !(iicprobe(0x0c) & 0x04))) && 818d58ac4cdScnst iicprobe(0x0e) == 0x7b && 8197c26d915Scnst (iicprobe(0x0f) & 0xf0) == 0x10 && 820d58ac4cdScnst ((iicprobe(0x0d) == 0x5c && (iicprobe(0x00) & 0x80)) || 821d58ac4cdScnst (iicprobe(0x0d) == 0xa3 && !(iicprobe(0x00) & 0x80)))) { 822d58ac4cdScnst name = "w83793g"; 8230c1990beSkettenis } else if (addr >= 0x28 && addr <= 0x2f && 82470eaf079Skettenis iicprobe(0x4f) == 0x12 && (iicprobe(0x4e) & 0x80)) { 825d60647f1Skettenis /* 826a1f396d4Sderaadt * We could toggle 0x4e bit 0x80, then re-read 0x4f to 827a1f396d4Sderaadt * see if the value changes to 0xc3 (indicating ASUS). 828a1f396d4Sderaadt * But we are trying to avoid writes. 829b486fbb1Sderaadt */ 83024b22cd5Sderaadt if (iicprobe(0x58) == 0x31) 831d60647f1Skettenis name = "as99127f"; /* rev 1 */ 832c09e2fbaSderaadt } else if ((addr == 0x2d || addr == 0x2e) && 833c09e2fbaSderaadt addr * 2 == iicprobe(0x04) && 834c09e2fbaSderaadt iicprobe(0x5d) == 0x19 && iicprobe(0x5e) == 0x34 && 835c09e2fbaSderaadt iicprobe(0x5a) == 0x03 && iicprobe(0x5b) == 0x06) { 836c09e2fbaSderaadt name = "f75375"; /* Fintek */ 837e19478bdSdjm } else if (addr == 0x2d && 838e19478bdSdjm ((iicprobe(0x4f) == 0x06 && (iicprobe(0x4e) & 0x80)) || 839e19478bdSdjm (iicprobe(0x4f) == 0x94 && !(iicprobe(0x4e) & 0x80)))) { 840e19478bdSdjm /* 841a1f396d4Sderaadt * We could toggle 0x4e bit 0x80, then re-read 0x4f to 842a1f396d4Sderaadt * see if the value changes to 0x94 (indicating ASUS). 843a1f396d4Sderaadt * But we are trying to avoid writes. 844e19478bdSdjm * 845e19478bdSdjm * NB. we won't match if the BIOS has selected a non-zero 846e19478bdSdjm * register bank (set via 0x4e). We could select bank 0 so 847a1f396d4Sderaadt * we see the right registers, but that would require a 848a1f396d4Sderaadt * write. In general though, we bet no BIOS would leave us 849a1f396d4Sderaadt * in the wrong state. 850e19478bdSdjm */ 851e19478bdSdjm if ((iicprobe(0x58) & 0x7f) == 0x31 && 852e19478bdSdjm (iicprobe(0x4e) & 0xf) == 0x00) 853e19478bdSdjm name = "asb100"; 854b3667398Skettenis } else if ((addr == 0x2c || addr == 0x2d) && 855b3667398Skettenis iicprobe(0x00) == 0x80 && 85642fb8b88Skettenis (iicprobe(0x01) == 0x00 || iicprobe(0x01) == 0x80) && 85742fb8b88Skettenis iicprobe(0x02) == 0x00 && (iicprobe(0x03) & 0x83) == 0x00 && 85842fb8b88Skettenis (iicprobe(0x0f) & 0x07) == 0x00 && 85942fb8b88Skettenis (iicprobe(0x11) & 0x80) == 0x00 && 86042fb8b88Skettenis (iicprobe(0x12) & 0x80) == 0x00) { 86142fb8b88Skettenis /* 86242fb8b88Skettenis * The GL518SM is really crappy. It has both byte and 86342fb8b88Skettenis * word registers, and reading a word register with a 86442fb8b88Skettenis * byte read command will make the device crap out and 86542fb8b88Skettenis * hang the bus. This has nasty consequences on some 86642fb8b88Skettenis * machines, like preventing warm reboots. The word 86742fb8b88Skettenis * registers are 0x07 through 0x0c, so make sure the 86842fb8b88Skettenis * checks above don't access those registers. We 86942fb8b88Skettenis * don't want to do this check right up front though 87042fb8b88Skettenis * since this chip is somewhat hard to detect (which 87142fb8b88Skettenis * is why we check for every single fixed bit it has). 87242fb8b88Skettenis */ 87342fb8b88Skettenis name = "gl518sm"; 874b3667398Skettenis } else if ((addr == 0x2c || addr == 0x2d || addr == 0x2e) && 875b3667398Skettenis iicprobe(0x16) == 0x41 && ((iicprobe(0x17) & 0xf0) == 0x40)) { 87680c89fdcSderaadt name = "adm1026"; 8771ab2fcb9Scnst } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x1131 && 878305d5022Sderaadt (iicprobew(0x07) & 0xfffc) == 0xa200) { 879305d5022Sderaadt name = "se97"; /* or se97b */ 8806869b31aSderaadt } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x1131 && 8813f8e4e1eSjsg (iicprobew(0x07) & 0xfffc) == 0xa100 && 8826869b31aSderaadt (iicprobew(0x00) & 0xfff0) == 0x0010) { 8836869b31aSderaadt name = "se98"; 8846869b31aSderaadt } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x004d && 8856869b31aSderaadt iicprobew(0x07) == 0x3e00 && 8866869b31aSderaadt (iicprobew(0x00) & 0xffe0) == 0x0000) { 8876869b31aSderaadt name = "max6604"; 8881ab2fcb9Scnst } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x0054 && 889462cb67aSjsg (iicprobew(0x07) & 0xfffc) == 0x0200 && 890462cb67aSjsg (iicprobew(0x00) & 0xffe0) == 0x0000) { 891462cb67aSjsg name = "mcp9804"; 892462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x0054 && 893305d5022Sderaadt (iicprobew(0x07) & 0xff00) == 0x0000 && 8947a2e6054Sderaadt (iicprobew(0x00) & 0xffe0) == 0x0000) { 895305d5022Sderaadt name = "mcp9805"; /* or mcp9843 */ 8961ab2fcb9Scnst } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x0054 && 8976869b31aSderaadt (iicprobew(0x07) & 0xfffc) == 0x2000 && 8984c930efaSderaadt (iicprobew(0x00) & 0xffe0) == 0x0000) { 8994c930efaSderaadt name = "mcp98242"; 9006869b31aSderaadt } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x0054 && 901305d5022Sderaadt (iicprobew(0x07) & 0xff00) == 0x2100 && 902a5f76fa9Sderaadt (iicprobew(0x00) & 0xff00) == 0x0000) { 9036869b31aSderaadt name = "mcp98243"; 904462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x0054 && 905462cb67aSjsg (iicprobew(0x07) & 0xfffc) == 0x2200 && 906462cb67aSjsg (iicprobew(0x00) & 0xff00) == 0x0000) { 907462cb67aSjsg name = "mcp98244"; 9081ab2fcb9Scnst } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x11d4 && 9096869b31aSderaadt iicprobew(0x07) == 0x0800 && 910e5f96281Sderaadt iicprobew(0x00) == 0x001d) { 911e5f96281Sderaadt name = "adt7408"; 9121ab2fcb9Scnst } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x104a && 913273857bcSderaadt (iicprobew(0x07) & 0xfffe) == 0x0000 && 9145061e512Sderaadt (iicprobew(0x00) == 0x002d || iicprobew(0x00) == 0x002f)) { 915273857bcSderaadt name = "stts424e02"; 9166869b31aSderaadt } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x104a && 917305d5022Sderaadt (iicprobew(0x07) & 0xfffe) == 0x0300 && 918305d5022Sderaadt (iicprobew(0x00) == 0x006f)) { 919305d5022Sderaadt name = "stts2002"; 920305d5022Sderaadt } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x104a && 921462cb67aSjsg (iicprobew(0x07) & 0xffff) == 0x2201 && 922462cb67aSjsg (iicprobew(0x00) == 0x00ef)) { 923462cb67aSjsg name = "stts2004"; 924462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x104a && 925462cb67aSjsg (iicprobew(0x07) & 0xffff) == 0x0200 && 926462cb67aSjsg (iicprobew(0x00) == 0x006f)) { 927462cb67aSjsg name = "stts3000"; 928462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x104a && 9293f8e4e1eSjsg (iicprobew(0x07) & 0xffff) == 0x0101 && 9306869b31aSderaadt (iicprobew(0x00) == 0x002d || iicprobew(0x00) == 0x002f)) { 9316869b31aSderaadt name = "stts424"; 9321ab2fcb9Scnst } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x1b09 && 93370281b6fScnst (iicprobew(0x07) & 0xffe0) == 0x0800 && 934305d5022Sderaadt (iicprobew(0x00) & 0x001f) == 0x001f) { 935305d5022Sderaadt name = "cat34ts02"; /* or cat6095, prod 0x0813 */ 936462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x1b09 && 937462cb67aSjsg (iicprobew(0x07) & 0xffff) == 0x0a00 && 938462cb67aSjsg (iicprobew(0x00) & 0x001f) == 0x001f) { 939462cb67aSjsg name = "cat34ts02c"; 9400bd5d415Sjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x1b09 && 9410bd5d415Sjsg (iicprobew(0x07) & 0xffff) == 0x2200 && 9420bd5d415Sjsg (iicprobew(0x00) == 0x007f)) { 9430bd5d415Sjsg name = "cat34ts04"; 944305d5022Sderaadt } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x00b3 && 945305d5022Sderaadt (iicprobew(0x07) & 0xffff) == 0x2903 && 946305d5022Sderaadt (iicprobew(0x00) == 0x004f)) { 947305d5022Sderaadt name = "ts3000b3"; /* or tse2002b3 */ 948462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x00b3 && 949462cb67aSjsg (iicprobew(0x07) & 0xffff) == 0x2912 && 950462cb67aSjsg (iicprobew(0x00) == 0x006f)) { 951462cb67aSjsg name = "ts3000gb2"; /* or tse2002gb2 */ 952462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x00b3 && 953462cb67aSjsg (iicprobew(0x07) & 0xffff) == 0x2913 && 954462cb67aSjsg (iicprobew(0x00) == 0x0077)) { 955462cb67aSjsg name = "ts3000gb0"; 956462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x00b3 && 957462cb67aSjsg (iicprobew(0x07) & 0xffff) == 0x3001 && 958462cb67aSjsg (iicprobew(0x00) == 0x006f)) { 959462cb67aSjsg name = "ts3001gb2"; 9600bd5d415Sjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x00b3 && 9610bd5d415Sjsg (iicprobew(0x07) & 0xffff) == 0x2214 && 9620bd5d415Sjsg (iicprobew(0x00) == 0x00ff)) { 9630bd5d415Sjsg name = "tse2004gb2"; 964462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x001f && 965462cb67aSjsg (iicprobew(0x07) & 0xffff) == 0x8201 && 966462cb67aSjsg (iicprobew(0x00) & 0xff00) == 0x0000) { 967462cb67aSjsg name = "at30ts00"; /* or at30tse002 */ 968462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x1114 && 969462cb67aSjsg (iicprobew(0x07) & 0xffff) == 0x2200 && 970462cb67aSjsg (iicprobew(0x00) & 0xff00) == 0x0000) { 971462cb67aSjsg name = "at30tse004"; 972462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x1c68 && 973462cb67aSjsg (iicprobew(0x07) & 0xffff) == 0x2201 && 974462cb67aSjsg (iicprobew(0x00) & 0xff00) == 0x0000) { 975462cb67aSjsg name = "gt30ts00"; 976462cb67aSjsg } else if ((addr & 0x78) == 0x18 && iicprobew(0x06) == 0x132d && 977462cb67aSjsg (iicprobew(0x07) & 0xffff) == 0x3300 && 978462cb67aSjsg (iicprobew(0x00) & 0x001f) == 0x001f) { 979462cb67aSjsg name = "gt34ts02"; 980143beb10Scnst } else if ((addr & 0x7e) == 0x1c && iicprobe(0x0f) == 0x3b && 981143beb10Scnst (iicprobe(0x21) & 0x60) == 0x00 && 982143beb10Scnst iicprobe(0x0f) == iicprobe(0x8f) && /* registers address is 7 bits */ 983143beb10Scnst iicprobe(0x20) == iicprobe(0xa0) && 984143beb10Scnst iicprobe(0x21) == iicprobe(0xa1) && 985143beb10Scnst iicprobe(0x22) == iicprobe(0xa2) && 986143beb10Scnst iicprobe(0x07) == 0x00) { /* 0x00 to 0x0e are reserved */ 987143beb10Scnst name = "lis331dl"; 988b3667398Skettenis } else if (name == NULL && 9899ef2fefcSderaadt (addr & 0x78) == 0x48) { /* addr 0b1001xxx */ 990010c3e6aSderaadt name = lm75probe(); 9917535fb6fSderaadt } 992d5a0db9eSkettenis #if 0 993d5a0db9eSkettenis /* 994d5a0db9eSkettenis * XXX This probe needs to be improved; the driver does some 995d5a0db9eSkettenis * dangerous writes. 996d5a0db9eSkettenis */ 997b3667398Skettenis if (name == NULL && (addr & 0x7c) == 0x48 && /* addr 0b1001xxx */ 9987535fb6fSderaadt (iicprobew(0xaa) & 0x0007) == 0x0000 && 9997535fb6fSderaadt (iicprobew(0xa1) & 0x0007) == 0x0000 && 10007535fb6fSderaadt (iicprobew(0xa2) & 0x0007) == 0x0000 && 10017535fb6fSderaadt (iicprobe(0xac) & 0x10) == 0x00) { 10027535fb6fSderaadt if ((iicprobe(0xac) & 0x7e) == 0x0a && 10037535fb6fSderaadt iicprobe(0xab) == 0x00 && iicprobe(0xa8) == 0x00) 100465b3882dSderaadt name = "ds1624"; 10057535fb6fSderaadt else if ((iicprobe(0xac) & 0x7e) == 0x0c) 10067535fb6fSderaadt name = "ds1631"; /* terrible probe */ 1007a7654efdSderaadt else if ((iicprobe(0xac) & 0x2e) == 0x2e) 10087535fb6fSderaadt name = "ds1721"; /* terrible probe */ 1009010c3e6aSderaadt } 1010d5a0db9eSkettenis #endif 10117540d812Sderaadt if (name == NULL && (addr & 0xf8) == 0x28 && iicprobe(0x48) == addr && 10127540d812Sderaadt (iicprobe(0x00) & 0x90) == 0x10 && iicprobe(0x58) == 0x90) { 10137540d812Sderaadt if (iicprobe(0x5b) == 0x12) 10147540d812Sderaadt name = "it8712"; 10157540d812Sderaadt else if (iicprobe(0x5b) == 0x00) 101625f3e8a5Sderaadt name = "it8712f-a"; /* sis950 too */ 10177540d812Sderaadt } 10187540d812Sderaadt 1019b35edbb1Skettenis if (name == NULL && iicprobe(0x48) == addr && 1020b35edbb1Skettenis (iicprobe(0x40) & 0x80) == 0x00 && iicprobe(0x58) == 0xac) 1021b35edbb1Skettenis name = "mtp008"; 1022b35edbb1Skettenis 1023010c3e6aSderaadt if (name == NULL) { 10245f31ae5bSkettenis name = adm1032cloneprobe(addr); 1025e616dcecSderaadt if (name) 1026e616dcecSderaadt skip_fc = 1; 102774ce0e42Sderaadt } 10284e1e7e6eSderaadt 102922ef5474Sderaadt return (name); 103022ef5474Sderaadt } 103122ef5474Sderaadt 103222ef5474Sderaadt char * 10331c658e45Scnst iic_probe_eeprom(struct device *self, u_int8_t addr) 103422ef5474Sderaadt { 1035dfbc0705Sjsg u_int8_t type; 103622ef5474Sderaadt char *name = NULL; 103722ef5474Sderaadt 1038dfbc0705Sjsg type = iicprobe(0x02); 1039dfbc0705Sjsg /* limit to SPD types seen in the wild */ 104061624148Sclaudio if (type < 4 || type > 16) 104147be2d17Sjsg return (name); 104247be2d17Sjsg 1043dfbc0705Sjsg /* more matching in driver(s) */ 1044dfbc0705Sjsg name = "eeprom"; 104522ef5474Sderaadt 104622ef5474Sderaadt return (name); 104747098ca3Sderaadt } 1048941c1a56Sderaadt 10491165b4a3Sgrange void 10501165b4a3Sgrange iic_scan(struct device *self, struct i2cbus_attach_args *iba) 10511165b4a3Sgrange { 10521165b4a3Sgrange i2c_tag_t ic = iba->iba_tag; 105322ef5474Sderaadt struct i2c_attach_args ia; 105422ef5474Sderaadt struct iicprobelist *pl; 105548a89adfSderaadt u_int8_t cmd = 0, addr; 105622ef5474Sderaadt char *name; 1057717c6620Scnst int i, j, k; 10581165b4a3Sgrange 1059b8fabd7dSderaadt bzero(ignore_addrs, sizeof(ignore_addrs)); 106022ef5474Sderaadt 106122ef5474Sderaadt for (i = 0; probes[i].probe; i++) { 10622349585bSderaadt #if NIPMI > 0 10632349585bSderaadt extern int ipmi_enabled; 10642349585bSderaadt 10652349585bSderaadt if ((probes[i].flags & PFLAG_SENSOR) && ipmi_enabled) { 10662349585bSderaadt printf("%s: skipping sensors to avoid ipmi0 interactions\n", 10672349585bSderaadt self->dv_xname); 10682349585bSderaadt continue; 10692349585bSderaadt } 10702349585bSderaadt #endif 107122ef5474Sderaadt pl = probes[i].pl; 107222ef5474Sderaadt for (j = 0; pl[j].start && pl[j].end; j++) { 107322ef5474Sderaadt for (addr = pl[j].start; addr <= pl[j].end; addr++) { 1074717c6620Scnst for (k = 0; k < sizeof(ignore_addrs); k++) 1075717c6620Scnst if (ignore_addrs[k] == addr) 107631309405Scnst break; 107731309405Scnst if (k < sizeof(ignore_addrs)) 1078717c6620Scnst continue; 1079717c6620Scnst 1080941c1a56Sderaadt /* Perform RECEIVE BYTE command */ 1081a5d919cdSgrange iic_acquire_bus(ic, 0); 1082643d52faSgrange if (iic_exec(ic, I2C_OP_READ_WITH_STOP, addr, 108391eacc75Sderaadt &cmd, sizeof cmd, NULL, 0, 0) == 0) { 1084a5d919cdSgrange iic_release_bus(ic, 0); 108547098ca3Sderaadt 108622ef5474Sderaadt /* Some device exists */ 108722ef5474Sderaadt iicprobeinit(iba, addr); 10881c658e45Scnst name = (*probes[i].probe)(self, addr); 1089d70d6113Scnst #ifndef I2C_VERBOSE 1090d70d6113Scnst if (name == NULL) 1091d70d6113Scnst name = "unknown"; 1092d70d6113Scnst #endif /* !I2C_VERBOSE */ 109322ef5474Sderaadt if (name) { 109422ef5474Sderaadt memset(&ia, 0, sizeof(ia)); 109522ef5474Sderaadt ia.ia_tag = iba->iba_tag; 109622ef5474Sderaadt ia.ia_addr = addr; 109722ef5474Sderaadt ia.ia_size = 1; 109822ef5474Sderaadt ia.ia_name = name; 1099d70d6113Scnst if (config_found(self, 1100d70d6113Scnst &ia, iic_print)) 1101d70d6113Scnst continue; 11021165b4a3Sgrange } 1103d70d6113Scnst #ifdef I2C_VERBOSE 1104ae06ac7aSderaadt if ((probes[i].flags & PFLAG_SENSOR)) 1105d70d6113Scnst iic_dump(self, addr, name); 1106d70d6113Scnst #endif /* I2C_VERBOSE */ 110722ef5474Sderaadt } else 1108a5d919cdSgrange iic_release_bus(ic, 0); 11091165b4a3Sgrange } 1110941c1a56Sderaadt } 11111165b4a3Sgrange } 111222ef5474Sderaadt } 1113